@01.software/sdk 0.73.1 → 0.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +30 -3
  3. package/dist/client.cjs +12 -9
  4. package/dist/client.cjs.map +1 -1
  5. package/dist/client.d.cts +6 -6
  6. package/dist/client.d.ts +6 -6
  7. package/dist/client.js +12 -9
  8. package/dist/client.js.map +1 -1
  9. package/dist/{collection-client-BH4dIZ6c.d.cts → collection-client-Bb1Wa6T6.d.cts} +4 -4
  10. package/dist/{collection-client-lLAl3xCZ.d.ts → collection-client-DBrLM9RR.d.ts} +4 -4
  11. package/dist/{const-CCvoknRY.d.ts → const-CkY2zB6J.d.ts} +1 -1
  12. package/dist/{const-BS2EaIp4.d.cts → const-DWTSgCkn.d.cts} +1 -1
  13. package/dist/{index-DVqNpmsc.d.ts → index-Daoh-98A.d.ts} +3 -3
  14. package/dist/{index-CHdrzJ8-.d.cts → index-Di5AybQN.d.cts} +3 -3
  15. package/dist/index.cjs +12 -9
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +7 -7
  18. package/dist/index.d.ts +7 -7
  19. package/dist/index.js +12 -9
  20. package/dist/index.js.map +1 -1
  21. package/dist/{payload-types-PXkmefhZ.d.cts → payload-types-zukuL1s_.d.cts} +345 -1755
  22. package/dist/{payload-types-PXkmefhZ.d.ts → payload-types-zukuL1s_.d.ts} +345 -1755
  23. package/dist/query.cjs +4 -0
  24. package/dist/query.cjs.map +1 -1
  25. package/dist/query.d.cts +5 -5
  26. package/dist/query.d.ts +5 -5
  27. package/dist/query.js +4 -0
  28. package/dist/query.js.map +1 -1
  29. package/dist/realtime.d.cts +2 -2
  30. package/dist/realtime.d.ts +2 -2
  31. package/dist/server.cjs +12 -9
  32. package/dist/server.cjs.map +1 -1
  33. package/dist/server.d.cts +7 -7
  34. package/dist/server.d.ts +7 -7
  35. package/dist/server.js +12 -9
  36. package/dist/server.js.map +1 -1
  37. package/dist/{types-CyMz0Kzc.d.cts → types-BI7aowdu.d.cts} +4 -4
  38. package/dist/{types-lbzbJSZh.d.ts → types-BsJokT6P.d.ts} +59 -16
  39. package/dist/{types-CQRsG6sA.d.ts → types-SsS04wGw.d.ts} +4 -4
  40. package/dist/{types-Chwgg4CQ.d.cts → types-evAvqRBj.d.cts} +59 -16
  41. package/dist/ui/form.d.cts +1 -1
  42. package/dist/ui/form.d.ts +1 -1
  43. package/dist/ui/video.d.cts +1 -1
  44. package/dist/ui/video.d.ts +1 -1
  45. package/dist/webhook.d.cts +5 -5
  46. package/dist/webhook.d.ts +5 -5
  47. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/core/internal/utils/credentials.ts","../src/core/internal/utils/api-url.ts","../src/core/internal/utils/http.ts","../src/core/internal/utils/query-string.ts","../src/core/api/parse-response.ts","../../../internal/http-contracts/src/index.ts","../src/core/api/endpoints.ts","../src/core/api/customer-scoped-api.ts","../src/core/api/benefit-voucher-types.ts","../src/core/api/customer-benefit-vouchers-api.ts","../src/core/api/customer-credit-types.ts","../src/core/api/customer-credits-api.ts","../src/core/collection/http-client.ts","../src/utils/types.ts","../src/core/collection/query-builder.ts","../src/core/collection/collection-client.ts","../src/core/community/community-client.ts","../src/core/content/content-client.ts","../src/core/api/canonical-response.ts","../src/core/customer/customer-auth.ts","../src/core/customer/customer-oauth.ts","../src/core/customer/customer-namespace.ts","../src/core/api/commerce-idempotency.ts","../src/core/api/cart-api.ts","../src/core/api/checkout-api.ts","../src/core/api/payment-session-api.ts","../src/utils/product-selection-media.ts","../src/utils/ecommerce.ts","../src/core/api/product-api.ts","../src/core/commerce/commerce-client.ts","../src/core/events/events-client.ts","../src/core/market/market-discovery.ts","../src/core/client/client.ts","../src/core/commerce/merge-catalog-stock.ts","../src/core/webhook/validation.ts","../src/core/webhook/receiver.ts","../src/core/webhook/index.ts","../src/core/collection/const.ts","../src/core/query/realtime.ts","../src/utils/image.ts","../src/utils/order/generateOrderNumber.ts","../src/utils/order/formatOrderName.ts","../src/utils/video.ts"],"sourcesContent":["import type { ClientConfig, RootClientWithEvents } from './core/client/types'\nimport { createClient as createClientInternal } from './core/client/client'\n\n// Public domain types\nexport type {\n Article,\n ArticleAuthor,\n ArticleCategory,\n ArticleTag,\n Image,\n Post,\n PostCategory,\n Video,\n Tenant,\n Document,\n} from './payload-types'\n\n// Core browser-safe SDK\nexport function createClient(options: ClientConfig): RootClientWithEvents {\n return createClientInternal(options) as RootClientWithEvents\n}\n\nexport type {\n ApiQueryOptions,\n ClientConfig,\n ClientMetadata,\n ClientState,\n Collection,\n DebugConfig,\n DeepPartial,\n ExtractArrayType,\n PayloadFindResponse,\n PayloadMutationResponse,\n PublicReadQueryOptions,\n PublicCollection,\n RootCollectionClient,\n RootClient as Client,\n RootClient as ClientType,\n RootClient,\n RootClientWithEvents,\n RootReadOnlyQueryBuilder,\n RetryConfig,\n Sort,\n Where,\n} from './core/client/types'\nexport type {\n CollectionType,\n PublicMarket as Market,\n PublicProduct as Product,\n PublicProductCollection as ProductCollection,\n PublicProductVariant as ProductVariant,\n} from './core/collection/types'\nexport type { MarketDTO } from './core/market/market-discovery'\nexport * from './core/api'\nexport { CommerceClient } from './core/commerce/commerce-client'\nexport type { CommerceClientOptions } from './core/commerce/commerce-client'\nexport {\n mergeProductDetailWithStock,\n type MergedProductDetailResult,\n type ProductDetailStockMergeStatus,\n} from './core/commerce/merge-catalog-stock'\nexport { CommunityClient } from './core/community/community-client'\nexport type {\n CommunityClientOptions,\n CommunityComment,\n CommunityCommentListSort,\n CommunityPost,\n CommunityPostCategory,\n CommunityPostListSort,\n CommunityPublicAuthorSnapshot,\n CommunityPublicMediaAsset,\n CommunityPublicReference,\n CommunityPostTag,\n Comment,\n} from './core/community/community-client'\nexport { ContentClient } from './core/content/content-client'\nexport type {\n ContentClientOptions,\n StorefrontContentListOptions,\n StorefrontContentReference,\n StorefrontGalleryItem,\n StorefrontGalleryItemsListOptions,\n StorefrontGalleryItemsSort,\n StorefrontLink,\n StorefrontLinksListOptions,\n StorefrontLinksSort,\n} from './core/content/content-client'\nexport { EventsClient } from './core/events/events-client'\nexport type { VideoPlaybackResponse } from './core/video/video-playback-client'\nexport type {\n EventAdmissionAvailabilityParams,\n EventAdmissionAvailabilityResponse,\n EventAdmissionAvailabilityType,\n EventAdmissionPricePresentment,\n EventMyRegistration,\n EventMyRegistrationsParams,\n EventMyRegistrationsResponse,\n EventGuestCancelParams,\n EventGuestRegistration,\n EventGuestRegistrationResponse,\n EventRegistrationAnswerInput,\n EventRegistrationAttendeeInput,\n EventRegistrationPublic,\n EventRegistrationRegisterParams,\n EventRegistrationRegisterResponse,\n EventsCalendarItem,\n EventsClientOptions,\n EventsDateParam,\n EventsExternalSource,\n EventsLocation,\n EventsOccurrenceLocation,\n EventsRangeEvent,\n EventsRangeOccurrence,\n EventsRangeParams,\n EventsRangeResponse,\n EventsTaxonomyItem,\n} from './core/events/events-client'\nexport * from './core/customer'\nexport * from './core/webhook'\nexport {\n COLLECTIONS,\n INTERNAL_COLLECTIONS,\n SERVER_COLLECTIONS,\n SERVER_ONLY_COLLECTIONS,\n} from './core/collection/const'\nexport {\n RealtimeConnection,\n type RealtimeEvent,\n type RealtimeListener,\n} from './core/query/realtime'\n\n// Utils\nexport * from './utils'\n\n// Errors\nexport {\n SDKError,\n NetworkError,\n ValidationError,\n ApiError,\n ConfigError,\n TimeoutError,\n GoneError,\n ServiceUnavailableError,\n UsageLimitError,\n AuthError,\n PermissionError,\n NotFoundError,\n ConflictError,\n RateLimitError,\n COMMERCE_ERROR_CODES,\n type CommerceErrorCode,\n type CommerceSDKError,\n isSDKError,\n isNetworkError,\n isValidationError,\n isApiError,\n isConfigError,\n isTimeoutError,\n isGoneError,\n isServiceUnavailableError,\n isUsageLimitError,\n isAuthError,\n isPermissionError,\n isNotFoundError,\n isConflictError,\n isRateLimitError,\n isCommerceSDKError,\n getSDKErrorReason,\n createAuthError,\n createPermissionError,\n createNotFoundError,\n createConflictError,\n createRateLimitError,\n} from './errors'\n\nexport type { BenefitVouchersApi } from './core/api/benefit-vouchers-api'\nexport type { CreditsApi } from './core/api/credits-api'\nexport type * from './core/api/customer-credit-types'\nexport type * from './core/api/benefit-voucher-types'\n","const SDK_ERROR_BRAND = Symbol.for('@01.software/sdk/SDKError')\nconst SDK_ERROR_TYPE_BRAND = Symbol.for('@01.software/sdk/SDKError.type')\n\ntype SDKErrorType =\n | 'NetworkError'\n | 'ValidationError'\n | 'ApiError'\n | 'ConfigError'\n | 'TimeoutError'\n | 'GoneError'\n | 'ServiceUnavailableError'\n | 'UsageLimitError'\n | 'AuthError'\n | 'PermissionError'\n | 'NotFoundError'\n | 'ConflictError'\n | 'RateLimitError'\n\nfunction defineSDKErrorBrand(error: SDKError): void {\n Object.defineProperty(error, SDK_ERROR_BRAND, {\n value: true,\n enumerable: false,\n configurable: false,\n writable: false,\n })\n}\n\nfunction defineSDKErrorType(error: SDKError, type: SDKErrorType): void {\n Object.defineProperty(error, SDK_ERROR_TYPE_BRAND, {\n value: type,\n enumerable: false,\n configurable: false,\n writable: false,\n })\n}\n\nexport class SDKError extends Error {\n readonly code: string\n readonly status?: number\n readonly details?: unknown\n readonly userMessage?: string\n readonly suggestion?: string\n readonly requestId?: string\n readonly kind?: 'commerce'\n readonly reason?: CommerceErrorCode | 'unknown_commerce_error'\n readonly rawReason?: string\n /** Machine-readable reason from a non-commerce API response. */\n readonly apiReason?: string\n readonly retryable?: boolean\n readonly retryAfter?: number\n\n constructor(\n code: string,\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(message)\n this.name = 'SDKError'\n this.code = code\n this.status = status\n this.details = details\n this.userMessage = userMessage\n this.suggestion = suggestion\n this.requestId = requestId\n defineSDKErrorBrand(this)\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, new.target)\n }\n }\n\n getUserMessage(): string {\n return this.userMessage || this.message\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n status: this.status,\n details: this.details,\n userMessage: this.userMessage,\n suggestion: this.suggestion,\n ...(this.requestId !== undefined && { requestId: this.requestId }),\n ...(this.kind !== undefined && { kind: this.kind }),\n ...(this.reason !== undefined && { reason: this.reason }),\n ...(this.rawReason !== undefined && { rawReason: this.rawReason }),\n ...(this.apiReason !== undefined && { apiReason: this.apiReason }),\n ...(this.retryable !== undefined && { retryable: this.retryable }),\n ...(this.retryAfter !== undefined && { retryAfter: this.retryAfter }),\n }\n }\n}\n\n/**\n * Canonical Cart/Checkout/PaymentSession error reasons. This public SDK mirror\n * intentionally does not import the private contracts package; parity is\n * enforced by a type test.\n */\nexport const COMMERCE_ERROR_CODES = [\n 'validation_failed',\n 'bad_request',\n 'unauthorized',\n 'forbidden',\n 'account_suspended',\n 'key_invalid',\n 'pat_tenant_header_forbidden',\n 'tenant_mismatch',\n 'test_tenant_expired',\n 'token_invalid',\n 'token_expired',\n 'origin_not_allowed',\n 'server_credentials_required',\n 'role_denied',\n 'scope_denied',\n 'feature_disabled',\n 'not_found',\n 'conflict',\n 'locked',\n 'cart_revision_conflict',\n 'rate_limit_exceeded',\n 'usage_limit_exceeded',\n 'service_unavailable',\n 'idempotency_conflict',\n 'idempotency_in_progress',\n 'idempotency_key_required',\n 'invalid_idempotency_key',\n 'cart_not_active',\n 'cart_locked',\n 'cart_empty',\n 'shipping_address_required',\n 'cart_market_unavailable',\n 'cart_market_mismatch',\n 'checkout_not_open',\n 'checkout_already_open',\n 'payment_slot_held',\n 'reservation_expired',\n 'payment_session_not_cancelable',\n 'payment_session_conflict',\n 'provider_identity_mismatch',\n 'managed_refund_attestation_forbidden',\n 'payment_method_unavailable',\n 'provider_unavailable',\n 'lock_timeout',\n 'price_changed',\n 'pricing_fact_in_use',\n 'insufficient_stock',\n 'credit_insufficient',\n 'reservation_conflict',\n 'stock_lock_unavailable',\n 'variant_not_found',\n 'variant_stock_write_failed',\n 'stock_invariant_violation',\n 'payment_confirmation_in_flight',\n 'checkout_reservation_release_requires_transaction',\n 'admission_metadata_invalid',\n 'admission_metadata_required',\n 'admission_not_eligible',\n 'admission_eligibility_unavailable',\n 'admission_authority_unavailable',\n 'admission_customer_binding_required',\n 'admission_eligibility_unproven',\n 'capacity_exceeded',\n 'admission_required',\n 'occurrence_lock_unavailable',\n 'occurrence_not_open',\n 'admission_type_capacity_exceeded',\n 'admission_type_occurrence_mismatch',\n 'admission_hold_expired',\n 'admission_hold_checkout_item_conflict',\n 'admission_hold_checkout_conflict',\n 'admission_hold_quantity_mismatch',\n 'admission_hold_unbound',\n 'admission_hold_missing',\n 'admission_hold_checkout_item_missing',\n 'admission_hold_expiry_failed',\n 'admission_hold_expiry_requires_transaction',\n 'admission_hold_line_item_mismatch',\n 'admission_materialization_failed',\n 'variant_inactive',\n 'variant_product_mismatch',\n 'product_not_public',\n 'product_not_eligible',\n 'purchase_limit_exceeded',\n 'market_not_found',\n 'market_shipping_currency_unsupported',\n 'missing_market_rate',\n 'missing_shipping_amount',\n 'no_enabled_payment_provider',\n 'product_market_unavailable',\n 'unsupported_currency',\n 'missing_price_row',\n 'payment_provider_currency_unsupported',\n 'discount_code_not_found',\n 'discount_not_started',\n 'discount_expired',\n 'discount_usage_limit',\n 'discount_per_customer_limit',\n 'discount_customer_required',\n 'discount_first_order_only',\n 'discount_customer_not_eligible',\n 'discount_customer_excluded',\n 'discount_items_required',\n 'discount_product_not_eligible',\n 'discount_product_excluded',\n 'discount_min_order_amount',\n 'discount_currency_scope_required',\n 'discount_allocation_method_unsupported',\n 'currency_mismatch',\n 'customer_token_required',\n 'market_required',\n 'server_derived',\n 'internal_error',\n] as const\n\nexport type CommerceErrorCode = (typeof COMMERCE_ERROR_CODES)[number]\n\ntype CommerceSDKErrorBase = SDKError & {\n readonly kind: 'commerce'\n readonly requestId: string\n readonly retryable: boolean\n readonly retryAfter?: number\n readonly details?: Record<string, unknown>\n}\n\nexport type CommerceSDKError = CommerceSDKErrorBase &\n (\n | { readonly reason: CommerceErrorCode; readonly rawReason?: never }\n | {\n readonly reason: 'unknown_commerce_error'\n readonly rawReason: string\n }\n )\n\nconst COMMERCE_ERROR_CODE_SET: ReadonlySet<string> = new Set(\n COMMERCE_ERROR_CODES,\n)\nconst COMMERCE_ERROR_ENVELOPE_KEYS = new Set([\n 'error',\n 'reason',\n 'requestId',\n 'retryable',\n 'details',\n])\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport type CommerceErrorEnvelope = {\n error: string\n reason: string\n requestId: string\n retryable: boolean\n details?: Record<string, unknown>\n}\n\nfunction commerceProtocolError(\n issue: string,\n trustedRequestId?: string,\n): SDKError {\n return createApiError(\n 'Invalid canonical commerce error response.',\n 502,\n { protocol: 'commerce-error-envelope', issue },\n 'The server returned an incompatible commerce error response.',\n 'Verify that the Console commerce contract is deployed before using this SDK version.',\n trustedRequestId,\n )\n}\n\n/** @internal Strictly parse a canonical commerce error without retaining its raw body. */\nexport function parseCommerceErrorEnvelope(\n body: unknown,\n headerRequestId?: string,\n): CommerceErrorEnvelope {\n if (headerRequestId === undefined) {\n throw commerceProtocolError('missing_request_id_header')\n }\n if (headerRequestId.length === 0) {\n throw commerceProtocolError('empty_request_id_header')\n }\n if (!isPlainRecord(body)) {\n throw commerceProtocolError('expected_object', headerRequestId)\n }\n if (Object.keys(body).some((key) => !COMMERCE_ERROR_ENVELOPE_KEYS.has(key))) {\n throw commerceProtocolError('unexpected_field', headerRequestId)\n }\n if (\n typeof body.error !== 'string' ||\n body.error.length === 0 ||\n typeof body.reason !== 'string' ||\n body.reason.length === 0 ||\n typeof body.requestId !== 'string' ||\n body.requestId.length === 0 ||\n (body.retryable !== undefined && typeof body.retryable !== 'boolean') ||\n (body.details !== undefined && !isPlainRecord(body.details))\n ) {\n throw commerceProtocolError('invalid_field', headerRequestId)\n }\n\n if (headerRequestId !== undefined && headerRequestId !== body.requestId) {\n throw commerceProtocolError('request_id_mismatch', headerRequestId)\n }\n\n return {\n error: body.error,\n reason: body.reason,\n requestId: body.requestId,\n retryable: body.retryable === true,\n ...(body.details === undefined ? {} : { details: body.details }),\n }\n}\n\n/** @internal Validate and apply the canonical commerce error envelope. */\nexport function enhanceCommerceError(\n error: SDKError,\n body: unknown,\n headerRequestId?: string,\n): SDKError {\n const envelope = parseCommerceErrorEnvelope(body, headerRequestId)\n\n const known = COMMERCE_ERROR_CODE_SET.has(envelope.reason)\n Object.assign(error, {\n code: envelope.reason,\n kind: 'commerce' as const,\n reason: known\n ? (envelope.reason as CommerceErrorCode)\n : 'unknown_commerce_error',\n ...(known ? {} : { rawReason: envelope.reason }),\n requestId: envelope.requestId,\n retryable: envelope.retryable,\n details: envelope.details,\n })\n return error\n}\n\n/** @internal Apply a non-commerce reason without canonical-commerce validation. */\nexport function enhanceNonCommerceError(\n error: SDKError,\n reason: unknown,\n): SDKError {\n if (typeof reason === 'string') Object.assign(error, { apiReason: reason })\n return error\n}\n\n/**\n * Read the server-provided machine reason across strict commerce and\n * non-commerce SDK errors. Unknown commerce reasons are returned verbatim.\n */\nexport function getSDKErrorReason(error: SDKError): string | undefined {\n if (error.kind !== 'commerce') return error.apiReason\n return error.reason === 'unknown_commerce_error'\n ? error.rawReason\n : error.reason\n}\n\nexport function isCommerceSDKError(error: unknown): error is CommerceSDKError {\n if (!isSDKError(error) || error.kind !== 'commerce') return false\n if (\n typeof error.requestId !== 'string' ||\n typeof error.retryable !== 'boolean' ||\n (error.retryAfter !== undefined &&\n (!Number.isSafeInteger(error.retryAfter) || error.retryAfter < 0)) ||\n typeof error.reason !== 'string'\n ) {\n return false\n }\n return error.reason === 'unknown_commerce_error'\n ? typeof error.rawReason === 'string'\n : COMMERCE_ERROR_CODE_SET.has(error.reason) && error.rawReason === undefined\n}\n\nexport class NetworkError extends SDKError {\n constructor(\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('NETWORK_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'NetworkError'\n defineSDKErrorType(this, 'NetworkError')\n }\n}\n\nexport class ValidationError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status = 400,\n ) {\n super('VALIDATION_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'ValidationError'\n defineSDKErrorType(this, 'ValidationError')\n }\n}\n\nexport class ApiError extends SDKError {\n constructor(\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'API_ERROR',\n message,\n status,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'ApiError'\n defineSDKErrorType(this, 'ApiError')\n }\n}\n\nexport class ConfigError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('CONFIG_ERROR', message, undefined, details, userMessage, suggestion)\n this.name = 'ConfigError'\n defineSDKErrorType(this, 'ConfigError')\n }\n}\n\nexport class TimeoutError extends SDKError {\n constructor(\n message = 'Request timed out.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('TIMEOUT_ERROR', message, 408, details, userMessage, suggestion)\n this.name = 'TimeoutError'\n defineSDKErrorType(this, 'TimeoutError')\n }\n}\n\nexport class GoneError extends SDKError {\n constructor(\n message = 'The requested resource is no longer available.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('GONE_ERROR', message, 410, details, userMessage, suggestion)\n this.name = 'GoneError'\n defineSDKErrorType(this, 'GoneError')\n }\n}\n\nexport class ServiceUnavailableError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message = 'Service temporarily unavailable.',\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super(\n 'SERVICE_UNAVAILABLE_ERROR',\n message,\n 503,\n details,\n userMessage,\n suggestion,\n )\n this.name = 'ServiceUnavailableError'\n this.retryAfter = retryAfter\n defineSDKErrorType(this, 'ServiceUnavailableError')\n }\n}\n\nexport class UsageLimitError extends SDKError {\n readonly usage: { limit: number; current: number; remaining: number }\n\n constructor(\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('USAGE_LIMIT_ERROR', message, 429, details, userMessage, suggestion)\n this.name = 'UsageLimitError'\n this.usage = usage\n defineSDKErrorType(this, 'UsageLimitError')\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n usage: this.usage,\n }\n }\n}\n\nexport class AuthError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'auth_error',\n message,\n 401,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'AuthError'\n defineSDKErrorType(this, 'AuthError')\n }\n}\n\nexport class PermissionError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'permission_error',\n message,\n 403,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'PermissionError'\n defineSDKErrorType(this, 'PermissionError')\n }\n}\n\nexport class NotFoundError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'not_found',\n message,\n 404,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'NotFoundError'\n defineSDKErrorType(this, 'NotFoundError')\n }\n}\n\nexport class ConflictError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super('conflict', message, 409, details, userMessage, suggestion, requestId)\n this.name = 'ConflictError'\n defineSDKErrorType(this, 'ConflictError')\n }\n}\n\nexport class RateLimitError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'rate_limit_exceeded',\n message,\n 429,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n defineSDKErrorType(this, 'RateLimitError')\n }\n}\n\nfunction hasBrandedSDKErrorShape(error: unknown): error is SDKError {\n if (error === null || typeof error !== 'object') return false\n\n const candidate = error as Record<PropertyKey, unknown>\n return (\n candidate[SDK_ERROR_BRAND] === true &&\n typeof candidate.name === 'string' &&\n typeof candidate.code === 'string' &&\n typeof candidate.message === 'string' &&\n (candidate.status === undefined || typeof candidate.status === 'number') &&\n (candidate.userMessage === undefined ||\n typeof candidate.userMessage === 'string') &&\n (candidate.suggestion === undefined ||\n typeof candidate.suggestion === 'string') &&\n (candidate.requestId === undefined ||\n typeof candidate.requestId === 'string') &&\n (candidate.kind === undefined || candidate.kind === 'commerce') &&\n (candidate.reason === undefined || typeof candidate.reason === 'string') &&\n (candidate.rawReason === undefined ||\n typeof candidate.rawReason === 'string') &&\n (candidate.apiReason === undefined ||\n typeof candidate.apiReason === 'string') &&\n (candidate.retryable === undefined ||\n typeof candidate.retryable === 'boolean') &&\n (candidate.retryAfter === undefined ||\n typeof candidate.retryAfter === 'number') &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nfunction hasSDKErrorType(error: unknown, type: SDKErrorType): boolean {\n return (\n hasBrandedSDKErrorShape(error) &&\n (error as unknown as Record<PropertyKey, unknown>)[SDK_ERROR_TYPE_BRAND] ===\n type\n )\n}\n\nexport function isSDKError(error: unknown): error is SDKError {\n return error instanceof SDKError || hasBrandedSDKErrorShape(error)\n}\n\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError || hasSDKErrorType(error, 'NetworkError')\n}\n\nexport function isValidationError(error: unknown): error is ValidationError {\n if (\n error instanceof ValidationError ||\n hasSDKErrorType(error, 'ValidationError')\n ) {\n return true\n }\n if (error == null || typeof error !== 'object') return false\n\n const candidate = error as {\n code?: unknown\n name?: unknown\n message?: unknown\n getUserMessage?: unknown\n toJSON?: unknown\n }\n return (\n candidate.name === 'ValidationError' &&\n candidate.code === 'VALIDATION_ERROR' &&\n typeof candidate.message === 'string' &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nexport function isApiError(error: unknown): error is ApiError {\n return error instanceof ApiError || hasSDKErrorType(error, 'ApiError')\n}\n\nexport function isConfigError(error: unknown): error is ConfigError {\n return error instanceof ConfigError || hasSDKErrorType(error, 'ConfigError')\n}\n\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return error instanceof TimeoutError || hasSDKErrorType(error, 'TimeoutError')\n}\n\nexport function isGoneError(error: unknown): error is GoneError {\n return error instanceof GoneError || hasSDKErrorType(error, 'GoneError')\n}\n\nexport function isServiceUnavailableError(\n error: unknown,\n): error is ServiceUnavailableError {\n return (\n error instanceof ServiceUnavailableError ||\n hasSDKErrorType(error, 'ServiceUnavailableError')\n )\n}\n\nexport function isUsageLimitError(error: unknown): error is UsageLimitError {\n return (\n error instanceof UsageLimitError ||\n hasSDKErrorType(error, 'UsageLimitError')\n )\n}\n\nexport function isAuthError(error: unknown): error is AuthError {\n return error instanceof AuthError || hasSDKErrorType(error, 'AuthError')\n}\n\nexport function isPermissionError(error: unknown): error is PermissionError {\n return (\n error instanceof PermissionError ||\n hasSDKErrorType(error, 'PermissionError')\n )\n}\n\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return (\n error instanceof NotFoundError || hasSDKErrorType(error, 'NotFoundError')\n )\n}\n\nexport function isConflictError(error: unknown): error is ConflictError {\n return (\n error instanceof ConflictError || hasSDKErrorType(error, 'ConflictError')\n )\n}\n\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return (\n error instanceof RateLimitError || hasSDKErrorType(error, 'RateLimitError')\n )\n}\n\nexport const createNetworkError = (\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new NetworkError(message, status, details, userMessage, suggestion)\n\nexport const createValidationError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status?: number,\n) => new ValidationError(message, details, userMessage, suggestion, status)\n\nexport const createApiError = (\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ApiError(message, status, details, userMessage, suggestion, requestId)\n\nexport const createConfigError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new ConfigError(message, details, userMessage, suggestion)\n\nexport const createTimeoutError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new TimeoutError(message, details, userMessage, suggestion)\n\nexport const createGoneError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new GoneError(message, details, userMessage, suggestion)\n\nexport const createServiceUnavailableError = (\n message?: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) =>\n new ServiceUnavailableError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n )\n\nexport const createUsageLimitError = (\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new UsageLimitError(message, usage, details, userMessage, suggestion)\n\nexport const createAuthError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new AuthError(message, details, userMessage, suggestion, requestId)\n\nexport const createPermissionError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new PermissionError(message, details, userMessage, suggestion, requestId)\n\nexport const createNotFoundError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new NotFoundError(message, details, userMessage, suggestion, requestId)\n\nexport const createConflictError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ConflictError(message, details, userMessage, suggestion, requestId)\n\nexport const createRateLimitError = (\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) =>\n new RateLimitError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n","import { createConfigError } from '../errors'\n\nexport function requirePublishableKeyForSecret(\n apiName: string,\n publishableKey: string | undefined,\n secretKey: string | undefined,\n): string {\n if (secretKey && !publishableKey) {\n throw createConfigError(\n `publishableKey is required for ${apiName} when secretKey is used. ` +\n 'It is sent as X-Publishable-Key for tenant routing, rate limiting, and quota enforcement.',\n )\n }\n\n return publishableKey ?? ''\n}\n","declare const __DEFAULT_API_URL__: string\n\nexport function resolveApiUrl(apiUrl?: string): string {\n if (apiUrl) {\n return apiUrl.replace(/\\/$/, '')\n }\n\n if (typeof process !== 'undefined' && process.env) {\n const envUrl =\n process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL\n if (envUrl) {\n return envUrl.replace(/\\/$/, '')\n }\n }\n return __DEFAULT_API_URL__\n}\n","import {\n createAuthError,\n createConflictError,\n createGoneError,\n createNetworkError,\n createNotFoundError,\n createPermissionError,\n createRateLimitError,\n createServiceUnavailableError,\n createValidationError,\n createUsageLimitError,\n createTimeoutError,\n enhanceCommerceError,\n enhanceNonCommerceError,\n isCommerceSDKError,\n parseCommerceErrorEnvelope,\n TimeoutError,\n NetworkError,\n RateLimitError,\n UsageLimitError,\n SDKError,\n} from '../errors'\nimport type { DebugConfig, RetryConfig } from '../../client/types'\nimport { resolveApiUrl } from './api-url'\nconst DEFAULT_TIMEOUT = 30000\nconst STOREFRONT_BROWSER_TIMEOUT = 15_000\n// 429 is intentionally NOT retryable: a real rate limit maps to RateLimitError\n// (terminal) so the SDK does not hammer a limited endpoint with plain backoff.\nconst DEFAULT_RETRYABLE_STATUSES = [408, 500, 502, 503, 504]\nconst NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422]\nconst SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']\nconst DEFAULT_MAX_RETRIES = 3\nconst STOREFRONT_BROWSER_MAX_RETRIES = 1\n// Do not keep a caller request open for an arbitrarily large server hint.\n// Longer windows are surfaced on the typed error for caller-controlled retry.\nconst MAX_AUTOMATIC_RETRY_AFTER_SECONDS = 5 * 60\n\nexport interface FetchOptions extends RequestInit {\n apiUrl?: string\n publishableKey?: string\n secretKey?: string\n customerToken?: string\n timeout?: number\n debug?: boolean | DebugConfig\n retry?: RetryConfig\n /** Called on 401 when customerToken is set and reason=token_expired. A new token permits retry only for GET/HEAD/OPTIONS; null fails. */\n onUnauthorized?: () => Promise<string | null>\n /** Selects a strict endpoint-owned error envelope. */\n errorFamily?: 'commerce'\n /** Strict commerce reasons on an otherwise legacy-compatible endpoint. */\n typedCommerceErrorReasons?: readonly string[]\n}\n\nfunction debugLog(\n debug: boolean | DebugConfig | undefined,\n type: 'request' | 'response' | 'error',\n message: string,\n data?: unknown,\n) {\n if (!debug) return\n\n const shouldLog =\n debug === true ||\n (type === 'request' && (debug as DebugConfig).logRequests) ||\n (type === 'response' && (debug as DebugConfig).logResponses) ||\n (type === 'error' && (debug as DebugConfig).logErrors)\n\n if (shouldLog) {\n console.group(`[SDK ${type.toUpperCase()}] ${message}`)\n if (data) console.log(data)\n console.groupEnd()\n }\n}\n\nfunction redactSensitiveHeader(value: string): string {\n const prefix = value.toLowerCase().startsWith('bearer ') ? 'Bearer ' : ''\n return value.length > 20 ? `${prefix}...****${value.slice(-8)}` : '****'\n}\n\nfunction redactSensitiveHeaders(headers: Headers): Record<string, string> {\n const redacted = Object.fromEntries(headers.entries())\n if (redacted.authorization) {\n redacted.authorization = redactSensitiveHeader(redacted.authorization)\n }\n if (redacted['x-preview-token']) {\n redacted['x-preview-token'] = redactSensitiveHeader(\n redacted['x-preview-token'],\n )\n }\n if (redacted['x-custom-payment-signature']) {\n redacted['x-custom-payment-signature'] = redactSensitiveHeader(\n redacted['x-custom-payment-signature'],\n )\n }\n return redacted\n}\n\nfunction getErrorSuggestion(status: number): string | undefined {\n if (status === 400)\n return 'The request data failed validation. Check field values and types.'\n if (status === 401) return 'Please check your authentication credentials.'\n if (status === 403)\n return 'Access denied. Check your credentials or permissions.'\n if (status === 404) return 'The requested resource was not found.'\n if (status === 422) return 'The request data failed validation.'\n if (status >= 500) return 'A server error occurred. Please try again later.'\n return undefined\n}\n\nfunction isUsageLimitExceededResponse(response: Response): boolean {\n if (response.status !== 429) return false\n\n const limit = parseInt(response.headers.get('X-Usage-Limit') || '', 10)\n const current = parseInt(response.headers.get('X-Usage-Current') || '', 10)\n if (!Number.isFinite(limit) || !Number.isFinite(current)) return false\n\n return response.headers.get('X-Usage-Exceeded') === 'true' || current > limit\n}\n\n/**\n * Parse error details from HTTP response body.\n * Supports Payload native format:\n * - ValidationError: { errors: [{ message, data: { errors: [{ path, message }] } }] }\n * - Simple: { errors: [{ message, field? }] }\n * Also supports custom endpoint format ({ error: string, reason?: string, message?: string }).\n */\nasync function parseErrorBody(response: Response): Promise<{\n errorMessage: string\n userMessage: string\n reason?: string\n /**\n * Machine reason a Payload `APIError` carries as `errors[0].data.code` (or\n * `.reason`). Surfaced only as the non-commerce `apiReason`; it never drives\n * commerce classification, token refresh, or retry decisions.\n */\n payloadErrorReason?: string\n body?: Record<string, unknown>\n errors?: Array<{ message?: string; field?: string }>\n}> {\n const fallback = {\n errorMessage: `HTTP ${response.status}: ${response.statusText}`,\n userMessage: `Request failed (status: ${response.status})`,\n }\n\n try {\n const body = await response.json()\n const reason: string | undefined =\n typeof body.reason === 'string'\n ? body.reason\n : typeof body.code === 'string'\n ? body.code\n : undefined\n const payloadErrorReason = Array.isArray(body.errors)\n ? readPayloadErrorReason(body.errors)\n : undefined\n const payloadReasonField =\n payloadErrorReason !== undefined ? { payloadErrorReason } : {}\n\n // Payload native: { errors: [{ message, field?, data? }] }\n if (body.errors && Array.isArray(body.errors)) {\n // Extract nested ValidationError field details\n // Payload ValidationError format: errors[].data.errors[].{path, message}\n const fieldErrors: Array<{ message?: string; field?: string }> = []\n for (const e of body.errors) {\n if (\n e.data?.errors &&\n Array.isArray(e.data.errors) &&\n e.data.errors.length > 0\n ) {\n for (const fe of e.data.errors) {\n fieldErrors.push({\n field: fe.path || fe.field,\n message: fe.message,\n })\n }\n } else if (e.field || e.message) {\n fieldErrors.push({ field: e.field, message: e.message })\n }\n }\n\n const details = (fieldErrors.length > 0 ? fieldErrors : body.errors)\n .map((e: { message?: string; field?: string }) =>\n e.field ? `${e.field}: ${e.message}` : e.message,\n )\n .filter(Boolean)\n .join('; ')\n if (details) {\n return {\n errorMessage: `HTTP ${response.status}: ${details}`,\n userMessage: details,\n reason,\n ...payloadReasonField,\n body,\n errors: fieldErrors.length > 0 ? fieldErrors : body.errors,\n }\n }\n }\n\n // Custom endpoint: { error: string, reason?: string, details?: { fieldErrors? } }\n if (typeof body.error === 'string') {\n return {\n errorMessage: `HTTP ${response.status}: ${body.error}`,\n userMessage: body.error,\n reason,\n ...payloadReasonField,\n body,\n }\n }\n\n // Fallback: { message: string }\n if (body.message) {\n return {\n errorMessage: `HTTP ${response.status}: ${body.message}`,\n userMessage: body.message,\n reason,\n ...payloadReasonField,\n body,\n }\n }\n\n return { ...fallback, reason, ...payloadReasonField, body }\n } catch {\n return fallback\n }\n}\n\n// Payload formats a thrown APIError as `{ errors: [{ name, message, data }] }`,\n// so its machine code is nested rather than top-level.\nfunction readPayloadErrorReason(errors: unknown[]): string | undefined {\n const data = (errors[0] as { data?: unknown } | null | undefined)?.data\n if (!data || typeof data !== 'object') return undefined\n const { reason, code } = data as { reason?: unknown; code?: unknown }\n if (typeof reason === 'string') return reason\n if (typeof code === 'string') return code\n return undefined\n}\n\nfunction getParsedErrorSuggestion(\n status: number,\n parsed: Awaited<ReturnType<typeof parseErrorBody>>,\n): string | undefined {\n if (status === 403 && parsed.reason === 'origin_not_allowed') {\n return 'Add the request origin to the tenant Browser API origins, then retry the browser request.'\n }\n\n return getErrorSuggestion(status)\n}\n\nasync function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n// Attach requestId to any SDKError instance (readonly bypass is intentional — internal transport layer only)\nexport function attachRequestId<T extends SDKError>(\n err: T,\n id: string | undefined,\n): T {\n if (id) (err as Record<string, unknown>).requestId = id\n return err\n}\n\nexport function parseRetryAfter(response: Response): {\n seconds?: number\n permitsAutomaticRetry: boolean\n} {\n const raw = response.headers.get('Retry-After')\n if (!raw) return { permitsAutomaticRetry: true }\n\n const trimmed = raw.trim()\n let seconds: number\n if (/^\\d+$/.test(trimmed)) {\n seconds = Number(trimmed)\n if (!Number.isSafeInteger(seconds)) {\n return { permitsAutomaticRetry: false }\n }\n } else {\n const retryAt = Date.parse(trimmed)\n if (!Number.isFinite(retryAt)) return { permitsAutomaticRetry: true }\n seconds = Math.max(0, Math.ceil((retryAt - Date.now()) / 1000))\n }\n\n return {\n seconds,\n permitsAutomaticRetry: seconds <= MAX_AUTOMATIC_RETRY_AFTER_SECONDS,\n }\n}\n\n/**\n * Single source of truth for HTTP-status → typed SDKError mapping. Both the\n * non-retryable and retryable paths go through here so the error taxonomy stays\n * consistent. Canonical commerce in-progress/lock errors may also expose it.\n */\nfunction mapResponseToError(\n status: number,\n parsed: Awaited<ReturnType<typeof parseErrorBody>>,\n details: Record<string, unknown>,\n requestId: string | undefined,\n retryAfter: number | undefined,\n canonicalCommerceError: boolean,\n): SDKError {\n const errorDetails = {\n ...details,\n ...(parsed.errors && { errors: parsed.errors }),\n ...(!canonicalCommerceError && parsed.body && { body: parsed.body }),\n }\n const suggestion = getParsedErrorSuggestion(status, parsed)\n const finalize = (error: SDKError): SDKError => {\n const withRequestId = attachRequestId(error, requestId)\n if (retryAfter !== undefined) {\n Object.assign(withRequestId, { retryAfter })\n }\n return canonicalCommerceError\n ? enhanceCommerceError(withRequestId, parsed.body, requestId)\n : enhanceNonCommerceError(\n withRequestId,\n parsed.reason ?? parsed.payloadErrorReason,\n )\n }\n\n if (status === 400 || status === 422) {\n return finalize(\n createValidationError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n status,\n ),\n )\n }\n\n if (status === 401) {\n return finalize(\n createAuthError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 403) {\n return finalize(\n createPermissionError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 404) {\n return finalize(\n createNotFoundError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 409) {\n return finalize(\n createConflictError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 410) {\n return finalize(\n createGoneError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 429) {\n // requestId is attached via attachRequestId below, matching the other\n // branches — do not also pass it to the factory.\n return finalize(\n createRateLimitError(\n parsed.errorMessage,\n retryAfter,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 503) {\n return finalize(\n createServiceUnavailableError(\n parsed.errorMessage,\n retryAfter,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n return finalize(\n createNetworkError(\n parsed.errorMessage,\n status,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n}\n\nexport async function httpFetch(\n url: string,\n options?: FetchOptions,\n): Promise<Response> {\n const {\n apiUrl,\n publishableKey,\n secretKey,\n customerToken,\n timeout: timeoutOption = DEFAULT_TIMEOUT,\n debug,\n retry,\n onUnauthorized,\n errorFamily,\n typedCommerceErrorReasons,\n ...requestInit\n } = options || {}\n\n const baseUrl = resolveApiUrl(apiUrl)\n const method = (requestInit.method || 'GET').toUpperCase()\n const isPublishableKeyBrowserGet =\n typeof window !== 'undefined' &&\n !secretKey &&\n !customerToken &&\n Boolean(publishableKey) &&\n SAFE_METHODS.includes(method)\n\n const timeout =\n timeoutOption === DEFAULT_TIMEOUT && isPublishableKeyBrowserGet\n ? STOREFRONT_BROWSER_TIMEOUT\n : timeoutOption\n\n const retryConfig = {\n maxRetries:\n retry?.maxRetries ??\n (isPublishableKeyBrowserGet\n ? STOREFRONT_BROWSER_MAX_RETRIES\n : DEFAULT_MAX_RETRIES),\n retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,\n retryDelay:\n retry?.retryDelay ??\n ((attempt: number) => Math.min(1000 * 2 ** attempt, 10000)),\n }\n\n // Server auth: secretKey is now the raw opaque bearer token (sk01_...).\n // Customer auth: customerToken is a JWT.\n let authToken: string | undefined\n if (secretKey) {\n authToken = secretKey\n } else if (customerToken) {\n authToken = customerToken\n }\n\n let lastError: Error | undefined\n let hasRetried401 = false\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n let terminalResponseError: SDKError | undefined\n try {\n const headers = new Headers(requestInit.headers)\n\n if (publishableKey) {\n headers.set('X-Publishable-Key', publishableKey)\n }\n\n if (authToken) {\n headers.set('Authorization', `Bearer ${authToken}`)\n }\n\n if (\n !headers.has('Content-Type') &&\n requestInit.body &&\n !(requestInit.body instanceof FormData)\n ) {\n headers.set('Content-Type', 'application/json')\n }\n\n // Redact sensitive headers for debug logging\n const redactedHeaders = redactSensitiveHeaders(headers)\n\n debugLog(debug, 'request', url, {\n method: requestInit.method || 'GET',\n headers: redactedHeaders,\n attempt: attempt + 1,\n })\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const response = await fetch(`${baseUrl}${url}`, {\n ...requestInit,\n headers,\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n const requestId = response.headers.get('x-request-id') ?? undefined\n\n debugLog(debug, 'response', url, {\n status: response.status,\n statusText: response.statusText,\n headers: redactSensitiveHeaders(response.headers),\n })\n\n if (!response.ok) {\n // Parse once. Strict error families validate the envelope before any\n // retry, refresh, or quota branch acts on its fields.\n const parsed = await parseErrorBody(response)\n const canonicalCommerceError =\n errorFamily === 'commerce' ||\n (typeof parsed.reason === 'string' &&\n typedCommerceErrorReasons?.includes(parsed.reason) === true)\n const commerceEnvelope = canonicalCommerceError\n ? parseCommerceErrorEnvelope(parsed.body, requestId)\n : undefined\n\n // Usage limit 429 — never retry. Older servers identify this when\n // current usage is above the limit; newer servers also send\n // X-Usage-Exceeded to avoid confusing other 429s with quota exhaustion.\n if (isUsageLimitExceededResponse(response)) {\n const limit = parseInt(\n response.headers.get('X-Usage-Limit') || '0',\n 10,\n )\n const current = parseInt(\n response.headers.get('X-Usage-Current') || '0',\n 10,\n )\n const remaining = parseInt(\n response.headers.get('X-Usage-Remaining') || '0',\n 10,\n )\n\n const usageError = attachRequestId(\n createUsageLimitError(\n `Monthly API usage limit exceeded (${current.toLocaleString('en-US')}/${limit.toLocaleString('en-US')})`,\n { limit, current, remaining },\n {\n url,\n method: requestInit.method || 'GET',\n attempt: attempt + 1,\n },\n 'Monthly API call limit exceeded. Please upgrade your plan.',\n 'Upgrade your tenant plan to increase the monthly API call limit.',\n ),\n requestId,\n )\n throw canonicalCommerceError\n ? enhanceCommerceError(usageError, parsed.body, requestId)\n : enhanceNonCommerceError(usageError, parsed.reason)\n }\n\n // Auto-refresh customer token on 401 — only when reason=token_expired\n if (\n response.status === 401 &&\n onUnauthorized &&\n customerToken &&\n !hasRetried401 &&\n (commerceEnvelope?.reason ?? parsed.reason) === 'token_expired'\n ) {\n hasRetried401 = true\n try {\n const newToken = await onUnauthorized()\n if (\n newToken &&\n SAFE_METHODS.includes((requestInit.method || 'GET').toUpperCase())\n ) {\n authToken = newToken\n // This one safe resend has its own hasRetried401 bound. Keep\n // the current attempt so refresh never consumes a transient retry.\n attempt--\n continue\n }\n } catch {\n // Refresh failed, fall through to throw\n }\n }\n\n const details = {\n url,\n method: requestInit.method || 'GET',\n attempt: attempt + 1,\n }\n\n const retryAfter = parseRetryAfter(response)\n const error = mapResponseToError(\n response.status,\n parsed,\n details,\n requestId,\n retryAfter.seconds,\n canonicalCommerceError,\n )\n\n const method = (requestInit.method || 'GET').toUpperCase()\n // Rate/usage limits are terminal: never retry them even if the caller\n // lists 429 in retryableStatuses — retrying only adds load.\n const isTerminal =\n error instanceof RateLimitError || error instanceof UsageLimitError\n const responseAllowsRetry = isCommerceSDKError(error)\n ? error.retryable\n : true\n if (\n attempt < retryConfig.maxRetries &&\n SAFE_METHODS.includes(method) &&\n !isTerminal &&\n responseAllowsRetry &&\n retryAfter.permitsAutomaticRetry &&\n !NON_RETRYABLE_STATUSES.includes(response.status) &&\n retryConfig.retryableStatuses.includes(response.status)\n ) {\n lastError = error\n const retryDelay = Math.max(\n retryConfig.retryDelay(attempt),\n (retryAfter.seconds ?? 0) * 1000,\n )\n debugLog(debug, 'error', `Retrying in ${retryDelay}ms...`, error)\n await delay(retryDelay)\n continue\n }\n\n terminalResponseError = error\n throw error\n }\n\n return response\n } catch (error) {\n debugLog(debug, 'error', url, error)\n\n // The HTTP branch already applied the complete response retry policy.\n // Keep its terminal decision out of the transport-failure retry path.\n if (terminalResponseError && error === terminalResponseError) {\n throw error\n }\n\n const method = (requestInit.method || 'GET').toUpperCase()\n const isSafe = SAFE_METHODS.includes(method)\n\n if (error instanceof Error && error.name === 'AbortError') {\n const timeoutError = createTimeoutError(\n `Request timed out after ${timeout}ms.`,\n { url, timeout, attempt: attempt + 1 },\n 'The request timed out.',\n 'Please check your network connection or try again later.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = timeoutError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw timeoutError\n }\n\n if (error instanceof TypeError) {\n const networkError = createNetworkError(\n 'Network connection failed.',\n undefined,\n { url, originalError: error.message, attempt: attempt + 1 },\n 'Network connection failed.',\n 'Please check your internet connection and try again.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = networkError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw networkError\n }\n\n if (error instanceof NetworkError || error instanceof TimeoutError) {\n if (\n isSafe &&\n attempt < retryConfig.maxRetries &&\n error.status &&\n !NON_RETRYABLE_STATUSES.includes(error.status) &&\n retryConfig.retryableStatuses.includes(error.status)\n ) {\n lastError = error\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw error\n }\n\n // Re-throw any other SDKError subclass (e.g. UsageLimitError) without wrapping\n if (error instanceof SDKError) {\n throw error\n }\n\n const unknownError = createNetworkError(\n error instanceof Error\n ? error.message\n : 'An unknown network error occurred.',\n undefined,\n { url, originalError: error, attempt: attempt + 1 },\n 'An unknown error occurred.',\n 'Please try again later.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = unknownError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw unknownError\n }\n }\n\n throw lastError ?? new NetworkError('Request failed after retries')\n}\n","import type {\n ProductFallbackLocaleOption,\n ProductLocaleOption,\n} from '../../api/product-api'\n\nfunction normalizedMarket(value: string | undefined): string | undefined {\n const market = value?.trim()\n return market || undefined\n}\n\ntype ProductLocaleQueryOptions = {\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n}\n\nfunction appendProductLocaleSearchParams(\n search: URLSearchParams,\n options?: ProductLocaleQueryOptions,\n): void {\n if (options?.locale) search.set('locale', options.locale)\n if (options?.fallbackLocale !== undefined) {\n search.set(\n 'fallbackLocale',\n options.fallbackLocale === false ? 'none' : options.fallbackLocale,\n )\n }\n}\n\nexport function productDetailSearchParams(\n params: ({ slug: string } | { id: string }) & {\n market?: string\n } & ProductLocaleQueryOptions,\n): string {\n const search = new URLSearchParams()\n if ('slug' in params) {\n search.set('slug', params.slug)\n } else {\n search.set('id', params.id)\n }\n const market = normalizedMarket(params.market)\n if (market) search.set('market', market)\n appendProductLocaleSearchParams(search, params)\n return search.toString()\n}\n\nexport function listingGroupsSearchParams(\n params: {\n productIds: string[]\n market?: string\n } & ProductLocaleQueryOptions,\n): string {\n const ids = params.productIds.map(encodeURIComponent).join(',')\n const search = new URLSearchParams()\n const market = normalizedMarket(params.market)\n if (market) search.set('market', market)\n appendProductLocaleSearchParams(search, params)\n const query = search.toString()\n return `ids=${ids}${query ? `&${query}` : ''}`\n}\n\ntype ListingGroupsQueryUrlOptions = {\n market?: string\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n page?: number\n limit?: number\n sort?: string | string[]\n where?: Record<string, unknown>\n}\n\nfunction appendListingGroupsQuerySearchParams(\n search: URLSearchParams,\n options?: ListingGroupsQueryUrlOptions,\n): void {\n const market = normalizedMarket(options?.market)\n if (market) search.set('market', market)\n appendProductLocaleSearchParams(search, options)\n if (options?.page != null) search.set('page', String(options.page))\n if (options?.limit != null) search.set('limit', String(options.limit))\n if (options?.sort != null) {\n const sort = options.sort\n search.set('sort', Array.isArray(sort) ? sort.join(',') : sort)\n }\n if (options?.where != null) {\n search.set('whereJson', JSON.stringify(options.where))\n }\n}\n\n/** Server-auth GET PLP listing-groups query (full variant stock fields). */\nexport function listingPageSearchParams(\n options?: ListingGroupsQueryUrlOptions,\n): string {\n const search = new URLSearchParams()\n appendListingGroupsQuerySearchParams(search, options)\n return search.toString()\n}\n\nexport function stockSnapshotSearchParams(params: {\n variantIds: string[]\n}): string {\n return `variantIds=${params.variantIds.map(encodeURIComponent).join(',')}`\n}\n","import {\n createApiError,\n createValidationError,\n createAuthError,\n createPermissionError,\n createNotFoundError,\n createConflictError,\n createRateLimitError,\n enhanceCommerceError,\n enhanceNonCommerceError,\n SDKError,\n} from '../internal/errors'\nimport { attachRequestId, parseRetryAfter } from '../internal/utils/http'\n\n/**\n * Shared JSON response parser for BaseApi and CartApi.\n * Parses response JSON body and throws typed errors based on the `reason` field.\n * Only called for responses that passed httpFetch (i.e. response.ok = true);\n * handles application-level errors embedded in 2xx bodies.\n */\nexport async function parseApiResponse<T>(\n response: Response,\n endpoint: string,\n options: { errorFamily?: 'commerce' } = {},\n): Promise<T> {\n if (\n response.status === 204 ||\n response.headers.get('content-length') === '0'\n ) {\n return undefined as T\n }\n\n let parsed: unknown\n try {\n parsed = await response.json()\n } catch {\n throw createApiError(\n `Invalid JSON response from ${endpoint}`,\n response.status,\n undefined,\n 'Server returned an invalid response.',\n 'Check if the API endpoint is available.',\n )\n }\n\n // A 2xx body may legitimately be `null` (e.g. memberships.me when the\n // customer has no membership) or another non-object value. Only object\n // bodies can carry an application-level `{ error, reason }` envelope, so\n // short-circuit everything else as the success value instead of touching\n // `.error` on a null body (which would throw a raw TypeError).\n if (parsed === null || typeof parsed !== 'object') {\n return parsed as T\n }\n const data = parsed as Record<string, unknown>\n const hasCommerceEnvelopeSignal =\n options.errorFamily === 'commerce' &&\n ['error', 'reason', 'requestId', 'retryable', 'details'].some((key) =>\n Object.prototype.hasOwnProperty.call(data, key),\n )\n\n if (data.error || hasCommerceEnvelopeSignal) {\n const errorMessage =\n typeof data.error === 'string' ? data.error : 'Unknown API error'\n const reason = typeof data.reason === 'string' ? data.reason : undefined\n const requestId = response.headers.get('x-request-id') ?? undefined\n const retryAfter = parseRetryAfter(response).seconds\n\n let error: SDKError\n if (reason === 'validation_failed') {\n error = createValidationError(errorMessage, data, errorMessage)\n } else if (\n reason === 'token_expired' ||\n reason === 'token_invalid' ||\n reason === 'preview_token_invalid' ||\n reason === 'preview_token_required' ||\n reason === 'key_invalid' ||\n reason === 'key_revoked'\n ) {\n error = createAuthError(errorMessage, data, errorMessage)\n } else if (reason === 'forbidden') {\n error = createPermissionError(errorMessage, data, errorMessage)\n } else if (reason === 'rate_limit_exceeded') {\n error = createRateLimitError(errorMessage, retryAfter, data, errorMessage)\n } else if (reason === 'not_found') {\n error = createNotFoundError(errorMessage, data, errorMessage)\n } else if (reason === 'conflict') {\n error = createConflictError(errorMessage, data, errorMessage)\n } else {\n error = createApiError(\n errorMessage,\n response.status,\n data,\n errorMessage,\n 'An error occurred while processing the request.',\n )\n }\n const withRequestId = attachRequestId(error, requestId)\n if (retryAfter !== undefined) Object.assign(withRequestId, { retryAfter })\n throw options.errorFamily === 'commerce'\n ? enhanceCommerceError(withRequestId, data, requestId)\n : enhanceNonCommerceError(withRequestId, reason)\n }\n\n return data as T\n}\n","const operationBrand: unique symbol = Symbol('sdk-http-operation')\n\n/** Successful legacy privileged-bearer response: canonical UTC rotation deadline. */\nexport const CREDENTIAL_ROTATION_DEADLINE_HEADER =\n 'X-01-Credential-Rotation-Deadline' as const\n\n/**\n * Opt-in representation for Standard V2 PortOne action capabilities.\n *\n * The default application/json projection stays byte-shape compatible with\n * strict SDK parsers released before these capability literals existed.\n */\nexport const PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE =\n 'application/vnd.01software.portone-action-capabilities.v1+json' as const\n\nexport function requestsPortOneStandardActionCapabilities(\n accept: string | null | undefined,\n): boolean {\n return (\n accept?.trim().toLowerCase() ===\n PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE\n )\n}\n\n/** Exact opt-in only: case-insensitive after outer whitespace trimming.\n * Lists, wildcards and parameters (including q/charset) do not opt in.\n * Only applicable successful credit funding representations carry this type;\n * those responses are private, no-store. This is never payment authority.\n */\nexport const CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE =\n 'application/vnd.01software.credit-funding.v1+json' as const\n\nexport function requestsCustomerCreditFunding(\n accept: string | null | undefined,\n): boolean {\n return accept?.trim().toLowerCase() === CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE\n}\n\nexport type HttpOperation = {\n readonly [operationBrand]: true\n readonly collection: string | null\n readonly method: 'get' | 'post' | 'patch' | 'delete'\n readonly path: `/${string}`\n readonly errorFamily?: 'commerce'\n /**\n * Canonical commerce reasons emitted by an otherwise legacy-compatible\n * endpoint. Only these responses may be normalized and parsed as the strict\n * commerce envelope; every other response retains its established shape.\n */\n readonly typedCommerceErrorReasons?: readonly string[]\n}\n\nconst operation = <\n TCollection extends string | null,\n TMethod extends HttpOperation['method'],\n TPath extends `/${string}`,\n>(\n collection: TCollection,\n method: TMethod,\n path: TPath,\n errorFamily?: HttpOperation['errorFamily'],\n) =>\n Object.freeze({\n [operationBrand]: true,\n collection,\n method,\n path,\n ...(errorFamily && { errorFamily }),\n } as const)\n\nconst strictCommerceOperation = <\n TCollection extends string | null,\n TMethod extends HttpOperation['method'],\n TPath extends `/${string}`,\n>(\n collection: TCollection,\n method: TMethod,\n path: TPath,\n) => operation(collection, method, path, 'commerce')\n\nconst selectiveCommerceOperation = <\n TCollection extends string | null,\n TMethod extends HttpOperation['method'],\n TPath extends `/${string}`,\n TReasons extends readonly [string, ...string[]],\n>(\n collection: TCollection,\n method: TMethod,\n path: TPath,\n typedCommerceErrorReasons: TReasons,\n) =>\n Object.freeze({\n ...operation(collection, method, path),\n typedCommerceErrorReasons: Object.freeze([...typedCommerceErrorReasons]),\n } as const)\n\nexport const COMMERCE_ENDPOINT_OPERATIONS = {\n products: {\n detail: operation('products', 'get', '/detail'),\n detailCatalog: operation('products', 'get', '/detail/catalog'),\n listingGroups: operation('products', 'get', '/listing-groups'),\n listingGroupsCatalog: operation(\n 'products',\n 'get',\n '/listing-groups/catalog',\n ),\n listingGroupsQuery: operation('products', 'post', '/listing-groups/query'),\n listingGroupsQueryGet: operation(\n 'products',\n 'get',\n '/listing-groups/query',\n ),\n listingGroupsQueryCatalog: operation(\n 'products',\n 'get',\n '/listing-groups/query/catalog',\n ),\n stockCheck: operation('products', 'post', '/stock-check'),\n stockSnapshot: operation('products', 'get', '/stock'),\n upsert: operation('products', 'post', '/upsert'),\n graphRevision: operation('products', 'get', '/:id/graph-revision'),\n variantsPatch: operation('products', 'patch', '/:id/variants'),\n },\n orders: {\n create: operation('orders', 'post', '/create'),\n update: operation('orders', 'post', '/update'),\n confirmPayment: operation('orders', 'post', '/confirm-payment'),\n byPayment: operation('orders', 'get', '/by-payment'),\n cancel: operation('orders', 'post', '/cancel'),\n resolveCancelRefund: selectiveCommerceOperation(\n 'orders',\n 'post',\n '/resolve-cancel-refund',\n ['managed_refund_attestation_forbidden'],\n ),\n checkout: strictCommerceOperation('orders', 'post', '/checkout'),\n createFulfillment: operation('orders', 'post', '/create-fulfillment'),\n updateFulfillment: operation('orders', 'post', '/update-fulfillment'),\n },\n checkouts: {\n detail: strictCommerceOperation('checkouts', 'post', '/detail'),\n query: strictCommerceOperation('checkouts', 'post', '/query'),\n },\n draftOrders: {\n calculate: operation('draft-orders', 'post', '/:id/calculate'),\n complete: operation('draft-orders', 'post', '/:id/complete'),\n finalize: operation('draft-orders', 'post', '/:id/finalize'),\n },\n transactions: {\n update: operation('transactions', 'post', '/update'),\n },\n returns: {\n create: operation('returns', 'post', '/create'),\n update: operation('returns', 'post', '/update'),\n returnRefund: operation('returns', 'post', '/return-refund'),\n },\n fulfillmentOrders: {\n prepare: operation(\n 'fulfillment-orders',\n 'post',\n '/prepare-fulfillment-order',\n ),\n },\n fulfillments: {\n bulkImport: operation('fulfillments', 'post', '/bulk-import'),\n },\n carts: {\n create: strictCommerceOperation('carts', 'post', '/create'),\n retrieve: strictCommerceOperation('carts', 'post', '/retrieve'),\n mine: strictCommerceOperation('carts', 'post', '/mine'),\n merge: strictCommerceOperation('carts', 'post', '/merge'),\n addItem: strictCommerceOperation('carts', 'post', '/add-item'),\n updateItem: strictCommerceOperation('carts', 'post', '/update-item'),\n removeItem: strictCommerceOperation('carts', 'post', '/remove-item'),\n updateDiscountCodes: strictCommerceOperation(\n 'carts',\n 'post',\n '/update-discount-codes',\n ),\n updateAttributes: strictCommerceOperation(\n 'carts',\n 'post',\n '/update-attributes',\n ),\n clear: strictCommerceOperation('carts', 'post', '/clear'),\n },\n paymentSessions: {\n create: strictCommerceOperation('payment-sessions', 'post', '/create'),\n retrieve: strictCommerceOperation('payment-sessions', 'post', '/retrieve'),\n cancel: strictCommerceOperation('payment-sessions', 'post', '/cancel'),\n server: {\n create: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/create',\n ),\n retrieve: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/retrieve',\n ),\n cancel: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/cancel',\n ),\n confirm: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/confirm',\n ),\n findPortOne: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/portone/find',\n ),\n reconcilePortOne: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/portone/reconcile',\n ),\n },\n custom: {\n create: operation('orders', 'post', '/custom-payment-sessions'),\n retrieve: operation(\n 'orders',\n 'post',\n '/custom-payment-sessions/retrieve',\n ),\n confirm: operation('orders', 'post', '/custom-payment-sessions/confirm'),\n },\n },\n shippingPolicies: {\n calculate: operation('shipping-policies', 'post', '/calculate'),\n },\n discounts: {\n validate: operation('discounts', 'post', '/validate'),\n },\n} as const\n\nconst portOneStandardActionCapabilityOperations = new Set<HttpOperation>([\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.create,\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.retrieve,\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.create,\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.retrieve,\n])\n\n/**\n * Whether this operation may negotiate the Standard V2 capability projection.\n *\n * Create still requires a Standard V2 request profile, while retrieve discovers\n * the provider/profile from the stored session. Cancel and confirm deliberately\n * remain on the released JSON representation.\n */\nexport function supportsPortOneStandardActionCapabilityNegotiation(\n descriptor: HttpOperation,\n): boolean {\n return portOneStandardActionCapabilityOperations.has(descriptor)\n}\n\nexport const MEMBERSHIP_ENDPOINT_OPERATIONS = {\n subscribe: operation(null, 'post', '/memberships/subscribe'),\n endSubscribeIntent: operation(\n null,\n 'post',\n '/memberships/subscribe-intent/end',\n ),\n billingCustody: operation(null, 'post', '/memberships/billing-custody'),\n cancel: operation(null, 'post', '/memberships/:id/cancel'),\n me: operation(null, 'get', '/memberships/me'),\n chargeResult: operation(null, 'post', '/memberships/:id/charge-result'),\n refundResult: operation(null, 'post', '/memberships/:id/refund-result'),\n revoke: operation(null, 'post', '/memberships/:id/revoke'),\n} as const\n\n/** Server-only tenant-owned operations; no raw claim collection is published. */\nexport const EXTERNAL_EFFECT_CLAIM_ENDPOINT_OPERATIONS = {\n claim: operation(null, 'post', '/external-effect-claims/claim'),\n get: operation(null, 'post', '/external-effect-claims/get'),\n arm: operation(null, 'post', '/external-effect-claims/arm'),\n release: operation(null, 'post', '/external-effect-claims/release'),\n report: operation(null, 'post', '/external-effect-claims/report'),\n recovery: operation(null, 'post', '/external-effect-claims/recovery'),\n} as const\n\n/** Bound-server, purpose-specific installation ciphertext operations. */\nexport const INSTALLATION_CREDENTIAL_ENDPOINT_OPERATIONS = {\n create: operation(null, 'post', '/installation-credentials/create'),\n get: operation(null, 'post', '/installation-credentials/get'),\n replace: operation(null, 'post', '/installation-credentials/replace'),\n dispose: operation(null, 'post', '/installation-credentials/dispose'),\n} as const\n\n/** Server-only shaped external Customer links owned by the Customers bucket. */\nexport const EXTERNAL_CUSTOMER_LINK_ENDPOINT_OPERATIONS = {\n connect: operation('customers', 'post', '/external-links/connect'),\n get: operation('customers', 'post', '/external-links/get'),\n list: operation('customers', 'post', '/external-links/list'),\n unlink: operation('customers', 'post', '/external-links/unlink'),\n capturePreviousState: operation(\n 'customers',\n 'post',\n '/external-links/capture-previous-state',\n ),\n clearPreviousState: operation(\n 'customers',\n 'post',\n '/external-links/clear-previous-state',\n ),\n} as const\n\n/** Customer-owned single-use benefit vouchers. */\nexport const BENEFIT_VOUCHER_ENDPOINT_OPERATIONS = {\n issue: operation('customers', 'post', '/benefit-vouchers/issue'),\n get: operation('customers', 'post', '/benefit-vouchers/get'),\n list: operation('customers', 'post', '/benefit-vouchers/list'),\n redeem: operation('customers', 'post', '/benefit-vouchers/redeem'),\n void: operation('customers', 'post', '/benefit-vouchers/void'),\n listMine: operation('customers', 'get', '/me/benefit-vouchers'),\n} as const\n\n/** Credit commands are server-only; self reads require a Customer session.\n * Configuration is Console-session-only and has no SDK method. */\nexport const CUSTOMER_CREDIT_ENDPOINT_OPERATIONS = {\n grant: strictCommerceOperation('customers', 'post', '/credits/grant'),\n getGrant: strictCommerceOperation('customers', 'post', '/credits/get-grant'),\n getAccount: strictCommerceOperation('customers', 'post', '/credits/account'),\n revoke: strictCommerceOperation('customers', 'post', '/credits/revoke'),\n mine: strictCommerceOperation('customers', 'get', '/me/credits'),\n history: strictCommerceOperation('customers', 'get', '/me/credits/history'),\n configure: strictCommerceOperation(\n 'customers',\n 'post',\n '/credits/configuration',\n ),\n} as const\n\n/** Server-authenticated source-aware Customer Group authority operations. */\nexport const CUSTOMER_GROUP_ENDPOINT_OPERATIONS = {\n members: operation('customer-groups', 'get', '/:id/members'),\n grant: operation('customer-groups', 'post', '/:id/members/grant'),\n revoke: operation('customer-groups', 'post', '/:id/members/revoke'),\n} as const\n\n/** Browser-public customer self actions; each operation owns its authentication. */\nexport const CUSTOMER_AUTH_ENDPOINT_OPERATIONS = {\n register: operation('customers', 'post', '/register'),\n login: operation('customers', 'post', '/login'),\n refresh: operation('customers', 'post', '/refresh'),\n me: operation('customers', 'get', '/me'),\n updateProfile: operation('customers', 'patch', '/me'),\n forgotPassword: operation('customers', 'post', '/forgot-password'),\n resetPassword: operation('customers', 'post', '/reset-password'),\n changePassword: operation('customers', 'post', '/change-password'),\n\n revokeRefresh: operation('customers', 'post', '/revoke-refresh'),\n withdraw: operation('customers', 'post', '/withdraw'),\n} as const\n\n/** PAT-only operator controls for the active tenant embedded admin binding. */\nexport const EMBEDDED_ADMIN_ENDPOINT_OPERATIONS = {\n show: operation('tenants', 'get', '/embedded-admin-app'),\n configure: operation('tenants', 'patch', '/embedded-admin-app'),\n disable: operation('tenants', 'delete', '/embedded-admin-app'),\n} as const\n\n/** Shaped event operations shared by their owning runtime and SDK surfaces. */\nexport const EVENTS_ENDPOINT_OPERATIONS = {\n registrations: {\n register: operation('event-registrations', 'post', '/register'),\n guestLookup: operation('event-registrations', 'post', '/guest/lookup'),\n guestLookupByUrl: operation('event-registrations', 'get', '/guest/:token'),\n guestCancel: operation('event-registrations', 'post', '/guest/cancel'),\n guestCancelByUrl: operation(\n 'event-registrations',\n 'post',\n '/guest/:token/cancel',\n ),\n listMine: operation('event-registrations', 'get', '/my'),\n },\n events: {\n convertSchedule: operation('events', 'post', '/:id/schedule'),\n },\n occurrences: {\n range: operation('event-occurrences', 'get', '/range'),\n admissionAvailability: operation(\n 'event-occurrences',\n 'get',\n '/admission-availability',\n ),\n },\n} as const\n\n/** Public, shaped browser reads served by community collections. */\nexport const COMMUNITY_ENDPOINT_OPERATIONS = {\n posts: {\n detail: operation('posts', 'get', '/detail'),\n },\n} as const\n\n/** Public, shaped gallery item reads. Linked raw videos remain server-only. */\nexport const GALLERY_ENDPOINT_OPERATIONS = {\n items: {\n storefront: operation('gallery-items', 'get', '/storefront'),\n },\n} as const\n\n/** Public, shaped VOD playback admission. Raw videos remain server-only. */\nexport const VIDEO_ENDPOINT_OPERATIONS = {\n playback: operation('videos', 'post', '/:id/playback'),\n} as const\n\nexport function resolveOperationTemplate(descriptor: HttpOperation): string {\n return descriptor.collection\n ? `/api/${descriptor.collection}${descriptor.path}`\n : `/api${descriptor.path}`\n}\n\nexport function resolveOperationPath(\n descriptor: HttpOperation,\n options?: {\n pathParams?: Readonly<Record<string, string>>\n query?: string | URLSearchParams\n },\n): string {\n const path = resolveOperationTemplate(descriptor).replace(\n /:([A-Za-z][A-Za-z0-9_]*)/g,\n (_, key) => {\n const value = options?.pathParams?.[key]\n if (value === undefined) {\n throw new TypeError(`Missing path parameter: ${key}`)\n }\n return encodeURIComponent(value)\n },\n )\n const unresolved = path.match(/:([A-Za-z][A-Za-z0-9_]*)/)\n if (unresolved) {\n throw new TypeError(`Missing path parameter: ${unresolved[1]}`)\n }\n\n const query = options?.query?.toString().replace(/^\\?/, '')\n return query ? `${path}?${query}` : path\n}\n\nexport function resolveOperationMethod(\n descriptor: HttpOperation,\n): Uppercase<HttpOperation['method']> {\n return descriptor.method.toUpperCase() as Uppercase<HttpOperation['method']>\n}\n","// SDK-facing semantic view over the shared commerce transport manifest.\n//\n// The private http-contracts workspace package is the sole authority for\n// commerce and membership transport identity (collection, method, path).\n// Console mounts the same operations, and\n// `apps/console/tests/unit/sdk/endpoint-contract-parity.test.ts` proves each\n// declared operation is registered exactly once with a handler — see\n// `docs/contracts/platform/public-api-boundary.md` (PLAT-API-016).\n//\n// This module only groups those operations under the names the SDK APIs call\n// them by, including the deliberate browser/server aliases that are an\n// authorization lane rather than a second transport. It must not declare a\n// method or path literal; `tests/unit/api/endpoint-transport-authority.test.ts`\n// fails closed if one reappears.\n//\n// Keep this internal — it is the transport contract, not public SDK surface.\nimport {\n CUSTOMER_GROUP_ENDPOINT_OPERATIONS,\n EXTERNAL_CUSTOMER_LINK_ENDPOINT_OPERATIONS,\n BENEFIT_VOUCHER_ENDPOINT_OPERATIONS,\n CUSTOMER_CREDIT_ENDPOINT_OPERATIONS,\n COMMERCE_ENDPOINT_OPERATIONS,\n EXTERNAL_EFFECT_CLAIM_ENDPOINT_OPERATIONS,\n INSTALLATION_CREDENTIAL_ENDPOINT_OPERATIONS,\n MEMBERSHIP_ENDPOINT_OPERATIONS,\n PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE,\n CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE,\n type HttpOperation,\n} from '@01.software/http-contracts'\n\nexport {\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\nexport {\n CUSTOMER_GROUP_ENDPOINT_OPERATIONS,\n CUSTOMER_CREDIT_ENDPOINT_OPERATIONS,\n EXTERNAL_CUSTOMER_LINK_ENDPOINT_OPERATIONS,\n BENEFIT_VOUCHER_ENDPOINT_OPERATIONS,\n COMMERCE_ENDPOINT_OPERATIONS,\n EXTERNAL_EFFECT_CLAIM_ENDPOINT_OPERATIONS,\n INSTALLATION_CREDENTIAL_ENDPOINT_OPERATIONS,\n MEMBERSHIP_ENDPOINT_OPERATIONS,\n PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE,\n CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE,\n}\n\nexport type CommerceEndpointDescriptor = HttpOperation\n\n/**\n * Widens a manifest operation to the nameable `HttpOperation` type. Without it\n * the inferred literal type leaks the manifest's private brand symbol into the\n * SDK declaration output (TS4023).\n */\nconst sharedEndpoint = (descriptor: HttpOperation): HttpOperation => descriptor\n\nexport function resolveOperationErrorFamily(\n descriptor: CommerceEndpointDescriptor,\n): 'commerce' | undefined {\n return descriptor.errorFamily\n}\n\nexport function resolveOperationTypedCommerceErrorReasons(\n descriptor: CommerceEndpointDescriptor,\n): readonly string[] | undefined {\n return descriptor.typedCommerceErrorReasons\n}\n\nexport const COMMERCE_ENDPOINTS = {\n products: {\n detail: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.products.detail),\n detailCatalog: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,\n ),\n listingGroups: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroups,\n ),\n listingGroupsCatalog: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,\n ),\n // The manifest keeps the GET read and the POST body-query apart; this\n // semantic name has always resolved to the GET one.\n listingGroupsQuery: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryGet,\n ),\n listingGroupsQueryCatalog: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryCatalog,\n ),\n stockCheck: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockCheck,\n ),\n stockSnapshot: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockSnapshot,\n ),\n upsert: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.products.upsert),\n },\n orders: {\n update: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.update),\n byPayment: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.byPayment),\n cancel: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.cancel),\n resolveCancelRefund: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.orders.resolveCancelRefund,\n ),\n createFulfillment: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.orders.createFulfillment,\n ),\n updateFulfillment: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.orders.updateFulfillment,\n ),\n },\n checkouts: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.checkout),\n retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.checkouts.detail),\n server: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.checkout),\n retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.checkouts.detail),\n query: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.checkouts.query),\n },\n },\n returns: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.returns.create),\n update: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.returns.update),\n returnRefund: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.returns.returnRefund,\n ),\n },\n fulfillmentOrders: {\n prepare: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.fulfillmentOrders.prepare,\n ),\n },\n fulfillments: {\n bulkImport: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.fulfillments.bulkImport,\n ),\n },\n carts: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.create),\n retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.retrieve),\n mine: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.mine),\n merge: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.merge),\n server: {\n // Server credentials are an authorization lane, not a second Cart\n // transport. These must stay bound to the registered shared operations.\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.create),\n retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.retrieve),\n mine: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.mine),\n merge: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.merge),\n addItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.addItem),\n updateItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.updateItem),\n removeItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.removeItem),\n updateDiscountCodes: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.carts.updateDiscountCodes,\n ),\n updateAttributes: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.carts.updateAttributes,\n ),\n clear: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.clear),\n },\n addItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.addItem),\n updateItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.updateItem),\n removeItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.removeItem),\n updateDiscountCodes: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.carts.updateDiscountCodes,\n ),\n updateAttributes: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.carts.updateAttributes,\n ),\n clear: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.clear),\n },\n paymentSessions: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.create),\n retrieve: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.retrieve,\n ),\n cancel: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.cancel),\n custom: {\n create: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.custom.create,\n ),\n retrieve: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.custom.retrieve,\n ),\n confirm: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.custom.confirm,\n ),\n },\n server: {\n create: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.create,\n ),\n retrieve: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.retrieve,\n ),\n cancel: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.cancel,\n ),\n confirm: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.confirm,\n ),\n findPortOne: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.findPortOne,\n ),\n reconcilePortOne: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.reconcilePortOne,\n ),\n },\n },\n shippingPolicies: {\n calculate: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.shippingPolicies.calculate,\n ),\n },\n} as const\n","import { createConfigError, SDKError } from '../internal/errors'\nimport { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\nimport { parseApiResponse } from './parse-response'\nimport {\n resolveOperationErrorFamily,\n resolveOperationMethod,\n resolveOperationPath,\n type CommerceEndpointDescriptor,\n} from './endpoints'\n\nexport interface CustomerScopedApiOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n requiresCredential?: boolean\n}\n\nexport interface CustomerScopedRequestOptions {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n body?: unknown\n headers?: Record<string, string>\n errorFamily?: 'commerce'\n}\n\ntype EndpointRequestOptions = {\n headers?: Record<string, string>\n pathParams?: Readonly<Record<string, string>>\n query?: string | URLSearchParams\n}\n\nclass CustomerScopedTransport {\n private readonly publishableKey: string\n private readonly secretKey?: string\n private readonly apiUrl?: string\n private readonly customerToken?: string | (() => string | null)\n private readonly onUnauthorized?: () => Promise<string | null>\n private readonly onRequestId?: (id: string | null) => void\n\n constructor(apiName: string, options: CustomerScopedApiOptions) {\n if (\n options.requiresCredential !== false &&\n !options.secretKey &&\n !options.customerToken\n ) {\n throw createConfigError(\n `Either secretKey or customerToken is required for ${apiName}.`,\n )\n }\n\n this.publishableKey = requirePublishableKeyForSecret(\n apiName,\n options.publishableKey,\n options.secretKey,\n )\n this.secretKey = options.secretKey\n this.apiUrl = options.apiUrl\n this.customerToken = options.customerToken\n this.onUnauthorized = options.onUnauthorized\n this.onRequestId = options.onRequestId\n }\n\n async request<T>(\n endpoint: string,\n options: CustomerScopedRequestOptions,\n ): Promise<T> {\n const token =\n typeof this.customerToken === 'function'\n ? this.customerToken()\n : this.customerToken\n\n try {\n const response = await httpFetch(endpoint, {\n method: options.method,\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n customerToken: token ?? undefined,\n ...(token &&\n this.onUnauthorized && { onUnauthorized: this.onUnauthorized }),\n ...(options.body !== undefined && {\n body: JSON.stringify(options.body),\n }),\n ...(options.headers && { headers: options.headers }),\n ...(options.errorFamily && { errorFamily: options.errorFamily }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint, {\n errorFamily: options.errorFamily,\n })\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n}\n\n/** Operation-only base for customer-scoped commerce APIs. */\nexport class CustomerScopedApi {\n private readonly transport: CustomerScopedTransport\n\n constructor(apiName: string, options: CustomerScopedApiOptions) {\n this.transport = new CustomerScopedTransport(apiName, options)\n }\n\n protected requestEndpoint<T>(\n endpoint: CommerceEndpointDescriptor,\n body?: unknown,\n options?: EndpointRequestOptions,\n ): Promise<T> {\n return this.transport.request<T>(resolveOperationPath(endpoint, options), {\n method: resolveOperationMethod(endpoint),\n body,\n headers: options?.headers,\n errorFamily: resolveOperationErrorFamily(endpoint),\n })\n }\n}\n\n/** Raw transport base reserved for non-commerce customer-scoped APIs. */\nexport class RawCustomerScopedApi {\n private readonly transport: CustomerScopedTransport\n\n constructor(apiName: string, options: CustomerScopedApiOptions) {\n this.transport = new CustomerScopedTransport(apiName, options)\n }\n\n protected request<T>(\n endpoint: string,\n options: CustomerScopedRequestOptions,\n ): Promise<T> {\n return this.transport.request<T>(endpoint, options)\n }\n}\n","import { createApiError } from '../internal/errors'\nexport const BENEFIT_VOUCHER_VOID_REASONS = [\n 'issued_in_error',\n 'benefit_revoked',\n 'customer_request',\n 'other',\n] as const\nexport const BENEFIT_VOUCHER_ERROR_REASONS = [\n 'invalid_request',\n 'forbidden',\n 'customer_not_found',\n 'customer_ineligible',\n 'definition_not_found',\n 'definition_archived',\n 'definition_in_use',\n 'voucher_not_found',\n 'source_conflict',\n 'request_conflict',\n 'voucher_already_redeemed',\n 'voucher_voided',\n 'voucher_expired',\n 'feature_disabled',\n 'authority_unavailable',\n 'internal_error',\n] as const\nexport type BenefitVoucherErrorReason =\n (typeof BENEFIT_VOUCHER_ERROR_REASONS)[number]\nexport type CustomerBenefitVoucher = {\n id: string\n name: string\n description: string | null\n state: 'issued' | 'redeemed' | 'expired' | 'voided'\n issuedAt: string\n expiresAt: string\n closedAt: string | null\n}\nexport type BenefitVoucher = {\n id: string\n name: string\n description: string | null\n state: CustomerBenefitVoucher['state']\n issuedAt: string\n expiresAt: string\n customerId: string\n definitionId: string\n source: { namespace: string; ref: string }\n closed: null | {\n at: string\n channel: 'server' | 'console'\n actor: { type: 'server_credential' | 'operator'; id: string }\n actorRef: string | null\n voidReason: (typeof BENEFIT_VOUCHER_VOID_REASONS)[number] | null\n }\n}\nexport type IssueBenefitVoucherRequest = {\n definitionId: string\n customerId: string\n sourceNamespace: string\n sourceRef: string\n expiresAt?: string\n}\nexport type GetBenefitVoucherRequest = { customerId: string; voucherId: string }\nexport type RedeemBenefitVoucherRequest = GetBenefitVoucherRequest & {\n requestId: string\n actorRef: string\n}\nexport type VoidBenefitVoucherRequest = RedeemBenefitVoucherRequest & {\n reason: (typeof BENEFIT_VOUCHER_VOID_REASONS)[number]\n}\nexport type ListBenefitVouchersRequest = {\n customerId: string\n state?: BenefitVoucher['state']\n definitionId?: string\n limit?: number\n cursor?: string\n}\nexport type ListMyBenefitVouchersRequest = {\n status?: 'available' | 'all'\n limit?: number\n cursor?: string\n}\nexport type IssueBenefitVoucherResponse = {\n voucher: BenefitVoucher\n created: boolean\n}\nexport type MutateBenefitVoucherResponse = {\n voucher: BenefitVoucher\n replayed: boolean\n}\nexport type ListBenefitVouchersResponse = {\n vouchers: BenefitVoucher[]\n nextCursor: string | null\n evaluatedAt: string\n}\nexport type ListMyBenefitVouchersResponse = {\n vouchers: CustomerBenefitVoucher[]\n nextCursor: string | null\n evaluatedAt: string\n}\n\nexport function invalidBenefitVoucherResponse(): never {\n throw createApiError('Invalid benefit voucher response', 200)\n}\nfunction object(value: unknown, keys: string[]): Record<string, unknown> {\n if (\n !value ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n Object.keys(value).length !== keys.length ||\n keys.some((key) => !(key in value))\n )\n invalidBenefitVoucherResponse()\n return value as Record<string, unknown>\n}\nconst uuid = (v: unknown): v is string =>\n typeof v === 'string' &&\n (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(\n v,\n ) ||\n v === '00000000-0000-0000-0000-000000000000' ||\n v.toLowerCase() === 'ffffffff-ffff-ffff-ffff-ffffffffffff')\nconst time = (v: unknown): v is string =>\n typeof v === 'string' &&\n /^\\d{4}-\\d{2}-\\d{2}T/.test(v) &&\n Number.isFinite(Date.parse(v)) &&\n new Date(Date.parse(v)).toISOString() === v\nconst actor = (v: unknown): v is string =>\n typeof v === 'string' && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(v)\nexport function parseBenefitVoucher(\n value: unknown,\n mine: true,\n): CustomerBenefitVoucher\nexport function parseBenefitVoucher(\n value: unknown,\n mine?: false,\n): BenefitVoucher\nexport function parseBenefitVoucher(\n value: unknown,\n mine = false,\n): CustomerBenefitVoucher | BenefitVoucher {\n const v = object(value, [\n 'id',\n 'name',\n 'description',\n 'state',\n 'issuedAt',\n 'expiresAt',\n ...(mine\n ? ['closedAt']\n : ['customerId', 'definitionId', 'source', 'closed']),\n ])\n if (\n !uuid(v.id) ||\n typeof v.name !== 'string' ||\n !v.name.length ||\n v.name.length > 120 ||\n (v.description !== null &&\n (typeof v.description !== 'string' || v.description.length > 1000)) ||\n !['issued', 'redeemed', 'expired', 'voided'].includes(v.state as string) ||\n !time(v.issuedAt) ||\n !time(v.expiresAt)\n )\n invalidBenefitVoucherResponse()\n if (mine) {\n if (v.closedAt !== null && !time(v.closedAt))\n invalidBenefitVoucherResponse()\n } else {\n if (!uuid(v.customerId) || !uuid(v.definitionId))\n invalidBenefitVoucherResponse()\n const source = object(v.source, ['namespace', 'ref'])\n if (\n typeof source.namespace !== 'string' ||\n !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(source.namespace) ||\n typeof source.ref !== 'string' ||\n !source.ref.length ||\n source.ref.length > 256\n )\n invalidBenefitVoucherResponse()\n if (v.closed !== null) {\n const closed = object(v.closed, [\n 'at',\n 'channel',\n 'actor',\n 'actorRef',\n 'voidReason',\n ])\n const principal = object(closed.actor, ['type', 'id'])\n if (\n !time(closed.at) ||\n !uuid(principal.id) ||\n !['server', 'console'].includes(closed.channel as string) ||\n !['server_credential', 'operator'].includes(principal.type as string) ||\n (closed.actorRef !== null && !actor(closed.actorRef)) ||\n (closed.voidReason !== null &&\n !BENEFIT_VOUCHER_VOID_REASONS.includes(closed.voidReason as never))\n )\n invalidBenefitVoucherResponse()\n }\n }\n return value as CustomerBenefitVoucher | BenefitVoucher\n}\nexport function parseBenefitVoucherList(\n value: unknown,\n mine: true,\n): ListMyBenefitVouchersResponse\nexport function parseBenefitVoucherList(\n value: unknown,\n mine?: false,\n): ListBenefitVouchersResponse\nexport function parseBenefitVoucherList(\n value: unknown,\n mine = false,\n): ListMyBenefitVouchersResponse | ListBenefitVouchersResponse {\n const v = object(value, ['vouchers', 'nextCursor', 'evaluatedAt'])\n if (\n !Array.isArray(v.vouchers) ||\n v.vouchers.length > 100 ||\n !time(v.evaluatedAt) ||\n (v.nextCursor !== null &&\n (typeof v.nextCursor !== 'string' ||\n !v.nextCursor.length ||\n v.nextCursor.length > 2048))\n )\n invalidBenefitVoucherResponse()\n for (const row of v.vouchers) {\n if (mine) parseBenefitVoucher(row, true)\n else parseBenefitVoucher(row)\n }\n return value as ListMyBenefitVouchersResponse | ListBenefitVouchersResponse\n}\n","import { CustomerScopedApi } from './customer-scoped-api'\nimport { BENEFIT_VOUCHER_ENDPOINT_OPERATIONS } from './endpoints'\nimport {\n parseBenefitVoucherList,\n type ListMyBenefitVouchersRequest,\n type ListMyBenefitVouchersResponse,\n} from './benefit-voucher-types'\nexport class CustomerBenefitVouchersApi extends CustomerScopedApi {\n async listMine(\n params: ListMyBenefitVouchersRequest = {},\n ): Promise<ListMyBenefitVouchersResponse> {\n const query = new URLSearchParams()\n for (const [key, value] of Object.entries(params))\n if (value !== undefined) query.set(key, String(value))\n return parseBenefitVoucherList(\n await this.requestEndpoint<unknown>(\n BENEFIT_VOUCHER_ENDPOINT_OPERATIONS.listMine,\n undefined,\n { query },\n ),\n true,\n )\n }\n}\n","import { createApiError } from '../internal/errors'\n\n/** Non-negative integer KRW, encoded without loss of aggregate precision. */\nexport type CustomerCreditBalances = {\n available: string\n held: string\n spent: string\n expired: string\n revoked: string\n}\nexport type GetCustomerCreditGrantRequest = {\n sourceNamespace: string\n sourceRef: string\n}\nexport type GrantCustomerCreditRequest = GetCustomerCreditGrantRequest & {\n customerId: string\n templateId: string\n amount?: number\n}\nexport type RevokeCustomerCreditRequest = GetCustomerCreditGrantRequest\nexport type CustomerCreditGrant = GetCustomerCreditGrantRequest & {\n id: string\n customerId: string\n templateId: string\n templateVersion: number\n mode: 'fixed' | 'bounded'\n maximum: string\n amount: string\n currency: 'KRW'\n validityDays: number\n grantedAt: string\n expiresAt: string\n}\nexport type RevokeCustomerCreditResponse = {\n revoked: string\n pending: string\n spent: string\n}\nexport type MyCustomerCreditsRequest = { page?: number }\nexport type MyCustomerCreditHistoryRequest = MyCustomerCreditsRequest\nexport type MyCustomerCreditsResponse = {\n currency: 'KRW'\n evaluatedAt: string\n granted: string\n balances: CustomerCreditBalances\n buckets: {\n id: string\n grantId: string\n kind: 'original' | 'grace'\n grantedAt: string\n expiresAt: string\n isRevoked: boolean\n balances: CustomerCreditBalances\n }[]\n page: number\n hasNextPage: boolean\n}\nexport type MyCustomerCreditHistoryResponse = {\n currency: 'KRW'\n evaluatedAt: string\n entries: {\n id: string\n grantId: string\n kind:\n | 'grant'\n | 'reserve'\n | 'consume'\n | 'release'\n | 'restore'\n | 'expire'\n | 'revoke'\n amount: string\n fromState: keyof CustomerCreditBalances | null\n toState: keyof CustomerCreditBalances | null\n createdAt: string\n }[]\n page: number\n hasNextPage: boolean\n}\nexport type GetCustomerCreditAccountRequest = {\n customerId: string\n page?: number\n}\nexport type CustomerCreditAccountResponse = {\n summary: MyCustomerCreditsResponse\n history: MyCustomerCreditHistoryResponse\n}\n\nexport function parseCustomerCreditAccount(\n value: unknown,\n): CustomerCreditAccountResponse {\n const data = object(value, ['summary', 'history'])\n return {\n summary: parseMyCustomerCredits(data.summary),\n history: parseMyCustomerCreditHistory(data.history),\n }\n}\n\nfunction invalid(): never {\n throw createApiError('Invalid customer credit response', 502)\n}\nfunction object(\n value: unknown,\n keys: readonly string[],\n): Record<string, unknown> {\n if (\n !value ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n Object.keys(value).length !== keys.length ||\n keys.some((key) => !Object.prototype.hasOwnProperty.call(value, key))\n )\n invalid()\n return value as Record<string, unknown>\n}\nfunction money(value: unknown): value is string {\n return typeof value === 'string' && /^(0|[1-9][0-9]*)$/.test(value)\n}\nfunction uuid(value: unknown): value is string {\n return (\n typeof value === 'string' &&\n /^([0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i.test(\n value,\n )\n )\n}\nfunction time(value: unknown): value is string {\n if (typeof value !== 'string') return false\n const match =\n /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.\\d+)?Z$/.exec(value)\n if (!match) return false\n const [, year, month, day, hour, minute, second = '0'] = match\n const y = Number(year),\n m = Number(month),\n d = Number(day)\n const days = [\n 31,\n y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0) ? 29 : 28,\n 31,\n 30,\n 31,\n 30,\n 31,\n 31,\n 30,\n 31,\n 30,\n 31,\n ]\n return (\n m >= 1 &&\n m <= 12 &&\n d >= 1 &&\n d <= days[m - 1]! &&\n Number(hour) < 24 &&\n Number(minute) < 60 &&\n Number(second) < 60\n )\n}\nconst states = ['available', 'held', 'spent', 'expired', 'revoked'] as const\nfunction balances(value: unknown): void {\n const data = object(value, states)\n if (states.some((key) => !money(data[key]))) invalid()\n}\nfunction page(value: Record<string, unknown>): void {\n if (\n value.currency !== 'KRW' ||\n !time(value.evaluatedAt) ||\n !Number.isSafeInteger(value.page) ||\n (value.page as number) < 1 ||\n typeof value.hasNextPage !== 'boolean'\n )\n invalid()\n}\n\nexport function parseCustomerCreditGrant(value: unknown): CustomerCreditGrant {\n const data = object(value, [\n 'id',\n 'customerId',\n 'templateId',\n 'templateVersion',\n 'mode',\n 'maximum',\n 'amount',\n 'currency',\n 'validityDays',\n 'grantedAt',\n 'expiresAt',\n 'sourceNamespace',\n 'sourceRef',\n ])\n if (\n !uuid(data.id) ||\n !uuid(data.customerId) ||\n !uuid(data.templateId) ||\n !Number.isSafeInteger(data.templateVersion) ||\n (data.templateVersion as number) < 1 ||\n !['fixed', 'bounded'].includes(data.mode as string) ||\n !money(data.maximum) ||\n !money(data.amount) ||\n data.currency !== 'KRW' ||\n !Number.isInteger(data.validityDays) ||\n (data.validityDays as number) < 1 ||\n (data.validityDays as number) > 1825 ||\n !time(data.grantedAt) ||\n !time(data.expiresAt) ||\n typeof data.sourceNamespace !== 'string' ||\n !/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/.test(data.sourceNamespace) ||\n typeof data.sourceRef !== 'string' ||\n !data.sourceRef.length ||\n data.sourceRef.length > 256 ||\n // eslint-disable-next-line no-control-regex -- The public source identity explicitly forbids ASCII control characters.\n /[\\u0000-\\u001f\\u007f]/.test(data.sourceRef)\n )\n invalid()\n return value as CustomerCreditGrant\n}\nexport function parseRevokeCustomerCredit(\n value: unknown,\n): RevokeCustomerCreditResponse {\n const data = object(value, ['revoked', 'pending', 'spent'])\n if (!money(data.revoked) || !money(data.pending) || !money(data.spent))\n invalid()\n return value as RevokeCustomerCreditResponse\n}\nexport function parseMyCustomerCredits(\n value: unknown,\n): MyCustomerCreditsResponse {\n const data = object(value, [\n 'currency',\n 'evaluatedAt',\n 'granted',\n 'balances',\n 'buckets',\n 'page',\n 'hasNextPage',\n ])\n page(data)\n balances(data.balances)\n if (\n !money(data.granted) ||\n !Array.isArray(data.buckets) ||\n data.buckets.length > 50\n )\n invalid()\n for (const value of data.buckets) {\n const bucket = object(value, [\n 'id',\n 'grantId',\n 'kind',\n 'grantedAt',\n 'expiresAt',\n 'isRevoked',\n 'balances',\n ])\n if (\n !uuid(bucket.id) ||\n !uuid(bucket.grantId) ||\n !['original', 'grace'].includes(bucket.kind as string) ||\n !time(bucket.grantedAt) ||\n !time(bucket.expiresAt) ||\n typeof bucket.isRevoked !== 'boolean'\n )\n invalid()\n balances(bucket.balances)\n }\n return value as MyCustomerCreditsResponse\n}\nexport function parseMyCustomerCreditHistory(\n value: unknown,\n): MyCustomerCreditHistoryResponse {\n const data = object(value, [\n 'currency',\n 'evaluatedAt',\n 'entries',\n 'page',\n 'hasNextPage',\n ])\n page(data)\n if (!Array.isArray(data.entries) || data.entries.length > 50) invalid()\n for (const value of data.entries) {\n const entry = object(value, [\n 'id',\n 'grantId',\n 'kind',\n 'amount',\n 'fromState',\n 'toState',\n 'createdAt',\n ])\n if (\n !uuid(entry.id) ||\n !uuid(entry.grantId) ||\n !money(entry.amount) ||\n !time(entry.createdAt) ||\n ![\n 'grant',\n 'reserve',\n 'consume',\n 'release',\n 'restore',\n 'expire',\n 'revoke',\n ].includes(entry.kind as string) ||\n (entry.fromState !== null &&\n !states.includes(entry.fromState as never)) ||\n (entry.toState !== null && !states.includes(entry.toState as never))\n )\n invalid()\n }\n return value as MyCustomerCreditHistoryResponse\n}\n","import { CustomerScopedApi } from './customer-scoped-api'\nimport { CUSTOMER_CREDIT_ENDPOINT_OPERATIONS as operations } from './endpoints'\nimport {\n parseMyCustomerCredits,\n parseMyCustomerCreditHistory,\n type MyCustomerCreditsRequest,\n type MyCustomerCreditsResponse,\n type MyCustomerCreditHistoryRequest,\n type MyCustomerCreditHistoryResponse,\n} from './customer-credit-types'\n\n/** Customer JWT + publishable key; no customer/tenant selector is accepted. */\nexport class CustomerCreditsApi extends CustomerScopedApi {\n async mine(\n params: MyCustomerCreditsRequest = {},\n ): Promise<MyCustomerCreditsResponse> {\n const query = new URLSearchParams()\n if (params.page !== undefined) query.set('page', String(params.page))\n return parseMyCustomerCredits(\n await this.requestEndpoint<unknown>(operations.mine, undefined, {\n query,\n }),\n )\n }\n async history(\n params: MyCustomerCreditHistoryRequest = {},\n ): Promise<MyCustomerCreditHistoryResponse> {\n const query = new URLSearchParams()\n if (params.page !== undefined) query.set('page', String(params.page))\n return parseMyCustomerCreditHistory(\n await this.requestEndpoint<unknown>(operations.history, undefined, {\n query,\n }),\n )\n }\n}\n","import { stringify } from 'qs-esm'\nimport {\n httpFetch,\n requirePublishableKeyForSecret,\n type FetchOptions,\n} from '../internal/utils'\nimport type {\n ApiQueryOptions,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport {\n SDKError,\n createApiError,\n createValidationError,\n} from '../internal/errors'\n\n// Payload parses bracketed queries with depth 10 and arrayLimit 1000. Reject\n// values that qs would discard or rewrite before any collection request.\n// Return whether Payload needs its native JSON where parameter to retain null.\nfunction validateWhere(where: ApiQueryOptions['where']): boolean {\n if (where === undefined) return false\n let hasNull = false\n function visit(value: unknown, depth: number, key?: string): void {\n if (depth > 10) {\n throw createValidationError(\n 'Collection where must not exceed nesting depth 10.',\n )\n }\n if (value === null && (key === 'equals' || key === 'not_equals')) {\n hasNull = true\n return\n }\n if (value == null) {\n throw createValidationError(\n 'Collection where must not contain null or undefined values.',\n )\n }\n if (Array.isArray(value)) {\n if (value.length === 0) {\n throw createValidationError(\n 'Collection where must not contain empty arrays, including and/or.',\n )\n }\n if (value.length > 1000) {\n throw createValidationError(\n 'Collection where arrays must not contain more than 1000 elements.',\n )\n }\n for (const item of value) visit(item, depth + 1)\n } else if (typeof value === 'object' && !(value instanceof Date)) {\n const values = Object.entries(value)\n if (values.length === 0) {\n throw createValidationError(\n 'Collection where must not contain empty condition objects.',\n )\n }\n for (const [key, item] of values) visit(item, depth + 1, key)\n }\n }\n visit(where, 0)\n return hasNull\n}\n\nexport class HttpClient {\n protected publishableKey: string\n protected secretKey?: string\n private getCustomerToken?: () => string | null\n private onUnauthorized?: () => Promise<string | null>\n private onRequestId?: (id: string | null) => void\n private apiUrl?: string\n\n constructor(\n publishableKey: string,\n secretKey?: string,\n getCustomerToken?: () => string | null,\n onUnauthorized?: () => Promise<string | null>,\n onRequestId?: (id: string | null) => void,\n apiUrl?: string,\n ) {\n this.publishableKey = requirePublishableKeyForSecret(\n 'CollectionClient',\n publishableKey,\n secretKey,\n )\n this.secretKey = secretKey\n this.getCustomerToken = getCustomerToken\n this.onUnauthorized = onUnauthorized\n this.onRequestId = onRequestId\n this.apiUrl = apiUrl\n }\n\n protected get defaultOptions(): FetchOptions {\n const opts: FetchOptions = {\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n }\n const token = this.getCustomerToken?.()\n if (token) {\n opts.customerToken = token\n if (this.onUnauthorized) {\n opts.onUnauthorized = this.onUnauthorized\n }\n }\n return opts\n }\n\n protected async fetchWithTracking(url: string, opts: FetchOptions): Promise<Response> {\n try {\n const response = await httpFetch(url, opts)\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return response\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n\n protected buildUrl(endpoint: string, options?: ApiQueryOptions): string {\n if (!options) return endpoint\n const { fallbackLocale, ...rest } = options\n const queryOptions =\n fallbackLocale === undefined\n ? rest\n : {\n ...rest,\n 'fallback-locale':\n fallbackLocale === false ? 'none' : fallbackLocale,\n }\n // Payload parseParams JSON-decodes a string where before field coercion.\n // The string 'null' alone is only coerced for some field types.\n const encodedOptions = validateWhere(queryOptions.where)\n ? { ...queryOptions, where: JSON.stringify(queryOptions.where) }\n : queryOptions\n const queryString = stringify(encodedOptions, { addQueryPrefix: true })\n return queryString ? `${endpoint}${queryString}` : endpoint\n }\n\n protected assertJsonResponse(response: Response): void {\n const contentType = response.headers.get('content-type')\n if (!contentType?.includes('application/json')) {\n throw createApiError('Response is not in JSON format.', response.status, {\n contentType,\n })\n }\n }\n\n /**\n * Parse Payload CMS find response (list query)\n * Returns native Payload response structure\n */\n protected async parseFindResponse<T>(\n response: Response,\n ): Promise<PayloadFindResponse<T>> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n\n // Validate it's a find response\n if (jsonData.docs === undefined) {\n throw createApiError('Invalid find response.', response.status, {\n jsonData,\n })\n }\n\n return {\n docs: jsonData.docs,\n totalDocs: jsonData.totalDocs ?? 0,\n limit: jsonData.limit || 20,\n totalPages: jsonData.totalPages ?? 0,\n page: jsonData.page || 1,\n pagingCounter: jsonData.pagingCounter || 1,\n hasPrevPage: jsonData.hasPrevPage ?? false,\n hasNextPage: jsonData.hasNextPage ?? false,\n prevPage: jsonData.prevPage ?? null,\n nextPage: jsonData.nextPage ?? null,\n }\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n\n /**\n * Parse Payload CMS mutation response (create/update)\n * Returns native Payload response structure\n */\n protected async parseMutationResponse<T>(\n response: Response,\n ): Promise<PayloadMutationResponse<T>> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n\n // Validate it's a mutation response\n if (jsonData.doc === undefined) {\n throw createApiError('Invalid mutation response.', response.status, {\n jsonData,\n })\n }\n\n return {\n message: jsonData.message || '',\n doc: jsonData.doc,\n errors: jsonData.errors,\n }\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n\n /**\n * Parse Payload CMS document response (findById/delete)\n * Returns document directly without wrapper\n */\n protected async parseDocumentResponse<T>(response: Response): Promise<T> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n return jsonData as T\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n}\n","/**\n * Resolves a Payload CMS relation field value.\n * When depth is 0, relation fields return just the ID (string or number).\n * When depth > 0, they return the full document object (T).\n * This utility normalizes both cases to T | null.\n *\n * @param ref - The relation field value (T, string, number, null, or undefined)\n * @returns The resolved document object, or null if not populated\n */\nexport function resolveRelation<T>(\n ref: T | string | number | null | undefined,\n): T | null\nexport function resolveRelation<T>(ref: unknown): T | null\nexport function resolveRelation<T>(ref: unknown): T | null {\n if (\n typeof ref === 'string' ||\n typeof ref === 'number' ||\n ref === null ||\n ref === undefined\n )\n return null\n return ref as T\n}\n","import type {\n ApiDeleteOptions,\n ApiDocumentWriteOptions,\n ApiQueryOptions,\n ApiWriteOptions,\n Collection,\n PublicCollection,\n PublicReadQueryOptions,\n ServerCollection,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport { generateMetadata, extractSeo } from '../metadata'\nimport type { GenerateMetadataOptions, Metadata } from '../metadata'\nimport type { CollectionClient } from './collection-client'\nimport type { CollectionType } from './types'\nimport { createValidationError } from '../errors'\n\ninterface ReadOnlyCollectionApi {\n requestFind<T = unknown>(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<PayloadFindResponse<T>>\n requestFindById<T = unknown>(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<T>\n requestCount(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<{ totalDocs: number }>\n}\n\nconst PUBLIC_READ_DEPTH_ERROR =\n 'Publishable collection reads require depth: 0. Use a shaped commerce endpoint or server client for populated data.'\nconst PUBLIC_READ_JOINS_ERROR =\n 'Publishable collection reads require joins: false. Use a shaped commerce endpoint or server client for joined data.'\nconst PUBLIC_READ_POPULATE_ERROR =\n 'Publishable collection reads do not support populate. Use a shaped commerce endpoint or server client for populated data.'\n\nfunction withDefaultPublicReadOptions(\n options?: PublicReadQueryOptions,\n): PublicReadQueryOptions {\n const rawOptions = options as ApiQueryOptions | undefined\n\n if (rawOptions?.depth !== undefined && rawOptions.depth !== 0) {\n throw createValidationError(PUBLIC_READ_DEPTH_ERROR)\n }\n if (rawOptions?.joins !== undefined && rawOptions.joins !== false) {\n throw createValidationError(PUBLIC_READ_JOINS_ERROR)\n }\n if (rawOptions?.populate !== undefined) {\n throw createValidationError(PUBLIC_READ_POPULATE_ERROR)\n }\n\n return {\n ...options,\n depth: options?.depth ?? 0,\n joins: options?.joins ?? false,\n }\n}\n\n// Forward only the write query fields so `file`/`filename` never reach the URL.\nfunction toWriteOptions(\n options?: ApiWriteOptions,\n): ApiWriteOptions | undefined {\n return options?.locale === undefined ? undefined : { locale: options.locale }\n}\n\n/**\n * Read-only subset of CollectionQueryBuilder.\n * Client.from() returns this type to prevent write operations at compile time.\n */\nexport type ReadOnlyQueryBuilder<T extends PublicCollection> =\n ReadOnlyCollectionQueryBuilder<T>\n\nexport class ReadOnlyCollectionQueryBuilder<T extends PublicCollection> {\n constructor(\n private api: ReadOnlyCollectionApi,\n private collection: T,\n ) {}\n\n async find(\n options?: PublicReadQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestFind<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n withDefaultPublicReadOptions(options),\n )\n }\n\n async findById(\n id: string | number,\n options?: PublicReadQueryOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestFindById<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n withDefaultPublicReadOptions(options),\n )\n }\n\n async count(\n options?: PublicReadQueryOptions,\n ): Promise<{ totalDocs: number }> {\n return this.api.requestCount(\n `/api/${String(this.collection)}/count`,\n withDefaultPublicReadOptions(options),\n )\n }\n}\n\nexport class CollectionQueryBuilder<T extends Collection> {\n constructor(\n private api: CollectionClient,\n private collection: T,\n ) {}\n\n /**\n * Find documents (list query)\n * GET /api/{collection}\n * @returns Payload CMS find response with docs array and pagination\n */\n async find(\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestFind<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n options,\n )\n }\n\n /**\n * Find document by ID\n * GET /api/{collection}/{id}\n * @returns Document object directly (no wrapper)\n */\n async findById(\n id: string | number,\n options?: ApiQueryOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestFindById<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n options,\n )\n }\n\n /**\n * Create a new document\n * POST /api/{collection}\n * Pass `locale` to write localized fields in a tenant-enabled locale.\n * @returns Payload CMS mutation response with doc and message\n */\n async create(\n data: Partial<CollectionType<T>>,\n options?: ApiDocumentWriteOptions,\n ): Promise<PayloadMutationResponse<CollectionType<T>>> {\n const endpoint = `/api/${String(this.collection)}`\n const writeOptions = toWriteOptions(options)\n if (options?.file) {\n return this.api.requestCreateWithFile<CollectionType<T>>(\n endpoint,\n data,\n options.file,\n options.filename,\n writeOptions,\n )\n }\n return this.api.requestCreate<CollectionType<T>>(\n endpoint,\n data,\n writeOptions,\n )\n }\n\n /**\n * Update a document by ID\n * PATCH /api/{collection}/{id}\n * Pass `locale` to write localized fields in a tenant-enabled locale.\n * @returns Payload CMS mutation response with doc and message\n */\n async update(\n id: string,\n data: Partial<CollectionType<T>>,\n options?: ApiDocumentWriteOptions,\n ): Promise<PayloadMutationResponse<CollectionType<T>>> {\n const endpoint = `/api/${String(this.collection)}/${String(id)}`\n const writeOptions = toWriteOptions(options)\n if (options?.file) {\n return this.api.requestUpdateWithFile<CollectionType<T>>(\n endpoint,\n data,\n options.file,\n options.filename,\n writeOptions,\n )\n }\n return this.api.requestUpdate<CollectionType<T>>(\n endpoint,\n data,\n writeOptions,\n )\n }\n\n /**\n * Count documents\n * GET /api/{collection}/count\n * @returns Count response with totalDocs\n */\n async count(options?: ApiQueryOptions): Promise<{ totalDocs: number }> {\n return this.api.requestCount(\n `/api/${String(this.collection)}/count`,\n options,\n )\n }\n\n /**\n * Find first matching document and return its Next.js Metadata.\n * Applies depth: 1 (SEO image populate) and limit: 1 automatically.\n * @returns Metadata or null if no document matches\n */\n async findMetadata(\n options?: ApiQueryOptions,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata | null> {\n const { docs } = await this.find({ ...options, limit: 1, depth: 1 })\n const doc = docs[0]\n if (!doc) return null\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n /**\n * Find document by ID and return its Next.js Metadata.\n * Applies depth: 1 (SEO image populate) automatically.\n * @returns Metadata (throws on 404)\n */\n async findMetadataById(\n id: string,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata> {\n const doc = await this.findById(id, { depth: 1 })\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n /**\n * Update multiple documents (bulk update)\n * PATCH /api/{collection}\n * @returns Payload CMS find response with updated docs\n */\n async updateMany(\n where: ApiQueryOptions['where'],\n data: Partial<CollectionType<T>>,\n options?: ApiWriteOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestUpdateMany<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n { where, data },\n toWriteOptions(options),\n )\n }\n\n /**\n * Delete a document by ID\n * DELETE /api/{collection}/{id}\n * @returns Deleted document object directly (no wrapper)\n */\n async remove(\n id: string,\n options?: ApiDeleteOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestDelete<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n options,\n )\n }\n\n /**\n * Delete multiple documents (bulk delete)\n * DELETE /api/{collection}\n * @returns Payload CMS find response with deleted docs\n */\n async removeMany(\n where: ApiQueryOptions['where'],\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestDeleteMany<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n { where },\n )\n }\n}\n\nexport class ServerCollectionQueryBuilder<\n T extends ServerCollection,\n> extends CollectionQueryBuilder<T> {}\n","import { HttpClient } from './http-client'\nimport type {\n ApiDeleteOptions,\n ApiQueryOptions,\n ApiWriteOptions,\n Collection,\n PublicCollection,\n PublicReadQueryOptions,\n ServerCollection,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport {\n CollectionQueryBuilder,\n ReadOnlyCollectionQueryBuilder,\n ServerCollectionQueryBuilder,\n type ReadOnlyQueryBuilder,\n} from './query-builder'\n\nfunction buildPayloadFormData(\n data: unknown,\n file: File | Blob,\n filename?: string,\n): FormData {\n const formData = new FormData()\n formData.append('file', file, filename)\n if (data != null) {\n formData.append('_payload', JSON.stringify(data))\n }\n return formData\n}\n\nexport class CollectionClient<\n TCollection extends Collection = PublicCollection,\n> extends HttpClient {\n from<T extends TCollection>(collection: T): CollectionQueryBuilder<T> {\n return new CollectionQueryBuilder(this, collection)\n }\n\n // ============================================================================\n // Payload-native methods\n // ============================================================================\n\n /**\n * Find documents (list query)\n * GET /api/{collection}\n */\n async requestFind<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find-like response from a custom endpoint\n * POST /api/...custom-endpoint\n */\n async requestFindEndpoint<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find-like response from a cacheable GET custom endpoint.\n */\n async requestFindEndpointGet<T = unknown>(\n endpoint: string,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find document by ID\n * GET /api/{collection}/{id}\n */\n async requestFindById<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n /**\n * Create document\n * POST /api/{collection}\n */\n async requestCreate<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: ApiWriteOptions,\n ): Promise<PayloadMutationResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Update document\n * PATCH /api/{collection}/{id}\n */\n async requestUpdate<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: ApiWriteOptions,\n ): Promise<PayloadMutationResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Count documents\n * GET /api/{collection}/count\n */\n async requestCount(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<{ totalDocs: number }> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<{ totalDocs: number }>(response)\n }\n\n /**\n * Update multiple documents (bulk update)\n * PATCH /api/{collection}\n */\n async requestUpdateMany<T = unknown>(\n endpoint: string,\n data: { where?: ApiQueryOptions['where']; data: unknown },\n options?: ApiWriteOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, { where: data.where, ...options })\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: JSON.stringify(data.data),\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Delete document\n * DELETE /api/{collection}/{id}\n */\n async requestDelete<T = unknown>(\n endpoint: string,\n options?: ApiDeleteOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'DELETE',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n /**\n * Delete multiple documents (bulk delete)\n * DELETE /api/{collection}\n */\n async requestDeleteMany<T = unknown>(\n endpoint: string,\n data: { where?: ApiQueryOptions['where'] },\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, { where: data.where })\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'DELETE',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Create document with file upload\n * POST /api/{collection} (multipart/form-data)\n */\n async requestCreateWithFile<T = unknown>(\n endpoint: string,\n data: unknown,\n file: File | Blob,\n filename?: string,\n options?: ApiWriteOptions,\n ): Promise<PayloadMutationResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'POST',\n body: buildPayloadFormData(data, file, filename),\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Update document with file upload\n * PATCH /api/{collection}/{id} (multipart/form-data)\n */\n async requestUpdateWithFile<T = unknown>(\n endpoint: string,\n data: unknown,\n file: File | Blob,\n filename?: string,\n options?: ApiWriteOptions,\n ): Promise<PayloadMutationResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: buildPayloadFormData(data, file, filename),\n })\n return this.parseMutationResponse<T>(response)\n }\n}\n\nexport class ServerCollectionClient extends CollectionClient<ServerCollection> {\n override from<T extends ServerCollection>(\n collection: T,\n ): ServerCollectionQueryBuilder<T> {\n return new ServerCollectionQueryBuilder(this, collection)\n }\n}\n\nexport class ReadOnlyCollectionClient extends HttpClient {\n from<T extends PublicCollection>(collection: T): ReadOnlyQueryBuilder<T> {\n return new ReadOnlyCollectionQueryBuilder(this, collection)\n }\n\n async requestFind<T = unknown>(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n async requestFindEndpoint<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseFindResponse<T>(response)\n }\n\n async requestFindEndpointGet<T = unknown>(\n endpoint: string,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n async requestFindById<T = unknown>(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n async requestCount(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<{ totalDocs: number }> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<{ totalDocs: number }>(response)\n }\n}\n","import { RawCustomerScopedApi } from '../api/customer-scoped-api'\nimport { getSDKErrorReason, NotFoundError, SDKError } from '../internal/errors'\nimport type { CollectionType } from '../collection/types'\nimport {\n COMMUNITY_ENDPOINT_OPERATIONS,\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\n\ntype RawCommunityPost = CollectionType<'posts'>\ntype RawCommunityComment = CollectionType<'comments'>\ntype RawCommunityReaction = CollectionType<'reactions'>\ntype RawCommunityBookmark = CollectionType<'bookmarks'>\n\nexport interface CommunityClientOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport type CommunityPublicMediaAsset =\n | string\n | {\n id?: string | number | null\n alt?: string | null\n width?: number | null\n height?: number | null\n mimeType?: string | null\n filename?: string | null\n url?: string | null\n sizes?: Record<\n string,\n {\n width?: number | null\n height?: number | null\n mimeType?: string | null\n filename?: string | null\n url?: string | null\n }\n > | null\n }\n\nexport type CommunityPublicReference =\n | string\n | {\n id?: string | number | null\n title?: string | null\n name?: string | null\n slug?: string | null\n displayName?: string | null\n handle?: string | null\n color?: string | null\n image?: CommunityPublicMediaAsset | null\n thumbnail?: CommunityPublicMediaAsset | null\n avatar?: CommunityPublicMediaAsset | null\n }\n\nexport interface CommunityPublicAuthorSnapshot {\n displayName?: string | null\n handle?: string | null\n avatarUrl?: string | null\n avatar?: CommunityPublicMediaAsset | null\n}\n\n/** Public read shape for projected community post endpoints. */\nexport interface CommunityPost {\n id: RawCommunityPost['id']\n title?: RawCommunityPost['title']\n slug?: RawCommunityPost['slug']\n content?: RawCommunityPost['content']\n status?: RawCommunityPost['status']\n thumbnail?: CommunityPublicMediaAsset | null\n categories?: CommunityPublicReference[] | null\n tags?: CommunityPublicReference[] | null\n authorProfile?: CommunityPublicReference | null\n authorSnapshot?: CommunityPublicAuthorSnapshot | null\n viewCount?: RawCommunityPost['viewCount']\n commentCount?: RawCommunityPost['commentCount']\n reactionCount?: RawCommunityPost['reactionCount']\n isPinned?: RawCommunityPost['isPinned']\n allowsComments?: RawCommunityPost['allowsComments']\n isEdited?: RawCommunityPost['isEdited']\n editedAt?: RawCommunityPost['editedAt']\n lastActivityAt?: RawCommunityPost['lastActivityAt']\n publishedAt?: RawCommunityPost['publishedAt']\n createdAt: RawCommunityPost['createdAt']\n updatedAt: RawCommunityPost['updatedAt']\n}\n\n/** Public read shape for projected community comment endpoints. */\nexport interface CommunityComment {\n id: RawCommunityComment['id']\n body?: RawCommunityComment['body']\n post?: CommunityPublicReference | null\n parent?: CommunityPublicReference | null\n rootComment?: CommunityPublicReference | null\n authorProfile?: CommunityPublicReference | null\n authorSnapshot?: CommunityPublicAuthorSnapshot | null\n depth?: RawCommunityComment['depth']\n status?: RawCommunityComment['status']\n reactionCount?: RawCommunityComment['reactionCount']\n replyCount?: RawCommunityComment['replyCount']\n isEdited?: RawCommunityComment['isEdited']\n editedAt?: RawCommunityComment['editedAt']\n createdAt: RawCommunityComment['createdAt']\n updatedAt: RawCommunityComment['updatedAt']\n}\n\n/** @deprecated Use {@link CommunityComment}. */\nexport type Comment = CommunityComment\n\n/** Public read shape for `post-categories`. */\nexport type CommunityPostCategory = CollectionType<'post-categories'>\n\n/** Public read shape for `post-tags`. */\nexport type CommunityPostTag = CollectionType<'post-tags'>\n\nexport type CommunityPostListSort =\n | 'createdAt'\n | '-createdAt'\n | 'lastActivityAt'\n | '-lastActivityAt'\n | 'viewCount'\n | '-viewCount'\n | 'commentCount'\n | '-commentCount'\n\nexport type CommunityCommentListSort = 'createdAt' | '-createdAt'\n\nexport interface Reaction {\n id: string\n post?: CommunityPublicReference | null\n comment?: CommunityPublicReference | null\n type?: CommunityPublicReference | null\n createdAt?: string\n updatedAt?: string\n [key: string]: unknown\n}\n\nexport interface ReactionSummary {\n counts: Record<string, number>\n total: number\n userReactions: string[]\n}\n\nexport interface Bookmark {\n id: string\n post?: string | CommunityPost | null\n createdAt?: string\n updatedAt?: string\n [key: string]: unknown\n}\n\nexport interface ReactionType {\n id: string\n title: string\n slug: string\n emoji?: string\n [key: string]: unknown\n}\n\nexport interface PaginatedResponse<T> {\n docs: T[]\n totalDocs: number\n limit: number\n totalPages: number\n page: number\n pagingCounter: number\n hasPrevPage: boolean\n hasNextPage: boolean\n prevPage: number | null\n nextPage: number | null\n}\n\nexport type CommunityPostMutationResponse = CommunityPost | RawCommunityPost\nexport type CommunityCommentMutationResponse =\n | CommunityComment\n | RawCommunityComment\nexport type CommunityReactionMutationResponse = Reaction | RawCommunityReaction\nexport type CommunityBookmarkMutationResponse = Bookmark | RawCommunityBookmark\n\nconst DEFAULT_POST_LIST_SORT: CommunityPostListSort = '-lastActivityAt'\nconst DEFAULT_COMMENT_LIST_SORT: CommunityCommentListSort = '-createdAt'\n\nfunction unwrapPayloadDoc<T>(value: T | { doc: T }): T {\n if (value && typeof value === 'object' && 'doc' in value) {\n return (value as { doc: T }).doc\n }\n return value as T\n}\n\nfunction hasCanonicalNotFoundReason(error: NotFoundError): boolean {\n return getSDKErrorReason(error) === 'not_found'\n}\n\nexport class CommunityClient extends RawCustomerScopedApi {\n private readonly requiresSafePublicRawReads: boolean\n\n constructor(options: CommunityClientOptions) {\n super('CommunityClient', { ...options, requiresCredential: false })\n this.requiresSafePublicRawReads = !options.secretKey\n }\n\n private buildQuery(\n params?: Record<string, string | number | undefined>,\n ): string {\n if (!params) return ''\n const entries = Object.entries(params)\n .filter((e): e is [string, string | number] => e[1] !== undefined)\n .map(([k, v]) => [k, String(v)])\n return entries.length ? `?${new URLSearchParams(entries).toString()}` : ''\n }\n\n private withSafePublicRawReadQuery(query: string): string {\n if (!this.requiresSafePublicRawReads) return query\n if (!query) return '?depth=0&joins=false'\n return `?depth=0&joins=false&${query.slice(1)}`\n }\n\n private buildSafePublicRawListQuery(params?: {\n page?: number\n limit?: number\n }): string {\n if (!this.requiresSafePublicRawReads) {\n return this.buildQuery(params)\n }\n\n const queryParams: Record<string, string | number> = {}\n if (params?.page !== undefined) queryParams.page = params.page\n if (params?.limit !== undefined) queryParams.limit = params.limit\n\n return this.withSafePublicRawReadQuery(this.buildQuery(queryParams))\n }\n\n private buildPostsListQuery(params?: {\n page?: number\n limit?: number\n categoryId?: string\n tagId?: string\n sort?: CommunityPostListSort\n }): string {\n const urlParams = new URLSearchParams()\n const sort = params?.sort ?? DEFAULT_POST_LIST_SORT\n urlParams.set('sort', sort)\n if (params?.limit !== undefined)\n urlParams.set('limit', String(params.limit))\n if (params?.page !== undefined) urlParams.set('page', String(params.page))\n if (params?.categoryId !== undefined) {\n urlParams.set('where[categories][in]', params.categoryId)\n }\n if (params?.tagId !== undefined) {\n urlParams.set('where[tags][in]', params.tagId)\n }\n return `/api/posts/public?${urlParams.toString()}`\n }\n\n private buildCommentsListQuery(params: {\n postId?: string\n parentId?: string\n rootComment?: string\n topLevelOnly?: boolean\n page?: number\n limit?: number\n sort?: CommunityCommentListSort\n }): string {\n const urlParams = new URLSearchParams()\n const sort = params.sort ?? DEFAULT_COMMENT_LIST_SORT\n urlParams.set('sort', sort)\n if (params.postId !== undefined) {\n urlParams.set('where[post][equals]', params.postId)\n }\n if (params.parentId !== undefined) {\n urlParams.set('where[parent][equals]', params.parentId)\n }\n if (params.rootComment !== undefined) {\n urlParams.set('where[rootComment][equals]', params.rootComment)\n }\n if (params.topLevelOnly) {\n urlParams.set('where[parent][exists]', 'false')\n }\n if (params.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params.page !== undefined) urlParams.set('page', String(params.page))\n return `/api/comments/public?${urlParams.toString()}`\n }\n\n private async execute<T>(\n endpoint: string,\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n body?: unknown,\n ): Promise<T> {\n return this.request<T>(endpoint, { method, body })\n }\n\n private async executeDoc<T>(\n endpoint: string,\n method: 'POST' | 'PATCH',\n body?: unknown,\n ): Promise<T> {\n const response = await this.execute<T | { doc: T }>(endpoint, method, body)\n return unwrapPayloadDoc(response)\n }\n\n createPost(params: {\n title?: string | null\n content?: unknown\n categories?: string[]\n thumbnail?: string\n }): Promise<CommunityPostMutationResponse> {\n return this.executeDoc<CommunityPostMutationResponse>(\n '/api/posts',\n 'POST',\n params,\n )\n }\n\n /**\n * Public post feed. Server applies the same visibility contract as\n * `communityPostRead` (published + visible + moderation-safe).\n */\n listPosts(params?: {\n page?: number\n limit?: number\n categoryId?: string\n tagId?: string\n sort?: CommunityPostListSort\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n this.buildPostsListQuery(params),\n 'GET',\n )\n }\n\n /**\n * Public post detail projected by the same allowlist as the public feed.\n * Missing, hidden, and cross-tenant posts all resolve to `null`.\n */\n async getPost(params: { postId: string }): Promise<CommunityPost | null> {\n const query = new URLSearchParams({ postId: params.postId })\n try {\n return await this.execute<CommunityPost>(\n resolveOperationPath(COMMUNITY_ENDPOINT_OPERATIONS.posts.detail, {\n query,\n }),\n resolveOperationMethod(COMMUNITY_ENDPOINT_OPERATIONS.posts.detail),\n )\n } catch (error) {\n if (error instanceof NotFoundError && hasCanonicalNotFoundReason(error)) {\n return null\n }\n throw error\n }\n }\n\n listPostCategories(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPostCategory>> {\n return this.execute<PaginatedResponse<CommunityPostCategory>>(\n `/api/post-categories${this.buildSafePublicRawListQuery(params)}`,\n 'GET',\n )\n }\n\n listPostTags(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPostTag>> {\n return this.execute<PaginatedResponse<CommunityPostTag>>(\n `/api/post-tags${this.buildSafePublicRawListQuery(params)}`,\n 'GET',\n )\n }\n\n getMyPosts(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n `/api/posts/my${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n getTrending(params?: {\n page?: number\n limit?: number\n period?: string\n metric?: 'reactions' | 'comments' | 'views' | 'activity'\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n `/api/posts/trending${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n incrementView(params: { postId: string }): Promise<{ viewCount: number }> {\n return this.execute<{ viewCount: number }>(\n `/api/posts/${params.postId}/view`,\n 'POST',\n )\n }\n\n reportPost(params: {\n postId: string\n reason?: string\n reasonDetail?: string\n }): Promise<{ success: boolean }> {\n const { postId, ...body } = params\n return this.execute<{ success: boolean }>(\n `/api/posts/${postId}/report`,\n 'POST',\n body,\n )\n }\n\n // Comments\n\n createComment(params: {\n postId: string\n body: string\n parentId?: string\n }): Promise<CommunityCommentMutationResponse> {\n const { postId, parentId, body: commentBody } = params\n const body: Record<string, unknown> = { post: postId, body: commentBody }\n if (parentId !== undefined) {\n body.parent = parentId\n }\n return this.executeDoc<CommunityCommentMutationResponse>(\n '/api/comments',\n 'POST',\n body,\n )\n }\n\n /**\n * List comments for a post.\n *\n * - Default: all visible comments on the post (any depth).\n * - `topLevelOnly: true`: only root comments (`parent` unset).\n * - `rootComment`: comments belonging to a thread rooted at that comment.\n */\n listComments(params: {\n postId: string\n page?: number\n limit?: number\n rootComment?: string\n topLevelOnly?: boolean\n sort?: CommunityCommentListSort\n }): Promise<PaginatedResponse<CommunityComment>> {\n const { postId, page, limit, rootComment, topLevelOnly, sort } = params\n return this.execute<PaginatedResponse<CommunityComment>>(\n this.buildCommentsListQuery({\n postId,\n page,\n limit,\n rootComment,\n topLevelOnly,\n sort,\n }),\n 'GET',\n )\n }\n\n /** Direct replies to a comment (`where[parent][equals]`). */\n listReplies(params: {\n commentId: string\n page?: number\n limit?: number\n sort?: CommunityCommentListSort\n }): Promise<PaginatedResponse<CommunityComment>> {\n const { commentId, page, limit, sort } = params\n return this.execute<PaginatedResponse<CommunityComment>>(\n this.buildCommentsListQuery({\n parentId: commentId,\n page,\n limit,\n sort,\n }),\n 'GET',\n )\n }\n\n updateComment(params: {\n commentId: string\n body: string\n }): Promise<CommunityCommentMutationResponse> {\n const { commentId, body } = params\n return this.executeDoc<CommunityCommentMutationResponse>(\n `/api/comments/${commentId}`,\n 'PATCH',\n { body },\n )\n }\n\n deleteComment(params: {\n commentId: string\n }): Promise<CommunityCommentMutationResponse> {\n return this.execute<CommunityCommentMutationResponse>(\n `/api/comments/${params.commentId}`,\n 'DELETE',\n )\n }\n\n reportComment(params: {\n commentId: string\n reason?: string\n reasonDetail?: string\n }): Promise<{ success: boolean }> {\n const { commentId, ...body } = params\n return this.execute<{ success: boolean }>(\n `/api/comments/${commentId}/report`,\n 'POST',\n body,\n )\n }\n\n // Reactions\n\n addReaction(params: {\n postId: string\n typeSlug?: string\n /** @deprecated Use `typeSlug`. */\n type?: string\n }): Promise<CommunityReactionMutationResponse> {\n const { postId, typeSlug, type } = params\n const reactionType = typeSlug ?? type\n if (!reactionType) {\n throw new SDKError(\n 'validation_failed',\n 'addReaction requires typeSlug (or deprecated type)',\n 400,\n )\n }\n return this.executeDoc<CommunityReactionMutationResponse>(\n '/api/reactions',\n 'POST',\n {\n post: postId,\n type: reactionType,\n },\n )\n }\n\n removeReaction(params: {\n postId: string\n type: string\n }): Promise<{ success: boolean }> {\n const { postId, type } = params\n return this.execute<{ success: boolean }>(\n `/api/posts/${postId}/react?type=${encodeURIComponent(type)}`,\n 'DELETE',\n )\n }\n\n addCommentReaction(params: {\n commentId: string\n typeSlug?: string\n /** @deprecated Use `typeSlug`. */\n type?: string\n }): Promise<CommunityReactionMutationResponse> {\n const { commentId, typeSlug, type } = params\n const reactionType = typeSlug ?? type\n if (!reactionType) {\n throw new SDKError(\n 'validation_failed',\n 'addCommentReaction requires typeSlug (or deprecated type)',\n 400,\n )\n }\n return this.executeDoc<CommunityReactionMutationResponse>(\n '/api/reactions',\n 'POST',\n {\n comment: commentId,\n type: reactionType,\n },\n )\n }\n\n removeCommentReaction(params: {\n commentId: string\n type: string\n }): Promise<{ success: boolean }> {\n const { commentId, type } = params\n return this.execute<{ success: boolean }>(\n `/api/comments/${commentId}/react?type=${encodeURIComponent(type)}`,\n 'DELETE',\n )\n }\n\n getReactionSummary(params: { postId: string }): Promise<ReactionSummary> {\n return this.execute<ReactionSummary>(\n `/api/posts/${params.postId}/reactions`,\n 'GET',\n )\n }\n\n getCommentReactionSummary(params: {\n commentId: string\n }): Promise<ReactionSummary> {\n return this.execute<ReactionSummary>(\n `/api/comments/${params.commentId}/reactions`,\n 'GET',\n )\n }\n\n getReactionTypes(): Promise<PaginatedResponse<ReactionType>> {\n return this.execute<PaginatedResponse<ReactionType>>(\n `/api/reaction-types${this.buildSafePublicRawListQuery({ limit: 100 })}`,\n 'GET',\n )\n }\n\n // Bookmarks\n\n addBookmark(params: {\n postId: string\n }): Promise<CommunityBookmarkMutationResponse> {\n return this.executeDoc<CommunityBookmarkMutationResponse>(\n '/api/bookmarks',\n 'POST',\n {\n post: params.postId,\n },\n )\n }\n\n removeBookmark(params: { postId: string }): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n `/api/posts/${params.postId}/bookmark`,\n 'DELETE',\n )\n }\n\n getMyBookmarks(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<Bookmark>> {\n return this.execute<PaginatedResponse<Bookmark>>(\n `/api/bookmarks/my${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n // Profiles\n\n listProfileLists(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CollectionType<'customer-profile-lists'>>> {\n return this.execute<\n PaginatedResponse<CollectionType<'customer-profile-lists'>>\n >(\n `/api/customer-profile-lists${this.buildSafePublicRawListQuery(params)}`,\n 'GET',\n )\n }\n\n async getProfileList(\n params: { slug: string } | { id: string },\n ): Promise<CollectionType<'customer-profile-lists'> | null> {\n const query =\n 'slug' in params\n ? `?where[slug][equals]=${encodeURIComponent(params.slug)}&limit=1`\n : `?where[id][equals]=${encodeURIComponent(params.id)}&limit=1`\n const res = await this.execute<\n PaginatedResponse<CollectionType<'customer-profile-lists'>>\n >(\n `/api/customer-profile-lists${this.withSafePublicRawReadQuery(query)}`,\n 'GET',\n )\n return res.docs[0] ?? null\n }\n\n updatePublicProfile(body: {\n displayName?: string | null\n handle?: string | null\n avatar?: string | null\n bio?: string | null\n bioRichText?: CollectionType<'customer-profiles'>['bioRichText']\n }): Promise<CollectionType<'customer-profiles'>> {\n return this.execute<CollectionType<'customer-profiles'>>(\n '/api/customers/me/profile',\n 'PATCH',\n body,\n )\n }\n}\n","import {\n GALLERY_ENDPOINT_OPERATIONS,\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\n\nimport { RawCustomerScopedApi } from '../api/customer-scoped-api'\nimport type { PublicMediaAsset } from '../api/public-media'\nimport type { PayloadFindResponse } from '../client/types'\n\nexport type StorefrontContentReference = {\n id?: string | number | null\n title?: string | null\n name?: string | null\n slug?: string | null\n displayName?: string | null\n handle?: string | null\n color?: string | null\n image?: PublicMediaAsset | null\n thumbnail?: PublicMediaAsset | null\n avatar?: PublicMediaAsset | null\n}\n\nexport type StorefrontLink = {\n id?: string | number | null\n title?: string | null\n subtitle?: string | null\n url?: string | null\n description?: string | null\n slug?: string | null\n type?: 'external' | 'social' | 'internal' | string | null\n platform?: string | null\n opensInNewTab?: boolean | null\n noFollow?: boolean | null\n expiresAt?: string | null\n isFeatured?: boolean | null\n publishedAt?: string | null\n createdAt?: string | null\n updatedAt?: string | null\n categories?: StorefrontContentReference[] | StorefrontContentReference | null\n tags?: StorefrontContentReference[] | StorefrontContentReference | null\n thumbnail?: PublicMediaAsset | null\n icon?: PublicMediaAsset | null\n}\n\nexport type StorefrontGalleryItem = {\n id?: string | number | null\n title?: string | null\n description?: string | null\n content?: unknown\n createdAt?: string | null\n updatedAt?: string | null\n gallery?: StorefrontContentReference | string | null\n /** Missing on older responses; treat it as image. */\n mediaType?: 'image' | 'video'\n image?: PublicMediaAsset | null\n video?: {\n id?: string | number | null\n thumbnail?: PublicMediaAsset | null\n availability: 'ready' | 'processing' | 'unavailable'\n }\n}\n\nexport type StorefrontLinksSort =\n | 'createdAt'\n | '-createdAt'\n | 'updatedAt'\n | '-updatedAt'\n | 'publishedAt'\n | '-publishedAt'\n | 'title'\n | '-title'\n | 'isFeatured'\n | '-isFeatured'\n\nexport type StorefrontGalleryItemsSort =\n | 'manual'\n | 'createdAt'\n | '-createdAt'\n | 'updatedAt'\n | '-updatedAt'\n | 'title'\n | '-title'\n\nexport type StorefrontContentListOptions<TSort extends string = string> = {\n page?: number\n limit?: number\n sort?: TSort\n}\n\nexport type StorefrontLinksListOptions =\n StorefrontContentListOptions<StorefrontLinksSort> & {\n categoryId?: string\n categorySlug?: string\n tagId?: string\n tagSlug?: string\n featured?: boolean\n }\n\nexport type StorefrontGalleryItemsListOptions =\n StorefrontContentListOptions<StorefrontGalleryItemsSort> &\n (\n | {\n galleryId: string\n gallerySlug?: string\n }\n | {\n galleryId?: string\n gallerySlug: string\n }\n )\n\nexport type ContentClientOptions = {\n publishableKey: string\n apiUrl?: string\n onRequestId?: (id: string | null) => void\n}\n\nclass PublicContentApi extends RawCustomerScopedApi {\n get<T>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET' })\n }\n\n galleryItems<T>(options: StorefrontGalleryItemsListOptions): Promise<T> {\n const operation = GALLERY_ENDPOINT_OPERATIONS.items.storefront\n return this.request<T>(\n resolveOperationPath(operation, {\n query: galleryItemsListQuery(options),\n }),\n { method: resolveOperationMethod(operation) },\n )\n }\n}\n\nfunction appendCommonParams<TSort extends string>(\n search: URLSearchParams,\n options: StorefrontContentListOptions<TSort> | undefined,\n defaultSort: string,\n): void {\n search.set('sort', options?.sort ?? defaultSort)\n if (options?.page != null) search.set('page', String(options.page))\n if (options?.limit != null) search.set('limit', String(options.limit))\n}\n\nfunction linksListPath(options?: StorefrontLinksListOptions): string {\n const search = new URLSearchParams()\n appendCommonParams(search, options, '-publishedAt,-createdAt')\n if (options?.categoryId) search.set('categoryId', options.categoryId)\n if (options?.categorySlug) {\n search.set('categorySlug', options.categorySlug)\n }\n if (options?.tagId) search.set('tagId', options.tagId)\n if (options?.tagSlug) search.set('tagSlug', options.tagSlug)\n if (options?.featured != null)\n search.set('featured', String(options.featured))\n return `/api/links/storefront?${search}`\n}\n\nfunction galleryItemsListQuery(\n options: StorefrontGalleryItemsListOptions,\n): URLSearchParams {\n const search = new URLSearchParams()\n appendCommonParams(search, options, 'manual')\n if (options?.galleryId) search.set('galleryId', options.galleryId)\n if (options?.gallerySlug) search.set('gallerySlug', options.gallerySlug)\n return search\n}\n\nexport class ContentClient {\n readonly links: {\n list: (\n options?: StorefrontLinksListOptions,\n ) => Promise<PayloadFindResponse<StorefrontLink>>\n }\n\n readonly galleryItems: {\n list: (\n options: StorefrontGalleryItemsListOptions,\n ) => Promise<PayloadFindResponse<StorefrontGalleryItem>>\n }\n\n constructor(options: ContentClientOptions) {\n const api = new PublicContentApi('ContentClient', {\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n onRequestId: options.onRequestId,\n requiresCredential: false,\n })\n\n this.links = {\n list: (params) =>\n api.get<PayloadFindResponse<StorefrontLink>>(linksListPath(params)),\n }\n\n this.galleryItems = {\n list: (params) =>\n api.galleryItems<PayloadFindResponse<StorefrontGalleryItem>>(params),\n }\n }\n}\n","import { createApiError } from '../internal/errors'\nimport type { CheckoutPaymentSessionRef } from './checkout-api'\n\ntype RecordValue = Record<string, unknown>\n\nconst CART_STATUSES = ['active', 'completed', 'abandoned'] as const\nconst MAX_CART_LINE_QUANTITY = 99\nconst MAX_COMMERCE_SHORT_TEXT_LENGTH = 200\nconst MAX_COMMERCE_ADDRESS_LENGTH = 500\nconst MAX_COMMERCE_EMAIL_LENGTH = 254\nconst MAX_COMMERCE_PHONE_LENGTH = 32\nconst MAX_COMMERCE_POSTAL_CODE_LENGTH = 32\nconst MAX_COMMERCE_EXTENSION_VALUE_LENGTH = 500\nconst MAX_COMMERCE_RESOURCE_ID_LENGTH = 255\nconst MAX_COMMERCE_CAPABILITY_LENGTH = 512\nconst MAX_CART_DISCOUNT_CODE_LENGTH = 128\nconst ORDER_FINANCIAL_STATUSES = [\n 'pending',\n 'authorized',\n 'expired',\n 'partially_paid',\n 'paid',\n 'canceled',\n 'partially_refunded',\n 'refunded',\n 'reconciliation_required',\n] as const\nconst ORDER_FULFILLMENT_STATUSES = [\n 'unfulfilled',\n 'in_progress',\n 'on_hold',\n 'partially_fulfilled',\n 'shipped',\n 'fulfilled',\n 'canceled',\n] as const\nconst ORDER_RETURN_STATUSES = [\n 'no_return',\n 'return_requested',\n 'in_progress',\n 'returned',\n] as const\nconst ORDER_CONFIRMATION_STATUSES = ['unconfirmed', 'confirmed'] as const\nconst ORDER_PRIMARY_DISPLAY_STATUSES = [\n 'pending',\n 'paid',\n 'canceled',\n 'refunded',\n 'preparing',\n 'shipped',\n 'delivered',\n 'confirmed',\n] as const\nconst CHECKOUT_STATUSES = ['open', 'placed', 'abandoned'] as const\nconst ABANDONED_REASONS = ['expired', 'customer', 'operator'] as const\ntype ManagedPaymentProvider = CheckoutPaymentSessionRef['provider']\n\nfunction managedPaymentProviders<\n const Providers extends readonly ManagedPaymentProvider[],\n>(\n providers: Providers &\n (ManagedPaymentProvider extends Providers[number] ? unknown : never),\n): Providers {\n return providers\n}\n\nconst PAYMENT_PROVIDERS = managedPaymentProviders([\n 'toss',\n 'portone',\n 'stripe',\n] as const)\n/**\n * Provider-specific cancel methods that can recover an applied cancellation.\n * `'stripe'` is accept-only until a Stripe method exists, so its mismatches\n * stay generic invalid-canonical errors.\n */\nconst CANCEL_RECOVERY_METHODS = {\n toss: 'cancel()',\n portone: 'cancelPortOne()',\n stripe: null,\n} as const satisfies Record<ManagedPaymentProvider, string | null>\n/** Same raw-value guards as the contracts Stripe action authority. */\n// eslint-disable-next-line no-control-regex -- rejecting C0 controls is the point.\nconst STRIPE_RETURN_URL_RAW_CHARACTERS = /^[^\\s\\u0000-\\u001F\\u007F\\\\]+$/\n// Exactly two slashes and a non-empty authority without `@`: WHATWG ignores\n// slash count for special schemes, so `https:@host` would hide an empty userinfo.\nconst STRIPE_RETURN_URL_AUTHORITY =\n /^[A-Za-z][A-Za-z0-9+.-]*:\\/\\/[^/?#@]+(?:[/?#]|$)/\nconst PAYMENT_PROVIDER_STATUSES = [\n 'requires_payment_method',\n 'requires_action',\n 'requires_confirmation',\n 'initializing',\n 'processing',\n 'authorized',\n 'canceling',\n 'unknown',\n 'captured',\n 'failed',\n 'canceled',\n] as const\nconst PAYMENT_FAILURE_REASONS = [\n 'payment_declined',\n 'authentication_failed',\n 'authorization_expired',\n 'payment_method_unavailable',\n 'provider_terminal_failure',\n 'unknown_provider_terminal_failure',\n] as const\nconst PAYMENT_RECONCILIATION_REASONS = [\n 'provider_outcome_unknown',\n 'local_commit_ambiguous',\n 'amount_mismatch',\n 'currency_mismatch',\n 'excess_capture_pending_order',\n 'inventory_unavailable',\n 'admission_unavailable',\n 'excess_capture',\n 'late_capture',\n 'cross_checkout_duplicate',\n] as const\nconst CART_WARNING_CODES = [\n 'DISCOUNT_CODE_NOT_HONOURED',\n 'DISCOUNT_CURRENTLY_INACTIVE',\n 'DISCOUNT_CUSTOMER_NOT_ELIGIBLE',\n 'DISCOUNT_CUSTOMER_USAGE_LIMIT_REACHED',\n 'DISCOUNT_ELIGIBLE_CUSTOMER_MISSING',\n 'DISCOUNT_NO_ENTITLED_LINE_ITEMS',\n 'DISCOUNT_NO_ENTITLED_SHIPPING_LINES',\n 'DISCOUNT_NOT_FOUND',\n 'DISCOUNT_PURCHASE_NOT_IN_RANGE',\n 'DISCOUNT_USAGE_LIMIT_REACHED',\n 'MERCHANDISE_NOT_ENOUGH_STOCK',\n 'MERCHANDISE_OUT_OF_STOCK',\n] as const\n\nexport function invalidCanonicalResponse(\n resource: string,\n details: Record<string, unknown>,\n): never {\n throw createApiError(\n `Invalid canonical ${resource} response.`,\n 502,\n { resource, ...details },\n `The server returned an incompatible ${resource} response.`,\n 'Verify that the Console commerce contract is deployed before using this SDK version.',\n )\n}\n\nfunction fail(resource: string, path: string, expected: string): never {\n invalidCanonicalResponse(resource, { path, expected })\n}\n\nfunction providerMismatch(\n resource: string,\n expected: ManagedPaymentProvider,\n actual: ManagedPaymentProvider,\n operation?: 'cancel',\n): never {\n const method = CANCEL_RECOVERY_METHODS[actual]\n if (operation === 'cancel' && method !== null) {\n throw createApiError(\n `Canonical ${resource} response provider mismatch: expected ${expected}, received ${actual}.`,\n 502,\n { resource, path: '$.provider', expected, actual },\n `The server applied the cancellation to a ${actual} PaymentSession, but this SDK method expects ${expected}.`,\n `Re-invoke ${method} with the same idempotencyKey; do not create a new key.`,\n )\n }\n invalidCanonicalResponse(resource, {\n path: '$.provider',\n expected,\n actual,\n })\n}\n\nfunction record(value: unknown, resource: string, path: string): RecordValue {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n fail(resource, path, 'object')\n }\n return value as RecordValue\n}\n\nfunction exact(\n value: RecordValue,\n required: readonly string[],\n optional: readonly string[],\n resource: string,\n path: string,\n): void {\n for (const key of required) {\n if (!(key in value)) fail(resource, `${path}.${key}`, 'required field')\n }\n const allowed = new Set([...required, ...optional])\n const unexpected = Object.keys(value).find((key) => !allowed.has(key))\n if (unexpected) fail(resource, `${path}.${unexpected}`, 'no unknown fields')\n}\n\n// A resource may come from either server generation, never a partial\n// expansion: any new key makes the whole set required by the caller's exact().\nfunction responseExtensionKeys(\n value: RecordValue,\n keys: readonly string[],\n resource: string,\n path: string,\n): string[] {\n if (!keys.some((key) => Object.prototype.hasOwnProperty.call(value, key)))\n return []\n enumValue(\n value.deliveryMethod,\n ['shipping', 'pickup'],\n resource,\n `${path}.deliveryMethod`,\n )\n return [...keys]\n}\n\nfunction string(value: unknown, resource: string, path: string): string {\n if (typeof value !== 'string' || value.length === 0) {\n fail(resource, path, 'non-empty string')\n }\n return value\n}\n\nfunction boundedString(\n value: unknown,\n maxLength: number,\n resource: string,\n path: string,\n allowEmpty = false,\n): string {\n if (\n typeof value !== 'string' ||\n (!allowEmpty && value.length === 0) ||\n value.length > maxLength\n ) {\n fail(\n resource,\n path,\n `${allowEmpty ? '' : 'non-empty '}string of at most ${maxLength} characters`,\n )\n }\n return value\n}\n\nfunction nullableString(value: unknown, resource: string, path: string): void {\n if (value !== null && typeof value !== 'string') {\n fail(resource, path, 'string or null')\n }\n}\n\nfunction nullableNonEmptyString(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== null) string(value, resource, path)\n}\n\nfunction nonBlankString(\n value: unknown,\n resource: string,\n path: string,\n): string {\n const parsed = string(value, resource, path)\n if (parsed.trim().length === 0) {\n fail(resource, path, 'non-blank string')\n }\n return parsed\n}\n\nfunction nullableNonBlankString(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== null) nonBlankString(value, resource, path)\n}\n\nfunction nullableResourceId(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== null) {\n boundedString(value, MAX_COMMERCE_RESOURCE_ID_LENGTH, resource, path)\n }\n}\n\nfunction cartLineQuantity(\n value: unknown,\n resource: string,\n path: string,\n): number {\n const quantity = positiveInteger(value, resource, path)\n if (quantity > MAX_CART_LINE_QUANTITY) {\n fail(resource, path, `integer between 1 and ${MAX_CART_LINE_QUANTITY}`)\n }\n return quantity\n}\n\nfunction boolean(value: unknown, resource: string, path: string): void {\n if (typeof value !== 'boolean') fail(resource, path, 'boolean')\n}\n\nfunction safeMinor(value: unknown, resource: string, path: string): number {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n fail(resource, path, 'non-negative safe integer')\n }\n return value as number\n}\n\nfunction positiveInteger(\n value: unknown,\n resource: string,\n path: string,\n): number {\n if (!Number.isSafeInteger(value) || (value as number) <= 0) {\n fail(resource, path, 'positive safe integer')\n }\n return value as number\n}\n\nfunction enumValue(\n value: unknown,\n values: readonly string[],\n resource: string,\n path: string,\n): string {\n if (typeof value !== 'string' || !values.includes(value)) {\n fail(resource, path, values.join(' | '))\n }\n return value\n}\n\nfunction timestamp(value: unknown, resource: string, path: string): void {\n if (\n typeof value !== 'string' ||\n !/^\\d{4}-\\d{2}-\\d{2}T.*(?:Z|[+-]\\d{2}:\\d{2})$/.test(value) ||\n !Number.isFinite(Date.parse(value))\n ) {\n fail(resource, path, 'ISO 8601 timestamp with offset')\n }\n}\n\nfunction currency(value: unknown, resource: string, path: string): void {\n if (typeof value !== 'string' || !/^[A-Z]{3}$/.test(value)) {\n fail(resource, path, 'three-letter uppercase currency code')\n }\n}\n\nfunction array(value: unknown, resource: string, path: string): unknown[] {\n if (!Array.isArray(value)) fail(resource, path, 'array')\n return value\n}\n\nfunction optionalNullableNumber(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== undefined && value !== null && typeof value !== 'number') {\n fail(resource, path, 'number or null')\n }\n}\n\nfunction validateMediaSize(value: unknown, resource: string, path: string) {\n const item = record(value, resource, path)\n exact(\n item,\n [],\n ['width', 'height', 'mimeType', 'filename', 'url'],\n resource,\n path,\n )\n optionalNullableNumber(item.width, resource, `${path}.width`)\n optionalNullableNumber(item.height, resource, `${path}.height`)\n for (const key of ['mimeType', 'filename', 'url'] as const) {\n if (item[key] !== undefined)\n nullableString(item[key], resource, `${path}.${key}`)\n }\n}\n\nfunction validateMedia(value: unknown, resource: string, path: string): void {\n if (typeof value === 'string') return\n const media = record(value, resource, path)\n exact(\n media,\n [],\n ['id', 'alt', 'width', 'height', 'mimeType', 'filename', 'url', 'sizes'],\n resource,\n path,\n )\n if (\n media.id !== undefined &&\n media.id !== null &&\n typeof media.id !== 'string' &&\n typeof media.id !== 'number'\n ) {\n fail(resource, `${path}.id`, 'string, number, or null')\n }\n for (const key of ['alt', 'mimeType', 'filename', 'url'] as const) {\n if (media[key] !== undefined)\n nullableString(media[key], resource, `${path}.${key}`)\n }\n optionalNullableNumber(media.width, resource, `${path}.width`)\n optionalNullableNumber(media.height, resource, `${path}.height`)\n if (media.sizes !== undefined) {\n const sizes = record(media.sizes, resource, `${path}.sizes`)\n Object.entries(sizes).forEach(([key, size]) =>\n validateMediaSize(size, resource, `${path}.sizes.${key}`),\n )\n }\n}\n\nfunction validateReference(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const ref = record(value, resource, path)\n exact(ref, ['id', 'title', 'handle', 'image'], [], resource, path)\n string(ref.id, resource, `${path}.id`)\n string(ref.title, resource, `${path}.title`)\n if (ref.handle !== null) string(ref.handle, resource, `${path}.handle`)\n if (ref.image !== null) validateMedia(ref.image, resource, `${path}.image`)\n}\n\nfunction validateAdmission(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const admission = record(value, resource, path)\n exact(\n admission,\n ['eventId', 'occurrenceId', 'admissionTypeId'],\n [],\n resource,\n path,\n )\n string(admission.eventId, resource, `${path}.eventId`)\n string(admission.occurrenceId, resource, `${path}.occurrenceId`)\n string(admission.admissionTypeId, resource, `${path}.admissionTypeId`)\n}\n\nfunction compareAdmissions(left: RecordValue, right: RecordValue): number {\n for (const field of ['eventId', 'occurrenceId', 'admissionTypeId'] as const) {\n if ((left[field] as string) < (right[field] as string)) return -1\n if ((left[field] as string) > (right[field] as string)) return 1\n }\n return 0\n}\n\nfunction validateAdmissions(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const admissions = array(value, resource, path)\n if (admissions.length > 32) fail(resource, path, 'at most 32 admissions')\n let prior: RecordValue | undefined\n admissions.forEach((admission, index) => {\n validateAdmission(admission, resource, `${path}[${index}]`)\n const item = admission as RecordValue\n const comparison = prior ? compareAdmissions(item, prior) : undefined\n if (comparison !== undefined && comparison <= 0) {\n fail(resource, `${path}[${index}]`, 'unique canonical-sorted admissions')\n }\n prior = item\n })\n}\n\nfunction validateAttributes(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const attributes = array(value, resource, path)\n if (attributes.length > 50) fail(resource, path, 'at most 50 attributes')\n const keys = new Set<string>()\n attributes.forEach((value, index) => {\n const itemPath = `${path}[${index}]`\n const attribute = record(value, resource, itemPath)\n exact(attribute, ['key', 'value'], [], resource, itemPath)\n const key = string(attribute.key, resource, `${itemPath}.key`)\n if (key.length > 40 || key.startsWith('__') || keys.has(key)) {\n fail(\n resource,\n `${itemPath}.key`,\n 'unique, non-reserved key of at most 40 characters',\n )\n }\n keys.add(key)\n if (typeof attribute.value !== 'string' || attribute.value.length > 500) {\n fail(resource, `${itemPath}.value`, 'string of at most 500 characters')\n }\n })\n}\n\nfunction validateCustomer(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const customer = record(value, resource, path)\n exact(customer, ['email'], ['name', 'phone'], resource, path)\n const email = boundedString(\n customer.email,\n MAX_COMMERCE_EMAIL_LENGTH,\n resource,\n `${path}.email`,\n )\n // Mirrors Zod's default email primitive used by the private contract.\n if (\n !/^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9-]*\\.)+[A-Za-z]{2,}$/.test(\n email,\n )\n ) {\n fail(resource, `${path}.email`, 'email address')\n }\n if (customer.name !== undefined)\n boundedString(\n customer.name,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.name`,\n )\n if (customer.phone !== undefined)\n boundedString(\n customer.phone,\n MAX_COMMERCE_PHONE_LENGTH,\n resource,\n `${path}.phone`,\n )\n}\n\nfunction validateShippingAddress(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const address = record(value, resource, path)\n exact(\n address,\n ['recipientName', 'phone', 'postalCode', 'address', 'detailAddress'],\n ['countryCode', 'regionCode', 'deliveryMessage'],\n resource,\n path,\n )\n boundedString(\n address.recipientName,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.recipientName`,\n )\n boundedString(\n address.phone,\n MAX_COMMERCE_PHONE_LENGTH,\n resource,\n `${path}.phone`,\n )\n boundedString(\n address.postalCode,\n MAX_COMMERCE_POSTAL_CODE_LENGTH,\n resource,\n `${path}.postalCode`,\n )\n for (const key of ['address', 'detailAddress'] as const) {\n boundedString(\n address[key],\n MAX_COMMERCE_ADDRESS_LENGTH,\n resource,\n `${path}.${key}`,\n )\n }\n if (address.countryCode !== undefined) {\n if (\n typeof address.countryCode !== 'string' ||\n address.countryCode.trim().length !== 2\n ) {\n fail(resource, `${path}.countryCode`, 'two-letter country code')\n }\n }\n if (address.regionCode !== undefined) {\n if (\n typeof address.regionCode !== 'string' ||\n address.regionCode.trim().length === 0 ||\n address.regionCode.trim().length > 64\n ) {\n fail(\n resource,\n `${path}.regionCode`,\n 'trimmed string of at most 64 characters',\n )\n }\n }\n if (address.deliveryMessage !== undefined) {\n boundedString(\n address.deliveryMessage,\n MAX_COMMERCE_EXTENSION_VALUE_LENGTH,\n resource,\n `${path}.deliveryMessage`,\n true,\n )\n }\n}\n\nfunction validateOrderReference(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const order = record(value, resource, path)\n exact(order, ['id', 'orderNumber'], [], resource, path)\n string(order.id, resource, `${path}.id`)\n string(order.orderNumber, resource, `${path}.orderNumber`)\n}\n\nfunction validateIntegrationMetadata(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const metadata = record(value, resource, path)\n if (Object.keys(metadata).length > 50)\n fail(resource, path, 'at most 50 entries')\n Object.entries(metadata).forEach(([key, entry]) => {\n if (!key || key.length > 40 || key.includes('[') || key.includes(']')) {\n fail(resource, `${path}.${key}`, 'valid metadata key')\n }\n if (typeof entry !== 'string' || entry.length > 500) {\n fail(resource, `${path}.${key}`, 'string of at most 500 characters')\n }\n })\n}\n\nfunction validateCartItem(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const item = record(value, resource, path)\n exact(\n item,\n [\n 'id',\n 'product',\n 'variant',\n 'admissions',\n 'quantity',\n 'unitPriceMinor',\n 'discountMinor',\n 'estimatedLineTotalMinor',\n 'requiresShipping',\n ],\n [],\n resource,\n path,\n )\n string(item.id, resource, `${path}.id`)\n validateReference(item.product, resource, `${path}.product`)\n validateReference(item.variant, resource, `${path}.variant`)\n validateAdmissions(item.admissions, resource, `${path}.admissions`)\n cartLineQuantity(item.quantity, resource, `${path}.quantity`)\n const unitPrice = safeMinor(\n item.unitPriceMinor,\n resource,\n `${path}.unitPriceMinor`,\n )\n const discount = safeMinor(\n item.discountMinor,\n resource,\n `${path}.discountMinor`,\n )\n const estimatedLineTotal = safeMinor(\n item.estimatedLineTotalMinor,\n resource,\n `${path}.estimatedLineTotalMinor`,\n )\n const quantity = item.quantity as number\n const expectedLineTotal =\n BigInt(unitPrice) * BigInt(quantity) - BigInt(discount)\n if (\n expectedLineTotal < 0n ||\n BigInt(estimatedLineTotal) !== expectedLineTotal\n ) {\n fail(\n resource,\n `${path}.estimatedLineTotalMinor`,\n 'unitPriceMinor * quantity - discountMinor',\n )\n }\n boolean(item.requiresShipping, resource, `${path}.requiresShipping`)\n}\n\nexport function validatePublicCart<T>(value: unknown, resource = 'Cart'): T {\n const cart = record(value, resource, '$')\n exact(\n cart,\n [\n ...responseExtensionKeys(\n cart,\n ['deliveryMethod', 'shippingMinor', 'totalMinor'],\n resource,\n '$',\n ),\n 'id',\n 'status',\n 'revision',\n 'currency',\n 'market',\n 'subtotalMinor',\n 'discountMinor',\n 'estimatedTotalMinor',\n 'discountCodes',\n 'attributes',\n 'items',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n ],\n [],\n resource,\n '$',\n )\n string(cart.id, resource, '$.id')\n enumValue(cart.status, CART_STATUSES, resource, '$.status')\n safeMinor(cart.revision, resource, '$.revision')\n currency(cart.currency, resource, '$.currency')\n const market = record(cart.market, resource, '$.market')\n exact(market, ['id', 'handle', 'name'], [], resource, '$.market')\n for (const key of ['id', 'handle', 'name'] as const)\n string(market[key], resource, `$.market.${key}`)\n const subtotal = safeMinor(cart.subtotalMinor, resource, '$.subtotalMinor')\n const discount = safeMinor(cart.discountMinor, resource, '$.discountMinor')\n const estimatedTotal = safeMinor(\n cart.estimatedTotalMinor,\n resource,\n '$.estimatedTotalMinor',\n )\n array(cart.discountCodes, resource, '$.discountCodes').forEach(\n (value, index) => {\n const itemPath = `$.discountCodes[${index}]`\n const code = record(value, resource, itemPath)\n exact(code, ['code', 'applicable'], [], resource, itemPath)\n boundedString(\n code.code,\n MAX_CART_DISCOUNT_CODE_LENGTH,\n resource,\n `${itemPath}.code`,\n )\n boolean(code.applicable, resource, `${itemPath}.applicable`)\n },\n )\n validateAttributes(cart.attributes, resource, '$.attributes')\n const items = array(cart.items, resource, '$.items')\n items.forEach((item, index) =>\n validateCartItem(item, resource, `$.items[${index}]`),\n )\n const expectedSubtotal = items.reduce<bigint>((total, value) => {\n const item = value as Record<string, unknown>\n return (\n total +\n BigInt(item.unitPriceMinor as number) * BigInt(item.quantity as number)\n )\n }, 0n)\n const expectedDiscount = items.reduce<bigint>((total, value) => {\n const item = value as Record<string, unknown>\n return total + BigInt(item.discountMinor as number)\n }, 0n)\n if (BigInt(subtotal) !== expectedSubtotal) {\n fail(resource, '$.subtotalMinor', 'sum of undiscounted cart line totals')\n }\n if (BigInt(discount) !== expectedDiscount) {\n fail(resource, '$.discountMinor', 'sum of cart line discounts')\n }\n if (\n expectedSubtotal - BigInt(discount) < 0n ||\n BigInt(estimatedTotal) !== expectedSubtotal - BigInt(discount)\n ) {\n fail(resource, '$.estimatedTotalMinor', 'subtotalMinor - discountMinor')\n }\n if ('deliveryMethod' in cart) {\n const shipping = safeMinor(cart.shippingMinor, resource, '$.shippingMinor')\n const total = safeMinor(cart.totalMinor, resource, '$.totalMinor')\n if (BigInt(total) !== BigInt(estimatedTotal) + BigInt(shipping)) {\n fail(resource, '$.totalMinor', 'estimatedTotalMinor + shippingMinor')\n }\n }\n timestamp(cart.expiresAt, resource, '$.expiresAt')\n timestamp(cart.createdAt, resource, '$.createdAt')\n timestamp(cart.updatedAt, resource, '$.updatedAt')\n return value as T\n}\n\nfunction validateWarnings(\n value: unknown,\n resource: string,\n path: string,\n): void {\n array(value, resource, path).forEach((value, index) => {\n const itemPath = `${path}[${index}]`\n const warning = record(value, resource, itemPath)\n exact(warning, ['code', 'message', 'target'], [], resource, itemPath)\n enumValue(warning.code, CART_WARNING_CODES, resource, `${itemPath}.code`)\n string(warning.message, resource, `${itemPath}.message`)\n string(warning.target, resource, `${itemPath}.target`)\n })\n}\n\nexport function validateCartMutationResult<T>(value: unknown): T {\n const result = record(value, 'Cart mutation result', '$')\n exact(result, ['cart', 'warnings'], [], 'Cart mutation result', '$')\n validatePublicCart(result.cart)\n validateWarnings(result.warnings, 'Cart mutation result', '$.warnings')\n return value as T\n}\n\nexport function validateCreateCartResult<T>(value: unknown): T {\n const result = record(value, 'Cart create result', '$')\n exact(\n result,\n ['cart', 'warnings', 'cartToken'],\n [],\n 'Cart create result',\n '$',\n )\n const cart = record(result.cart, 'Cart create result', '$.cart')\n validatePublicCart(cart)\n if (cart.revision !== 0) {\n fail('Cart create result', '$.cart.revision', '0 for a newly created Cart')\n }\n validateWarnings(result.warnings, 'Cart create result', '$.warnings')\n boundedString(\n result.cartToken,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n 'Cart create result',\n '$.cartToken',\n )\n return value as T\n}\n\nexport function validateCartMineResult<T>(value: unknown): T {\n const result = record(value, 'Cart mine result', '$')\n exact(result, ['cart', 'cartToken'], [], 'Cart mine result', '$')\n if (result.cart === null || result.cartToken === null) {\n if (result.cart !== null || result.cartToken !== null) {\n fail('Cart mine result', '$', 'cart and cartToken must both be null')\n }\n } else {\n validatePublicCart(result.cart)\n boundedString(\n result.cartToken,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n 'Cart mine result',\n '$.cartToken',\n )\n }\n return value as T\n}\n\nexport function validateCartMergeResult<T>(value: unknown): T {\n const result = record(value, 'Cart merge result', '$')\n exact(\n result,\n ['cart', 'warnings', 'cartToken', 'resolution', 'merged', 'claimed'],\n [],\n 'Cart merge result',\n '$',\n )\n validatePublicCart(result.cart)\n validateWarnings(result.warnings, 'Cart merge result', '$.warnings')\n boundedString(\n result.cartToken,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n 'Cart merge result',\n '$.cartToken',\n )\n const resolution = enumValue(\n result.resolution,\n ['unchanged', 'claimed', 'merged'],\n 'Cart merge result',\n '$.resolution',\n )\n boolean(result.merged, 'Cart merge result', '$.merged')\n boolean(result.claimed, 'Cart merge result', '$.claimed')\n const expected =\n resolution === 'merged'\n ? [true, false]\n : resolution === 'claimed'\n ? [false, true]\n : [false, false]\n if (result.merged !== expected[0] || result.claimed !== expected[1]) {\n fail('Cart merge result', '$', 'resolution-consistent merged/claimed flags')\n }\n return value as T\n}\n\nfunction validatePublicOrderItem(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const item = record(value, resource, path)\n exact(\n item,\n [\n 'id',\n 'product',\n 'variant',\n 'productTitle',\n 'variantTitle',\n 'sku',\n 'admissions',\n 'quantity',\n 'unitPriceMinor',\n 'discountMinor',\n 'lineTotalMinor',\n 'requiresShipping',\n ],\n [],\n resource,\n path,\n )\n string(item.id, resource, `${path}.id`)\n if (item.product !== null) {\n validateReference(item.product, resource, `${path}.product`)\n }\n if (item.variant !== null) {\n validateReference(item.variant, resource, `${path}.variant`)\n }\n string(item.productTitle, resource, `${path}.productTitle`)\n nullableNonEmptyString(item.variantTitle, resource, `${path}.variantTitle`)\n nullableNonEmptyString(item.sku, resource, `${path}.sku`)\n validateAdmissions(item.admissions, resource, `${path}.admissions`)\n // Order snapshots can contain quantities created before the current cart\n // mutation cap, so only enforce the durable positive-integer invariant here.\n const quantity = positiveInteger(item.quantity, resource, `${path}.quantity`)\n const unitPrice = safeMinor(\n item.unitPriceMinor,\n resource,\n `${path}.unitPriceMinor`,\n )\n const discount = safeMinor(\n item.discountMinor,\n resource,\n `${path}.discountMinor`,\n )\n const lineTotal = safeMinor(\n item.lineTotalMinor,\n resource,\n `${path}.lineTotalMinor`,\n )\n const expected = BigInt(unitPrice) * BigInt(quantity) - BigInt(discount)\n if (expected < 0n || BigInt(lineTotal) !== expected) {\n fail(\n resource,\n `${path}.lineTotalMinor`,\n 'unitPriceMinor * quantity - discountMinor',\n )\n }\n boolean(item.requiresShipping, resource, `${path}.requiresShipping`)\n}\n\nfunction validatePublicOrderAt(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const order = record(value, resource, path)\n exact(\n order,\n [\n ...responseExtensionKeys(\n order,\n ['deliveryMethod', 'pickup', 'source'],\n resource,\n path,\n ),\n 'id',\n 'orderNumber',\n 'amounts',\n 'market',\n 'customerSnapshot',\n 'shippingAddress',\n 'attributes',\n 'items',\n 'financialStatus',\n 'fulfillmentStatus',\n 'returnStatus',\n 'confirmationStatus',\n 'primaryDisplayStatus',\n 'placedAt',\n 'createdAt',\n 'updatedAt',\n ],\n [],\n resource,\n path,\n )\n if ('deliveryMethod' in order) {\n enumValue(\n order.source,\n ['web', 'app', 'manual', 'api', 'import', 'in_person'],\n resource,\n `${path}.source`,\n )\n if (order.deliveryMethod === 'shipping') {\n if (order.pickup !== null)\n fail(resource, `${path}.pickup`, 'null for shipping')\n } else {\n const pickup = record(order.pickup, resource, `${path}.pickup`)\n exact(\n pickup,\n ['status', 'readyAt', 'pickedUpAt'],\n [],\n resource,\n `${path}.pickup`,\n )\n enumValue(\n pickup.status,\n ['pending', 'ready_for_pickup', 'picked_up', 'canceled'],\n resource,\n `${path}.pickup.status`,\n )\n for (const key of ['readyAt', 'pickedUpAt'] as const) {\n if (pickup[key] !== null)\n timestamp(pickup[key], resource, `${path}.pickup.${key}`)\n }\n }\n }\n string(order.id, resource, `${path}.id`)\n string(order.orderNumber, resource, `${path}.orderNumber`)\n\n const amounts = record(order.amounts, resource, `${path}.amounts`)\n exact(\n amounts,\n [\n 'currency',\n 'subtotalMinor',\n 'shippingMinor',\n 'discountMinor',\n 'totalMinor',\n 'refundedMinor',\n 'currentTotalMinor',\n ],\n [],\n resource,\n `${path}.amounts`,\n )\n currency(amounts.currency, resource, `${path}.amounts.currency`)\n const subtotal = safeMinor(\n amounts.subtotalMinor,\n resource,\n `${path}.amounts.subtotalMinor`,\n )\n const shipping = safeMinor(\n amounts.shippingMinor,\n resource,\n `${path}.amounts.shippingMinor`,\n )\n const discount = safeMinor(\n amounts.discountMinor,\n resource,\n `${path}.amounts.discountMinor`,\n )\n const total = safeMinor(\n amounts.totalMinor,\n resource,\n `${path}.amounts.totalMinor`,\n )\n const refunded = safeMinor(\n amounts.refundedMinor,\n resource,\n `${path}.amounts.refundedMinor`,\n )\n const current = safeMinor(\n amounts.currentTotalMinor,\n resource,\n `${path}.amounts.currentTotalMinor`,\n )\n const expectedTotal = BigInt(subtotal) + BigInt(shipping) - BigInt(discount)\n if (expectedTotal < 0n || BigInt(total) !== expectedTotal) {\n fail(\n resource,\n `${path}.amounts.totalMinor`,\n 'subtotalMinor + shippingMinor - discountMinor',\n )\n }\n if (BigInt(total) - BigInt(refunded) < 0n || current !== total - refunded) {\n fail(\n resource,\n `${path}.amounts.currentTotalMinor`,\n 'totalMinor - refundedMinor',\n )\n }\n\n if (order.market !== null) {\n const market = record(order.market, resource, `${path}.market`)\n exact(market, ['id', 'handle', 'name'], [], resource, `${path}.market`)\n for (const key of ['id', 'handle', 'name'] as const) {\n string(market[key], resource, `${path}.market.${key}`)\n }\n }\n validateCustomer(order.customerSnapshot, resource, `${path}.customerSnapshot`)\n if (order.shippingAddress !== null) {\n validateShippingAddress(\n order.shippingAddress,\n resource,\n `${path}.shippingAddress`,\n )\n }\n validateAttributes(order.attributes, resource, `${path}.attributes`)\n\n const items = array(order.items, resource, `${path}.items`)\n if (items.length === 0) fail(resource, `${path}.items`, 'non-empty array')\n items.forEach((item, index) =>\n validatePublicOrderItem(item, resource, `${path}.items[${index}]`),\n )\n const expectedSubtotal = items.reduce<bigint>((sum, value) => {\n const item = value as RecordValue\n return (\n sum +\n BigInt(item.unitPriceMinor as number) * BigInt(item.quantity as number)\n )\n }, 0n)\n const expectedDiscount = items.reduce<bigint>((sum, value) => {\n const item = value as RecordValue\n return sum + BigInt(item.discountMinor as number)\n }, 0n)\n if (BigInt(subtotal) !== expectedSubtotal) {\n fail(resource, `${path}.amounts.subtotalMinor`, 'sum of line subtotals')\n }\n if (BigInt(discount) !== expectedDiscount) {\n fail(resource, `${path}.amounts.discountMinor`, 'sum of line discounts')\n }\n\n enumValue(\n order.financialStatus,\n ORDER_FINANCIAL_STATUSES,\n resource,\n `${path}.financialStatus`,\n )\n enumValue(\n order.fulfillmentStatus,\n ORDER_FULFILLMENT_STATUSES,\n resource,\n `${path}.fulfillmentStatus`,\n )\n enumValue(\n order.returnStatus,\n ORDER_RETURN_STATUSES,\n resource,\n `${path}.returnStatus`,\n )\n enumValue(\n order.confirmationStatus,\n ORDER_CONFIRMATION_STATUSES,\n resource,\n `${path}.confirmationStatus`,\n )\n enumValue(\n order.primaryDisplayStatus,\n ORDER_PRIMARY_DISPLAY_STATUSES,\n resource,\n `${path}.primaryDisplayStatus`,\n )\n timestamp(order.placedAt, resource, `${path}.placedAt`)\n timestamp(order.createdAt, resource, `${path}.createdAt`)\n timestamp(order.updatedAt, resource, `${path}.updatedAt`)\n}\n\nexport function validatePublicOrder<T>(value: unknown): T {\n validatePublicOrderAt(value, 'Order', '$')\n return value as T\n}\n\nfunction nullablePositiveInteger(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== null) positiveInteger(value, resource, path)\n}\n\nexport function validatePublicOrderList<T>(value: unknown): T {\n const resource = 'Order list'\n const result = record(value, resource, '$')\n exact(\n result,\n [\n 'docs',\n 'totalDocs',\n 'limit',\n 'totalPages',\n 'page',\n 'pagingCounter',\n 'hasPrevPage',\n 'hasNextPage',\n 'prevPage',\n 'nextPage',\n ],\n [],\n resource,\n '$',\n )\n array(result.docs, resource, '$.docs').forEach((order, index) =>\n validatePublicOrderAt(order, resource, `$.docs[${index}]`),\n )\n safeMinor(result.totalDocs, resource, '$.totalDocs')\n positiveInteger(result.limit, resource, '$.limit')\n safeMinor(result.totalPages, resource, '$.totalPages')\n positiveInteger(result.page, resource, '$.page')\n positiveInteger(result.pagingCounter, resource, '$.pagingCounter')\n boolean(result.hasPrevPage, resource, '$.hasPrevPage')\n boolean(result.hasNextPage, resource, '$.hasNextPage')\n nullablePositiveInteger(result.prevPage, resource, '$.prevPage')\n nullablePositiveInteger(result.nextPage, resource, '$.nextPage')\n return value as T\n}\n\nfunction validateCheckoutItem(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const item = record(value, resource, path)\n exact(\n item,\n [\n 'id',\n 'product',\n 'variant',\n 'productTitle',\n 'variantTitle',\n 'sku',\n 'admissions',\n 'quantity',\n 'unitPriceMinor',\n 'discountMinor',\n 'lineTotalMinor',\n 'requiresShipping',\n ],\n [],\n resource,\n path,\n )\n string(item.id, resource, `${path}.id`)\n validateReference(item.product, resource, `${path}.product`)\n validateReference(item.variant, resource, `${path}.variant`)\n string(item.productTitle, resource, `${path}.productTitle`)\n nullableNonEmptyString(item.variantTitle, resource, `${path}.variantTitle`)\n nullableNonEmptyString(item.sku, resource, `${path}.sku`)\n validateAdmissions(item.admissions, resource, `${path}.admissions`)\n cartLineQuantity(item.quantity, resource, `${path}.quantity`)\n const unitPrice = safeMinor(\n item.unitPriceMinor,\n resource,\n `${path}.unitPriceMinor`,\n )\n const discount = safeMinor(\n item.discountMinor,\n resource,\n `${path}.discountMinor`,\n )\n const lineTotal = safeMinor(\n item.lineTotalMinor,\n resource,\n `${path}.lineTotalMinor`,\n )\n const expectedLineTotal =\n BigInt(unitPrice) * BigInt(item.quantity as number) - BigInt(discount)\n if (expectedLineTotal < 0n || BigInt(lineTotal) !== expectedLineTotal) {\n fail(\n resource,\n `${path}.lineTotalMinor`,\n 'unitPriceMinor * quantity - discountMinor',\n )\n }\n boolean(item.requiresShipping, resource, `${path}.requiresShipping`)\n}\n\nfunction validateCheckoutAmounts(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const amounts = record(value, resource, path)\n exact(\n amounts,\n [\n 'currency',\n 'subtotalMinor',\n 'shippingMinor',\n 'discountMinor',\n 'totalMinor',\n ],\n [],\n resource,\n path,\n )\n currency(amounts.currency, resource, `${path}.currency`)\n const subtotal = safeMinor(\n amounts.subtotalMinor,\n resource,\n `${path}.subtotalMinor`,\n )\n const shipping = safeMinor(\n amounts.shippingMinor,\n resource,\n `${path}.shippingMinor`,\n )\n const discount = safeMinor(\n amounts.discountMinor,\n resource,\n `${path}.discountMinor`,\n )\n const total = safeMinor(amounts.totalMinor, resource, `${path}.totalMinor`)\n if (\n BigInt(total) !==\n BigInt(subtotal) + BigInt(shipping) - BigInt(discount)\n ) {\n fail(\n resource,\n `${path}.totalMinor`,\n 'subtotalMinor + shippingMinor - discountMinor',\n )\n }\n}\n\nfunction validatePaymentSessionReference(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const session = record(value, resource, path)\n exact(session, ['id', 'provider', 'providerStatus'], [], resource, path)\n string(session.id, resource, `${path}.id`)\n enumValue(session.provider, PAYMENT_PROVIDERS, resource, `${path}.provider`)\n enumValue(\n session.providerStatus,\n PAYMENT_PROVIDER_STATUSES,\n resource,\n `${path}.providerStatus`,\n )\n}\n\nfunction checkoutVariantKeys(\n status: string,\n placedVia: unknown,\n): {\n required: string[]\n optional: string[]\n} {\n const base = [\n 'id',\n 'amounts',\n 'items',\n 'customerSnapshot',\n 'shippingAddress',\n 'attributes',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n 'status',\n 'paymentState',\n 'order',\n ]\n if (status === 'open') return { required: base, optional: [] }\n if (status === 'abandoned') {\n return {\n required: [...base, 'abandonedAt', 'abandonedReason'],\n optional: [],\n }\n }\n return placedVia === 'late_capture'\n ? {\n required: [\n ...base,\n 'placedAt',\n 'placedVia',\n 'abandonedAt',\n 'abandonedReason',\n ],\n optional: [],\n }\n : { required: [...base, 'placedAt'], optional: [] }\n}\n\nfunction validateCheckoutCore(\n value: unknown,\n resource: string,\n list: boolean,\n server: boolean,\n): void {\n const checkout = record(value, resource, '$')\n const status = enumValue(\n checkout.status,\n CHECKOUT_STATUSES,\n resource,\n '$.status',\n )\n const keys = checkoutVariantKeys(status, checkout.placedVia)\n keys.required.push(\n ...responseExtensionKeys(\n checkout,\n ['deliveryMethod', 'source'],\n resource,\n '$',\n ),\n )\n if ('deliveryMethod' in checkout)\n enumValue(checkout.source, ['web', 'in_person'], resource, '$.source')\n keys.optional.push('funding')\n if (list) {\n keys.required = keys.required.filter(\n (key) => !['items', 'shippingAddress', 'attributes'].includes(key),\n )\n keys.required.push('clientReferenceId')\n } else if (server) {\n keys.required.push('clientReferenceId', 'integrationMetadata')\n }\n exact(checkout, keys.required, keys.optional, resource, '$')\n string(checkout.id, resource, '$.id')\n validateCheckoutAmounts(checkout.amounts, resource, '$.amounts')\n if (Object.prototype.hasOwnProperty.call(checkout, 'funding')) {\n const funding = record(checkout.funding, resource, '$.funding')\n exact(\n funding,\n ['creditAmount', 'providerPayableAmount'],\n [],\n resource,\n '$.funding',\n )\n const credit = safeMinor(\n funding.creditAmount,\n resource,\n '$.funding.creditAmount',\n )\n const provider = safeMinor(\n funding.providerPayableAmount,\n resource,\n '$.funding.providerPayableAmount',\n )\n const amounts = checkout.amounts as Record<string, unknown>\n if (\n BigInt(credit) + BigInt(provider) !==\n BigInt(amounts.totalMinor as number) ||\n (credit > 0 && amounts.currency !== 'KRW')\n )\n fail(\n resource,\n '$.funding',\n 'exact purchase total split; positive credits require KRW',\n )\n }\n if (!list) {\n const items = array(checkout.items, resource, '$.items')\n if (items.length === 0) fail(resource, '$.items', 'non-empty array')\n items.forEach((item, index) =>\n validateCheckoutItem(item, resource, `$.items[${index}]`),\n )\n const expectedSubtotal = items.reduce<bigint>((total, value) => {\n const item = value as Record<string, unknown>\n return (\n total +\n BigInt(item.unitPriceMinor as number) * BigInt(item.quantity as number)\n )\n }, 0n)\n const expectedDiscount = items.reduce<bigint>((total, value) => {\n const item = value as Record<string, unknown>\n return total + BigInt(item.discountMinor as number)\n }, 0n)\n const amounts = checkout.amounts as Record<string, unknown>\n if (BigInt(amounts.subtotalMinor as number) !== expectedSubtotal) {\n fail(\n resource,\n '$.amounts.subtotalMinor',\n 'sum of undiscounted checkout line totals',\n )\n }\n if (BigInt(amounts.discountMinor as number) !== expectedDiscount) {\n fail(\n resource,\n '$.amounts.discountMinor',\n 'sum of checkout line discounts',\n )\n }\n if (checkout.shippingAddress !== null) {\n validateShippingAddress(\n checkout.shippingAddress,\n resource,\n '$.shippingAddress',\n )\n }\n validateAttributes(checkout.attributes, resource, '$.attributes')\n }\n validateCustomer(checkout.customerSnapshot, resource, '$.customerSnapshot')\n timestamp(checkout.expiresAt, resource, '$.expiresAt')\n timestamp(checkout.createdAt, resource, '$.createdAt')\n timestamp(checkout.updatedAt, resource, '$.updatedAt')\n\n const paymentState = record(checkout.paymentState, resource, '$.paymentState')\n exact(paymentState, ['activePaymentSession'], [], resource, '$.paymentState')\n if (status === 'open') {\n if (paymentState.activePaymentSession !== null) {\n validatePaymentSessionReference(\n paymentState.activePaymentSession,\n resource,\n '$.paymentState.activePaymentSession',\n )\n }\n if (checkout.order !== null)\n fail(resource, '$.order', 'null for open Checkout')\n } else {\n if (paymentState.activePaymentSession !== null) {\n fail(\n resource,\n '$.paymentState.activePaymentSession',\n 'null for spent Checkout',\n )\n }\n if (status === 'placed') {\n timestamp(checkout.placedAt, resource, '$.placedAt')\n validateOrderReference(checkout.order, resource, '$.order')\n if (\n checkout.placedVia !== undefined &&\n checkout.placedVia !== 'late_capture'\n ) {\n fail(resource, '$.placedVia', 'late_capture')\n }\n if (checkout.placedVia === 'late_capture') {\n timestamp(checkout.abandonedAt, resource, '$.abandonedAt')\n enumValue(\n checkout.abandonedReason,\n ABANDONED_REASONS,\n resource,\n '$.abandonedReason',\n )\n }\n } else {\n timestamp(checkout.abandonedAt, resource, '$.abandonedAt')\n enumValue(\n checkout.abandonedReason,\n ABANDONED_REASONS,\n resource,\n '$.abandonedReason',\n )\n if (checkout.order !== null)\n fail(resource, '$.order', 'null for abandoned Checkout')\n }\n }\n if (list || server) {\n if (checkout.clientReferenceId !== null) {\n boundedString(\n checkout.clientReferenceId,\n MAX_COMMERCE_RESOURCE_ID_LENGTH,\n resource,\n '$.clientReferenceId',\n )\n }\n }\n if (server)\n validateIntegrationMetadata(\n checkout.integrationMetadata,\n resource,\n '$.integrationMetadata',\n )\n}\n\nexport function validatePublicCheckout<T>(value: unknown): T {\n validateCheckoutCore(value, 'Checkout', false, false)\n return value as T\n}\n\nexport function validateServerCheckout<T>(value: unknown): T {\n validateCheckoutCore(value, 'Server Checkout', false, true)\n return value as T\n}\n\nexport function validateCreateCheckoutResult<T>(\n value: unknown,\n server: boolean,\n): T {\n const resource = server\n ? 'Server Checkout create result'\n : 'Checkout create result'\n const result = record(value, resource, '$')\n exact(result, ['checkout', 'checkoutToken'], [], resource, '$')\n if (server) validateServerCheckout(result.checkout)\n else validatePublicCheckout(result.checkout)\n boundedString(\n result.checkoutToken,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n resource,\n '$.checkoutToken',\n )\n return value as T\n}\n\nexport function validateCheckoutQueryResult<T>(value: unknown): T {\n const result = record(value, 'Checkout query result', '$')\n exact(\n result,\n ['data', 'hasMore', 'nextCursor'],\n [],\n 'Checkout query result',\n '$',\n )\n array(result.data, 'Checkout query result', '$.data').forEach((item) =>\n validateCheckoutCore(item, 'Checkout list item', true, false),\n )\n boolean(result.hasMore, 'Checkout query result', '$.hasMore')\n if (result.nextCursor !== null)\n boundedString(\n result.nextCursor,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n 'Checkout query result',\n '$.nextCursor',\n )\n if (result.hasMore === true && result.nextCursor === null) {\n fail(\n 'Checkout query result',\n '$.nextCursor',\n 'non-null when hasMore is true',\n )\n }\n return value as T\n}\n\nfunction validateMoney(value: unknown, resource: string, path: string): void {\n const money = record(value, resource, path)\n exact(money, ['amountMinor', 'currency'], [], resource, path)\n safeMinor(money.amountMinor, resource, `${path}.amountMinor`)\n currency(money.currency, resource, `${path}.currency`)\n}\n\nexport function validateCustomPaymentSession<T>(value: unknown): T {\n const resource = 'custom PaymentSession'\n const session = record(value, resource, '$')\n exact(\n session,\n ['id', 'provider', 'providerSessionId', 'money'],\n [],\n resource,\n '$',\n )\n string(session.id, resource, '$.id')\n const provider = string(session.provider, resource, '$.provider')\n if (!/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(provider)) {\n fail(resource, '$.provider', 'provider slug')\n }\n string(session.providerSessionId, resource, '$.providerSessionId')\n validateMoney(session.money, resource, '$.money')\n return value as T\n}\n\nexport function validateRetrievedCustomPaymentSession<T>(value: unknown): T {\n const resource = 'retrieved custom PaymentSession'\n const session = record(value, resource, '$')\n exact(\n session,\n [\n 'id',\n 'provider',\n 'providerSessionId',\n 'providerPaymentId',\n 'status',\n 'providerStatus',\n 'finalizationStatus',\n 'money',\n 'orderId',\n ],\n [],\n resource,\n '$',\n )\n boundedString(session.id, MAX_COMMERCE_RESOURCE_ID_LENGTH, resource, '$.id')\n const provider = string(session.provider, resource, '$.provider')\n if (!/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(provider)) {\n fail(resource, '$.provider', 'provider slug')\n }\n nonBlankString(session.providerSessionId, resource, '$.providerSessionId')\n nullableNonBlankString(\n session.providerPaymentId,\n resource,\n '$.providerPaymentId',\n )\n enumValue(\n session.status,\n ['pending', 'captured', 'failed', 'canceled'] as const,\n resource,\n '$.status',\n )\n enumValue(\n session.providerStatus,\n PAYMENT_PROVIDER_STATUSES,\n resource,\n '$.providerStatus',\n )\n enumValue(\n session.finalizationStatus,\n ['not_ready', 'pending', 'committed'] as const,\n resource,\n '$.finalizationStatus',\n )\n validateMoney(session.money, resource, '$.money')\n nullableResourceId(session.orderId, resource, '$.orderId')\n return value as T\n}\n\nfunction validatePortOnePaymentCurrentState(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const current = record(value, resource, path)\n exact(\n current,\n ['paymentSession', 'checkout', 'order', 'money'],\n [],\n resource,\n path,\n )\n const session = record(\n current.paymentSession,\n resource,\n `${path}.paymentSession`,\n )\n exact(\n session,\n [\n 'id',\n 'provider',\n 'providerStatus',\n 'finalizationStatus',\n 'sessionRole',\n 'reconciliation',\n ],\n [],\n resource,\n `${path}.paymentSession`,\n )\n boundedString(\n session.id,\n MAX_COMMERCE_RESOURCE_ID_LENGTH,\n resource,\n `${path}.paymentSession.id`,\n )\n if (session.provider !== 'portone') {\n fail(resource, `${path}.paymentSession.provider`, 'portone')\n }\n enumValue(\n session.providerStatus,\n PAYMENT_PROVIDER_STATUSES,\n resource,\n `${path}.paymentSession.providerStatus`,\n )\n enumValue(\n session.finalizationStatus,\n ['not_ready', 'pending', 'committed'] as const,\n resource,\n `${path}.paymentSession.finalizationStatus`,\n )\n enumValue(\n session.sessionRole,\n ['active', 'canonical_candidate', 'canonical', 'residual', 'historical'],\n resource,\n `${path}.paymentSession.sessionRole`,\n )\n const reconciliation = record(\n session.reconciliation,\n resource,\n `${path}.paymentSession.reconciliation`,\n )\n if (reconciliation.status === 'none') {\n validateNoReconciliation(\n reconciliation,\n resource,\n `${path}.paymentSession.reconciliation`,\n )\n } else {\n validateRequiredReconciliation(\n reconciliation,\n PAYMENT_RECONCILIATION_REASONS,\n resource,\n `${path}.paymentSession.reconciliation`,\n )\n }\n\n const checkout = record(current.checkout, resource, `${path}.checkout`)\n exact(checkout, ['id'], [], resource, `${path}.checkout`)\n boundedString(\n checkout.id,\n MAX_COMMERCE_RESOURCE_ID_LENGTH,\n resource,\n `${path}.checkout.id`,\n )\n if (current.order !== null) {\n const order = record(current.order, resource, `${path}.order`)\n exact(order, ['id', 'orderNumber'], [], resource, `${path}.order`)\n boundedString(\n order.id,\n MAX_COMMERCE_RESOURCE_ID_LENGTH,\n resource,\n `${path}.order.id`,\n )\n nonBlankString(order.orderNumber, resource, `${path}.order.orderNumber`)\n }\n validateMoney(current.money, resource, `${path}.money`)\n}\n\nexport function validatePortOnePaymentFacadeResult<T>(\n value: unknown,\n mutating: boolean,\n): T {\n const resource = mutating\n ? 'PortOne payment reconciliation result'\n : 'PortOne payment find result'\n const result = record(value, resource, '$')\n boolean(result.found, resource, '$.found')\n if (result.found === false) {\n exact(\n result,\n mutating ? ['found', 'disposition'] : ['found'],\n [],\n resource,\n '$',\n )\n if (mutating && result.disposition !== 'requires_attention') {\n fail(resource, '$.disposition', 'requires_attention')\n }\n return value as T\n }\n\n exact(\n result,\n mutating ? ['found', 'disposition', 'current'] : ['found', 'current'],\n [],\n resource,\n '$',\n )\n if (mutating) {\n enumValue(\n result.disposition,\n [\n 'applied',\n 'observed',\n 'recovered_after_ambiguous_result',\n 'requires_attention',\n ],\n resource,\n '$.disposition',\n )\n }\n validatePortOnePaymentCurrentState(result.current, resource, '$.current')\n return value as T\n}\n\nexport function validateConfirmCustomPaymentSessionResponse<T>(\n value: unknown,\n): T {\n const resource = 'custom PaymentSession confirmation'\n const result = record(value, resource, '$')\n exact(\n result,\n ['orderId', 'transactionId', 'status'],\n ['alreadyConfirmed'],\n resource,\n '$',\n )\n string(result.orderId, resource, '$.orderId')\n string(result.transactionId, resource, '$.transactionId')\n if (result.status !== 'paid') fail(resource, '$.status', 'paid')\n if (result.alreadyConfirmed !== undefined) {\n boolean(result.alreadyConfirmed, resource, '$.alreadyConfirmed')\n }\n return value as T\n}\n\nfunction validateCaptureEvidence(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const evidence = record(value, resource, path)\n exact(evidence, ['amountMinor', 'currency', 'observedAt'], [], resource, path)\n safeMinor(evidence.amountMinor, resource, `${path}.amountMinor`)\n currency(evidence.currency, resource, `${path}.currency`)\n timestamp(evidence.observedAt, resource, `${path}.observedAt`)\n}\n\nfunction validateNoReconciliation(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const reconciliation = record(value, resource, path)\n exact(reconciliation, ['status'], [], resource, path)\n if (reconciliation.status !== 'none') fail(resource, `${path}.status`, 'none')\n}\n\nfunction validateRequiredReconciliation(\n value: unknown,\n allowed: readonly string[],\n resource: string,\n path: string,\n): void {\n const reconciliation = record(value, resource, path)\n exact(reconciliation, ['status', 'reasons'], [], resource, path)\n if (reconciliation.status !== 'required')\n fail(resource, `${path}.status`, 'required')\n const reasons = array(reconciliation.reasons, resource, `${path}.reasons`)\n if (reasons.length === 0) fail(resource, `${path}.reasons`, 'non-empty array')\n let previous = -1\n reasons.forEach((reason, index) => {\n const current = allowed.indexOf(reason as string)\n if (current < 0 || current <= previous) {\n fail(\n resource,\n `${path}.reasons[${index}]`,\n 'unique canonical-sorted reconciliation reason',\n )\n }\n previous = current\n })\n}\n\nfunction validateNextAction(\n value: unknown,\n provider: ManagedPaymentProvider,\n resource: string,\n path: string,\n): void {\n const action = record(value, resource, path)\n if (provider === 'stripe') {\n exact(\n action,\n ['type', 'clientSecret', 'publishableKey', 'returnUrl'],\n [],\n resource,\n path,\n )\n if (action.type !== 'stripe_payment_element')\n fail(resource, `${path}.type`, 'stripe_payment_element')\n const clientSecret = boundedString(\n action.clientSecret,\n 255,\n resource,\n `${path}.clientSecret`,\n )\n if (!/^pi_[A-Za-z0-9]+_secret_[A-Za-z0-9]+$/.test(clientSecret)) {\n fail(\n resource,\n `${path}.clientSecret`,\n 'Stripe PaymentIntent client secret',\n )\n }\n const publishableKey = boundedString(\n action.publishableKey,\n 255,\n resource,\n `${path}.publishableKey`,\n )\n if (!/^pk_(?:test|live)_[A-Za-z0-9]+$/.test(publishableKey)) {\n fail(resource, `${path}.publishableKey`, 'Stripe publishable key')\n }\n const returnUrl = boundedString(\n action.returnUrl,\n 2048,\n resource,\n `${path}.returnUrl`,\n )\n if (\n !STRIPE_RETURN_URL_RAW_CHARACTERS.test(returnUrl) ||\n !STRIPE_RETURN_URL_AUTHORITY.test(returnUrl)\n ) {\n fail(\n resource,\n `${path}.returnUrl`,\n 'HTTPS or loopback URL without embedded credentials',\n )\n }\n try {\n const parsed = new URL(returnUrl)\n const loopback =\n parsed.protocol === 'http:' &&\n (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1')\n if (\n (!loopback && parsed.protocol !== 'https:') ||\n parsed.username ||\n parsed.password\n )\n throw new Error('unsafe return URL')\n } catch {\n fail(\n resource,\n `${path}.returnUrl`,\n 'HTTPS or loopback URL without embedded credentials',\n )\n }\n return\n }\n if (provider === 'portone') {\n if (action.type === 'portone_sdk') {\n const hasCancelable = 'cancelable' in action\n const hasRetryPolicy = 'retryPolicy' in action\n if (hasCancelable !== hasRetryPolicy) {\n fail(\n resource,\n path,\n 'exact released action or exact negotiated capability action',\n )\n }\n exact(\n action,\n [\n 'type',\n 'version',\n ...(hasCancelable ? ['cancelable', 'retryPolicy'] : []),\n 'storeId',\n 'channelKey',\n 'paymentId',\n 'orderName',\n 'totalAmount',\n 'currency',\n 'payMethod',\n 'redirectUrl',\n ],\n [],\n resource,\n path,\n )\n if (action.version !== 'v2') fail(resource, `${path}.version`, 'v2')\n if (hasCancelable && action.cancelable !== false)\n fail(resource, `${path}.cancelable`, 'false')\n if (hasRetryPolicy && action.retryPolicy !== 'same_action_only') {\n fail(resource, `${path}.retryPolicy`, 'same_action_only')\n }\n for (const key of ['storeId', 'channelKey'] as const) {\n boundedString(action[key], 255, resource, `${path}.${key}`)\n }\n const paymentId = boundedString(\n action.paymentId,\n 40,\n resource,\n `${path}.paymentId`,\n )\n if (!/^[A-Za-z0-9]{6,40}$/.test(paymentId)) {\n fail(\n resource,\n `${path}.paymentId`,\n '6-40 ASCII alphanumeric characters',\n )\n }\n boundedString(\n action.orderName,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.orderName`,\n )\n positiveInteger(action.totalAmount, resource, `${path}.totalAmount`)\n if (action.currency !== 'CURRENCY_KRW') {\n fail(resource, `${path}.currency`, 'CURRENCY_KRW')\n }\n if (action.payMethod !== 'CARD')\n fail(resource, `${path}.payMethod`, 'CARD')\n const redirectUrl = boundedString(\n action.redirectUrl,\n 2048,\n resource,\n `${path}.redirectUrl`,\n )\n try {\n const parsed = new URL(redirectUrl)\n const loopback =\n parsed.protocol === 'http:' &&\n (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1')\n if (\n (!loopback && parsed.protocol !== 'https:') ||\n parsed.username ||\n parsed.password\n )\n throw new Error('unsafe redirect URL')\n } catch {\n fail(\n resource,\n `${path}.redirectUrl`,\n 'HTTPS or loopback URL without embedded credentials',\n )\n }\n if (!hasCancelable) {\n action.cancelable = false\n action.retryPolicy = 'same_action_only'\n }\n return\n }\n exact(action, ['type', 'checkoutUrl'], [], resource, path)\n if (action.type !== 'portone_checkout') {\n fail(resource, `${path}.type`, 'portone_checkout | portone_sdk')\n }\n const checkoutUrl = boundedString(\n action.checkoutUrl,\n 2048,\n resource,\n `${path}.checkoutUrl`,\n )\n try {\n const parsed = new URL(checkoutUrl)\n if (\n parsed.protocol !== 'https:' ||\n parsed.username !== '' ||\n parsed.password !== ''\n ) {\n throw new Error('unsafe checkout URL')\n }\n } catch {\n fail(\n resource,\n `${path}.checkoutUrl`,\n 'absolute HTTPS URL without embedded credentials',\n )\n }\n return\n }\n exact(\n action,\n [\n 'type',\n 'clientKey',\n 'paymentMethodVariantKey',\n 'agreementVariantKey',\n 'providerOrderId',\n 'providerCustomerKey',\n 'orderName',\n ],\n ['customerName', 'customerEmail'],\n resource,\n path,\n )\n if (action.type !== 'toss_widget')\n fail(resource, `${path}.type`, 'toss_widget')\n for (const key of [\n 'clientKey',\n 'paymentMethodVariantKey',\n 'agreementVariantKey',\n ] as const) {\n boundedString(action[key], 255, resource, `${path}.${key}`)\n }\n string(action.providerOrderId, resource, `${path}.providerOrderId`)\n string(action.providerCustomerKey, resource, `${path}.providerCustomerKey`)\n boundedString(\n action.orderName,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.orderName`,\n )\n if (!/^[A-Za-z0-9_-]{6,64}$/.test(action.providerOrderId as string)) {\n fail(resource, `${path}.providerOrderId`, 'valid Toss provider order ID')\n }\n if (\n action.providerCustomerKey !== 'ANONYMOUS' &&\n !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(\n action.providerCustomerKey as string,\n )\n ) {\n fail(resource, `${path}.providerCustomerKey`, 'ANONYMOUS or UUIDv4')\n }\n if (action.customerName !== undefined)\n boundedString(\n action.customerName,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.customerName`,\n )\n if (action.customerEmail !== undefined)\n validateCustomer({ email: action.customerEmail }, resource, path)\n}\n\nexport function validatePublicPaymentSession<T>(\n value: unknown,\n expectedProvider?: ManagedPaymentProvider,\n operation?: 'cancel',\n): T {\n const resource = 'PaymentSession'\n const session = record(value, resource, '$')\n const provider = enumValue(\n session.provider,\n PAYMENT_PROVIDERS,\n resource,\n '$.provider',\n ) as (typeof PAYMENT_PROVIDERS)[number]\n const status = enumValue(\n session.providerStatus,\n PAYMENT_PROVIDER_STATUSES,\n resource,\n '$.providerStatus',\n )\n const common = [\n 'id',\n 'money',\n 'expiresAt',\n 'sessionRole',\n 'provider',\n 'providerStatus',\n 'presentationStatus',\n 'finalizationStatus',\n 'reconciliation',\n 'order',\n ]\n const optional: string[] = []\n if (status === 'requires_payment_method' || status === 'requires_action')\n optional.push('nextAction')\n else if (status === 'captured') common.push('providerEvidence')\n else if (status === 'failed') common.push('failure')\n else if (status === 'canceled') common.push('cancellationReason')\n exact(session, common, optional, resource, '$')\n string(session.id, resource, '$.id')\n validateMoney(session.money, resource, '$.money')\n if (session.expiresAt !== null)\n timestamp(session.expiresAt, resource, '$.expiresAt')\n\n if (status === 'requires_payment_method' || status === 'requires_action') {\n if (session.sessionRole === 'active') {\n if (\n session.presentationStatus !== 'actionable' ||\n session.finalizationStatus !== 'not_ready'\n ) {\n fail(resource, '$', 'actionable active not-ready state')\n }\n if (!('nextAction' in session))\n fail(resource, '$.nextAction', 'required field')\n validateNextAction(\n session.nextAction,\n provider as ManagedPaymentProvider,\n resource,\n '$.nextAction',\n )\n } else if (session.sessionRole === 'residual') {\n if (\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready'\n ) {\n fail(resource, '$', 'suppressed residual not-ready state')\n }\n if ('nextAction' in session)\n fail(resource, '$.nextAction', 'absent for suppressed state')\n } else fail(resource, '$.sessionRole', 'active | residual')\n validateNoReconciliation(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n if (session.order !== null) fail(resource, '$.order', 'null')\n } else if (\n [\n 'requires_confirmation',\n 'initializing',\n 'processing',\n 'authorized',\n 'canceling',\n ].includes(status)\n ) {\n enumValue(\n session.sessionRole,\n ['active', 'residual'],\n resource,\n '$.sessionRole',\n )\n if (\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready'\n ) {\n fail(resource, '$', 'suppressed not-ready state')\n }\n validateNoReconciliation(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n if (session.order !== null) fail(resource, '$.order', 'null')\n } else if (status === 'unknown') {\n enumValue(\n session.sessionRole,\n ['active', 'residual'],\n resource,\n '$.sessionRole',\n )\n if (\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready'\n ) {\n fail(resource, '$', 'suppressed not-ready state')\n }\n validateRequiredReconciliation(\n session.reconciliation,\n ['provider_outcome_unknown'],\n resource,\n '$.reconciliation',\n )\n if (session.order !== null) fail(resource, '$.order', 'null')\n } else if (status === 'captured') {\n validateCaptureEvidence(\n session.providerEvidence,\n resource,\n '$.providerEvidence',\n )\n if (session.presentationStatus !== 'suppressed')\n fail(resource, '$.presentationStatus', 'suppressed')\n if (session.finalizationStatus === 'pending') {\n enumValue(\n session.sessionRole,\n ['canonical_candidate', 'residual'],\n resource,\n '$.sessionRole',\n )\n if (session.order !== null)\n fail(resource, '$.order', 'null for pending finalization')\n const reconciliation = record(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n if (reconciliation.status === 'none')\n validateNoReconciliation(reconciliation, resource, '$.reconciliation')\n else\n validateRequiredReconciliation(\n reconciliation,\n [\n 'local_commit_ambiguous',\n 'amount_mismatch',\n 'currency_mismatch',\n 'excess_capture_pending_order',\n ],\n resource,\n '$.reconciliation',\n )\n } else if (session.finalizationStatus === 'committed') {\n validateOrderReference(session.order, resource, '$.order')\n const reconciliation = record(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n if (reconciliation.status === 'none') {\n enumValue(\n session.sessionRole,\n ['canonical', 'historical'],\n resource,\n '$.sessionRole',\n )\n validateNoReconciliation(reconciliation, resource, '$.reconciliation')\n } else {\n enumValue(\n session.sessionRole,\n ['canonical', 'residual'],\n resource,\n '$.sessionRole',\n )\n validateRequiredReconciliation(\n reconciliation,\n [\n 'inventory_unavailable',\n 'admission_unavailable',\n 'amount_mismatch',\n 'currency_mismatch',\n 'excess_capture',\n 'late_capture',\n 'cross_checkout_duplicate',\n ],\n resource,\n '$.reconciliation',\n )\n }\n } else fail(resource, '$.finalizationStatus', 'pending | committed')\n } else if (status === 'failed') {\n if (\n session.sessionRole !== 'historical' ||\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready' ||\n session.order !== null\n ) {\n fail(resource, '$', 'historical suppressed failed state')\n }\n validateNoReconciliation(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n const failure = record(session.failure, resource, '$.failure')\n exact(failure, ['reason'], ['message'], resource, '$.failure')\n enumValue(\n failure.reason,\n PAYMENT_FAILURE_REASONS,\n resource,\n '$.failure.reason',\n )\n if (failure.message !== undefined)\n string(failure.message, resource, '$.failure.message')\n } else {\n if (\n session.sessionRole !== 'historical' ||\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready' ||\n session.order !== null\n ) {\n fail(resource, '$', 'historical suppressed canceled state')\n }\n validateNoReconciliation(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n enumValue(\n session.cancellationReason,\n ['expired', 'customer', 'operator', 'provider'],\n resource,\n '$.cancellationReason',\n )\n }\n if (expectedProvider !== undefined && provider !== expectedProvider) {\n if (\n operation === 'cancel' &&\n CANCEL_RECOVERY_METHODS[provider] !== null &&\n status !== 'canceling' &&\n status !== 'canceled'\n ) {\n fail(\n resource,\n '$.providerStatus',\n 'canceling or canceled after a successful cancellation',\n )\n }\n providerMismatch(resource, expectedProvider, provider, operation)\n }\n return value as T\n}\n","import { ApiError, SDKError } from '../internal/errors'\nimport {\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS,\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\nimport { parseApiResponse } from '../api/parse-response'\nimport { httpFetch } from '../internal/utils'\nimport type { PayloadFindResponse } from '../client/types'\nimport type { PublicOrder } from '../api/order-api'\nimport { validatePublicOrderList } from '../api/canonical-response'\nimport { resolveApiUrl } from '../internal/utils/api-url'\nimport type {\n CustomerAuthResponse,\n CustomerWithdrawalResult,\n CustomerRefreshResponse,\n CustomerRegisterData,\n CustomerRegisterResponse,\n CustomerLoginData,\n CustomerProfile,\n CustomerAuthOptions,\n UpdateProfileData,\n} from './types'\n\nconst DEFAULT_TIMEOUT = 15000\n\n/**\n * Upper bound for waiting on the cross-context refresh lock.\n *\n * A lease holder occupies the lease for at most one refresh request, which\n * `DEFAULT_TIMEOUT` already bounds, so the budget is derived from that hold\n * time rather than from a flat margin: it covers a serialized queue of three\n * contexts whose predecessors each burn their entire request timeout. A deeper\n * queue still degrades to an uncoordinated rotation by design — the server\n * adjudicates it through single-use rotation and refresh-family reuse\n * detection — but an ordinary slow API no longer pushes a waiter there.\n */\nconst REFRESH_LOCK_TIMEOUT = DEFAULT_TIMEOUT * 3\n\n/**\n * Canonical persisted session.\n *\n * The access and refresh tokens live in ONE JSON value written with one store\n * operation, so a partial failure can never publish a new access token beside\n * an already-consumed refresh token. `rev` increases on every commit, which\n * lets an in-flight rotation detect a logout, a fresh login, or a manual setter\n * that landed while it was waiting for the server.\n */\ntype SessionRecord = {\n v: number\n rev: number\n token: string | null\n refreshToken: string | null\n}\n\nconst SESSION_RECORD_VERSION = 1\n\n/**\n * The credentials a refresh call set out to present. The refresh token — or the\n * access token on the compatibility bearer path — is the credential the server\n * adjudicates, so it is what every fence compares.\n */\ntype SpentCredentials = {\n token: string | null\n refreshToken: string | null\n}\n\n/**\n * How canonical storage relates to the credential a call captured.\n *\n * - `current`: the spent credential is still canonical, so this call owns the\n * rotation and its successor must land.\n * - `superseded`: another context replaced the spent credential.\n * - `cleared`: the session was ended.\n */\ntype CanonicalState = 'cleared' | 'superseded' | 'current'\n\n/**\n * Canonical storage cannot be used: the read was denied, or the record is one\n * this version must not interpret. Either way the instance keeps its in-memory\n * session and stops participating in coordination.\n */\nconst STORAGE_UNUSABLE = Symbol('storage-unusable')\n\n/**\n * A canonical read plus its provenance. `stored: false` means the record key\n * was absent and the pair was synthesized from the earlier layout (or from\n * nothing), which a commit must not mistake for an existing persisted state.\n */\ntype CanonicalRead = {\n record: SessionRecord\n stored: boolean\n}\n\n/** A single-field or whole-pair change to publish. */\ntype SessionChange = {\n token?: string | null\n refreshToken?: string | null\n}\n\ntype RefreshLockRequester = (\n name: string,\n options: { signal: AbortSignal },\n callback: () => Promise<CustomerRefreshResponse>,\n) => Promise<CustomerRefreshResponse>\n\n/**\n * Two spellings of the same API endpoint must resolve to the same coordination\n * namespace, otherwise `https://api.example.com` and\n * `https://API.EXAMPLE.COM:443/` would rotate the same stored session under two\n * leases. Scheme and host are compared case-insensitively, a default port is\n * dropped, and a trailing slash is not significant.\n */\nfunction canonicalApiIdentity(apiUrl: string): string {\n try {\n const url = new URL(apiUrl)\n return `${url.protocol.toLowerCase()}//${url.host.toLowerCase()}${url.pathname.replace(/\\/+$/, '')}`\n } catch {\n return apiUrl.trim().toLowerCase().replace(/\\/+$/, '')\n }\n}\n\n/**\n * Coordination name for one persisted session. It is derived only from the\n * storage key and the canonical API/tenant identity the instance already sends\n * on every request; token material never appears in a lease name.\n */\nfunction buildRefreshLockName(\n apiUrl: string,\n publishableKey: string,\n storageKey: string,\n): string {\n return `01software:customer-auth-refresh:${canonicalApiIdentity(apiUrl)}:${publishableKey}:${storageKey}`\n}\n\n/**\n * Web Locks is the cross-context serialization primitive. Browsers without it,\n * environments whose `navigator.locks` accessor itself throws, and every\n * non-browser runtime get `null` and fall back to the instance-local single\n * flight. A platform exception never escapes to the caller.\n */\nfunction getRefreshLockRequester(): RefreshLockRequester | null {\n try {\n if (typeof navigator === 'undefined') return null\n const locks = (navigator as Navigator & { locks?: LockManager }).locks\n if (!locks || typeof locks.request !== 'function') return null\n return (name, options, callback) =>\n locks.request(name, options, () =>\n callback(),\n ) as Promise<CustomerRefreshResponse>\n } catch {\n return null\n }\n}\n\nfunction parseSessionRecord(raw: string): SessionRecord | null {\n try {\n const parsed: unknown = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object') return null\n const candidate = parsed as Partial<SessionRecord>\n // A record written by a newer SDK is not ours to interpret.\n if (candidate.v !== SESSION_RECORD_VERSION) return null\n if (typeof candidate.rev !== 'number' || !Number.isFinite(candidate.rev)) {\n return null\n }\n const token = candidate.token\n const refreshToken = candidate.refreshToken\n if (token !== null && typeof token !== 'string') return null\n if (refreshToken !== null && typeof refreshToken !== 'string') return null\n return {\n v: SESSION_RECORD_VERSION,\n rev: candidate.rev,\n token,\n refreshToken,\n }\n } catch {\n return null\n }\n}\n\nexport type CustomerOrderListOptions = {\n page?: number\n limit?: number\n financialStatus?: PublicOrder['financialStatus']\n fulfillmentStatus?: PublicOrder['fulfillmentStatus']\n returnStatus?: PublicOrder['returnStatus']\n confirmationStatus?: PublicOrder['confirmationStatus']\n primaryDisplayStatus?: PublicOrder['primaryDisplayStatus']\n}\n\n/**\n * Read the canonical session.\n *\n * The record is the only canonical source. When it is present but this version\n * cannot interpret it — corrupt, or written by a newer layout — the pre-record\n * mirror is NOT consulted: reinterpreting it would resurrect state the record's\n * writer already replaced. The mirror is a migration source only while the\n * record key is absent.\n */\nfunction readSessionRecord(\n recordKey: string,\n mirrorKey: string,\n mirrorRefreshKey: string,\n): CanonicalRead | typeof STORAGE_UNUSABLE {\n let raw: string | null\n try {\n raw = localStorage.getItem(recordKey)\n } catch {\n return STORAGE_UNUSABLE\n }\n if (raw !== null) {\n const parsed = parseSessionRecord(raw)\n return parsed ? { record: parsed, stored: true } : STORAGE_UNUSABLE\n }\n try {\n return {\n record: {\n v: SESSION_RECORD_VERSION,\n rev: 0,\n token: localStorage.getItem(mirrorKey),\n refreshToken: localStorage.getItem(mirrorRefreshKey),\n },\n stored: false,\n }\n } catch {\n return STORAGE_UNUSABLE\n }\n}\n\n/**\n * Customer authentication client.\n *\n * Manages customer registration, login, logout, and token lifecycle.\n * All requests include X-Publishable-Key for tenant resolution.\n */\nexport class CustomerAuth {\n private publishableKey: string\n private baseUrl: string\n private token: string | null\n private refreshTokenValue: string | null\n private onTokenChange?: (token: string | null) => void\n private onRefreshTokenChange?: (refreshToken: string | null) => void\n private refreshPromise: Promise<CustomerRefreshResponse> | null = null\n /** Canonical record key; null unless persistence is active in a browser. */\n private persistRecordKey: string | null = null\n /** Advisory single-value access mirror, plus the retired refresh mirror. */\n private persistMirrorKey: string | null = null\n private persistMirrorRefreshKey: string | null = null\n /** Cross-context refresh lock name; null when there is no shared storage. */\n private refreshLockName: string | null = null\n /** Revision of the canonical record this instance last observed. */\n private sessionRev = 0\n\n constructor(\n publishableKey: string,\n options?: CustomerAuthOptions,\n apiUrl?: string,\n ) {\n this.publishableKey = publishableKey\n this.baseUrl = resolveApiUrl(apiUrl)\n\n const persist = options?.persist ?? true\n if (persist) {\n const key = typeof persist === 'string' ? persist : 'customer-token'\n const isBrowser = typeof window !== 'undefined'\n this.token = null\n this.refreshTokenValue = null\n if (isBrowser) {\n this.persistRecordKey = `${key}:session`\n this.persistMirrorKey = key\n this.persistMirrorRefreshKey = `${key}:refresh`\n this.refreshLockName = buildRefreshLockName(\n this.baseUrl,\n publishableKey,\n key,\n )\n this.syncFromPersistedStorage()\n }\n } else {\n this.token = options?.token ?? null\n this.refreshTokenValue = options?.refreshToken ?? null\n this.onTokenChange = options?.onTokenChange\n this.onRefreshTokenChange = options?.onRefreshTokenChange\n }\n }\n\n /**\n * Register a new customer account\n */\n async register(\n data: CustomerRegisterData,\n ): Promise<CustomerRegisterResponse> {\n return this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.register),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.register,\n ),\n body: JSON.stringify(data),\n },\n )\n }\n\n /**\n * Login with email and password. Stores the token internally.\n */\n async login(data: CustomerLoginData): Promise<CustomerAuthResponse> {\n const result: CustomerAuthResponse = await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.login),\n {\n method: resolveOperationMethod(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.login),\n body: JSON.stringify(data),\n },\n )\n\n if (result.refreshToken) this.setSession(result.token, result.refreshToken)\n else this.setToken(result.token)\n return result\n }\n\n /**\n * Refresh the current token. Uses a refresh token when available, otherwise\n * falls back to the legacy bearer-token compatibility path.\n *\n * Refresh tokens are single-use, so a persisted session shared by several\n * tabs or SDK instances must rotate at most once: concurrent rotations of the\n * same token are replay from the server's point of view and revoke the whole\n * family. Persisted browser sessions therefore serialize rotation across\n * contexts and re-read the canonical persisted credentials inside the lock.\n */\n async refreshToken(): Promise<CustomerRefreshResponse> {\n this.syncFromPersistedStorage()\n if (!this.refreshTokenValue && !this.token) {\n throw new ApiError('Not authenticated', 401)\n }\n\n if (this.refreshPromise) return this.refreshPromise\n\n const intended = this.currentFence()\n this.refreshPromise = this.rotateAcrossContexts(intended)\n try {\n return await this.refreshPromise\n } finally {\n this.refreshPromise = null\n }\n }\n\n /**\n * Re-read the canonical persisted session. In persisted mode the shared\n * record — not this instance's memory — is the source of truth, so another\n * context's rotation, login, or logout is observed before the next credential\n * use. Change callbacks are deliberately not invoked: this is a read.\n */\n private syncFromPersistedStorage(): void {\n const canonical = this.readCanonicalSession()\n if (canonical === STORAGE_UNUSABLE) {\n this.disablePersistence()\n return\n }\n if (!canonical) return\n this.sessionRev = canonical.record.rev\n this.token = canonical.record.token\n this.refreshTokenValue = canonical.record.refreshToken\n }\n\n /** `null` when this instance does not persist. */\n private readCanonicalSession():\n | CanonicalRead\n | null\n | typeof STORAGE_UNUSABLE {\n if (\n !this.persistRecordKey ||\n !this.persistMirrorKey ||\n !this.persistMirrorRefreshKey\n ) {\n return null\n }\n return readSessionRecord(\n this.persistRecordKey,\n this.persistMirrorKey,\n this.persistMirrorRefreshKey,\n )\n }\n\n /**\n * Publish a change to canonical storage.\n *\n * The canonical pair is re-read immediately before the single record write so\n * that a field this call does not change is taken from that read rather than\n * from this instance's possibly stale copy. That merge is BEST-EFFORT: it\n * removes the stale counterpart an instance would otherwise carry, but it is\n * not a compare-and-swap. Web Storage offers none, and the synchronous public\n * mutators cannot await the refresh lease, so a commit that lands between\n * this read and the store operation is lost by ordering — including the\n * counterpart just read, which is then republished stale. The window is one\n * store operation wide and the server remains authoritative; see\n * `CUST-AUTH-033` for the stated limit.\n *\n * Returns `false` only when `requireLiveSession` refused a write because the\n * canonical session had already been cleared.\n */\n private commitPersistedSession(\n change: SessionChange,\n options?: { requireLiveSession?: boolean },\n ): boolean {\n const recordKey = this.persistRecordKey\n const mirrorKey = this.persistMirrorKey\n const mirrorRefreshKey = this.persistMirrorRefreshKey\n const canonical = this.readCanonicalSession()\n if (canonical === null || !recordKey || !mirrorKey || !mirrorRefreshKey) {\n return true\n }\n if (canonical === STORAGE_UNUSABLE) {\n this.disablePersistence()\n return true\n }\n // Decided on the same read that produces the revision below, so nothing\n // observable happens between the check and the write.\n const current = canonical.record\n if (\n options?.requireLiveSession &&\n !current.token &&\n !current.refreshToken\n ) {\n return false\n }\n\n const next: SessionRecord = {\n v: SESSION_RECORD_VERSION,\n rev: current.rev + 1,\n token: 'token' in change ? (change.token ?? null) : current.token,\n refreshToken:\n 'refreshToken' in change\n ? (change.refreshToken ?? null)\n : current.refreshToken,\n }\n if (\n // Only a state that is genuinely persisted can already say what this\n // write would say. An absent record reads as an empty pair, and treating\n // that as a no-op would drop the very tombstone that stops a later\n // migration from resurrecting the session out of the earlier layout.\n canonical.stored &&\n next.token === current.token &&\n next.refreshToken === current.refreshToken\n ) {\n this.sessionRev = current.rev\n this.token = current.token\n this.refreshTokenValue = current.refreshToken\n return true\n }\n try {\n localStorage.setItem(recordKey, JSON.stringify(next))\n } catch {\n // Safari private mode, quota, iframe sandbox: nothing was published.\n this.disablePersistence()\n return true\n }\n this.sessionRev = next.rev\n this.token = next.token\n this.refreshTokenValue = next.refreshToken\n\n // Single-value compatibility publication. Only the access token is\n // mirrored, because two mirror keys cannot be written together.\n try {\n // Retire the pre-record refresh entry FIRST. Publishing a fresh access\n // token beside a refresh token this rotation consumed is the exact pair\n // a downlevel reader would replay, and doing it in this order means that\n // pair is never published — not transiently, and not permanently if the\n // removal below throws.\n localStorage.removeItem(mirrorRefreshKey)\n } catch {\n // The stale refresh entry survives, so do not put a newer access token\n // next to it. The record stays authoritative for this SDK version.\n return true\n }\n try {\n if (next.token) localStorage.setItem(mirrorKey, next.token)\n else localStorage.removeItem(mirrorKey)\n } catch {\n // The mirror is advisory; the record above already holds canonical state.\n }\n return true\n }\n\n /**\n * Storage rejected a write or a read, so it is not a canonical store for this\n * instance. Fall back to the memory-only session and take no lease: there is\n * no shared state left to coordinate. Nothing is purged — the record commit\n * is atomic, so no inconsistent state was published, and another context's\n * valid session must not be destroyed by this instance's local failure.\n */\n private disablePersistence(): void {\n this.persistRecordKey = null\n this.persistMirrorKey = null\n this.persistMirrorRefreshKey = null\n this.refreshLockName = null\n }\n\n /**\n * Compare the canonical record with the fence this call captured before it\n * left. Every persisted decision — rotate, converge, or fail closed — goes\n * through this one comparison. The revision catches a logout, a fresh login,\n * or a manual setter even when token values coincide; the value comparison\n * additionally catches a mirror-only writer that cannot bump a revision.\n */\n private classifyCanonicalState(intended: SpentCredentials): CanonicalState {\n if (!this.persistRecordKey) return 'current'\n this.syncFromPersistedStorage()\n // A denied read during the re-check drops persistence; nothing to fence.\n if (!this.persistRecordKey) return 'current'\n\n if (!this.token && !this.refreshTokenValue) return 'cleared'\n if (intended.refreshToken !== null) {\n // Only the refresh credential decides ownership. An access token can be\n // replaced or invalidated by another context while this family stays\n // ours, and its absence is not evidence that the rotation was lost.\n return this.refreshTokenValue === intended.refreshToken\n ? 'current'\n : 'superseded'\n }\n // Compatibility bearer path: a refresh credential appearing anywhere is\n // strictly better than rotating a bearer token, so it supersedes this call.\n return this.token === intended.token && !this.refreshTokenValue\n ? 'current'\n : 'superseded'\n }\n\n /** The canonical persisted pair, as a refresh result. */\n private canonicalPair(token: string): CustomerRefreshResponse {\n return {\n token,\n ...(this.refreshTokenValue\n ? { refreshToken: this.refreshTokenValue }\n : {}),\n }\n }\n\n /** Current credentials plus the revision they were observed at. */\n private currentFence(): SpentCredentials {\n return { token: this.token, refreshToken: this.refreshTokenValue }\n }\n\n /**\n * Clear an access credential a 401 just proved unusable — but only while it\n * is still the canonical one. A rotation committed by another context while\n * the request was in flight is newer than this 401, so it must survive; the\n * instance adopts it instead. The refresh entry is never touched here: a\n * rejected access token says nothing about the refresh family.\n */\n private invalidateAccessToken(spentToken: string): void {\n this.syncFromPersistedStorage()\n if (this.token !== spentToken) return\n this.setToken(null)\n }\n\n /** Commit both credentials in one canonical write. */\n private setSession(\n token: string | null,\n refreshToken: string | null,\n options?: { requireLiveSession?: boolean },\n ): boolean {\n this.token = token\n this.refreshTokenValue = refreshToken\n const committed = this.commitPersistedSession(\n { token, refreshToken },\n options,\n )\n if (!committed) return false\n this.onTokenChange?.(this.token)\n this.onRefreshTokenChange?.(this.refreshTokenValue)\n return true\n }\n\n /**\n * Serialize rotation against every other context sharing the same storage\n * key and API/tenant identity. Coordination is best-effort: when it is\n * unavailable or times out the rotation still happens, so server-side reuse\n * detection is never bypassed by a client that failed to coordinate.\n */\n private async rotateAcrossContexts(\n intended: SpentCredentials,\n ): Promise<CustomerRefreshResponse> {\n const lockName = this.refreshLockName\n const requestLock = lockName ? getRefreshLockRequester() : null\n if (!lockName || !requestLock) {\n return this.rotateWithCanonicalState(intended)\n }\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), REFRESH_LOCK_TIMEOUT)\n let entered = false\n try {\n return await requestLock(\n lockName,\n { signal: controller.signal },\n async () => {\n entered = true\n return this.rotateWithCanonicalState(intended)\n },\n )\n } catch (error) {\n // A failure raised inside the lock is the caller's refresh failure.\n if (entered) throw error\n // The lock was never held: bounded wait aborted, or the API rejected the\n // request. Degrade to an uncoordinated rotation.\n return this.rotateWithCanonicalState(intended)\n } finally {\n // Always drop the abort timer; the lease itself is released when the\n // Web Locks callback settles.\n clearTimeout(timer)\n }\n }\n\n /**\n * Decide, against freshly re-read canonical state, whether this context still\n * owns the rotation.\n */\n private async rotateWithCanonicalState(\n intended: SpentCredentials,\n ): Promise<CustomerRefreshResponse> {\n let fence = intended\n // One re-fence is enough: it turns \"canonical moved and left no usable\n // access token\" into a rotation of the canonical refresh credential.\n for (let attempt = 0; attempt < 2; attempt += 1) {\n const state = this.classifyCanonicalState(fence)\n // Another context logged out while this call waited.\n if (state === 'cleared') throw new ApiError('Not authenticated', 401)\n if (state === 'current') return this._doRefreshToken(fence)\n // Another context already rotated the credential this call captured.\n // Converge on its successor instead of replaying a consumed token.\n if (this.token) return this.canonicalPair(this.token)\n // No usable access token, but a live canonical refresh credential:\n // rotate that one rather than the stale credential captured earlier.\n fence = this.currentFence()\n }\n throw new ApiError('Not authenticated', 401)\n }\n\n private async _doRefreshToken(\n intended: SpentCredentials,\n ): Promise<CustomerRefreshResponse> {\n const init: RequestInit = intended.refreshToken\n ? {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.refresh,\n ),\n body: JSON.stringify({ refreshToken: intended.refreshToken }),\n }\n : {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.refresh,\n ),\n headers: { Authorization: `Bearer ${intended.token as string}` },\n }\n const result: CustomerRefreshResponse = await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.refresh),\n init,\n )\n\n // The rotation was in flight for a whole round trip. Re-check the canonical\n // state before writing: a successor must never resurrect a session another\n // context ended, nor overwrite one it established in the meantime.\n const state = this.classifyCanonicalState(intended)\n // Logout wins: never resurrect a session another context ended.\n if (state === 'cleared') throw new ApiError('Not authenticated', 401)\n if (state === 'superseded') {\n // Another context owns the family now. Converge on what it published, or\n // fail closed rather than hand back an unusable pair.\n if (this.token) return this.canonicalPair(this.token)\n throw new ApiError('Not authenticated', 401)\n }\n\n // Still ours. The presented credential is consumed server-side, so the\n // successor is the only live one and MUST land — stranding it would leave\n // every context replaying a consumed token. Only an access token another\n // context deliberately replaced is preserved; an absent one is not a\n // replacement, so the freshly issued token fills it.\n const replacedAccessToken =\n this.token !== null && this.token !== intended.token ? this.token : null\n const nextToken = replacedAccessToken ?? result.token\n const nextRefresh = result.refreshToken ?? null\n // Decided on the write's own canonical read, so a logout committed before\n // it is not resurrected.\n if (\n !this.setSession(nextToken, nextRefresh, { requireLiveSession: true })\n ) {\n throw new ApiError('Not authenticated', 401)\n }\n return {\n token: nextToken,\n ...(nextRefresh ? { refreshToken: nextRefresh } : {}),\n }\n }\n\n /**\n * Clear local credentials synchronously. This compatibility API cannot\n * revoke the server-side refresh family; use logoutAsync() for that.\n * @deprecated Use logoutAsync() to end the direct server session.\n */\n logout(): void {\n // One canonical write, so no context can observe a half-cleared session.\n this.setSession(null, null)\n }\n\n /**\n * End the current direct refresh family and clear local credentials even if\n * revocation fails. A legacy access-only session has no refresh family here.\n */\n async logoutAsync(): Promise<void> {\n this.syncFromPersistedStorage()\n const refreshToken = this.refreshTokenValue\n this.logout()\n if (!refreshToken) return\n\n const operation = CUSTOMER_AUTH_ENDPOINT_OPERATIONS.revokeRefresh\n await this.requestJson(resolveOperationPath(operation), {\n method: resolveOperationMethod(operation),\n body: JSON.stringify({ refreshToken }),\n })\n }\n\n /** Archive the current password account and clear this client's credentials on success. */\n async withdraw(currentPassword: string): Promise<CustomerWithdrawalResult> {\n const token = this.getToken()\n if (!token) throw new ApiError('Not authenticated', 401)\n const operation = CUSTOMER_AUTH_ENDPOINT_OPERATIONS.withdraw\n const result = await this.requestJson<CustomerWithdrawalResult>(\n resolveOperationPath(operation),\n {\n method: resolveOperationMethod(operation),\n headers: { Authorization: `Bearer ${token}` },\n body: JSON.stringify({ currentPassword }),\n },\n )\n if (\n !result ||\n typeof result.withdrawnAt !== 'string' ||\n !Number.isFinite(Date.parse(result.withdrawnAt))\n )\n throw new ApiError('Invalid customer withdrawal response', 502)\n this.logout()\n return { withdrawnAt: result.withdrawnAt }\n }\n\n /**\n * Get the current authenticated customer's profile\n */\n async me(): Promise<CustomerProfile | null> {\n const token = this.getToken()\n if (!token) return null\n\n try {\n const data = await this.requestJson<{ customer: CustomerProfile }>(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.me),\n {\n method: resolveOperationMethod(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.me),\n headers: { Authorization: `Bearer ${token}` },\n },\n )\n return data.customer ?? null\n } catch (error) {\n if (error instanceof SDKError && error.status === 401) {\n this.invalidateAccessToken(token)\n return null\n }\n throw error\n }\n }\n\n /**\n * Request a password reset email\n */\n async forgotPassword(email: string): Promise<void> {\n await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.forgotPassword),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.forgotPassword,\n ),\n body: JSON.stringify({ email }),\n },\n )\n }\n\n /**\n * Reset password using a token from the reset email\n */\n async resetPassword(token: string, password: string): Promise<void> {\n await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.resetPassword),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.resetPassword,\n ),\n body: JSON.stringify({ token, password }),\n },\n )\n }\n\n /**\n * Update the authenticated customer's profile (name, phone, marketingConsent)\n */\n async updateProfile(data: UpdateProfileData): Promise<CustomerProfile> {\n const token = this.getToken()\n if (!token) throw new ApiError('Not authenticated', 401)\n\n const result = await this.requestJson<{ customer: CustomerProfile }>(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.updateProfile),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.updateProfile,\n ),\n headers: { Authorization: `Bearer ${token}` },\n body: JSON.stringify(data),\n },\n )\n return result.customer\n }\n\n /**\n * Change the password of the currently authenticated customer\n */\n async changePassword(\n currentPassword: string,\n newPassword: string,\n ): Promise<void> {\n const token = this.getToken()\n if (!token) throw new ApiError('Not authenticated', 401)\n\n await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.changePassword),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.changePassword,\n ),\n headers: { Authorization: `Bearer ${token}` },\n body: JSON.stringify({ currentPassword, newPassword }),\n },\n )\n }\n\n /**\n * Get the authenticated customer's orders with pagination and optional status filter\n */\n async getMyOrders(\n options?: CustomerOrderListOptions,\n ): Promise<PayloadFindResponse<PublicOrder>> {\n const token = this.getToken()\n if (!token) throw new ApiError('Not authenticated', 401)\n\n const params = new URLSearchParams()\n if (options?.page) params.set('page', String(options.page))\n if (options?.limit) params.set('limit', String(options.limit))\n if (options?.financialStatus) {\n params.set('financialStatus', options.financialStatus)\n }\n if (options?.fulfillmentStatus) {\n params.set('fulfillmentStatus', options.fulfillmentStatus)\n }\n if (options?.returnStatus) params.set('returnStatus', options.returnStatus)\n if (options?.confirmationStatus) {\n params.set('confirmationStatus', options.confirmationStatus)\n }\n if (options?.primaryDisplayStatus) {\n params.set('primaryDisplayStatus', options.primaryDisplayStatus)\n }\n const qs = params.toString()\n const result = await this.requestJson<unknown>(\n `/api/customers/me/orders${qs ? `?${qs}` : ''}`,\n {\n method: 'GET',\n headers: { Authorization: `Bearer ${token}` },\n },\n )\n return validatePublicOrderList<PayloadFindResponse<PublicOrder>>(result)\n }\n\n /**\n * Get the current token (or null if not authenticated).\n *\n * In persisted mode this re-reads shared storage first, so a rotation or\n * logout performed by another tab is observed before the token is used.\n */\n getToken(): string | null {\n this.syncFromPersistedStorage()\n return this.token\n }\n\n /**\n * Get the current refresh token (or null if unavailable). Persisted mode\n * re-reads shared storage first, like {@link CustomerAuth.getToken}.\n */\n getRefreshToken(): string | null {\n this.syncFromPersistedStorage()\n return this.refreshTokenValue\n }\n\n /**\n * Set the token manually (e.g. from SSR)\n */\n setToken(token: string | null): void {\n this.token = token\n // Access only: the latest canonical refresh token is preserved.\n this.commitPersistedSession({ token })\n this.onTokenChange?.(token)\n }\n\n /**\n * Set the refresh token manually (e.g. from SSR cookie)\n */\n setRefreshToken(refreshToken: string | null): void {\n this.refreshTokenValue = refreshToken\n // Refresh only: the latest canonical access token is preserved.\n this.commitPersistedSession({ refreshToken })\n this.onRefreshTokenChange?.(refreshToken)\n }\n\n /**\n * Check if the customer is currently authenticated\n */\n isAuthenticated(): boolean {\n return this.getToken() !== null\n }\n\n /**\n * Internal: make a request with timeout and error handling.\n * Auth endpoints don't retry — failures are final.\n */\n private async requestJson<T = unknown>(\n path: string,\n init: RequestInit,\n ): Promise<T> {\n const headers = new Headers(init.headers)\n headers.set('X-Publishable-Key', this.publishableKey)\n if (!headers.has('Content-Type') && init.body) {\n headers.set('Content-Type', 'application/json')\n }\n\n const response = await httpFetch(path, {\n ...init,\n apiUrl: this.baseUrl,\n publishableKey: this.publishableKey,\n headers,\n timeout: DEFAULT_TIMEOUT,\n retry: { maxRetries: 0 },\n })\n\n return parseApiResponse<T>(response, path)\n }\n}\n","import { parseApiResponse } from '../api/parse-response'\nimport { httpFetch } from '../internal/utils'\nimport { resolveApiUrl } from '../internal/utils/api-url'\n\nconst DEFAULT_SCOPES = ['openid', 'profile', 'email'] as const\nconst DEFAULT_TIMEOUT = 15000\n\nexport interface CustomerOAuthConfig {\n clientId: string\n issuer: string\n timeout?: number\n}\n\nexport interface CustomerAuthorizationUrlInput {\n redirectUri: string\n returnTo?: string\n scopes?: readonly string[]\n}\n\nexport interface CustomerAuthorizationUrlResult {\n authorizationUrl: string\n codeChallenge: string\n codeVerifier: string\n nonce: string\n returnTo: string | null\n state: string\n}\n\nexport interface CustomerOAuthCallbackResult {\n code: string\n state: string\n}\n\nexport interface CustomerOAuthTokenSet {\n accessToken: string\n expiresAt: number\n expiresIn: number\n idToken?: string\n refreshToken: string\n scope?: string\n tokenType: 'Bearer'\n}\n\ninterface TokenEndpointResponse {\n access_token: string\n expires_in: number\n id_token?: string\n refresh_token: string\n scope?: string\n token_type: string\n}\n\nfunction issuerUrl(issuer: string, path: string): string {\n const base = resolveApiUrl(issuer)\n return new URL(path, base.endsWith('/') ? base : `${base}/`).toString()\n}\n\nfunction randomBase64Url(bytes: number): string {\n const buffer = new Uint8Array(bytes)\n crypto.getRandomValues(buffer)\n\n let binary = ''\n for (const value of buffer) {\n binary += String.fromCharCode(value)\n }\n\n return btoa(binary)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/g, '')\n}\n\nasync function sha256Base64Url(value: string): Promise<string> {\n const data = new TextEncoder().encode(value)\n const digest = await crypto.subtle.digest('SHA-256', data)\n\n let binary = ''\n for (const byte of new Uint8Array(digest)) {\n binary += String.fromCharCode(byte)\n }\n\n return btoa(binary)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/g, '')\n}\n\nfunction normalizeToken(body: TokenEndpointResponse): CustomerOAuthTokenSet {\n if (body.token_type !== 'Bearer') {\n throw new Error('Unsupported customer OAuth token type')\n }\n\n return {\n accessToken: body.access_token,\n expiresAt: Date.now() + body.expires_in * 1000,\n expiresIn: body.expires_in,\n ...(body.id_token ? { idToken: body.id_token } : {}),\n refreshToken: body.refresh_token,\n ...(body.scope ? { scope: body.scope } : {}),\n tokenType: 'Bearer',\n }\n}\n\nexport class CustomerOAuth {\n private readonly clientId: string\n private readonly issuer: string\n private readonly timeout: number\n\n constructor(config: CustomerOAuthConfig) {\n if (!config.clientId) throw new Error('customer OAuth clientId is required')\n if (!config.issuer) throw new Error('customer OAuth issuer is required')\n\n this.clientId = config.clientId\n this.issuer = config.issuer\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT\n }\n\n async createAuthorizationUrl(\n input: CustomerAuthorizationUrlInput,\n ): Promise<CustomerAuthorizationUrlResult> {\n const codeVerifier = randomBase64Url(48)\n const codeChallenge = await sha256Base64Url(codeVerifier)\n const state = randomBase64Url(32)\n const nonce = randomBase64Url(32)\n const scopes = input.scopes ?? DEFAULT_SCOPES\n const url = new URL(issuerUrl(this.issuer, 'customer-oauth/authorize'))\n\n url.searchParams.set('response_type', 'code')\n url.searchParams.set('client_id', this.clientId)\n url.searchParams.set('redirect_uri', input.redirectUri)\n url.searchParams.set('scope', scopes.join(' '))\n url.searchParams.set('state', state)\n url.searchParams.set('nonce', nonce)\n url.searchParams.set('code_challenge', codeChallenge)\n url.searchParams.set('code_challenge_method', 'S256')\n\n return {\n authorizationUrl: url.toString(),\n codeChallenge,\n codeVerifier,\n nonce,\n returnTo: input.returnTo ?? null,\n state,\n }\n }\n\n parseCallback(\n callbackUrl: string,\n options: { expectedState: string },\n ): CustomerOAuthCallbackResult {\n const url = new URL(callbackUrl)\n const error = url.searchParams.get('error')\n\n if (error) {\n throw new Error(\n url.searchParams.get('error_description') ?? `OAuth error: ${error}`,\n )\n }\n\n const code = url.searchParams.get('code')\n const state = url.searchParams.get('state')\n\n if (!code || !state) throw new Error('OAuth callback is missing code/state')\n if (state !== options.expectedState) throw new Error('OAuth state mismatch')\n\n return { code, state }\n }\n\n async exchangeCode(input: {\n code: string\n codeVerifier: string\n redirectUri: string\n }): Promise<CustomerOAuthTokenSet> {\n const body = new URLSearchParams({\n client_id: this.clientId,\n code: input.code,\n code_verifier: input.codeVerifier,\n grant_type: 'authorization_code',\n redirect_uri: input.redirectUri,\n })\n\n return this.tokenRequest(body)\n }\n\n async refresh(input: {\n refreshToken: string\n }): Promise<CustomerOAuthTokenSet> {\n const body = new URLSearchParams({\n client_id: this.clientId,\n grant_type: 'refresh_token',\n refresh_token: input.refreshToken,\n })\n\n return this.tokenRequest(body)\n }\n\n async logout(input: {\n postLogoutRedirectUri?: string\n refreshToken?: string\n }): Promise<{ redirectUrl?: string; success: boolean }> {\n const body: Record<string, string> = { client_id: this.clientId }\n\n if (input.refreshToken) body.refresh_token = input.refreshToken\n if (input.postLogoutRedirectUri) {\n body.post_logout_redirect_uri = input.postLogoutRedirectUri\n }\n\n const response = await httpFetch('/customer-oauth/logout', {\n apiUrl: this.issuer,\n method: 'POST',\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n timeout: this.timeout,\n retry: { maxRetries: 0 },\n })\n\n return parseApiResponse<{ redirectUrl?: string; success: boolean }>(\n response,\n '/customer-oauth/logout',\n )\n }\n\n verifyIdToken(): never {\n throw new Error(\n 'Customer OAuth ID token verification is not implemented; treat idToken as opaque.',\n )\n }\n\n private async tokenRequest(\n body: URLSearchParams,\n ): Promise<CustomerOAuthTokenSet> {\n const response = await httpFetch('/api/customer-oauth/token', {\n apiUrl: this.issuer,\n method: 'POST',\n body,\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n timeout: this.timeout,\n retry: { maxRetries: 0 },\n })\n\n return normalizeToken(\n await parseApiResponse<TokenEndpointResponse>(\n response,\n '/api/customer-oauth/token',\n ),\n )\n }\n}\n","import { CustomerAuth } from './customer-auth'\nimport { CustomerOAuth } from './customer-oauth'\nimport type { CustomerAuthOptions } from './types'\n\n/**\n * Customer namespace. Currently exposes .auth; reserved for future customer-\n * scoped capabilities (addresses, preferences, etc.).\n */\nexport class CustomerNamespace {\n readonly auth: CustomerAuth\n readonly oauth?: CustomerOAuth\n\n constructor(\n publishableKey: string,\n options?: CustomerAuthOptions,\n apiUrl?: string,\n ) {\n this.auth = new CustomerAuth(publishableKey, options, apiUrl)\n if (options?.oauth) {\n this.oauth = new CustomerOAuth(options.oauth)\n }\n }\n}\n","import { createValidationError } from '../internal/errors'\n\nconst UUID_V4_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\nconst PREFIXED_BASE64URL_PATTERN = /^ik_[A-Za-z0-9_-]{22}$/\n\nexport function isCommerceIdempotencyKey(value: unknown): value is string {\n return (\n typeof value === 'string' &&\n value.length <= 255 &&\n (UUID_V4_PATTERN.test(value) || PREFIXED_BASE64URL_PATTERN.test(value))\n )\n}\n\nexport function assertCommerceIdempotencyKey(\n value: unknown,\n): asserts value is string {\n if (isCommerceIdempotencyKey(value)) return\n throw createValidationError(\n 'idempotencyKey must be a UUIDv4 or ik_-prefixed 128-bit base64url value.',\n { field: 'idempotencyKey' },\n )\n}\n\n/** Create a cryptographically strong key for one logical commerce operation. */\nexport function createCommerceIdempotencyKey(): string {\n return globalThis.crypto.randomUUID()\n}\n","import { CustomerScopedApi } from './customer-scoped-api'\nimport {\n COMMERCE_ENDPOINTS,\n type CommerceEndpointDescriptor,\n} from './endpoints'\nimport type { PublicMediaAsset } from './public-media'\nimport {\n validateCartMergeResult,\n validateCartMineResult,\n validateCartMutationResult,\n validateCreateCartResult,\n validatePublicCart,\n} from './canonical-response'\nimport { assertCommerceIdempotencyKey } from './commerce-idempotency'\n\nexport interface CartApiOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport const MAX_CART_LINE_ADMISSIONS = 32\n\nexport type PublicAttribute = { key: string; value: string }\n\nexport type CreateCartParams = {\n market?: string\n attributes?: PublicAttribute[]\n}\n\nexport type PublicCartItemAdmission = {\n eventId: string\n occurrenceId: string\n admissionTypeId: string\n}\n\nexport type AddItemParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n productId: string\n variantId: string\n quantity: number\n admissions?: readonly [PublicCartItemAdmission, ...PublicCartItemAdmission[]]\n}\n\nexport type UpdateItemParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n cartItemId: string\n quantity: number\n}\n\nexport type ServerAddItemParams = AddItemParams & { customerToken?: string }\nexport type ServerUpdateItemParams = UpdateItemParams & {\n customerToken?: string\n}\n\nexport type RemoveItemParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n cartItemId: string\n}\n\nexport type UpdateDiscountCodesParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n discountCodes: string[]\n}\n\nexport type UpdateCartAttributesParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n attributes: PublicAttribute[]\n}\n\nexport type ClearCartParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n}\nexport type RetrieveCartParams = { cartToken: string }\nexport type CartMineParams = Record<string, never>\nexport type ServerCartMineParams = { customerToken: string }\nexport type CartMergeParams = { guestCartToken: string; idempotencyKey: string }\nexport type ServerCartMergeParams = CartMergeParams & { customerToken: string }\n\nexport type CartDiscountCode = {\n code: string\n applicable: boolean\n}\n\nexport type CartWarningCode =\n | 'DISCOUNT_CODE_NOT_HONOURED'\n | 'DISCOUNT_CURRENTLY_INACTIVE'\n | 'DISCOUNT_CUSTOMER_NOT_ELIGIBLE'\n | 'DISCOUNT_CUSTOMER_USAGE_LIMIT_REACHED'\n | 'DISCOUNT_ELIGIBLE_CUSTOMER_MISSING'\n | 'DISCOUNT_NO_ENTITLED_LINE_ITEMS'\n | 'DISCOUNT_NO_ENTITLED_SHIPPING_LINES'\n | 'DISCOUNT_NOT_FOUND'\n | 'DISCOUNT_PURCHASE_NOT_IN_RANGE'\n | 'DISCOUNT_USAGE_LIMIT_REACHED'\n | 'MERCHANDISE_NOT_ENOUGH_STOCK'\n | 'MERCHANDISE_OUT_OF_STOCK'\n\nexport type CartWarning = {\n code: CartWarningCode\n message: string\n target: string\n}\n\nexport type PublicCartReference = {\n id: string\n title: string\n handle: string | null\n image: PublicMediaAsset | null\n}\n\nexport type PublicCartMarket = {\n id: string\n handle: string\n name: string\n}\n\nexport type PublicCartItem = {\n id: string\n product: PublicCartReference\n variant: PublicCartReference\n admissions: PublicCartItemAdmission[]\n quantity: number\n unitPriceMinor: number\n discountMinor: number\n estimatedLineTotalMinor: number\n requiresShipping: boolean\n}\n\ntype PublicCartBase = {\n id: string\n status: 'active' | 'completed' | 'abandoned'\n revision: number\n currency: Uppercase<string>\n market: PublicCartMarket\n subtotalMinor: number\n discountMinor: number\n estimatedTotalMinor: number\n discountCodes: CartDiscountCode[]\n attributes: PublicAttribute[]\n items: PublicCartItem[]\n expiresAt: string\n createdAt: string\n updatedAt: string\n}\n\ntype PublicCartPickupResponse = PublicCartBase & {\n deliveryMethod: 'shipping' | 'pickup'\n shippingMinor: number\n totalMinor: number\n}\n\n/**\n * Released response or the complete ADR 0125 cutover response; no fields are\n * synthesized. Narrow with `'deliveryMethod' in value` to read the new fields.\n */\nexport type PublicCart =\n | PublicCartBase\n | {\n [K in keyof PublicCartPickupResponse]: PublicCartPickupResponse[K]\n }\n\nexport type CartMutationResult = {\n cart: PublicCart\n warnings: CartWarning[]\n}\n\nexport type CreateCartResult = {\n cart: PublicCart\n warnings: CartWarning[]\n cartToken: string\n}\n\nexport type CartMergeResultBase = CreateCartResult\n\nexport type CartMergeResult = CartMergeResultBase &\n (\n | { resolution: 'unchanged'; merged: false; claimed: false }\n | { resolution: 'claimed'; merged: false; claimed: true }\n | { resolution: 'merged'; merged: true; claimed: false }\n )\n\nexport type CartMineResult =\n | { cart: PublicCart; cartToken: string }\n | { cart: null; cartToken: null }\n\nexport class CartApi extends CustomerScopedApi {\n private readonly serverTransport: boolean\n\n constructor(options: CartApiOptions) {\n super('CartApi', { ...options, requiresCredential: false })\n this.serverTransport = Boolean(options.secretKey)\n }\n\n private endpoint<Key extends keyof typeof COMMERCE_ENDPOINTS.carts.server>(\n key: Key,\n ): CommerceEndpointDescriptor {\n return this.serverTransport\n ? COMMERCE_ENDPOINTS.carts.server[key]\n : COMMERCE_ENDPOINTS.carts[key]\n }\n\n private execute(\n endpoint: CommerceEndpointDescriptor,\n body: unknown,\n idempotencyKey?: string,\n ): Promise<unknown> {\n return this.requestEndpoint<unknown>(endpoint, body, {\n ...(idempotencyKey && {\n headers: { 'X-Idempotency-Key': idempotencyKey },\n }),\n })\n }\n\n create(params: CreateCartParams = {}): Promise<CreateCartResult> {\n return this.execute(this.endpoint('create'), params).then((value) =>\n validateCreateCartResult<CreateCartResult>(value),\n )\n }\n\n retrieve(params: RetrieveCartParams): Promise<PublicCart> {\n return this.execute(this.endpoint('retrieve'), params).then((value) =>\n validatePublicCart<PublicCart>(value),\n )\n }\n\n mine(\n params: CartMineParams | ServerCartMineParams = {},\n ): Promise<CartMineResult> {\n const endpoint = this.endpoint('mine')\n return this.execute(endpoint, params).then((value) =>\n validateCartMineResult<CartMineResult>(value),\n )\n }\n\n merge(\n params: CartMergeParams | ServerCartMergeParams,\n ): Promise<CartMergeResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n const endpoint = this.endpoint('merge')\n return this.execute(endpoint, body, idempotencyKey).then((value) =>\n validateCartMergeResult<CartMergeResult>(value),\n )\n }\n\n addItem(\n params: AddItemParams | ServerAddItemParams,\n ): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('addItem'), params)\n }\n\n private mutate(\n endpoint: CommerceEndpointDescriptor,\n params: { idempotencyKey: string },\n ): Promise<CartMutationResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n return this.execute(endpoint, body, idempotencyKey).then((value) =>\n validateCartMutationResult<CartMutationResult>(value),\n )\n }\n\n updateItem(\n params: UpdateItemParams | ServerUpdateItemParams,\n ): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('updateItem'), params)\n }\n\n removeItem(params: RemoveItemParams): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('removeItem'), params)\n }\n\n clear(params: ClearCartParams): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('clear'), params)\n }\n\n updateDiscountCodes(\n params: UpdateDiscountCodesParams,\n ): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('updateDiscountCodes'), params)\n }\n\n updateAttributes(\n params: UpdateCartAttributesParams,\n ): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('updateAttributes'), params)\n }\n}\n","import { createApiError, createValidationError } from '../internal/errors'\nimport {\n CustomerScopedApi,\n type CustomerScopedApiOptions,\n} from './customer-scoped-api'\nimport {\n COMMERCE_ENDPOINTS,\n CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE,\n type CommerceEndpointDescriptor,\n} from './endpoints'\nimport type {\n PublicAttribute,\n PublicCartItemAdmission,\n PublicCartReference,\n} from './cart-api'\nimport { assertCommerceIdempotencyKey } from './commerce-idempotency'\nimport {\n validateCheckoutQueryResult,\n validateCreateCheckoutResult,\n validatePublicCheckout,\n validateServerCheckout,\n} from './canonical-response'\n\nexport type CheckoutApiOptions = CustomerScopedApiOptions\nexport type CheckoutStatus = 'open' | 'placed' | 'abandoned'\n\nexport type CustomerSnapshot = {\n email: string\n name?: string\n phone?: string\n}\n\nexport type CheckoutShippingAddress = {\n recipientName: string\n phone: string\n countryCode?: string\n regionCode?: string\n postalCode: string\n address: string\n detailAddress: string\n deliveryMessage?: string\n}\n\nexport type PublicCheckoutItem = {\n id: string\n product: PublicCartReference\n variant: PublicCartReference\n productTitle: string\n variantTitle: string | null\n sku: string | null\n admissions: PublicCartItemAdmission[]\n quantity: number\n unitPriceMinor: number\n discountMinor: number\n lineTotalMinor: number\n requiresShipping: boolean\n}\n\nexport type CheckoutAmounts = {\n currency: Uppercase<string>\n subtotalMinor: number\n shippingMinor: number\n discountMinor: number\n totalMinor: number\n}\n\nexport type CheckoutPaymentSessionRef = {\n id: string\n /**\n * Closed managed-provider vocabulary. `'stripe'` is accepted ahead of the\n * server and is not emitted until Stripe becomes available.\n */\n provider: 'toss' | 'portone' | 'stripe'\n providerStatus:\n | 'requires_payment_method'\n | 'requires_action'\n | 'requires_confirmation'\n | 'initializing'\n | 'processing'\n | 'authorized'\n | 'canceling'\n | 'unknown'\n | 'captured'\n | 'failed'\n | 'canceled'\n}\n\nexport type OpenCheckoutPaymentState = {\n activePaymentSession: CheckoutPaymentSessionRef | null\n}\n\nexport type SpentCheckoutPaymentState = {\n activePaymentSession: null\n}\n\nexport type CheckoutFunding = {\n creditAmount: number\n providerPayableAmount: number\n}\n\nexport type PublicCheckoutBase = {\n /** Frozen purchase split. Absence means legacy/unknown server support,\n * never creditAmount=0. Refunds do not rewrite these original amounts. */\n funding?: CheckoutFunding\n id: string\n amounts: CheckoutAmounts\n items: PublicCheckoutItem[]\n customerSnapshot: CustomerSnapshot\n shippingAddress: CheckoutShippingAddress | null\n attributes: PublicAttribute[]\n expiresAt: string\n createdAt: string\n updatedAt: string\n}\n\nexport type CheckoutOrderReference = { id: string; orderNumber: string }\nexport type CheckoutAbandonedReason = 'expired' | 'customer' | 'operator'\n\n/**\n * Released response or the complete ADR 0125 cutover response; no fields are\n * synthesized. Narrow with `'deliveryMethod' in value` to read the new fields.\n */\nexport type PublicCheckout = (\n | PublicCheckoutBase\n | (PublicCheckoutBase & {\n deliveryMethod: 'shipping' | 'pickup'\n source: 'web' | 'in_person'\n })\n) &\n (\n | {\n status: 'open'\n paymentState: OpenCheckoutPaymentState\n order: null\n placedAt?: never\n placedVia?: never\n abandonedAt?: never\n abandonedReason?: never\n }\n | {\n status: 'placed'\n placedAt: string\n paymentState: SpentCheckoutPaymentState\n order: CheckoutOrderReference\n placedVia?: never\n abandonedAt?: never\n abandonedReason?: never\n }\n | {\n status: 'placed'\n placedAt: string\n placedVia: 'late_capture'\n abandonedAt: string\n abandonedReason: CheckoutAbandonedReason\n paymentState: SpentCheckoutPaymentState\n order: CheckoutOrderReference\n }\n | {\n status: 'abandoned'\n abandonedAt: string\n abandonedReason: CheckoutAbandonedReason\n paymentState: {\n activePaymentSession: null\n }\n order: null\n placedAt?: never\n placedVia?: never\n }\n )\n\nexport type ServerCheckout = PublicCheckout & {\n clientReferenceId: string | null\n integrationMetadata: Record<string, string>\n}\n\nexport type RetrieveCheckoutParams = { checkoutToken: string }\nexport type RetrieveServerCheckoutParams = { checkoutId: string }\n\nexport type CreateCheckoutParams = {\n /** Exact positive integer KRW request. Never clamped or silently retried without credit. */\n creditAmount?: number\n cartToken: string\n customer: CustomerSnapshot\n shippingAddress?: CheckoutShippingAddress\n idempotencyKey: string\n}\n\nexport type CreateServerCheckoutParams = CreateCheckoutParams & {\n customerToken?: string\n clientReferenceId?: string\n integrationMetadata?: Record<string, string>\n}\n\nexport type CreateCheckoutResult = {\n checkout: PublicCheckout\n checkoutToken: string\n}\n\nexport type CreateServerCheckoutResult = {\n checkout: ServerCheckout\n checkoutToken: string\n}\n\nexport type CheckoutQueryParams = {\n limit?: number\n cursor?: string\n status?: CheckoutStatus[]\n createdAtFrom?: string\n createdAtTo?: string\n clientReferenceId?: string\n}\n\nexport type CheckoutListItem = PublicCheckout extends infer Checkout\n ? Checkout extends unknown\n ? Omit<Checkout, 'items' | 'shippingAddress' | 'attributes'> & {\n clientReferenceId: string | null\n }\n : never\n : never\n\nexport type CheckoutQueryResult = {\n data: CheckoutListItem[]\n hasMore: boolean\n nextCursor: string | null\n}\n\nexport class CheckoutApi extends CustomerScopedApi {\n constructor(options: CheckoutApiOptions) {\n super('CheckoutApi', { ...options, requiresCredential: false })\n }\n\n private post(\n endpoint: CommerceEndpointDescriptor,\n body: unknown,\n idempotencyKey?: string,\n ): Promise<unknown> {\n return this.requestEndpoint<unknown>(endpoint, body, {\n headers: {\n Accept: CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE,\n ...(idempotencyKey && { 'X-Idempotency-Key': idempotencyKey }),\n },\n })\n }\n\n private async publicCheckout(\n result: Promise<unknown>,\n ): Promise<PublicCheckout> {\n return validatePublicCheckout<PublicCheckout>(await result)\n }\n\n private async serverCheckout(\n result: Promise<unknown>,\n ): Promise<ServerCheckout> {\n return validateServerCheckout<ServerCheckout>(await result)\n }\n\n private async createResult(\n result: Promise<unknown>,\n creditAmount?: number,\n ): Promise<CreateCheckoutResult> {\n const parsed = validateCreateCheckoutResult<CreateCheckoutResult>(\n await result,\n false,\n )\n this.assertRequestedCredit(parsed.checkout, creditAmount)\n return parsed\n }\n\n private async createServerResult(\n result: Promise<unknown>,\n creditAmount?: number,\n ): Promise<CreateServerCheckoutResult> {\n const parsed = validateCreateCheckoutResult<CreateServerCheckoutResult>(\n await result,\n true,\n )\n this.assertRequestedCredit(parsed.checkout, creditAmount)\n return parsed\n }\n\n private assertCreditInput(amount: number | undefined): void {\n if (amount !== undefined && (!Number.isSafeInteger(amount) || amount <= 0))\n throw createValidationError(\n 'creditAmount must be a positive safe integer.',\n )\n }\n\n private assertRequestedCredit(\n checkout: PublicCheckout,\n requested: number | undefined,\n ): void {\n if (requested !== undefined && checkout.funding?.creditAmount !== requested)\n throw createApiError(\n 'Credit funding was not confirmed by the server.',\n 502,\n { resource: 'Checkout', path: '$.funding' },\n 'The response does not confirm the requested credit funding.',\n 'Retry the same create with the original idempotency key and credit amount, or retrieve the Checkout; never retry without credit.',\n )\n }\n\n create(params: CreateCheckoutParams): Promise<CreateCheckoutResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n this.assertCreditInput(body.creditAmount)\n return this.createResult(\n this.post(COMMERCE_ENDPOINTS.checkouts.create, body, idempotencyKey),\n body.creditAmount,\n )\n }\n\n createServer(\n params: CreateServerCheckoutParams,\n ): Promise<CreateServerCheckoutResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n this.assertCreditInput(body.creditAmount)\n return this.createServerResult(\n this.post(\n COMMERCE_ENDPOINTS.checkouts.server.create,\n body,\n idempotencyKey,\n ),\n body.creditAmount,\n )\n }\n\n retrieve(params: RetrieveCheckoutParams): Promise<PublicCheckout> {\n return this.publicCheckout(\n this.post(COMMERCE_ENDPOINTS.checkouts.retrieve, params),\n )\n }\n\n retrieveServer(\n params: RetrieveServerCheckoutParams,\n ): Promise<ServerCheckout> {\n return this.serverCheckout(\n this.post(COMMERCE_ENDPOINTS.checkouts.server.retrieve, params),\n )\n }\n\n async query(params: CheckoutQueryParams = {}): Promise<CheckoutQueryResult> {\n const result = await this.post(\n COMMERCE_ENDPOINTS.checkouts.server.query,\n params,\n )\n return validateCheckoutQueryResult<CheckoutQueryResult>(result)\n }\n}\n","import {\n CustomerScopedApi,\n type CustomerScopedApiOptions,\n} from './customer-scoped-api'\nimport { BaseApi, type ServerApiOptions } from './base-api'\nimport {\n COMMERCE_ENDPOINTS,\n PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE,\n type CommerceEndpointDescriptor,\n} from './endpoints'\nimport { assertCommerceIdempotencyKey } from './commerce-idempotency'\nimport {\n validateConfirmCustomPaymentSessionResponse,\n validateCustomPaymentSession,\n validatePortOnePaymentFacadeResult,\n validatePublicPaymentSession,\n validateRetrievedCustomPaymentSession,\n} from './canonical-response'\n\nexport type PaymentSessionApiOptions = CustomerScopedApiOptions\n\nexport type Money = { amountMinor: number; currency: Uppercase<string> }\n\nexport type PortOneHostedPaymentMethod =\n | 'CARD_KR'\n | 'N_PAY'\n | 'KAKAO_PAY'\n | 'TOSS_PAY'\n | 'CARD_INTERNATIONAL'\n | 'PAY_PAL'\n | 'UNION_PAY'\n | 'ALIPAY_CN'\n | 'ALIPAY_HK'\n | 'TRUE_MONEY'\n | 'DANA'\n | 'TOUCH_N_GO'\n | 'G_CASH'\n | 'WE_CHAT_PAY'\n | 'KLARNA'\n | 'E_CONTEXT'\n | 'GRAB_PAY_MY'\n | 'GRAB_PAY_SG'\n | 'SHOPEE_PAY_TH'\n | 'PAY_PAY'\n | 'BPI'\n | 'RABBIT_LINE_PAY'\n | 'CONVENIENCE_STORE_JP'\n | 'AMAZON_PAY'\n | 'RAKUTEN_PAY'\n | 'D_BARAI'\n | 'AU_PAY'\n | 'MERPAY'\n\n/** Standard Browser SDK methods intentionally do not reuse Hosted methods. */\nexport type PortOneStandardPaymentMethod = 'CARD'\n\nexport type CreatePaymentSessionParams = {\n checkoutToken: string\n idempotencyKey: string\n provider: 'toss'\n providerOptions: { profile: 'widget_v2' }\n}\n\nexport type CreateServerPaymentSessionParams = CreatePaymentSessionParams & {\n customerToken?: string\n}\n\nexport type CreatePortOnePaymentSessionParams = {\n checkoutToken: string\n idempotencyKey: string\n provider: 'portone'\n providerOptions:\n | {\n profile: 'hosted_v2'\n paymentMethod: PortOneHostedPaymentMethod\n }\n | {\n profile: 'standard_v2'\n paymentMethod: PortOneStandardPaymentMethod\n }\n}\n\nexport type CreateServerPortOnePaymentSessionParams =\n CreatePortOnePaymentSessionParams & { customerToken?: string }\n\nexport type RetrieveBrowserPaymentSessionParams = {\n paymentSessionId: string\n checkoutToken: string\n}\n\nexport type RetrieveServerPaymentSessionParams = { paymentSessionId: string }\n\nexport type PortOnePaymentSelector = {\n provider: 'portone'\n providerAccountKey: string\n environment: 'test' | 'live'\n providerPaymentId: string\n}\n\nexport type FindPortOnePaymentParams = PortOnePaymentSelector\n\nexport type ReconcilePortOnePaymentParams = PortOnePaymentSelector & {\n idempotencyKey: string\n}\n\nexport type CancelBrowserPaymentSessionParams =\n RetrieveBrowserPaymentSessionParams & { idempotencyKey: string }\n\nexport type CancelServerPaymentSessionParams =\n RetrieveServerPaymentSessionParams & { idempotencyKey: string }\n\nexport type ConfirmTossPaymentSessionParams = {\n paymentSessionId: string\n idempotencyKey: string\n action: {\n type: 'toss_authorization'\n paymentKey: string\n providerOrderId: string\n }\n}\n\nexport type CreateCustomPaymentSessionParams = {\n provider: string\n checkoutToken: string\n idempotencyKey: string\n customerToken?: string\n}\n\nexport type CustomPaymentSession = {\n id: string\n provider: string\n providerSessionId: string\n money: Money\n}\n\nexport type RetrieveCustomPaymentSessionParams = {\n provider: string\n by: { providerSessionId: string } | { providerPaymentId: string }\n}\n\nexport type RetrievedCustomPaymentSession = {\n id: string\n provider: string\n providerSessionId: string\n providerPaymentId: string | null\n status: 'pending' | 'captured' | 'failed' | 'canceled'\n providerStatus: PaymentProviderStatus\n finalizationStatus: 'not_ready' | 'pending' | 'committed'\n money: Money\n orderId: string | null\n}\n\nexport type PortOnePaymentCurrentState = {\n paymentSession: {\n id: string\n provider: 'portone'\n providerStatus: PaymentProviderStatus\n finalizationStatus: 'not_ready' | 'pending' | 'committed'\n sessionRole: PaymentSessionRole\n reconciliation:\n | { status: 'none' }\n | {\n status: 'required'\n reasons: readonly PaymentReconciliationReason[]\n }\n }\n checkout: { id: string }\n order: { id: string; orderNumber: string } | null\n money: Money\n}\n\nexport type FindPortOnePaymentResult =\n | { found: false }\n | { found: true; current: PortOnePaymentCurrentState }\n\nexport type PortOneReconciliationDisposition =\n | 'applied'\n | 'observed'\n | 'recovered_after_ambiguous_result'\n | 'requires_attention'\n\nexport type ReconcilePortOnePaymentResult =\n | { found: false; disposition: 'requires_attention' }\n | {\n found: true\n disposition: PortOneReconciliationDisposition\n current: PortOnePaymentCurrentState\n }\n\nexport type ConfirmCustomPaymentSessionParams = {\n provider: string\n providerSessionId: string\n providerPaymentId: string\n providerEventId: string\n /** Captured amount in the currency's minor unit. */\n amount: number\n currency: string\n occurredAt: string\n}\n\nexport type ConfirmCustomPaymentSessionResponse = {\n orderId: string\n transactionId: string\n status: 'paid'\n /**\n * `true` when the session was already confirmed at observation time.\n *\n * This field is absent from the initial successful confirmation. It does not\n * prove that this call caused the transition and is not an exactly-once gate;\n * a lost initial response followed by a retry also returns `true`.\n */\n alreadyConfirmed?: boolean\n}\n\nexport type CustomPaymentSessionProof = {\n timestamp: string\n signature: string\n}\n\nexport type ConfirmCustomPaymentSessionOptions = {\n /** Receives the exact JSON bytes the SDK will send. Required only where the Console custom-provider policy requires HMAC. */\n createProof?: (\n rawBody: string,\n ) => CustomPaymentSessionProof | Promise<CustomPaymentSessionProof>\n}\n\nexport type TossPaymentNextAction = {\n type: 'toss_widget'\n clientKey: string\n paymentMethodVariantKey: string\n agreementVariantKey: string\n providerOrderId: string\n providerCustomerKey: 'ANONYMOUS' | string\n orderName: string\n customerName?: string\n customerEmail?: string\n}\n\nexport type PortOnePaymentNextAction = {\n type: 'portone_checkout'\n checkoutUrl: string\n}\n\nexport type PortOneSdkPaymentNextAction = {\n type: 'portone_sdk'\n version: 'v2'\n /** Standard V2 actions cannot release their Checkout payment slot. */\n cancelable: false\n /** Retry only this exact action and payment ID; never start a sibling session. */\n retryPolicy: 'same_action_only'\n storeId: string\n channelKey: string\n paymentId: string\n orderName: string\n totalAmount: number\n /** PortOne Browser SDK V2 currency constant, not an ISO 4217 code. */\n currency: 'CURRENCY_KRW'\n payMethod: PortOneStandardPaymentMethod\n redirectUrl: string\n}\n\n/**\n * Accept-only Stripe Payment Element action. Not exported from a package entry\n * until a Stripe PaymentSession method exists; the parser validates it so a\n * provider mismatch can report the actual provider.\n */\nexport type StripePaymentNextAction = {\n type: 'stripe_payment_element'\n /** PaymentIntent client secret for Stripe.js; never capture evidence. */\n clientSecret: string\n publishableKey: string\n returnUrl: string\n}\n\n/** Existing Toss action surface retained for source compatibility. */\nexport type PaymentNextAction = TossPaymentNextAction\n\nexport type ManagedPaymentNextAction =\n | TossPaymentNextAction\n | PortOnePaymentNextAction\n | PortOneSdkPaymentNextAction\n\nexport type PaymentSessionRole =\n | 'active'\n | 'canonical_candidate'\n | 'canonical'\n | 'residual'\n | 'historical'\n\nexport type PaymentProviderStatus =\n | 'requires_payment_method'\n | 'requires_action'\n | 'requires_confirmation'\n | 'initializing'\n | 'processing'\n | 'authorized'\n | 'canceling'\n | 'unknown'\n | 'captured'\n | 'failed'\n | 'canceled'\n\nexport type PaymentReconciliationReason =\n | 'provider_outcome_unknown'\n | 'local_commit_ambiguous'\n | 'amount_mismatch'\n | 'currency_mismatch'\n | 'excess_capture_pending_order'\n | 'inventory_unavailable'\n | 'admission_unavailable'\n | 'excess_capture'\n | 'late_capture'\n | 'cross_checkout_duplicate'\n\nexport type PaymentFailureReason =\n | 'payment_declined'\n | 'authentication_failed'\n | 'authorization_expired'\n | 'payment_method_unavailable'\n | 'provider_terminal_failure'\n | 'unknown_provider_terminal_failure'\n\nexport type PublicCaptureEvidence = {\n amountMinor: number\n currency: Uppercase<string>\n observedAt: string\n}\n\nexport type ReconciliationRequired<Reason extends string> = {\n status: 'required'\n reasons: readonly [Reason, ...Reason[]]\n}\n\ntype PublicPaymentSessionBase = {\n id: string\n money: Money\n expiresAt: string | null\n sessionRole: PaymentSessionRole\n}\n\ntype PublicPaymentSessionState<\n Action extends ManagedPaymentNextAction | StripePaymentNextAction,\n> =\n | ({\n providerStatus: 'requires_payment_method' | 'requires_action'\n finalizationStatus: 'not_ready'\n reconciliation: { status: 'none' }\n order: null\n } & (\n | {\n sessionRole: 'active'\n presentationStatus: 'actionable'\n nextAction: Action\n }\n | {\n sessionRole: 'residual'\n presentationStatus: 'suppressed'\n nextAction?: never\n }\n ))\n | {\n providerStatus: 'requires_confirmation'\n sessionRole: 'active' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n reconciliation: { status: 'none' }\n order: null\n }\n | {\n providerStatus: 'initializing' | 'processing' | 'authorized'\n sessionRole: 'active' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n reconciliation: { status: 'none' }\n order: null\n }\n | {\n providerStatus: 'canceling'\n sessionRole: 'active' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n reconciliation: { status: 'none' }\n order: null\n }\n | {\n providerStatus: 'unknown'\n sessionRole: 'active' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n reconciliation: ReconciliationRequired<'provider_outcome_unknown'>\n order: null\n }\n | {\n providerStatus: 'captured'\n sessionRole: 'canonical_candidate' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'pending'\n nextAction?: never\n reconciliation: { status: 'none' }\n providerEvidence: PublicCaptureEvidence\n order: null\n }\n | {\n providerStatus: 'captured'\n sessionRole: 'canonical' | 'historical'\n presentationStatus: 'suppressed'\n finalizationStatus: 'committed'\n nextAction?: never\n reconciliation: { status: 'none' }\n providerEvidence: PublicCaptureEvidence\n order: { id: string; orderNumber: string }\n }\n | {\n providerStatus: 'captured'\n sessionRole: 'canonical_candidate' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'pending'\n nextAction?: never\n reconciliation: ReconciliationRequired<\n | 'local_commit_ambiguous'\n | 'amount_mismatch'\n | 'currency_mismatch'\n | 'excess_capture_pending_order'\n >\n providerEvidence: PublicCaptureEvidence\n order: null\n }\n | {\n providerStatus: 'captured'\n sessionRole: 'canonical' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'committed'\n nextAction?: never\n reconciliation: ReconciliationRequired<\n | 'inventory_unavailable'\n | 'admission_unavailable'\n | 'amount_mismatch'\n | 'currency_mismatch'\n | 'excess_capture'\n | 'late_capture'\n | 'cross_checkout_duplicate'\n >\n providerEvidence: PublicCaptureEvidence\n order: { id: string; orderNumber: string }\n }\n | {\n providerStatus: 'failed'\n sessionRole: 'historical'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n providerEvidence?: never\n cancellationReason?: never\n reconciliation: { status: 'none' }\n failure: { reason: PaymentFailureReason; message?: string }\n order: null\n }\n | {\n providerStatus: 'canceled'\n sessionRole: 'historical'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n providerEvidence?: never\n failure?: never\n cancellationReason: 'expired' | 'customer' | 'operator' | 'provider'\n reconciliation: { status: 'none' }\n order: null\n }\n\nexport type PublicPaymentSession = PublicPaymentSessionBase & {\n provider: 'toss'\n} & PublicPaymentSessionState<TossPaymentNextAction>\n\nexport type PortOnePublicPaymentSession = PublicPaymentSessionBase & {\n provider: 'portone'\n} & PublicPaymentSessionState<\n PortOnePaymentNextAction | PortOneSdkPaymentNextAction\n >\n\n/** Accept-only Stripe session shape; see `StripePaymentNextAction`. */\nexport type StripePublicPaymentSession = PublicPaymentSessionBase & {\n provider: 'stripe'\n} & PublicPaymentSessionState<StripePaymentNextAction>\n\nexport type ManagedPublicPaymentSession =\n | PublicPaymentSession\n | PortOnePublicPaymentSession\n\nexport class PaymentSessionApi extends CustomerScopedApi {\n private readonly serverTransport: boolean\n\n constructor(options: PaymentSessionApiOptions) {\n super('PaymentSessionApi', { ...options, requiresCredential: false })\n this.serverTransport = Boolean(options.secretKey)\n }\n\n private post(\n endpoint: CommerceEndpointDescriptor,\n body: unknown,\n idempotencyKey?: string,\n negotiateStandardActionCapabilities = false,\n ): Promise<unknown> {\n const headers = {\n ...(idempotencyKey && { 'X-Idempotency-Key': idempotencyKey }),\n ...(negotiateStandardActionCapabilities && {\n Accept: PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE,\n }),\n }\n return this.requestEndpoint<unknown>(endpoint, body, {\n ...(Object.keys(headers).length > 0 && { headers }),\n })\n }\n\n private async paymentSession<T extends ManagedPublicPaymentSession>(\n result: Promise<unknown>,\n expectedProvider: T['provider'],\n operation?: 'cancel',\n ): Promise<T> {\n return validatePublicPaymentSession<T>(\n await result,\n expectedProvider,\n operation,\n )\n }\n\n create(\n params: CreatePaymentSessionParams | CreateServerPaymentSessionParams,\n ): Promise<PublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n return this.paymentSession<PublicPaymentSession>(\n this.post(\n this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.create\n : COMMERCE_ENDPOINTS.paymentSessions.create,\n body,\n idempotencyKey,\n ),\n 'toss',\n )\n }\n\n createPortOne(\n params:\n | CreatePortOnePaymentSessionParams\n | CreateServerPortOnePaymentSessionParams,\n ): Promise<PortOnePublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n return this.paymentSession<PortOnePublicPaymentSession>(\n this.post(\n this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.create\n : COMMERCE_ENDPOINTS.paymentSessions.create,\n body,\n idempotencyKey,\n body.providerOptions.profile === 'standard_v2',\n ),\n 'portone',\n )\n }\n\n retrieve(\n params:\n | RetrieveBrowserPaymentSessionParams\n | RetrieveServerPaymentSessionParams,\n ): Promise<PublicPaymentSession> {\n const endpoint = this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.retrieve\n : COMMERCE_ENDPOINTS.paymentSessions.retrieve\n return this.paymentSession<PublicPaymentSession>(\n this.post(endpoint, params),\n 'toss',\n )\n }\n\n retrievePortOne(\n params:\n | RetrieveBrowserPaymentSessionParams\n | RetrieveServerPaymentSessionParams,\n ): Promise<PortOnePublicPaymentSession> {\n const endpoint = this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.retrieve\n : COMMERCE_ENDPOINTS.paymentSessions.retrieve\n return this.paymentSession<PortOnePublicPaymentSession>(\n this.post(endpoint, params, undefined, true),\n 'portone',\n )\n }\n\n cancel(\n params:\n | CancelBrowserPaymentSessionParams\n | CancelServerPaymentSessionParams,\n ): Promise<PublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n const endpoint = this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.cancel\n : COMMERCE_ENDPOINTS.paymentSessions.cancel\n return this.paymentSession<PublicPaymentSession>(\n this.post(endpoint, body, idempotencyKey),\n 'toss',\n 'cancel',\n )\n }\n\n cancelPortOne(\n params:\n | CancelBrowserPaymentSessionParams\n | CancelServerPaymentSessionParams,\n ): Promise<PortOnePublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n const endpoint = this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.cancel\n : COMMERCE_ENDPOINTS.paymentSessions.cancel\n return this.paymentSession<PortOnePublicPaymentSession>(\n this.post(endpoint, body, idempotencyKey),\n 'portone',\n 'cancel',\n )\n }\n\n confirm(\n params: ConfirmTossPaymentSessionParams,\n ): Promise<PublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n return this.paymentSession<PublicPaymentSession>(\n this.post(\n COMMERCE_ENDPOINTS.paymentSessions.server.confirm,\n body,\n idempotencyKey,\n ),\n 'toss',\n )\n }\n}\n\n/** Server-only facade over the managed PortOne local/convergence engine. */\nexport class PortOnePaymentReconciliationApi extends BaseApi {\n constructor(options: ServerApiOptions) {\n super('PortOnePaymentReconciliationApi', options)\n }\n\n async find(\n params: FindPortOnePaymentParams,\n ): Promise<FindPortOnePaymentResult> {\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.server.findPortOne,\n params,\n )\n return validatePortOnePaymentFacadeResult<FindPortOnePaymentResult>(\n result,\n false,\n )\n }\n\n async reconcile(\n params: ReconcilePortOnePaymentParams,\n ): Promise<ReconcilePortOnePaymentResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.server.reconcilePortOne,\n body,\n { headers: { 'X-Idempotency-Key': idempotencyKey } },\n )\n return validatePortOnePaymentFacadeResult<ReconcilePortOnePaymentResult>(\n result,\n true,\n )\n }\n}\n\nexport class CustomPaymentSessionApi extends BaseApi {\n constructor(options: ServerApiOptions) {\n super('CustomPaymentSessionApi', options)\n }\n\n async create(\n params: CreateCustomPaymentSessionParams,\n ): Promise<CustomPaymentSession> {\n assertCommerceIdempotencyKey(params.idempotencyKey)\n const body = {\n provider: params.provider,\n checkoutToken: params.checkoutToken,\n }\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.custom.create,\n body,\n { headers: { 'X-Idempotency-Key': params.idempotencyKey } },\n )\n return validateCustomPaymentSession<CustomPaymentSession>(result)\n }\n\n async retrieve(\n params: RetrieveCustomPaymentSessionParams,\n ): Promise<RetrievedCustomPaymentSession> {\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.custom.retrieve,\n params,\n )\n return validateRetrievedCustomPaymentSession<RetrievedCustomPaymentSession>(\n result,\n )\n }\n\n async confirm(\n params: ConfirmCustomPaymentSessionParams,\n options: ConfirmCustomPaymentSessionOptions = {},\n ): Promise<ConfirmCustomPaymentSessionResponse> {\n const body = {\n provider: params.provider,\n providerSessionId: params.providerSessionId,\n providerPaymentId: params.providerPaymentId,\n providerEventId: params.providerEventId,\n amount: params.amount,\n currency: params.currency,\n occurredAt: params.occurredAt,\n }\n const proof = await options.createProof?.(JSON.stringify(body))\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.custom.confirm,\n body,\n proof\n ? {\n headers: {\n 'X-Custom-Payment-Timestamp': proof.timestamp,\n 'X-Custom-Payment-Signature': proof.signature,\n },\n }\n : undefined,\n )\n return validateConfirmCustomPaymentSessionResponse<ConfirmCustomPaymentSessionResponse>(\n result,\n )\n }\n}\n","export type NormalizedOptionSwatch<TMedia = unknown> = {\n type: 'color' | 'media' | null\n color?: string | null\n mediaItemId?: string | number | null\n /** Inlined swatch media when the API populated mediaItemId before pool indexing. */\n inlineMedia?: TMedia | null\n}\n\nexport function selectedSwatchMediaItemId(\n swatch: NormalizedOptionSwatch | null | undefined,\n): string | null {\n if (!swatch || swatch.type !== 'media') return null\n const id = swatch.mediaItemId\n if (id == null || id === '') return null\n return String(id)\n}\n\nexport type ProductSelectionMediaSource =\n | 'variant_media_selected'\n | 'variant_media_matching'\n | 'option_swatch'\n | 'none'\n\nexport type ProductDisplayMediaSource =\n | 'featured_image'\n | 'product_pool'\n | 'none'\n\n/** @deprecated Use {@link ProductSelectionMediaSource} or {@link ProductDisplayMediaSource}. */\nexport type ProductMediaResolutionSource =\n | ProductSelectionMediaSource\n | ProductDisplayMediaSource\n\nexport type ProductSelectionVariant<TMedia> = {\n id?: string | number | null\n images?: Array<TMedia | string | number | null | undefined> | null\n}\n\nexport type ProductSelectionOptionValue = {\n id?: string | number | null\n swatch?: NormalizedOptionSwatch<unknown> | null\n}\n\nexport type ProductSelectionMediaPointer =\n | string\n | number\n | { id?: string | number | null }\n | null\n\nexport type ResolveProductSelectionMediaInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n selectedVariant?: ProductSelectionVariant<TMedia> | null\n matchingVariants?: Array<\n ProductSelectionVariant<TMedia> | null | undefined\n > | null\n selectedOptionValues?: Array<\n ProductSelectionOptionValue | null | undefined\n > | null\n}\n\nexport type ResolveProductSelectionMediaResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductSelectionMediaSource\n}\n\nexport type ResolveProductDisplayMediaInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n featuredImage?: ProductSelectionMediaPointer\n}\n\nexport type ResolveProductDisplayMediaResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductDisplayMediaSource\n}\n\ntype MediaWithOptionalId = {\n id?: string | number | null\n}\n\nfunction getMediaId(value: unknown): string | null {\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value)\n }\n\n if (typeof value === 'object' && value !== null && 'id' in value) {\n const id = (value as MediaWithOptionalId).id\n if (typeof id === 'string' || typeof id === 'number') return String(id)\n }\n\n return null\n}\n\nfunction toPointerId(\n value: ProductSelectionMediaPointer | undefined,\n): string | null {\n return getMediaId(value)\n}\n\nfunction mediaArray<TMedia>(value: TMedia[] | null | undefined): TMedia[] {\n if (!Array.isArray(value)) return []\n return value.filter((entry): entry is TMedia => entry != null)\n}\n\nfunction uniqueWithPrimaryFirst<TMedia>(\n primary: TMedia | null,\n items: TMedia[],\n): TMedia[] {\n const unique = new Map<string, TMedia>()\n\n for (const item of items) {\n const id = getMediaId(item)\n const key = id ?? `inline:${unique.size}`\n if (!unique.has(key)) unique.set(key, item)\n }\n\n if (primary) {\n const primaryId = getMediaId(primary)\n const prefixed = new Map<string, TMedia>()\n const primaryKey = primaryId ?? 'inline:primary'\n prefixed.set(primaryKey, primary)\n\n for (const [key, value] of unique.entries()) {\n if (!prefixed.has(key)) prefixed.set(key, value)\n }\n\n return Array.from(prefixed.values())\n }\n\n return Array.from(unique.values())\n}\n\nfunction buildPoolById<TMedia>(pool: TMedia[]): Map<string, TMedia> {\n const poolById = new Map<string, TMedia>()\n\n for (const item of pool) {\n const id = getMediaId(item)\n if (id) poolById.set(id, item)\n }\n\n return poolById\n}\n\nfunction resolveVariantImageItems<TMedia>(\n variant: ProductSelectionVariant<TMedia> | null | undefined,\n poolById: Map<string, TMedia>,\n): TMedia[] {\n if (!variant || !Array.isArray(variant.images)) return []\n\n const resolved: TMedia[] = []\n\n for (const entry of variant.images) {\n if (entry == null) continue\n\n if (typeof entry === 'string' || typeof entry === 'number') {\n const pooled = poolById.get(String(entry))\n if (pooled) resolved.push(pooled)\n continue\n }\n\n const mediaId = getMediaId(entry)\n if (mediaId) {\n const pooled = poolById.get(mediaId)\n if (pooled) {\n resolved.push(pooled)\n }\n continue\n }\n }\n\n return resolved\n}\n\nfunction resolveOptionSwatchPrimary<TMedia>(\n selectedOptionValues:\n | Array<ProductSelectionOptionValue | null | undefined>\n | null\n | undefined,\n poolById: Map<string, TMedia>,\n): TMedia | null {\n if (!selectedOptionValues?.length) return null\n\n for (const optionValue of selectedOptionValues) {\n const swatch = optionValue?.swatch\n const swatchPointer = selectedSwatchMediaItemId(swatch)\n if (swatchPointer) {\n const pooled = poolById.get(swatchPointer)\n if (pooled) return pooled\n }\n\n const inline = swatch?.inlineMedia\n if (inline != null && typeof inline === 'object') {\n return inline as TMedia\n }\n }\n\n return null\n}\n\nexport function resolveProductSelectionMedia<TMedia>(\n input: ResolveProductSelectionMediaInput<TMedia>,\n): ResolveProductSelectionMediaResult<TMedia> {\n const pool = mediaArray(input.productMediaPool)\n const poolById = buildPoolById(pool)\n\n const selectedVariantImages = resolveVariantImageItems(\n input.selectedVariant,\n poolById,\n )\n\n if (selectedVariantImages.length > 0) {\n const primaryImage = selectedVariantImages[0] ?? null\n\n return {\n primaryImage,\n images: uniqueWithPrimaryFirst(primaryImage, selectedVariantImages),\n source: 'variant_media_selected',\n }\n }\n\n if (\n input.selectedVariant == null &&\n (input.matchingVariants?.length ?? 0) > 0\n ) {\n const mergedMatchingImages: TMedia[] = []\n\n for (const matchingVariant of input.matchingVariants ?? []) {\n mergedMatchingImages.push(\n ...resolveVariantImageItems(matchingVariant, poolById),\n )\n }\n\n if (mergedMatchingImages.length > 0) {\n const primaryImage = mergedMatchingImages[0] ?? null\n\n return {\n primaryImage,\n images: uniqueWithPrimaryFirst(primaryImage, mergedMatchingImages),\n source: 'variant_media_matching',\n }\n }\n }\n\n const optionSwatchPrimary = resolveOptionSwatchPrimary(\n input.selectedOptionValues,\n poolById,\n )\n\n if (optionSwatchPrimary) {\n return {\n primaryImage: optionSwatchPrimary,\n images: [optionSwatchPrimary],\n source: 'option_swatch',\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\nexport function resolveProductDisplayMedia<TMedia>(\n input: ResolveProductDisplayMediaInput<TMedia>,\n): ResolveProductDisplayMediaResult<TMedia> {\n const pool = mediaArray(input.productMediaPool)\n const poolById = buildPoolById(pool)\n\n const featuredImagePointer = toPointerId(input.featuredImage)\n if (featuredImagePointer) {\n const featuredImage = poolById.get(featuredImagePointer)\n if (featuredImage) {\n return {\n primaryImage: featuredImage,\n images: uniqueWithPrimaryFirst(featuredImage, pool),\n source: 'featured_image',\n }\n }\n }\n\n if (pool.length > 0) {\n const productPoolPrimary = pool[0] ?? null\n\n if (productPoolPrimary) {\n return {\n primaryImage: productPoolPrimary,\n images: uniqueWithPrimaryFirst(productPoolPrimary, pool),\n source: 'product_pool',\n }\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\nexport type FeaturedImagePointerInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n featuredImage?: TMedia | string | number | null\n resolvedPrimary?: TMedia | null\n resolvedSource?: ProductMediaResolutionSource\n}\n\nexport function resolveFeaturedImagePointer<TMedia>(\n input: FeaturedImagePointerInput<TMedia>,\n): string | null {\n const pool = mediaArray(input.productMediaPool)\n const resolvedPointer = getMediaId(input.resolvedPrimary)\n if (\n resolvedPointer &&\n input.resolvedSource !== 'product_pool' &&\n input.resolvedSource !== 'none'\n ) {\n return resolvedPointer\n }\n\n const poolById = buildPoolById(pool)\n const featuredImagePointer = getMediaId(input.featuredImage)\n if (featuredImagePointer && poolById.has(featuredImagePointer)) {\n return featuredImagePointer\n }\n\n if (pool.length > 0) {\n const firstPoolId = getMediaId(pool[0])\n if (firstPoolId) return firstPoolId\n }\n\n return null\n}\n","import type {\n ProductDetail,\n ProductDetailCatalog,\n ProductDetailMedia,\n ProductDetailOptionValue,\n ProductDetailVariant,\n ProductListingGroupsCatalogItem,\n ProductListingGroupsItem,\n ProductOptionValueSwatch,\n ProductLocalizedText,\n} from '../core/api/product-api'\nimport type { ApiQueryOptions } from '../core/client/types'\nimport {\n resolveProductDisplayMedia,\n resolveProductSelectionMedia,\n resolveFeaturedImagePointer,\n type NormalizedOptionSwatch,\n type ProductMediaResolutionSource,\n type ProductSelectionMediaSource,\n} from './product-selection-media'\n\ntype ProductSelectionDetail = ProductDetail | ProductDetailCatalog\ntype ProductSelectionVariant =\n | ProductDetailVariant\n | ProductDetailCatalog['variants'][number]\ntype ProductSelectionVariantForDetail<TDetail extends ProductSelectionDetail> =\n TDetail extends ProductDetail\n ? ProductDetailVariant\n : ProductDetailCatalog['variants'][number]\n\nfunction normalizeMatrixSwatch(\n swatch: ProductDetailOptionValue['swatch'],\n): NormalizedOptionSwatch<ProductDetailMedia> | null {\n if (!swatch) return null\n const rawMedia = swatch.mediaItemId as MediaValue\n const inlineMedia =\n rawMedia != null &&\n typeof rawMedia === 'object' &&\n 'url' in rawMedia &&\n typeof (rawMedia as { url?: unknown }).url === 'string'\n ? (rawMedia as ProductDetailMedia)\n : null\n return {\n type: swatch.type ?? null,\n color: swatch.color ?? null,\n mediaItemId: extractEntityId(rawMedia),\n inlineMedia,\n }\n}\n\ntype EntityID = string\n\ntype RelationshipValue =\n | string\n | number\n | null\n | undefined\n | { id?: string | number | null }\n\nexport type MediaValue = ProductDetailMedia | null | undefined\n\nexport type { ProductOptionValueSwatch }\n\n/** Raw Payload / REST swatch before strict public normalization. */\nexport type ProductOptionValueSwatchInput = {\n type?: 'color' | 'media' | null\n color?: string | null\n mediaItemId?: RelationshipValue\n}\n\nexport interface ProductOptionValueShape {\n id?: string | number | null\n option?: RelationshipValue\n value?: string | null\n slug?: string | null\n swatch?: ProductOptionValueSwatch | ProductOptionValueSwatchInput | null\n _order?: string | null\n '_product-option-values_values_order'?: string | null\n}\n\nexport interface ProductOptionShape {\n id?: string | number | null\n title?: string | null\n slug?: string | null\n _order?: string | null\n '_product-options_options_order'?: string | null\n values?: {\n docs?: unknown[]\n } | null\n}\n\nexport interface ProductVariantShape {\n id?: string | number | null\n optionValues?: unknown[] | null\n price?: number | null\n compareAtPrice?: number | null\n resolvedPrice?: {\n amount: number\n compareAtPrice?: number | null\n currency?: string | null\n marketId?: string | null\n source?: 'fixed' | 'computed'\n }\n stock?: number | null\n reservedStock?: number | null\n isUnlimited?: boolean | null\n inventoryPolicy?: ('deny' | 'continue') | null\n isActive?: boolean | null\n availableForSale?: boolean | null\n thumbnail?: MediaValue\n images?: MediaValue[] | null\n _order?: string | null\n}\n\nexport interface ProductListingProductShape {\n id?: EntityID\n title?: ProductLocalizedText\n images?: MediaValue[] | null\n featuredImage?: MediaValue\n priceRange?: {\n minVariantPrice?: { amount?: number | null } | null\n maxVariantPrice?: { amount?: number | null } | null\n isPriceRange?: boolean | null\n } | null\n compareAtPriceRange?: {\n minVariantPrice?: { amount?: number | null } | null\n maxVariantPrice?: { amount?: number | null } | null\n } | null\n availableForSale?: boolean | null\n selectedOrFirstAvailableVariant?: RelationshipValue | ProductVariantShape\n}\n\nexport type ProductOptionMatrixValue = {\n id: string\n optionId: string\n optionSlug: string\n label: string\n slug: string | null\n swatch: ProductOptionValueSwatch\n order: string\n}\n\nexport type ProductOptionMatrixOption = {\n id: string\n title: string\n slug: string\n order: string\n values: ProductOptionMatrixValue[]\n}\n\nexport type ProductOptionMatrixVariant<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n id: string\n optionValueIds: string[]\n optionValueByOptionId: Map<string, string>\n optionValueByOptionSlug: Map<string, string>\n source: TVariant\n}\n\nexport type ProductOptionMatrix<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n options: ProductOptionMatrixOption[]\n optionIds: string[]\n optionSlugs: string[]\n optionById: Map<string, ProductOptionMatrixOption>\n optionBySlug: Map<string, ProductOptionMatrixOption>\n valueById: Map<string, ProductOptionMatrixValue>\n valueToOptionId: Map<string, string>\n valueToOptionSlug: Map<string, string>\n variants: ProductOptionMatrixVariant<TVariant>[]\n}\n\nexport type ProductListingGroupProjection = {\n selectionHintVariant: EntityID | null\n primaryImage: EntityID | null\n minPrice: number | null\n maxPrice: number | null\n minCompareAtPrice: number | null\n maxCompareAtPrice: number | null\n isPriceRange: boolean\n availableForSale: boolean\n}\n\nexport type ProductListingGroup<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n optionId: EntityID\n optionTitle: string\n optionSlug: string\n optionValueId: EntityID\n optionValueLabel: string\n optionValueSlug: string | null\n optionValueSwatch: ProductOptionValueSwatch\n variantIds: EntityID[]\n variantCount: number\n variants: TVariant[]\n listing: ProductListingGroupProjection\n}\n\nexport type ProductListingCardPriceRange = {\n minPrice: number | null\n maxPrice: number | null\n minCompareAtPrice: number | null\n maxCompareAtPrice: number | null\n isPriceRange: boolean\n}\n\nexport type ProductListingSwatch = {\n optionId: EntityID\n optionValueId: EntityID\n label: string\n swatch: ProductOptionValueSwatch<ProductDetailMedia>\n href: string\n availableForSale: boolean\n}\n\ntype ProductListingCardSourceItem =\n | ProductListingGroupsCatalogItem\n | ProductListingGroupsItem\n\nexport type ProductListingCardRepresentativeVariant =\n ProductListingCardSourceItem['groups'][number]['variants'][number]\n\nexport type ProductListingCard = {\n id: EntityID\n href: string\n title: ProductLocalizedText\n representativeVariant?: ProductListingCardRepresentativeVariant | null\n primaryImage: ProductDetailMedia | null\n priceRange: ProductListingCardPriceRange\n availableForSale: boolean\n swatches: ProductListingSwatch[]\n}\n\nexport type ProductSelectionByOptionValue =\n | string\n | number\n | null\n | undefined\n | {\n valueId?: string | number | null\n valueSlug?: string | null\n }\n\nexport type ProductSelectionInput = {\n variantId?: string | number | null\n byOptionSlug?: Record<string, ProductSelectionByOptionValue>\n byOptionId?: Record<string, ProductSelectionByOptionValue>\n valueIds?: Iterable<unknown>\n search?: string | URLSearchParams | URL | null\n}\n\nexport type NormalizedProductSelection = {\n byOptionSlug: Record<string, string>\n byOptionId: Record<string, string>\n valueIds: string[]\n variantId: string | null\n}\n\nexport type CompatibilityProductSelectionParamEvent = {\n optionId: string\n optionSlug: string\n valueSlug: string\n searchParam: string\n}\n\nexport type LegacyProductSelectionParamEvent =\n CompatibilityProductSelectionParamEvent\n\nexport type ProductSelectionUrlEmit = 'slug-compat' | 'canonical-id'\n\nconst DEFAULT_PRODUCT_SELECTION_URL_EMIT: ProductSelectionUrlEmit =\n 'slug-compat'\n\nfunction resolveProductSelectionUrlEmit(\n emit?: ProductSelectionUrlEmit,\n): ProductSelectionUrlEmit {\n return emit ?? DEFAULT_PRODUCT_SELECTION_URL_EMIT\n}\n\nfunction appendSlugCompatSelectionParam(\n params: URLSearchParams,\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n optionId: string,\n valueId: string,\n): boolean {\n const option = matrix.optionById.get(optionId)\n const value = matrix.valueById.get(valueId)\n if (!option?.slug || !value?.slug) return false\n\n const slugMatches = option.values.filter(\n (candidate) => candidate.slug === value.slug,\n )\n if (slugMatches.length !== 1) return false\n\n params.append(`opt.${option.slug}`, value.slug)\n return true\n}\n\nfunction appendCanonicalSelectionParam(\n params: URLSearchParams,\n optionId: string,\n valueId: string,\n): void {\n params.append(`opt.${optionId}`, valueId)\n}\n\nexport type ProductSelectionCodecOptions = {\n emit?: ProductSelectionUrlEmit\n /**\n * When true, `resolveProductSelection()` fills unselected options to reach a\n * concrete variant. Does not change codec parse/stringify behavior.\n */\n fillDefaults?: boolean\n onCompatibilityOptionIdParam?: (\n event: CompatibilityProductSelectionParamEvent,\n ) => void\n onLegacyOptionIdParam?: (event: LegacyProductSelectionParamEvent) => void\n}\n\nexport type ProductSelectionResolutionContext = {\n detail?: Pick<\n ProductSelectionDetail,\n 'featuredImage' | 'images' | 'selectedOrFirstAvailableVariant'\n >\n featuredImage?: ProductSelectionDetail['featuredImage']\n images?: ProductSelectionDetail['images']\n selectedOrFirstAvailableVariant?: ProductSelectionDetail['selectedOrFirstAvailableVariant']\n}\n\nexport type ProductSelectionAvailableSwatch = {\n color?: string | null\n image?: MediaValue | null\n}\n\nexport type ProductSelectionAvailableValue = {\n valueId: string\n value: string\n label: string\n slug: string\n selected: boolean\n available: boolean\n exists: boolean\n availableForSale: boolean\n isUnlimited: boolean\n availableStock: number | null\n swatch: ProductOptionValueSwatch\n}\n\nexport type ProductSelectionResolution<\n TVariant extends ProductVariantShape = ProductSelectionVariant,\n> = {\n normalizedSelection: NormalizedProductSelection\n selectedVariant: TVariant | null\n matchingVariants: TVariant[]\n partialVariants: TVariant[]\n availableValuesByOptionSlug: Record<string, ProductSelectionAvailableValue[]>\n availableValuesByOptionId: Record<string, ProductSelectionAvailableValue[]>\n allOptionsSelected: boolean\n price: {\n min: number | null\n max: number | null\n compareAtMin: number | null\n compareAtMax: number | null\n isRange: boolean\n }\n media: {\n primaryImage: ProductDetailMedia | null\n images: ProductDetailMedia[]\n source?: ProductMediaResolutionSource\n }\n stock: {\n availableForSale: boolean\n isUnlimited: boolean\n stock: number | null\n reservedStock: number | null\n availableStock: number | null\n }\n}\n\nexport class ProductSelectionCodecError extends Error {\n code = 'ambiguous_product_selection_query'\n\n constructor(message: string) {\n super(message)\n this.name = 'ProductSelectionCodecError'\n }\n}\n\nfunction getRelationID(value: RelationshipValue): string | undefined {\n if (typeof value === 'string') return value\n if (typeof value === 'number') return String(value)\n if (value && typeof value === 'object' && 'id' in value) {\n const id = value.id\n if (typeof id === 'string') return id\n if (typeof id === 'number') return String(id)\n }\n return undefined\n}\n\n// Payload orderable `_order` values are fractional-indexing keys whose order is\n// defined by code-unit comparison (`0-9` < `A-Z` < `a-z`). A locale-aware\n// comparison would reorder them by the runtime locale (Danish sorts `aa` as\n// `å`, and every locale folds `Zz` after `a0`), so compare ordinally instead.\nfunction compareOrdinal(left: string, right: string): number {\n if (left < right) return -1\n if (left > right) return 1\n return 0\n}\n\nfunction compareOrder(\n left: string | null | undefined,\n right: string | null | undefined,\n): number {\n return compareOrdinal(left ?? '', right ?? '')\n}\n\nfunction isProductOptionValueDoc(\n value: unknown,\n): value is ProductOptionValueShape {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n ('value' in value || 'slug' in value)\n )\n}\n\nfunction extractEntityId(value: MediaValue): EntityID | null {\n if (typeof value === 'string') return value\n if (typeof value === 'number') return String(value)\n if (value && typeof value === 'object' && 'id' in value) {\n if (typeof value.id === 'string') return value.id\n if (typeof value.id === 'number') return String(value.id)\n }\n return null\n}\n\nfunction getFirstMediaId(\n values: MediaValue[] | null | undefined,\n): EntityID | null {\n if (!Array.isArray(values)) return null\n\n for (const value of values) {\n const id = extractEntityId(value)\n if (id != null) return id\n }\n\n return null\n}\n\nfunction inProductMediaPool(\n product: ProductListingProductShape | null | undefined,\n mediaId: EntityID | null,\n): EntityID | null {\n if (mediaId == null) return null\n const images = Array.isArray(product?.images) ? product.images : []\n for (const image of images) {\n if (extractEntityId(image) === mediaId) return mediaId\n }\n return null\n}\n\nfunction getVariantPrimaryImage(\n variant: ProductVariantShape | null | undefined,\n): EntityID | null {\n if (!variant) return null\n return extractEntityId(variant.thumbnail) ?? getFirstMediaId(variant.images)\n}\n\nfunction resolveGenericListingPrimaryImage(\n product: ProductListingProductShape | null | undefined,\n resolvedPrimary: MediaValue | null,\n resolvedSource?: ProductSelectionMediaSource,\n): EntityID | null {\n return resolveFeaturedImagePointer({\n productMediaPool: product?.images ?? [],\n featuredImage: product?.featuredImage ?? null,\n resolvedPrimary,\n resolvedSource,\n })\n}\n\nfunction getFirstAvailableVariantPrimaryImage(\n variants: ProductVariantShape[],\n): EntityID | null {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n\n for (const variant of orderedVariants) {\n if (!isVariantAvailableForSale(variant)) continue\n const image = getVariantPrimaryImage(variant)\n if (image != null) return image\n }\n\n return null\n}\n\nfunction normalizeProductOptionValueSwatch(\n swatch:\n | ProductOptionValueSwatch\n | ProductOptionValueSwatchInput\n | null\n | undefined,\n): ProductOptionValueSwatch {\n if (swatch == null) return null\n if (typeof swatch !== 'object') return null\n\n const raw = swatch as ProductOptionValueSwatchInput\n const mediaItemId = extractEntityId(raw.mediaItemId as MediaValue)\n const color = typeof raw.color === 'string' ? raw.color.trim() : ''\n const hasColor = color.length > 0\n\n if (raw.type === 'media' || (mediaItemId && raw.type !== 'color')) {\n if (!mediaItemId || hasColor) return null\n return {\n type: 'media',\n mediaItemId: mediaItemId as ProductDetailMedia,\n color: null,\n }\n }\n\n if (raw.type === 'color' || hasColor) {\n if (mediaItemId || !hasColor) return null\n return { type: 'color', color, mediaItemId: null }\n }\n\n return null\n}\n\nfunction normalizeOptionValue(\n value: ProductOptionValueShape,\n fallbackOptionId: string,\n fallbackOptionSlug: string,\n): ProductOptionMatrixValue {\n return {\n id: String(value.id),\n optionId: getRelationID(value.option) ?? fallbackOptionId,\n optionSlug: fallbackOptionSlug,\n label: value.value || value.slug || String(value.id),\n slug: value.slug ?? null,\n swatch: normalizeProductOptionValueSwatch(value.swatch),\n order: value._order ?? value['_product-option-values_values_order'] ?? '',\n }\n}\n\nfunction normalizeVariantOptionValues<TVariant extends ProductVariantShape>(\n variant: TVariant,\n optionById: Map<string, ProductOptionMatrixOption>,\n valueToOptionId: Map<string, string>,\n optionIds: string[],\n): ProductOptionMatrixVariant<TVariant> {\n const optionValueByOptionId = new Map<string, string>()\n const optionValueByOptionSlug = new Map<string, string>()\n\n for (const rawValue of Array.isArray(variant.optionValues)\n ? variant.optionValues\n : []) {\n const valueId = getRelationID(rawValue as RelationshipValue)\n if (!valueId) continue\n\n const optionId =\n valueToOptionId.get(valueId) ??\n (isProductOptionValueDoc(rawValue)\n ? getRelationID(rawValue.option)\n : undefined)\n if (!optionId || optionValueByOptionId.has(optionId)) continue\n\n optionValueByOptionId.set(optionId, valueId)\n const optionSlug = optionById.get(optionId)?.slug\n if (optionSlug && !optionValueByOptionSlug.has(optionSlug)) {\n optionValueByOptionSlug.set(optionSlug, valueId)\n }\n }\n\n const optionValueIds = optionIds\n .map((optionId) => optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n\n return {\n id: String(variant.id),\n optionValueIds,\n optionValueByOptionId,\n optionValueByOptionSlug,\n source: variant,\n }\n}\n\nexport function buildProductOptionMatrix<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>({\n options,\n variants = [],\n}: {\n options: ProductOptionShape[]\n variants?: TVariant[]\n}): ProductOptionMatrix<TVariant> {\n const normalizedOptions = options\n .map((option) => {\n const valuesById = new Map<string, ProductOptionMatrixValue>()\n const optionSlug = option.slug ?? String(option.id)\n\n for (const rawValue of option.values?.docs ?? []) {\n if (!isProductOptionValueDoc(rawValue)) continue\n\n const normalizedValue = normalizeOptionValue(\n rawValue,\n String(option.id),\n optionSlug,\n )\n valuesById.set(normalizedValue.id, normalizedValue)\n }\n\n return {\n id: String(option.id),\n title: option.title ?? String(option.id),\n slug: optionSlug,\n order: option._order ?? option['_product-options_options_order'] ?? '',\n values: Array.from(valuesById.values()).sort((left, right) =>\n compareOrder(left.order, right.order),\n ),\n }\n })\n .sort((left, right) => compareOrder(left.order, right.order))\n\n const optionById = new Map(\n normalizedOptions.map((option) => [option.id, option]),\n )\n const optionBySlug = new Map(\n normalizedOptions.map((option) => [option.slug, option]),\n )\n const valueById = new Map<string, ProductOptionMatrixValue>()\n const valueToOptionId = new Map<string, string>()\n const valueToOptionSlug = new Map<string, string>()\n\n for (const option of normalizedOptions) {\n for (const value of option.values) {\n valueById.set(value.id, value)\n valueToOptionId.set(value.id, option.id)\n valueToOptionSlug.set(value.id, option.slug)\n }\n }\n\n const optionIds = normalizedOptions.map((option) => option.id)\n const optionSlugs = normalizedOptions.map((option) => option.slug)\n const normalizedVariants = variants.map((variant) =>\n normalizeVariantOptionValues(\n variant,\n optionById,\n valueToOptionId,\n optionIds,\n ),\n )\n\n return {\n options: normalizedOptions,\n optionIds,\n optionSlugs,\n optionById,\n optionBySlug,\n valueById,\n valueToOptionId,\n valueToOptionSlug,\n variants: normalizedVariants,\n }\n}\n\nfunction matrixOrder(index: number): string {\n return String(index).padStart(6, '0')\n}\n\nexport function buildProductOptionMatrixFromDetail<\n TDetail extends ProductSelectionDetail,\n>(\n detail: TDetail,\n): ProductOptionMatrix<ProductSelectionVariantForDetail<TDetail>> {\n const normalizedOptions = detail.options.map((option, optionIndex) => ({\n id: String(option.id),\n title: option.title || String(option.id),\n slug: option.slug,\n order: matrixOrder(optionIndex),\n values: option.values.map((value, valueIndex) => ({\n id: String(value.id),\n optionId: String(option.id),\n optionSlug: option.slug,\n label: value.value || value.slug || String(value.id),\n slug: value.slug,\n swatch: normalizeProductOptionValueSwatch(value.swatch),\n order: matrixOrder(valueIndex),\n })),\n }))\n\n const optionById = new Map(\n normalizedOptions.map((option) => [option.id, option]),\n )\n const optionBySlug = new Map(\n normalizedOptions.map((option) => [option.slug, option]),\n )\n const valueById = new Map<string, ProductOptionMatrixValue>()\n const valueToOptionId = new Map<string, string>()\n const valueToOptionSlug = new Map<string, string>()\n\n for (const option of normalizedOptions) {\n for (const value of option.values) {\n valueById.set(value.id, value)\n valueToOptionId.set(value.id, option.id)\n valueToOptionSlug.set(value.id, option.slug)\n }\n }\n\n const optionIds = normalizedOptions.map((option) => option.id)\n const optionSlugs = normalizedOptions.map((option) => option.slug)\n const normalizedVariants = detail.variants.map((variant) => {\n const optionValueByOptionId = new Map<string, string>()\n const optionValueByOptionSlug = new Map<string, string>()\n\n for (const rawValue of variant.optionValues) {\n const optionId = String(rawValue.optionId)\n const valueId = String(rawValue.valueId)\n const optionSlug = rawValue.optionSlug\n if (!optionById.has(optionId)) continue\n if (valueToOptionId.get(valueId) !== optionId) continue\n if (optionValueByOptionId.has(optionId)) continue\n optionValueByOptionId.set(optionId, valueId)\n if (optionSlug && !optionValueByOptionSlug.has(optionSlug)) {\n optionValueByOptionSlug.set(optionSlug, valueId)\n }\n }\n\n const optionValueIds = optionIds\n .map((optionId) => optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n\n return {\n id: String(variant.id),\n optionValueIds,\n optionValueByOptionId,\n optionValueByOptionSlug,\n source: variant,\n }\n }) as ProductOptionMatrixVariant<ProductSelectionVariantForDetail<TDetail>>[]\n\n return {\n options: normalizedOptions,\n optionIds,\n optionSlugs,\n optionById,\n optionBySlug,\n valueById,\n valueToOptionId,\n valueToOptionSlug,\n variants: normalizedVariants,\n }\n}\n\nexport function getSelectedValueByOptionId<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): Map<string, string> {\n const selectedByOption = new Map<string, string>()\n\n for (const rawValue of selectedValueIds) {\n const valueId = getRelationID(rawValue as RelationshipValue)\n if (!valueId) continue\n\n const optionId = matrix.valueToOptionId.get(valueId)\n if (!optionId || selectedByOption.has(optionId)) continue\n\n selectedByOption.set(optionId, valueId)\n }\n\n return selectedByOption\n}\n\nexport function normalizeSelectedValueIds<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): string[] {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n\n return matrix.optionIds\n .map((optionId) => selectedByOption.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n}\n\nexport function getAvailableOptionValues<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n optionId: string,\n selectedValueIds: Iterable<unknown>,\n): ProductOptionMatrixValue[] {\n const option = matrix.optionById.get(optionId)\n if (!option) return []\n\n if (matrix.variants.length === 0) {\n return option.values\n }\n\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n selectedByOption.delete(optionId)\n\n const matchingVariants = matrix.variants.filter((variant) =>\n Array.from(selectedByOption.entries()).every(\n ([selectedOptionId, selectedValueId]) =>\n variant.optionValueByOptionId.get(selectedOptionId) === selectedValueId,\n ),\n )\n\n const availableValueIds = new Set(\n matchingVariants\n .filter((variant) => variant.source.isActive !== false)\n .map((variant) => variant.optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId)),\n )\n\n return option.values.filter((value) => availableValueIds.has(value.id))\n}\n\nexport function resolveVariantForSelection<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): ProductOptionMatrixVariant<TVariant> | undefined {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n if (selectedByOption.size !== matrix.optionIds.length) {\n return undefined\n }\n\n return matrix.variants.find((variant) =>\n matrix.optionIds.every(\n (optionId) =>\n variant.optionValueByOptionId.get(optionId) ===\n selectedByOption.get(optionId),\n ),\n )\n}\n\nfunction getVariantSelection(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n variantId: string | number | null | undefined,\n): ProductOptionMatrixVariant<ProductSelectionVariant> | undefined {\n if (variantId == null) return undefined\n const id = String(variantId)\n return matrix.variants.find((variant) => variant.id === id)\n}\n\nfunction hasExplicitSelection(selection: ProductSelectionInput): boolean {\n return Boolean(\n selection.variantId != null ||\n selection.search ||\n selection.valueIds ||\n Object.keys(selection.byOptionId ?? {}).length > 0 ||\n Object.keys(selection.byOptionSlug ?? {}).length > 0,\n )\n}\n\nfunction assignSelectedValue(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n optionId: string,\n valueId: string | number | null | undefined,\n): boolean {\n if (valueId == null) return false\n const normalizedValueId = String(valueId)\n if (matrix.valueToOptionId.get(normalizedValueId) !== optionId) return false\n selectedByOptionId.set(optionId, normalizedValueId)\n return true\n}\n\nfunction assignSelectedValueSlugByOptionId(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n optionId: string,\n valueSlug: string | null | undefined,\n): boolean {\n if (!valueSlug) return false\n const option = matrix.optionById.get(optionId)\n if (!option) return false\n const values = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (values.length > 1) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection value slug \"${valueSlug}\" for option \"${optionId}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n const value = values[0]\n if (!value) return false\n selectedByOptionId.set(optionId, value.id)\n return true\n}\n\nfunction assignSelectedValueSlugByOptionSlug(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n optionSlug: string,\n valueSlug: string | null | undefined,\n): boolean {\n if (!valueSlug) return false\n const option = matrix.optionBySlug.get(optionSlug)\n if (!option) return false\n const values = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (values.length > 1) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection value slug \"${valueSlug}\" for option \"${optionSlug}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n const value = values[0]\n if (!value) return false\n selectedByOptionId.set(option.id, value.id)\n return true\n}\n\nfunction toSearchParams(\n search: string | URLSearchParams | URL | null | undefined,\n): URLSearchParams {\n if (!search) return new URLSearchParams()\n if (search instanceof URLSearchParams) return new URLSearchParams(search)\n if (search instanceof URL) return new URLSearchParams(search.searchParams)\n\n const trimmed = search.trim()\n if (!trimmed) return new URLSearchParams()\n\n try {\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(trimmed)) {\n return new URL(trimmed).searchParams\n }\n } catch {\n return new URLSearchParams()\n }\n\n return new URLSearchParams(\n trimmed.startsWith('?') ? trimmed.slice(1) : trimmed,\n )\n}\n\nfunction slugLike(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\nfunction assertNoAmbiguousSelectionParams(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n params: URLSearchParams,\n) {\n const knownSelectionKeys = new Set<string>()\n const hasVariantParam = params.has('variant')\n const hasOptionParams = Array.from(params.keys()).some((key) =>\n key.startsWith('opt.'),\n )\n\n if (hasVariantParam && hasOptionParams) {\n throw new ProductSelectionCodecError(\n 'Product selection URL cannot mix variant=<variantId> with opt.<optionId>=<valueId> params.',\n )\n }\n\n for (const option of matrix.options) {\n knownSelectionKeys.add(slugLike(option.slug))\n knownSelectionKeys.add(slugLike(option.title))\n for (const value of option.values) {\n if (value.slug) knownSelectionKeys.add(slugLike(value.slug))\n }\n }\n\n for (const [key, value] of params.entries()) {\n if (key.startsWith('opt.')) {\n const optionToken = key.slice(4)\n if (\n !optionToken ||\n (!matrix.optionBySlug.has(optionToken) &&\n !matrix.optionById.has(optionToken))\n ) {\n throw new ProductSelectionCodecError(\n `Unknown product selection query parameter \"${key}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n if (!value) {\n throw new ProductSelectionCodecError(\n `Product selection query parameter \"${key}\" requires a value ID or compatibility value slug.`,\n )\n }\n continue\n }\n\n if (key === 'variant') {\n if (!value) {\n throw new ProductSelectionCodecError(\n 'Product selection query parameter \"variant\" requires a variant ID.',\n )\n }\n if (!getVariantSelection(matrix, value)) {\n throw new ProductSelectionCodecError(\n `Unknown product selection variant \"${value}\".`,\n )\n }\n continue\n }\n\n const keyToken = slugLike(key)\n if (\n knownSelectionKeys.has(keyToken) ||\n (value === '' && knownSelectionKeys.has(keyToken))\n ) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection query parameter \"${key}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n }\n}\n\nfunction emitCompatibilityOptionIdParam(\n options: ProductSelectionCodecOptions | undefined,\n event: CompatibilityProductSelectionParamEvent,\n) {\n try {\n if (options?.onCompatibilityOptionIdParam) {\n options.onCompatibilityOptionIdParam(event)\n return\n }\n options?.onLegacyOptionIdParam?.(event)\n } catch {\n // Compatibility telemetry must not change parser semantics.\n }\n}\n\nfunction assignSearchSelection(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n search: string | URLSearchParams | URL | null | undefined,\n options?: ProductSelectionCodecOptions,\n): string | null {\n if (!search) return null\n const params = toSearchParams(search)\n assertNoAmbiguousSelectionParams(matrix, params)\n\n const variantParam = params.get('variant')\n if (variantParam != null) {\n const variantSelection = getVariantSelection(matrix, variantParam)\n if (!variantSelection) {\n throw new ProductSelectionCodecError(\n `Unknown product selection variant \"${variantParam}\".`,\n )\n }\n for (const [optionId, valueId] of variantSelection.optionValueByOptionId) {\n selectedByOptionId.set(optionId, valueId)\n }\n return variantSelection.id\n }\n\n for (const [key, valueToken] of params.entries()) {\n if (!key.startsWith('opt.')) continue\n const optionToken = key.slice(4)\n\n const optionById = matrix.optionById.get(optionToken)\n if (optionById) {\n if (\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n optionById.id,\n valueToken,\n )\n ) {\n continue\n }\n\n const before = selectedByOptionId.get(optionById.id)\n if (\n assignSelectedValueSlugByOptionId(\n matrix,\n selectedByOptionId,\n optionById.id,\n valueToken,\n ) &&\n selectedByOptionId.get(optionById.id) !== before\n ) {\n emitCompatibilityOptionIdParam(options, {\n optionId: optionById.id,\n optionSlug: optionById.slug,\n valueSlug: valueToken,\n searchParam: key,\n })\n continue\n }\n\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n\n const optionBySlug = matrix.optionBySlug.get(optionToken)\n if (optionBySlug) {\n if (\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionBySlug.slug,\n valueToken,\n )\n ) {\n continue\n }\n\n if (matrix.valueById.has(valueToken)) {\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionSlug>=<valueSlug> for compatibility URLs.`,\n )\n }\n }\n\n return null\n}\n\nexport function normalizeProductSelection(\n detail: ProductSelectionDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n return normalizeProductSelectionFromMatrix(matrix, selection, options)\n}\n\nexport function normalizeProductSelectionFromMatrix(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const selectedByOptionId = new Map<string, string>()\n const variantSelection = getVariantSelection(matrix, selection.variantId)\n const variantId = variantSelection?.id ?? null\n\n if (variantSelection) {\n for (const [optionId, valueId] of variantSelection.optionValueByOptionId) {\n selectedByOptionId.set(optionId, valueId)\n }\n }\n\n for (const rawValueId of selection.valueIds ?? []) {\n const valueId = getRelationID(rawValueId as RelationshipValue)\n if (!valueId) continue\n const optionId = matrix.valueToOptionId.get(valueId)\n if (!optionId) continue\n selectedByOptionId.set(optionId, valueId)\n }\n\n const searchVariantId = assignSearchSelection(\n matrix,\n selectedByOptionId,\n selection.search,\n options,\n )\n\n for (const [rawOptionId, rawSelection] of Object.entries(\n selection.byOptionId ?? {},\n )) {\n const optionId = String(rawOptionId)\n if (!matrix.optionById.has(optionId)) continue\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueId' in rawSelection &&\n rawSelection.valueId != null\n ) {\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n optionId,\n rawSelection.valueId,\n )\n continue\n }\n\n if (typeof rawSelection === 'string' || typeof rawSelection === 'number') {\n assignSelectedValue(matrix, selectedByOptionId, optionId, rawSelection)\n continue\n }\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueSlug' in rawSelection\n ) {\n assignSelectedValueSlugByOptionId(\n matrix,\n selectedByOptionId,\n optionId,\n rawSelection.valueSlug,\n )\n }\n }\n\n for (const [rawOptionSlug, rawSelection] of Object.entries(\n selection.byOptionSlug ?? {},\n )) {\n const optionSlug = String(rawOptionSlug)\n if (!matrix.optionBySlug.has(optionSlug)) continue\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueId' in rawSelection &&\n rawSelection.valueId != null\n ) {\n const option = matrix.optionBySlug.get(optionSlug)\n if (option) {\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n option.id,\n rawSelection.valueId,\n )\n }\n continue\n }\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueSlug' in rawSelection\n ) {\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionSlug,\n rawSelection.valueSlug,\n )\n continue\n }\n\n if (typeof rawSelection === 'string' || typeof rawSelection === 'number') {\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionSlug,\n String(rawSelection),\n )\n }\n }\n\n const byOptionId = Object.fromEntries(\n matrix.optionIds\n .map((optionId) => [optionId, selectedByOptionId.get(optionId)])\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n const byOptionSlug = Object.fromEntries(\n matrix.options\n .map((option) => {\n const valueId = selectedByOptionId.get(option.id)\n const value = valueId ? matrix.valueById.get(valueId) : undefined\n return [option.slug, value?.slug ?? undefined]\n })\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n\n return {\n byOptionSlug,\n byOptionId,\n valueIds: matrix.optionIds\n .map((optionId) => byOptionId[optionId])\n .filter((valueId): valueId is string => Boolean(valueId)),\n variantId: searchVariantId ?? variantId,\n }\n}\n\nexport function parseProductSelection(\n detail: ProductSelectionDetail,\n search: string | URLSearchParams | URL | null | undefined,\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n return normalizeProductSelection(detail, { search }, options)\n}\n\nexport function stringifyProductSelection(\n detail: ProductSelectionDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): string {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n const normalized = normalizeProductSelectionFromMatrix(\n matrix,\n selection,\n options,\n )\n const params = new URLSearchParams()\n\n if (hasExplicitSelection(selection)) {\n const matchingVariants = getMatchingVariantEntries(matrix, normalized)\n const exactVariant = getExactSelectedVariantEntry(\n matrix,\n normalized,\n matchingVariants,\n )\n if (exactVariant) {\n params.set('variant', exactVariant.id)\n return params.toString()\n }\n }\n\n const emit = resolveProductSelectionUrlEmit(options?.emit)\n\n for (const optionId of matrix.optionIds) {\n const valueId = normalized.byOptionId[optionId]\n if (!valueId) continue\n if (!matrix.optionById.has(optionId) || !matrix.valueById.has(valueId)) {\n continue\n }\n\n if (emit === 'slug-compat') {\n if (appendSlugCompatSelectionParam(params, matrix, optionId, valueId)) {\n continue\n }\n }\n\n appendCanonicalSelectionParam(params, optionId, valueId)\n }\n\n return params.toString()\n}\n\nexport function createProductSelectionCodec(\n detail: ProductSelectionDetail,\n options?: ProductSelectionCodecOptions,\n): {\n parse: (\n search: string | URLSearchParams | URL | null | undefined,\n ) => NormalizedProductSelection\n stringify: (selection?: ProductSelectionInput) => string\n} {\n return {\n parse: (search) => parseProductSelection(detail, search, options),\n stringify: (selection = {}) =>\n stringifyProductSelection(detail, selection, options),\n }\n}\n\nfunction selectedEntries(\n selection: NormalizedProductSelection,\n): Array<[string, string]> {\n return Object.entries(selection.byOptionId)\n}\n\nfunction getMatchingVariantEntries(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selection: NormalizedProductSelection,\n): ProductOptionMatrixVariant<ProductSelectionVariant>[] {\n const entries = selectedEntries(selection)\n if (entries.length === 0) return matrix.variants\n\n return matrix.variants.filter((variant) =>\n entries.every(\n ([optionId, valueId]) =>\n variant.optionValueByOptionId.get(optionId) === valueId,\n ),\n )\n}\n\nfunction activeVariantEntries(\n variants: ProductOptionMatrixVariant<ProductSelectionVariant>[],\n): ProductOptionMatrixVariant<ProductSelectionVariant>[] {\n return variants.filter((variant) => variant.source.isActive !== false)\n}\n\nfunction getExactSelectedVariantEntry(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selection: NormalizedProductSelection,\n matchingVariants: ProductOptionMatrixVariant<ProductSelectionVariant>[],\n): ProductOptionMatrixVariant<ProductSelectionVariant> | null {\n if (matrix.optionIds.length === 0) {\n return (\n getVariantSelection(matrix, selection.variantId) ??\n (matchingVariants.length === 1 ? (matchingVariants[0] ?? null) : null)\n )\n }\n\n const allOptionsSelected = matrix.optionIds.every((optionId) =>\n Boolean(selection.byOptionId[optionId]),\n )\n if (!allOptionsSelected) return null\n\n return (\n matchingVariants.find((variant) =>\n matrix.optionIds.every(\n (optionId) =>\n variant.optionValueByOptionId.get(optionId) ===\n selection.byOptionId[optionId],\n ),\n ) ?? null\n )\n}\n\nfunction normalizedSelectionFromByOptionId(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n variantId: string | null,\n): NormalizedProductSelection {\n const byOptionId = Object.fromEntries(\n matrix.optionIds\n .map((optionId) => [optionId, selectedByOptionId.get(optionId)])\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n const byOptionSlug = Object.fromEntries(\n matrix.options\n .map((option) => {\n const valueId = selectedByOptionId.get(option.id)\n const value = valueId ? matrix.valueById.get(valueId) : undefined\n return [option.slug, value?.slug ?? undefined]\n })\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n\n return {\n byOptionSlug,\n byOptionId,\n valueIds: matrix.optionIds\n .map((optionId) => byOptionId[optionId])\n .filter((valueId): valueId is string => Boolean(valueId)),\n variantId,\n }\n}\n\nfunction buildFilledNormalizedSelection(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n normalizedSelection: NormalizedProductSelection,\n selectionHintVariant: string | number | null | undefined,\n): NormalizedProductSelection {\n const selectedByOptionId = new Map<string, string>(\n Object.entries(normalizedSelection.byOptionId),\n )\n\n if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n const variantId =\n normalizedSelection.variantId ??\n resolveVariantIdForCompleteSelection(matrix, selectedByOptionId)\n if (variantId === normalizedSelection.variantId) {\n return normalizedSelection\n }\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n variantId,\n )\n }\n\n for (const option of matrix.options) {\n if (selectedByOptionId.has(option.id)) continue\n if (option.values.length === 1) {\n selectedByOptionId.set(option.id, option.values[0]!.id)\n }\n }\n\n if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n const variantId =\n normalizedSelection.variantId ??\n resolveVariantIdForCompleteSelection(matrix, selectedByOptionId)\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n variantId,\n )\n }\n\n const partialNormalized = normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n normalizedSelection.variantId,\n )\n const matchingVariantEntries = getMatchingVariantEntries(\n matrix,\n partialNormalized,\n )\n const orderedMatches = [...matchingVariantEntries].sort((left, right) =>\n compareVariantOrder(left.source, right.source),\n )\n\n const hintVariantId =\n selectionHintVariant != null ? String(selectionHintVariant) : null\n const hintedEntry =\n hintVariantId != null\n ? orderedMatches.find((entry) => entry.id === hintVariantId)\n : undefined\n const availableEntry = orderedMatches.find((entry) =>\n isVariantAvailableForSale(entry.source),\n )\n const chosenEntry = hintedEntry ?? availableEntry ?? orderedMatches[0]\n\n if (!chosenEntry) {\n return normalizedSelection\n }\n\n for (const optionId of matrix.optionIds) {\n if (selectedByOptionId.has(optionId)) continue\n const valueId = chosenEntry.optionValueByOptionId.get(optionId)\n if (valueId) selectedByOptionId.set(optionId, valueId)\n }\n\n const filledVariantId = matrix.optionIds.every((optionId) =>\n selectedByOptionId.has(optionId),\n )\n ? (resolveVariantIdForCompleteSelection(matrix, selectedByOptionId) ??\n chosenEntry.id)\n : normalizedSelection.variantId\n\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n filledVariantId,\n )\n}\n\nfunction resolveVariantIdForCompleteSelection(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n): string | null {\n if (!matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n return null\n }\n\n const normalized = normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n null,\n )\n const matchingVariantEntries = getMatchingVariantEntries(matrix, normalized)\n return (\n getExactSelectedVariantEntry(matrix, normalized, matchingVariantEntries)\n ?.id ?? null\n )\n}\n\nfunction buildSelectionPrice(\n variants: ProductSelectionVariant[],\n): ProductSelectionResolution['price'] {\n const { min, max } = getMinMax(\n variants.map((variant) => variant.resolvedPrice?.amount ?? variant.price),\n )\n const { min: compareAtMin, max: compareAtMax } = getMinMax(\n variants.map(\n (variant) =>\n variant.resolvedPrice?.compareAtPrice ?? variant.compareAtPrice,\n ),\n )\n\n return {\n min,\n max,\n compareAtMin,\n compareAtMax,\n isRange: min !== null && max !== null ? min !== max : false,\n }\n}\n\nfunction isPresentMedia(value: MediaValue): value is ProductDetailMedia {\n return value != null\n}\n\nfunction mediaArray(\n values: MediaValue[] | null | undefined,\n): ProductDetailMedia[] {\n if (!Array.isArray(values)) return []\n return values.filter(isPresentMedia)\n}\n\nfunction buildSelectionMedia(\n detail: {\n featuredImage?: ProductDetail['featuredImage']\n images: ProductDetail['images']\n },\n selectedVariant: ProductSelectionVariant | null,\n matchingVariants: ProductSelectionVariant[],\n selectedValues: ProductOptionMatrixValue[],\n): ProductSelectionResolution['media'] {\n const productPool = mediaArray(detail.images)\n const resolvedMedia = resolveProductSelectionMedia<ProductDetailMedia>({\n productMediaPool: productPool,\n selectedVariant: selectedVariant\n ? {\n id: selectedVariant.id,\n images: selectedVariant.images,\n }\n : null,\n matchingVariants: matchingVariants.map((variant) => ({\n id: variant.id,\n images: variant.images,\n })),\n selectedOptionValues: selectedValues.map((value) => ({\n id: value.id,\n swatch: normalizeMatrixSwatch(value.swatch),\n })),\n })\n if (resolvedMedia.source !== 'none') {\n return {\n primaryImage: resolvedMedia.primaryImage,\n images: resolvedMedia.images,\n source: resolvedMedia.source,\n }\n }\n\n const displayMedia = resolveProductDisplayMedia<ProductDetailMedia>({\n productMediaPool: productPool,\n featuredImage: detail.featuredImage ?? null,\n })\n if (displayMedia.source !== 'none') {\n return {\n primaryImage: displayMedia.primaryImage,\n images: displayMedia.images,\n source: displayMedia.source,\n }\n }\n\n return { primaryImage: null, images: [], source: 'none' }\n}\n\nfunction buildSelectionStock(\n selectedVariant: ProductSelectionVariant | null,\n matchingVariants: ProductSelectionVariant[],\n): ProductSelectionResolution['stock'] {\n if (selectedVariant) {\n const availableStock = getVariantAvailableStock(selectedVariant)\n return {\n availableForSale: getVariantAvailableForSale(selectedVariant),\n isUnlimited: selectedVariant.isUnlimited,\n stock: 'stock' in selectedVariant ? selectedVariant.stock : null,\n reservedStock:\n 'reservedStock' in selectedVariant\n ? selectedVariant.reservedStock\n : null,\n availableStock,\n }\n }\n\n return {\n availableForSale: matchingVariants.some(isVariantAvailableForSale),\n isUnlimited: matchingVariants.some((variant) => variant.isUnlimited),\n stock: null,\n reservedStock: null,\n availableStock: null,\n }\n}\n\nfunction buildAvailableValueStock(\n variants: ProductSelectionVariant[],\n): Pick<\n ProductSelectionAvailableValue,\n 'availableForSale' | 'availableStock' | 'isUnlimited'\n> {\n const activeVariants = variants.filter(\n (variant) => variant.isActive !== false,\n )\n const isUnlimited = activeVariants.some((variant) => variant.isUnlimited)\n const availableStock = isUnlimited\n ? null\n : activeVariants.reduce(\n (sum, variant) => sum + (getVariantAvailableStock(variant) ?? 0),\n 0,\n )\n\n return {\n availableForSale: activeVariants.some(isVariantAvailableForSale),\n isUnlimited,\n availableStock,\n }\n}\n\nfunction buildProductSelectionAvailableValue(\n matrixValue: ProductOptionMatrixValue,\n _productImages: ProductDetailMedia[],\n selected: boolean,\n available: boolean,\n stock: Pick<\n ProductSelectionAvailableValue,\n 'availableForSale' | 'availableStock' | 'isUnlimited'\n >,\n): ProductSelectionAvailableValue {\n return {\n valueId: matrixValue.id,\n value: matrixValue.label,\n label: matrixValue.label,\n slug: matrixValue.slug ?? '',\n selected,\n available,\n exists: available,\n ...stock,\n swatch: matrixValue.swatch ?? null,\n }\n}\n\nfunction getCandidateVariantsForValue(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n optionId: string,\n valueId: string,\n selectedValueIds: Iterable<unknown>,\n): ProductSelectionVariant[] {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n selectedByOption.set(optionId, valueId)\n\n return matrix.variants\n .filter((variant) =>\n Array.from(selectedByOption.entries()).every(\n ([selectedOptionId, selectedValueId]) =>\n variant.optionValueByOptionId.get(selectedOptionId) ===\n selectedValueId,\n ),\n )\n .map((variant) => variant.source)\n}\n\nfunction getResolutionContext(context?: ProductSelectionResolutionContext): {\n featuredImage: ProductSelectionDetail['featuredImage']\n images: ProductSelectionDetail['images']\n selectedOrFirstAvailableVariant:\n | ProductSelectionDetail['selectedOrFirstAvailableVariant']\n | undefined\n} {\n return {\n featuredImage: context?.featuredImage ?? context?.detail?.featuredImage,\n images: context?.images ?? context?.detail?.images ?? [],\n selectedOrFirstAvailableVariant:\n context?.selectedOrFirstAvailableVariant ??\n context?.detail?.selectedOrFirstAvailableVariant,\n }\n}\n\nexport function resolveProductSelectionFromMatrix(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n context?: ProductSelectionResolutionContext,\n): ProductSelectionResolution {\n const { featuredImage, images, selectedOrFirstAvailableVariant } =\n getResolutionContext(context)\n const selectionHintVariant = getRelationID(selectedOrFirstAvailableVariant)\n const effectiveSelection =\n hasExplicitSelection(selection) || selectionHintVariant == null\n ? selection\n : { ...selection, variantId: selectionHintVariant }\n let normalizedSelection = normalizeProductSelectionFromMatrix(\n matrix,\n effectiveSelection,\n options,\n )\n\n if (options?.fillDefaults) {\n normalizedSelection = buildFilledNormalizedSelection(\n matrix,\n normalizedSelection,\n selectionHintVariant,\n )\n }\n const matchingVariantEntries = getMatchingVariantEntries(\n matrix,\n normalizedSelection,\n )\n const activeMatchingVariantEntries = activeVariantEntries(\n matchingVariantEntries,\n )\n const selectedVariantEntry = getExactSelectedVariantEntry(\n matrix,\n normalizedSelection,\n matchingVariantEntries,\n )\n const selectedVariant = selectedVariantEntry?.source ?? null\n const matchingVariants = activeMatchingVariantEntries.map(\n (variant) => variant.source,\n )\n const selectedValues = matrix.optionIds\n .map((optionId) => normalizedSelection.byOptionId[optionId])\n .map((valueId) => (valueId ? matrix.valueById.get(valueId) : undefined))\n .filter((value): value is ProductOptionMatrixValue => value !== undefined)\n const availableValuesByOptionId = Object.fromEntries(\n matrix.options.map((option) => {\n const availableValueIds = new Set(\n getAvailableOptionValues(\n matrix,\n option.id,\n normalizedSelection.valueIds,\n ).map((value) => value.id),\n )\n return [\n option.id,\n option.values.map((value) =>\n buildProductSelectionAvailableValue(\n value,\n images,\n normalizedSelection.byOptionId[option.id] === value.id,\n availableValueIds.has(value.id),\n buildAvailableValueStock(\n getCandidateVariantsForValue(\n matrix,\n option.id,\n value.id,\n normalizedSelection.valueIds,\n ),\n ),\n ),\n ),\n ]\n }),\n )\n const availableValuesByOptionSlug = Object.fromEntries(\n matrix.options.map((option) => [\n option.slug,\n availableValuesByOptionId[option.id] ?? [],\n ]),\n )\n const allOptionsSelected = matrix.optionIds.every((optionId) =>\n Boolean(normalizedSelection.byOptionId[optionId]),\n )\n const priceVariants = selectedVariant ? [selectedVariant] : matchingVariants\n\n return {\n normalizedSelection,\n selectedVariant,\n matchingVariants,\n partialVariants: selectedVariant ? [] : matchingVariants,\n availableValuesByOptionSlug,\n availableValuesByOptionId,\n allOptionsSelected,\n price: buildSelectionPrice(priceVariants),\n media: buildSelectionMedia(\n {\n featuredImage,\n images,\n },\n selectedVariant,\n matchingVariants,\n selectedValues,\n ),\n stock: buildSelectionStock(selectedVariant, matchingVariants),\n }\n}\n\nexport function resolveProductSelection<TDetail extends ProductSelectionDetail>(\n detail: TDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): ProductSelectionResolution<ProductSelectionVariantForDetail<TDetail>> {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n return resolveProductSelectionFromMatrix(matrix, selection, options, {\n detail,\n }) as ProductSelectionResolution<ProductSelectionVariantForDetail<TDetail>>\n}\n\nexport function selectNext(\n detail: ProductDetail,\n current: ProductSelectionInput = {},\n optionSlug: string,\n valueSlug: string,\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n const selectionHintVariant = getRelationID(\n detail.selectedOrFirstAvailableVariant,\n )\n const normalizedCurrent = normalizeProductSelectionFromMatrix(\n matrix,\n current,\n options,\n )\n\n const option = matrix.optionBySlug.get(optionSlug)\n if (!option) return normalizedCurrent\n\n const valueMatches = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (valueMatches.length !== 1) return normalizedCurrent\n const clickedValueId = valueMatches[0]!.id\n\n const keepClickedSelection = (): NormalizedProductSelection => {\n const selectedByOptionId = new Map<string, string>()\n selectedByOptionId.set(option.id, clickedValueId)\n\n for (const otherOptionId of matrix.optionIds) {\n if (otherOptionId === option.id) continue\n const otherValueId = normalizedCurrent.byOptionId[otherOptionId]\n if (!otherValueId) continue\n\n const constraintIds = normalizeSelectedValueIds(\n matrix,\n Array.from(selectedByOptionId.values()),\n )\n const available = getAvailableOptionValues(\n matrix,\n otherOptionId,\n constraintIds,\n )\n if (available.some((candidate) => candidate.id === otherValueId)) {\n selectedByOptionId.set(otherOptionId, otherValueId)\n }\n }\n\n return buildFilledNormalizedSelection(\n matrix,\n normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),\n selectionHintVariant,\n )\n }\n\n const keepPriorSelection = (): NormalizedProductSelection => {\n const selectedByOptionId = new Map<string, string>(\n Object.entries(normalizedCurrent.byOptionId),\n )\n selectedByOptionId.delete(option.id)\n\n return buildFilledNormalizedSelection(\n matrix,\n normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),\n selectionHintVariant,\n )\n }\n\n const clickedResult = keepClickedSelection()\n const clickedVariantId = resolveVariantIdForCompleteSelection(\n matrix,\n new Map(Object.entries(clickedResult.byOptionId)),\n )\n\n const priorValueIds = Object.entries(normalizedCurrent.byOptionId)\n .filter(([otherOptionId]) => otherOptionId !== option.id)\n .map(([, valueId]) => valueId)\n\n const clickedAvailableWithPrior =\n priorValueIds.length === 0 ||\n getAvailableOptionValues(matrix, option.id, priorValueIds).some(\n (candidate) => candidate.id === clickedValueId,\n )\n\n if (clickedVariantId != null) {\n const priorClickedValue = normalizedCurrent.byOptionId[option.id]\n if (priorClickedValue != null && priorClickedValue !== clickedValueId) {\n return clickedResult\n }\n if (clickedAvailableWithPrior) {\n return clickedResult\n }\n }\n\n return keepPriorSelection()\n}\n\nexport type ProductDetailImageMedia = Extract<\n ProductDetailMedia,\n { id?: string | number | null; url?: string | null }\n>\n\nfunction isProductDetailImageMedia(\n value: ProductDetailMedia | null | undefined,\n): value is ProductDetailImageMedia {\n return typeof value === 'object' && value !== null\n}\n\nfunction mediaDedupeKey(value: ProductDetailImageMedia): string | null {\n if (value.id != null) return `id:${String(value.id)}`\n if (value.url) return `url:${value.url}`\n return null\n}\n\nexport function getProductSelectionImages(\n resolution: Pick<ProductSelectionResolution, 'media'>,\n): ProductDetailImageMedia[] {\n const seen = new Set<string>()\n const images: ProductDetailImageMedia[] = []\n const candidates = [\n resolution.media.primaryImage,\n ...resolution.media.images,\n ].filter(isProductDetailImageMedia)\n\n for (const candidate of candidates) {\n const key = mediaDedupeKey(candidate)\n if (key && seen.has(key)) continue\n if (key) seen.add(key)\n images.push(candidate)\n }\n\n return images\n}\n\nexport type ProductHrefProduct =\n | ProductDetail\n | {\n slug?: string | null\n product?: { slug?: string | null } | null\n }\n\nexport type ProductHrefGroup = {\n optionId?: string | number | null\n optionSlug?: string | null\n optionValueId?: string | number | null\n optionValueSlug?: string | null\n variantId?: string | number | null\n listing?: {\n selectionHintVariant?: string | number | null\n } | null\n}\n\nexport type ProductHrefOptions = {\n basePath?: string\n detail?: ProductSelectionDetail\n matrix?: ProductOptionMatrix<ProductSelectionVariant>\n selection?: ProductSelectionInput\n trailingSlash?: boolean\n emit?: ProductSelectionUrlEmit\n preferCompleteVariantFromHint?: boolean\n}\n\nexport type ProductListingCardOptions = {\n basePath?: string\n trailingSlash?: boolean\n emit?: ProductSelectionUrlEmit\n preferCompleteVariantFromHint?: boolean\n}\n\nfunction getProductHrefSlug(product: ProductHrefProduct): string {\n if ('product' in product && product.product?.slug) {\n return product.product.slug\n }\n if ('slug' in product && product.slug) return product.slug\n throw new ProductSelectionCodecError(\n 'Product slug is required to build a product href.',\n )\n}\n\nfunction joinProductPath(\n basePath: string,\n slug: string,\n trailingSlash: boolean,\n) {\n const base = basePath.replace(/\\/+$/, '')\n const encodedSlug = encodeURIComponent(slug)\n return `${base}/${encodedSlug}${trailingSlash ? '/' : ''}`\n}\n\nfunction getProductHrefGroupSelection(\n group: ProductHrefGroup | null | undefined,\n matrix?: ProductOptionMatrix<ProductSelectionVariant>,\n): ProductSelectionInput | null {\n if (!group) return null\n\n if (group.variantId != null) return { variantId: group.variantId }\n\n const optionId =\n group.optionId != null\n ? String(group.optionId)\n : group.optionSlug\n ? matrix?.optionBySlug.get(group.optionSlug)?.id\n : undefined\n if (!optionId) return null\n\n const option = matrix?.optionById.get(optionId)\n const optionValueId =\n group.optionValueId != null\n ? String(group.optionValueId)\n : group.optionValueSlug && option\n ? option.values.find((value) => value.slug === group.optionValueSlug)\n ?.id\n : undefined\n\n if (!optionValueId) return null\n return { byOptionId: { [optionId]: optionValueId } }\n}\n\nfunction getProductHrefCodecOptions(\n options: ProductHrefOptions,\n): ProductSelectionCodecOptions | undefined {\n return options.emit != null ? { emit: options.emit } : undefined\n}\n\nfunction appendGroupByOptionIdHrefParams(\n params: URLSearchParams,\n group: ProductHrefGroup | null | undefined,\n groupSelection: ProductSelectionInput,\n options: ProductHrefOptions,\n): boolean {\n const emit = resolveProductSelectionUrlEmit(options.emit)\n const byOptionId = groupSelection.byOptionId ?? {}\n const entries = Object.entries(byOptionId)\n if (entries.length === 0) return false\n\n for (const [optionId, valueId] of entries) {\n const optionSlug =\n group?.optionSlug ??\n options.matrix?.optionById.get(optionId)?.slug ??\n null\n const valueSlug =\n group?.optionValueSlug ??\n options.matrix?.valueById.get(String(valueId))?.slug ??\n null\n\n if (\n emit === 'slug-compat' &&\n optionSlug &&\n valueSlug &&\n entries.length === 1\n ) {\n params.set(`opt.${optionSlug}`, valueSlug)\n return true\n }\n\n if (\n emit === 'slug-compat' &&\n options.matrix &&\n appendSlugCompatSelectionParam(\n params,\n options.matrix,\n optionId,\n String(valueId),\n )\n ) {\n continue\n }\n appendCanonicalSelectionParam(params, optionId, String(valueId))\n }\n\n return params.size > 0\n}\n\nfunction getPreferCompleteVariantFromHintSelection(\n group: ProductHrefGroup | null | undefined,\n options: ProductHrefOptions,\n): ProductSelectionInput | null {\n if (!options.preferCompleteVariantFromHint) return null\n if (group?.optionValueId != null || group?.optionValueSlug) return null\n\n const hintVariantId = group?.listing?.selectionHintVariant\n if (hintVariantId == null) return null\n\n return { variantId: hintVariantId }\n}\n\nexport function buildProductHref(\n product: ProductHrefProduct,\n group?: ProductHrefGroup | null,\n options: ProductHrefOptions = {},\n): string {\n const path = joinProductPath(\n options.basePath ?? '/products',\n getProductHrefSlug(product),\n options.trailingSlash ?? false,\n )\n const params = new URLSearchParams()\n\n if (options.detail && options.selection) {\n const selection = stringifyProductSelection(\n options.detail,\n options.selection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n\n const preferVariantSelection = getPreferCompleteVariantFromHintSelection(\n group,\n options,\n )\n if (preferVariantSelection) {\n if (options.detail) {\n const selection = stringifyProductSelection(\n options.detail,\n preferVariantSelection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n if (preferVariantSelection.variantId != null) {\n params.set('variant', String(preferVariantSelection.variantId))\n return `${path}?${params.toString()}`\n }\n }\n\n const groupSelection = getProductHrefGroupSelection(group, options.matrix)\n if (groupSelection) {\n if (options.detail) {\n const selection = stringifyProductSelection(\n options.detail,\n groupSelection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n if (groupSelection.variantId != null) {\n params.set('variant', String(groupSelection.variantId))\n return `${path}?${params.toString()}`\n }\n if (\n appendGroupByOptionIdHrefParams(params, group, groupSelection, options)\n ) {\n return `${path}?${params.toString()}`\n }\n }\n\n if (group?.optionValueSlug) {\n const optionSlug =\n group.optionSlug ??\n (group.optionId != null\n ? options.matrix?.optionById.get(String(group.optionId))?.slug\n : undefined)\n if (optionSlug) {\n params.set(`opt.${optionSlug}`, group.optionValueSlug)\n }\n }\n\n return params.size > 0 ? `${path}?${params.toString()}` : path\n}\n\nfunction compareVariantOrder(a: ProductVariantShape, b: ProductVariantShape) {\n const aOrder = Number(a._order ?? Number.MAX_SAFE_INTEGER)\n const bOrder = Number(b._order ?? Number.MAX_SAFE_INTEGER)\n\n if (Number.isFinite(aOrder) && Number.isFinite(bOrder) && aOrder !== bOrder) {\n return aOrder - bOrder\n }\n\n const aId = String(getRelationID(a.id) ?? '')\n const bId = String(getRelationID(b.id) ?? '')\n return compareOrdinal(aId, bId)\n}\n\n/**\n * Server-equivalent sellability for a single variant: active, and either\n * unlimited or with positive sellable stock (`stock - reservedStock`). This is\n * the same rule the SDK applies when rolling availability up to the product, so\n * storefronts can compute a Shopify-style `availableForSale` without\n * re-implementing the check or shipping raw `stock`/`reservedStock` to the\n * browser.\n */\nexport function getVariantAvailableForSale(\n variant: ProductVariantShape,\n): boolean {\n if (variant.isActive === false) return false\n if (typeof variant.availableForSale === 'boolean') {\n return variant.availableForSale\n }\n if (variant.isUnlimited) return true\n // `continue` (Shopify backorder) stays purchasable past available stock.\n if (variant.inventoryPolicy === 'continue') return true\n return (variant.stock ?? 0) - (variant.reservedStock ?? 0) > 0\n}\n\n/**\n * Sellable quantity for a single variant (`stock - reservedStock`, clamped at\n * zero), or `null` when the variant is unlimited and has no finite quantity.\n * Mirrors Shopify's `ProductVariant.quantityAvailable` (a single computed\n * number, never the raw stock/reserved breakdown).\n */\nexport function getVariantAvailableStock(\n variant: ProductVariantShape,\n): number | null {\n if (variant.isUnlimited) return null\n return Math.max(0, (variant.stock ?? 0) - (variant.reservedStock ?? 0))\n}\n\nfunction isVariantAvailableForSale(variant: ProductVariantShape) {\n return getVariantAvailableForSale(variant)\n}\n\nfunction sortVariantsForMediaSelection(\n variants: ProductVariantShape[],\n): ProductVariantShape[] {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n const activeVariants = orderedVariants.filter(\n (variant) => variant.isActive !== false,\n )\n const availableVariants = activeVariants.filter(isVariantAvailableForSale)\n const unavailableActiveVariants = activeVariants.filter(\n (variant) => !isVariantAvailableForSale(variant),\n )\n\n return [...availableVariants, ...unavailableActiveVariants]\n}\n\nfunction variantHasPoolMedia(\n variant: ProductVariantShape | null,\n productMediaPool: MediaValue[],\n): boolean {\n if (!variant?.images?.length) return false\n return variant.images.some((image) => {\n const imageId = getRelationID(image)\n return Boolean(\n imageId &&\n productMediaPool.some((poolItem) => getRelationID(poolItem) === imageId),\n )\n })\n}\n\nfunction getMinMax(values: Array<number | null | undefined>) {\n const numbers = values.filter(\n (value): value is number => typeof value === 'number',\n )\n if (numbers.length === 0) {\n return { min: null, max: null }\n }\n\n return {\n min: Math.min(...numbers),\n max: Math.max(...numbers),\n }\n}\n\nexport function buildProductListingGroupProjection(\n product: ProductListingProductShape | null | undefined,\n variants: ProductVariantShape[],\n): ProductListingGroupProjection {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n const activeVariants = orderedVariants.filter(\n (variant) => variant.isActive !== false,\n )\n const availableVariants = activeVariants.filter(isVariantAvailableForSale)\n const selectionHintVariant = availableVariants[0] ?? activeVariants[0] ?? null\n\n const { min: minPrice, max: maxPrice } = getMinMax(\n activeVariants.map((variant) => variant.price),\n )\n const { min: minCompareAtPrice, max: maxCompareAtPrice } = getMinMax(\n activeVariants.map((variant) => variant.compareAtPrice),\n )\n\n const productMediaPool = product?.images ?? []\n const selectionHintHasPoolMedia = variantHasPoolMedia(\n selectionHintVariant,\n productMediaPool,\n )\n const mediaSelectionVariants = sortVariantsForMediaSelection(variants)\n const resolvedProductMedia = resolveProductSelectionMedia<MediaValue>({\n productMediaPool,\n selectedVariant:\n selectionHintVariant && selectionHintHasPoolMedia\n ? {\n id: selectionHintVariant.id,\n images: selectionHintVariant.images,\n }\n : null,\n matchingVariants: selectionHintHasPoolMedia ? [] : mediaSelectionVariants,\n })\n\n return {\n selectionHintVariant: getRelationID(selectionHintVariant?.id) ?? null,\n primaryImage: resolveGenericListingPrimaryImage(\n product,\n resolvedProductMedia.primaryImage,\n resolvedProductMedia.source,\n ),\n minPrice,\n maxPrice,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange:\n minPrice !== null && maxPrice !== null ? minPrice !== maxPrice : false,\n availableForSale: availableVariants.length > 0,\n }\n}\n\nexport function buildProductListingCard(\n item: ProductListingCardSourceItem,\n options: ProductListingCardOptions = {},\n): ProductListingCard {\n const product = item.product\n const groups = item.groups\n const variants = getProductListingCardVariants(item)\n const projectedListing = buildProductListingGroupProjection(product, variants)\n const selectionHintVariant =\n getRelationID(product.selectedOrFirstAvailableVariant) ??\n projectedListing.selectionHintVariant\n const representativeVariant = findListingCardRepresentativeVariant(\n variants,\n selectionHintVariant,\n )\n\n const productMediaPool = mediaArray(product.images)\n // Resolve featuredImage against the product media pool first so a bare-id\n // pointer becomes the populated media object (a card's primaryImage must be\n // consumable as media, not a dangling pointer). Falls back to the raw\n // featuredImage when it is not a pool member (e.g. a populated variant image).\n const featuredImageId = getRelationID(product.featuredImage)\n const featuredImageFromPool = featuredImageId\n ? productMediaPool.find((item) => getRelationID(item) === featuredImageId)\n : undefined\n const listingPrimaryMedia =\n featuredImageFromPool ??\n product.featuredImage ??\n productMediaPool[0] ??\n null\n\n const priceRange = resolveListingCardPriceRange(\n product,\n projectedListing,\n groups,\n )\n\n const availableForSale =\n product.availableForSale != null\n ? product.availableForSale\n : groups.length > 0\n ? groups.some((group) => group.listing.availableForSale)\n : projectedListing.availableForSale\n\n const swatches: ProductListingSwatch[] =\n groups.length > 1\n ? groups.map((group) => buildListingSwatch(product, group, options))\n : []\n\n return {\n id: String(product.id),\n href: buildProductHref(\n { slug: product.slug },\n { listing: { selectionHintVariant } },\n options,\n ),\n title: product.title ?? '',\n representativeVariant,\n primaryImage: listingPrimaryMedia,\n priceRange,\n availableForSale,\n swatches,\n }\n}\n\nfunction getProductListingCardVariants(\n item: ProductListingCardSourceItem,\n): ProductListingCardRepresentativeVariant[] {\n const productVariants = item.product.variants?.docs\n if (Array.isArray(productVariants) && productVariants.length > 0) {\n return productVariants\n }\n\n const variants: ProductListingCardRepresentativeVariant[] = []\n const seen = new Set<string>()\n\n for (const group of item.groups) {\n for (const variant of group.variants) {\n const id = getRelationID(variant.id)\n if (id && seen.has(id)) continue\n if (id) seen.add(id)\n variants.push(variant)\n }\n }\n\n return variants\n}\n\nfunction findListingCardRepresentativeVariant(\n variants: ProductListingCardRepresentativeVariant[],\n representativeVariantId: EntityID | null,\n): ProductListingCardRepresentativeVariant | null {\n if (representativeVariantId == null) return null\n return (\n variants.find(\n (variant) => getRelationID(variant.id) === representativeVariantId,\n ) ?? null\n )\n}\n\n/** Shopify `priceRangeV2` naming for persisted listing projection fields. */\nexport function toShopifyPriceRangeV2(listing: {\n minPrice?: number | null\n maxPrice?: number | null\n}): {\n minVariantPrice: { amount: number | null }\n maxVariantPrice: { amount: number | null }\n} {\n return {\n minVariantPrice: { amount: listing.minPrice ?? null },\n maxVariantPrice: { amount: listing.maxPrice ?? null },\n }\n}\n\nfunction hasCompleteProductPriceRange(\n priceRange: ProductListingCardSourceItem['product']['priceRange'],\n): priceRange is NonNullable<\n ProductListingCardSourceItem['product']['priceRange']\n> & {\n minVariantPrice: { amount: number }\n maxVariantPrice: { amount: number }\n} {\n return (\n priceRange?.minVariantPrice?.amount != null &&\n priceRange?.maxVariantPrice?.amount != null\n )\n}\n\nfunction resolveListingCardPriceRange(\n product: ProductListingCardSourceItem['product'],\n projectedListing: ReturnType<typeof buildProductListingGroupProjection>,\n groups: ProductListingCardSourceItem['groups'],\n): ProductListingCardPriceRange {\n if (hasCompleteProductPriceRange(product.priceRange)) {\n const groupRange =\n groups.length > 0 ? aggregateListingPriceRange(groups) : null\n const minCompareAtPrice =\n product.compareAtPriceRange?.minVariantPrice?.amount ??\n groupRange?.minCompareAtPrice ??\n null\n const maxCompareAtPrice =\n product.compareAtPriceRange?.maxVariantPrice?.amount ??\n groupRange?.maxCompareAtPrice ??\n null\n\n return {\n minPrice: product.priceRange.minVariantPrice.amount,\n maxPrice: product.priceRange.maxVariantPrice.amount,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange:\n product.priceRange.isPriceRange ??\n product.priceRange.minVariantPrice.amount !==\n product.priceRange.maxVariantPrice.amount,\n }\n }\n\n if (groups.length > 0) {\n return aggregateListingPriceRange(groups)\n }\n\n return {\n minPrice: projectedListing.minPrice,\n maxPrice: projectedListing.maxPrice,\n minCompareAtPrice: projectedListing.minCompareAtPrice,\n maxCompareAtPrice: projectedListing.maxCompareAtPrice,\n isPriceRange: projectedListing.isPriceRange,\n }\n}\n\nfunction aggregateListingPriceRange(\n groups: ProductListingCardSourceItem['groups'],\n): ProductListingCardPriceRange {\n const minPrice = minOfNullable(groups.map((g) => g.listing.minPrice))\n const maxPrice = maxOfNullable(groups.map((g) => g.listing.maxPrice))\n const minCompareAtPrice = minOfNullable(\n groups.map((g) => g.listing.minCompareAtPrice),\n )\n const maxCompareAtPrice = maxOfNullable(\n groups.map((g) => g.listing.maxCompareAtPrice),\n )\n const isPriceRange =\n minPrice !== null && maxPrice !== null && minPrice !== maxPrice\n return {\n minPrice,\n maxPrice,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange,\n }\n}\n\nfunction buildListingSwatch(\n product: ProductListingCardSourceItem['product'],\n group: ProductListingCardSourceItem['groups'][number],\n options: ProductListingCardOptions,\n): ProductListingSwatch {\n return {\n optionId: group.optionId,\n optionValueId: group.optionValueId,\n label: group.optionValueLabel,\n swatch: group.optionValueSwatch ?? null,\n href: buildProductHref(\n { slug: product.slug },\n {\n optionId: group.optionId,\n optionSlug: group.optionSlug,\n optionValueId: group.optionValueId,\n optionValueSlug: group.optionValueSlug,\n listing: group.listing,\n },\n options,\n ),\n availableForSale: group.listing.availableForSale,\n }\n}\n\nfunction minOfNullable(values: Array<number | null>): number | null {\n const numbers = values.filter((v): v is number => v !== null)\n return numbers.length === 0 ? null : Math.min(...numbers)\n}\n\nfunction maxOfNullable(values: Array<number | null>): number | null {\n const numbers = values.filter((v): v is number => v !== null)\n return numbers.length === 0 ? null : Math.max(...numbers)\n}\n\n/**\n * Server-side PLP query preset for raw `products` collection reads.\n *\n * Greenfield storefronts should prefer\n * `client.commerce.product.listingPage()` because it calls the shaped catalog\n * endpoint, preserves pagination metadata, returns card-ready `cards`, and\n * avoids exposing inventory quantities.\n *\n * This preset remains only for server-auth raw product query code\n * that deliberately understands Payload join behavior. It raises top-level\n * `products.options` and `products.variants` join limits, but it cannot fix\n * nested `options[].values.docs` joins because the Payload REST `joins` param\n * is flat.\n *\n * It is not accepted by publishable\n * `createClient().collections.from('products').find()` because browser-public\n * raw reads are constrained to `depth: 0`, `joins: false`, and no `populate`.\n */\nexport const PRODUCT_PLP_FIND_OPTIONS: ApiQueryOptions = {\n joins: {\n variants: { limit: 200, sort: '_order' },\n options: { limit: 50, sort: '_order' },\n },\n}\n\n/**\n * Adapts a raw Payload product document (from\n * `collections.from('products').find()`) into the listing shape the SDK\n * listing builders consume. A raw product already carries `priceRange`,\n * `compareAtPriceRange`, `availableForSale`, and `selectedOrFirstAvailableVariant`,\n * but it has no `featuredImage` field — only the `images` gallery. This pure,\n * non-lossy adapter fills `featuredImage` from the first non-null gallery image\n * (when not already set) so SSG/sitemap consumers on the raw `find()` escape\n * hatch can feed `buildProductListingGroupsByOption` / `buildProductListingCard`\n * without hand-rolling the projection. An explicit `featuredImage` is preserved.\n */\nexport function projectProductToListingShape<\n T extends ProductListingProductShape,\n>(product: T): T & { featuredImage: MediaValue } {\n const featuredImage =\n product.featuredImage != null\n ? product.featuredImage\n : product.images?.find((image) => image != null)\n // Always return a fresh shallow copy so reference semantics are uniform\n // regardless of whether featuredImage was synthesized.\n return { ...product, featuredImage }\n}\n\n/**\n * Builds product-first listing groups for one primary option.\n *\n * The returned groups are intended for product cards with nested swatches or\n * option-value sections. They do not make a product-paginated API response into\n * an expanded-card paginator; one product can still emit several groups.\n */\nexport function buildProductListingGroupsByOption<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(args: {\n product: ProductListingProductShape | null | undefined\n options: ProductOptionShape[]\n variants: TVariant[]\n primaryOptionId?: string | null\n}): ProductListingGroup<TVariant>[] {\n const primaryOptionId = args.primaryOptionId ?? undefined\n if (!primaryOptionId) return []\n\n const matrix = buildProductOptionMatrix({\n options: args.options,\n variants: args.variants,\n })\n const primaryOption = matrix.optionById.get(primaryOptionId)\n if (!primaryOption) return []\n\n return primaryOption.values.flatMap((value) => {\n const variants = matrix.variants\n .filter(\n (variant) =>\n variant.optionValueByOptionId.get(primaryOption.id) === value.id,\n )\n .map((variant) => variant.source)\n\n if (variants.length === 0) {\n return []\n }\n\n const listingBase = buildProductListingGroupProjection(undefined, variants)\n const normalizedSwatch = normalizeMatrixSwatch(value.swatch)\n const swatchMediaId =\n normalizedSwatch?.mediaItemId == null\n ? null\n : String(normalizedSwatch.mediaItemId)\n const groupPrimaryImage =\n inProductMediaPool(args.product, swatchMediaId) ??\n inProductMediaPool(\n args.product,\n getFirstAvailableVariantPrimaryImage(variants),\n ) ??\n getFirstMediaId(args.product?.images)\n\n return [\n {\n optionId: primaryOption.id,\n optionTitle: primaryOption.title,\n optionSlug: primaryOption.slug,\n optionValueId: value.id,\n optionValueLabel: value.label,\n optionValueSlug: value.slug,\n optionValueSwatch: value.swatch ?? null,\n variantIds: variants.map((variant) => String(variant.id)),\n variantCount: variants.length,\n variants,\n listing: {\n ...listingBase,\n primaryImage: groupPrimaryImage,\n },\n },\n ]\n })\n}\n","import { BaseApi, type ServerApiOptions } from './base-api'\nimport { COMMERCE_ENDPOINT_OPERATIONS } from './endpoints'\nimport {\n createValidationError,\n getSDKErrorReason,\n SDKError,\n} from '../internal/errors'\nimport {\n listingGroupsSearchParams,\n listingPageSearchParams,\n productDetailSearchParams,\n stockSnapshotSearchParams,\n} from '../internal/utils/query-string'\nimport type {\n ProductListingCard,\n ProductListingCardOptions,\n ProductListingGroup,\n ProductVariantShape,\n} from '../../utils/ecommerce'\nimport { buildProductListingCard } from '../../utils/ecommerce'\nimport type { PublicProduct } from '../collection/types'\nimport type { PayloadFindResponse } from '../client/types'\nimport type { ProductUpsertInput } from './product-upsert-contract'\n\nexport type ProductApiOptions = ServerApiOptions\n\nexport type StockCheckParams = {\n items: Array<{\n variantId: string\n quantity: number\n }>\n}\n\nexport type StockCheckResult = {\n variantId: string\n status: 'available' | 'not_published' | 'archived' | 'not_found'\n available: boolean\n availableStock: number\n isUnlimited: boolean\n requestedQuantity: number\n error?: string\n}\n\nexport type StockCheckResponse = {\n results: StockCheckResult[]\n allAvailable: boolean\n}\n\nexport type ListingGroupsParams = {\n productIds: string[]\n market?: string\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n}\n\nexport type ProductListingGroupVariant = Pick<\n ProductVariantShape,\n | 'id'\n | 'optionValues'\n | 'price'\n | 'compareAtPrice'\n | 'resolvedPrice'\n | 'stock'\n | 'isUnlimited'\n | 'inventoryPolicy'\n | 'isActive'\n | 'thumbnail'\n | 'images'\n | '_order'\n>\n\nexport type ProductListingGroupSummary =\n ProductListingGroup<ProductListingGroupVariant>\nexport type ProductListingGroupCatalogVariant = Omit<\n ProductListingGroupVariant,\n 'stock'\n>\nexport type ProductListingGroupCatalogSummary =\n ProductListingGroup<ProductListingGroupCatalogVariant>\n\ntype ProductListingGroupsProductVariants = NonNullable<\n PublicProduct['variants']\n>\ntype ProductListingGroupsProductSeo = Omit<\n NonNullable<PublicProduct['seo']>,\n 'title' | 'description' | 'openGraph'\n> & {\n title?: ProductLocalizedText | null\n description?: ProductLocalizedText | null\n openGraph?: Omit<\n NonNullable<NonNullable<PublicProduct['seo']>['openGraph']>,\n 'title' | 'description'\n > & {\n title?: ProductLocalizedText | null\n description?: ProductLocalizedText | null\n }\n}\nexport type ProductListingGroupsProduct = Omit<\n PublicProduct,\n | 'content'\n | 'createdAt'\n | 'description'\n | 'seo'\n | 'subtitle'\n | 'title'\n | 'updatedAt'\n | 'variants'\n> & {\n id: string\n slug: string\n title: ProductLocalizedText\n subtitle?: ProductLocalizedText | null\n description?: ProductLocalizedText | null\n content?: ProductLocalizedValue<NonNullable<PublicProduct['content']>> | null\n seo?: ProductListingGroupsProductSeo\n createdAt?: PublicProduct['createdAt']\n updatedAt?: PublicProduct['updatedAt']\n featuredImage?: ProductDetailMedia | null\n priceRange?: ProductPriceRange\n compareAtPriceRange?: ProductMoneyRange\n availableForSale?: boolean | null\n selectedOrFirstAvailableVariant?:\n | ProductListingGroupVariant\n | string\n | number\n | null\n variants?:\n | (Omit<ProductListingGroupsProductVariants, 'docs'> & {\n docs: ProductListingGroupVariant[]\n })\n | null\n}\n\nexport type ProductListingGroupsCatalogProduct = {\n id: string\n slug: string\n handle?: string | null\n title: ProductLocalizedText\n subtitle?: ProductListingGroupsProduct['subtitle']\n images?: ProductListingGroupsProduct['images']\n featuredImage?: ProductDetailMedia | null\n priceRange?: ProductPriceRange\n compareAtPriceRange?: ProductMoneyRange\n availableForSale?: boolean | null\n selectedOrFirstAvailableVariant?:\n | ProductListingGroupCatalogVariant\n | string\n | number\n | null\n variants?:\n | (Omit<NonNullable<ProductListingGroupsProduct['variants']>, 'docs'> & {\n docs: ProductListingGroupCatalogVariant[]\n })\n | null\n}\n\nexport type ProductListingGroupsItem = {\n product: ProductListingGroupsProduct\n groups: ProductListingGroupSummary[]\n}\nexport type ProductListingGroupsCatalogItem = {\n product: ProductListingGroupsCatalogProduct\n groups: ProductListingGroupCatalogSummary[]\n}\n\nexport type ProductListingGroupsResponse = {\n /**\n * Matching products in the same order as the requested productIds, excluding\n * ids that were not found, not published, or not accessible for the current\n * tenant/key.\n */\n docs: ProductListingGroupsItem[]\n /** Requested productIds that could not be returned. */\n missing: string[]\n}\nexport type ProductListingGroupsCatalogResponse = Omit<\n ProductListingGroupsResponse,\n 'docs'\n> & {\n docs: ProductListingGroupsCatalogItem[]\n}\n\nexport type ProductListingPageSort =\n | 'id'\n | '-id'\n | 'slug'\n | '-slug'\n | 'handle'\n | '-handle'\n | 'createdAt'\n | '-createdAt'\n | 'updatedAt'\n | '-updatedAt'\n | 'title'\n | '-title'\n | 'priceRange.minVariantPrice.amount'\n | '-priceRange.minVariantPrice.amount'\n | 'priceRange.maxVariantPrice.amount'\n | '-priceRange.maxVariantPrice.amount'\n | 'availableForSale'\n | '-availableForSale'\n\nexport type ProductListingPageFilters = {\n ids?: string[]\n slugs?: string[]\n handles?: string[]\n categoryIds?: string[]\n tagIds?: string[]\n price?: {\n min?: number\n max?: number\n }\n availableForSale?: boolean\n}\n\nexport type ProductListingPageBaseParams = {\n market?: string\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n page?: number\n limit?: number\n search?: string\n sort?: ProductListingPageSort | ProductListingPageSort[]\n filters?: ProductListingPageFilters\n} & ProductListingCardOptions\n\nexport type ProductListingPageCatalogParams = ProductListingPageBaseParams & {\n mode?: 'catalog'\n}\n\nexport type ProductListingPageFullParams = ProductListingPageBaseParams & {\n mode: 'full'\n}\n\nexport type ProductListingPageParams =\n | ProductListingPageCatalogParams\n | ProductListingPageFullParams\n\nexport type ProductListingPageResult<TItem> = PayloadFindResponse<TItem> & {\n cards: ProductListingCard[]\n}\n\nexport type ProductLocaleOption = 'ko' | 'en' | 'all'\nexport type ProductFallbackLocaleOption = 'ko' | 'en' | false\n\nexport type ProductLocaleReadParams = {\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n}\n\nexport type ProductLocalizedValue<T> =\n | T\n | {\n en?: T | null\n ko?: T | null\n }\n\nexport type ProductLocalizedText = ProductLocalizedValue<string>\n\nexport type ProductDetailParams = ({ slug: string } | { id: string }) & {\n market?: string\n} & ProductLocaleReadParams\nexport type ProductDetailPreviewParams = { id: string }\nexport type ProductDetailPreviewOptions = {\n previewToken: string\n}\n\nexport interface ProductDetailVariantOptionValue {\n optionId: string | number\n optionSlug: string\n valueId: string | number\n valueSlug: string\n value?: string | null\n}\n\nexport type ProductDetailMedia =\n | string\n | number\n | {\n id?: string | number | null\n url?: string | null\n alt?: string | null\n width?: number | null\n height?: number | null\n }\n\nexport type ProductOptionValueColorSwatch = {\n type: 'color'\n color: string\n mediaItemId?: null\n}\n\nexport type ProductOptionValueMediaSwatch<TMedia = ProductDetailMedia> = {\n type: 'media'\n mediaItemId: TMedia\n color?: null\n}\n\nexport type ProductOptionValueSwatch<TMedia = ProductDetailMedia> =\n | ProductOptionValueColorSwatch\n | ProductOptionValueMediaSwatch<TMedia>\n | null\n\nexport type ProductUpsertColorSwatchInput = {\n type: 'color'\n color: string\n mediaItemId?: null\n}\n\nexport type ProductUpsertMediaSwatchInput = {\n type: 'media'\n mediaItemId: string\n color?: null\n}\n\nexport type ProductUpsertSwatchInput =\n | ProductUpsertColorSwatchInput\n | ProductUpsertMediaSwatchInput\n\nexport type ProductDetailSelectionMediaSource =\n | 'variant_media_selected'\n | 'variant_media_matching'\n | 'option_swatch'\n | 'none'\n\nexport type ProductDetailDisplayMediaSource =\n | 'featured_image'\n | 'product_pool'\n | 'none'\n\n/** Selection + display sources returned by `resolveProductSelection()` media. */\nexport type ProductDetailMediaPointerSource =\n | ProductDetailSelectionMediaSource\n | ProductDetailDisplayMediaSource\n\nexport interface ResolvedCatalogPrice {\n amount: number\n compareAtPrice?: number | null\n currency?: string | null\n marketId?: string | null\n source?: 'fixed' | 'computed'\n}\n\nexport interface ProductDetailVariant {\n id: string | number\n optionKey: string\n title?: string | null\n displayName: string\n sku?: string | null\n price: number\n compareAtPrice?: number | null\n resolvedPrice?: ResolvedCatalogPrice\n stock: number\n reservedStock: number\n isUnlimited: boolean\n inventoryPolicy?: ('deny' | 'continue') | null\n isActive: boolean\n thumbnail?: ProductDetailMedia | null\n images?: ProductDetailMedia[]\n media?: {\n primaryImage: ProductDetailMedia | null\n images: ProductDetailMedia[]\n source: ProductDetailSelectionMediaSource\n }\n optionValues: ProductDetailVariantOptionValue[]\n}\n\nexport interface ProductDetailOptionValue {\n id: string | number\n value: string\n slug: string\n swatch?: ProductOptionValueSwatch<ProductDetailMedia>\n}\n\nexport interface ProductDetailOption {\n id: string | number\n title: string\n slug: string\n values: ProductDetailOptionValue[]\n}\n\nexport interface ProductDetailBrand {\n id: string | number\n name: string\n slug?: string | null\n logo?: unknown | null\n}\n\nexport interface ProductDetailCategory {\n id: string | number\n title: string\n slug?: string | null\n}\n\nexport interface ProductDetailTag {\n id: string | number\n title: string\n slug?: string | null\n}\n\nexport interface ProductDetailImage {\n id: string | number\n url?: string | null\n alt?: string | null\n width?: number | null\n height?: number | null\n}\n\nexport interface ProductDetailVideo {\n id: string | number\n url?: string | null\n}\n\nexport interface ProductMoneyRange {\n minVariantPrice: { amount: number | null }\n maxVariantPrice: { amount: number | null }\n}\n\nexport interface ProductPriceRange extends ProductMoneyRange {\n isPriceRange?: boolean | null\n}\n\nexport type ProductDetailCatalogVariant = Omit<\n ProductDetailVariant,\n 'stock' | 'reservedStock'\n> & {\n availableForSale?: boolean | null\n}\n\nexport interface ProductDetailCatalog {\n product: Omit<ProductDetail['product'], 'totalInventory'>\n variants: ProductDetailCatalogVariant[]\n options: ProductDetail['options']\n brand: ProductDetail['brand']\n categories: ProductDetail['categories']\n tags: ProductDetail['tags']\n images: ProductDetail['images']\n videos: ProductDetail['videos']\n featuredImage?: ProductDetail['featuredImage']\n priceRange?: ProductPriceRange\n compareAtPriceRange?: ProductMoneyRange\n availableForSale?: boolean | null\n selectedOrFirstAvailableVariant?:\n | ProductDetailCatalogVariant\n | string\n | number\n | null\n}\n\nexport type StockSnapshotItemStatus =\n | 'available'\n | 'not_published'\n | 'archived'\n | 'not_found'\n\nexport interface StockSnapshotItem {\n variantId: string\n status: StockSnapshotItemStatus\n availableStock: number\n availableForSale: boolean\n isUnlimited: boolean\n /**\n * Backorder policy for tracked variants (Shopify `inventoryPolicy`).\n * `continue` means the variant stays purchasable past available stock.\n */\n inventoryPolicy?: ('deny' | 'continue') | null\n}\n\nexport interface StockSnapshotResponse {\n snapshots: StockSnapshotItem[]\n}\n\nexport type StockSnapshotParams = {\n variantIds: string[]\n}\n\nexport interface ProductDetail {\n product: {\n id: string | number\n slug: string\n title: ProductLocalizedText\n subtitle?: ProductLocalizedText | null\n description?: ProductLocalizedText | null\n content?: unknown\n publishedAt?: string | null\n status: string\n totalInventory: number | null\n totalVariants: number\n hasUnlimitedVariant: boolean\n hasOnlyDefaultVariant: boolean\n }\n variants: ProductDetailVariant[]\n options: ProductDetailOption[]\n brand: ProductDetailBrand | null\n categories: ProductDetailCategory[]\n tags: ProductDetailTag[]\n images: ProductDetailImage[]\n videos: ProductDetailVideo[]\n /** Shopify-shaped product/card image, resolved from the first product image. */\n featuredImage?: ProductDetailMedia | null\n /** Shopify-shaped product price range derived from active variants. */\n priceRange?: ProductPriceRange\n /** Shopify-shaped compare-at price range derived from active variants. */\n compareAtPriceRange?: ProductMoneyRange\n /** Product-level sellability derived from active variants and inventory. */\n availableForSale?: boolean | null\n /** Default variant for PDP/card selection, equivalent to Shopify selectedOrFirstAvailableVariant. */\n selectedOrFirstAvailableVariant?:\n | ProductDetailVariant\n | string\n | number\n | null\n}\n\nexport type ProductDetailUnavailableReason =\n | 'not_found'\n | 'not_published'\n | 'feature_disabled'\n\nexport type ProductDetailResult =\n | { found: true; product: ProductDetail }\n | { found: false; reason: ProductDetailUnavailableReason }\n\nexport type ProductDetailCatalogResult =\n | { found: true; product: ProductDetailCatalog }\n | { found: false; reason: ProductDetailUnavailableReason }\n\nconst PRODUCT_DETAIL_UNAVAILABLE_REASONS = new Set<string>([\n 'not_found',\n 'not_published',\n 'feature_disabled',\n])\n\nexport function productDetailResultFromError(\n error: unknown,\n): ProductDetailResult | undefined {\n if (!(error instanceof SDKError) || error.status !== 404) return undefined\n\n const reason = getSDKErrorReason(error)\n if (!reason || !PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(reason))\n return undefined\n\n return { found: false, reason: reason as ProductDetailUnavailableReason }\n}\n\ntype ProductListingPageWhere = Record<string, unknown>\nconst MARKET_PRICE_QUERY_UNSUPPORTED_MESSAGE =\n 'Market listing pages do not support base price filters or price sorts.'\nconst BASE_PRICE_RANGE_SORT_FIELDS = new Set([\n 'priceRange.minVariantPrice.amount',\n 'priceRange.maxVariantPrice.amount',\n])\n\nfunction nonEmpty(values: string[] | undefined): string[] | undefined {\n return values?.length ? values : undefined\n}\n\nfunction buildProductListingPageWhere(\n params: ProductListingPageParams,\n): ProductListingPageWhere | undefined {\n const clauses: ProductListingPageWhere[] = []\n const search = params.search?.trim()\n if (search) {\n clauses.push({\n or: [\n { title: { like: search } },\n { slug: { like: search } },\n { handle: { like: search } },\n ],\n })\n }\n\n const filters = params.filters\n const ids = nonEmpty(filters?.ids)\n if (ids) clauses.push({ id: { in: ids } })\n const slugs = nonEmpty(filters?.slugs)\n if (slugs) clauses.push({ slug: { in: slugs } })\n const handles = nonEmpty(filters?.handles)\n if (handles) clauses.push({ handle: { in: handles } })\n const categoryIds = nonEmpty(filters?.categoryIds)\n if (categoryIds) clauses.push({ categories: { in: categoryIds } })\n const tagIds = nonEmpty(filters?.tagIds)\n if (tagIds) clauses.push({ tags: { in: tagIds } })\n\n const minPrice = filters?.price?.min\n if (minPrice != null) {\n clauses.push({\n 'priceRange.maxVariantPrice.amount': { greater_than_equal: minPrice },\n })\n }\n const maxPrice = filters?.price?.max\n if (maxPrice != null) {\n clauses.push({\n 'priceRange.minVariantPrice.amount': { less_than_equal: maxPrice },\n })\n }\n\n if (filters?.availableForSale != null) {\n clauses.push({\n availableForSale: { equals: filters.availableForSale },\n })\n }\n\n if (clauses.length === 0) return undefined\n if (clauses.length === 1) return clauses[0]\n return { and: clauses }\n}\n\nfunction productListingPageUsesBasePriceSort(\n sort: ProductListingPageParams['sort'],\n): boolean {\n const values = Array.isArray(sort) ? sort : sort ? [sort] : []\n return values.some((value) =>\n BASE_PRICE_RANGE_SORT_FIELDS.has(String(value).replace(/^-/, '')),\n )\n}\n\nfunction assertMarketListingPageQuerySupported(\n params: ProductListingPageParams,\n): void {\n if (!params.market?.trim()) return\n const priceFilter = params.filters?.price\n if (\n priceFilter?.min != null ||\n priceFilter?.max != null ||\n productListingPageUsesBasePriceSort(params.sort)\n ) {\n throw new TypeError(MARKET_PRICE_QUERY_UNSUPPORTED_MESSAGE)\n }\n}\n\nexport function buildProductListingPageRequest(\n params: ProductListingPageParams,\n): {\n operation:\n | typeof COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryGet\n | typeof COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryCatalog\n query: string\n} {\n assertMarketListingPageQuerySupported(params)\n const options = {\n market: params.market,\n locale: params.locale,\n fallbackLocale: params.fallbackLocale,\n page: params.page,\n limit: params.limit,\n sort: params.sort,\n where: buildProductListingPageWhere(params),\n }\n\n return {\n operation:\n params.mode === 'full'\n ? COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryGet\n : COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryCatalog,\n query: listingPageSearchParams(options),\n }\n}\n\nexport function withProductListingCards<\n TItem extends ProductListingGroupsCatalogItem,\n>(\n response: PayloadFindResponse<TItem>,\n options: ProductListingCardOptions,\n): ProductListingPageResult<TItem>\nexport function withProductListingCards<TItem extends ProductListingGroupsItem>(\n response: PayloadFindResponse<TItem>,\n options: ProductListingCardOptions,\n): ProductListingPageResult<TItem>\nexport function withProductListingCards<\n TItem extends ProductListingGroupsCatalogItem | ProductListingGroupsItem,\n>(\n response: PayloadFindResponse<TItem>,\n options: ProductListingCardOptions,\n): ProductListingPageResult<TItem> {\n return {\n ...response,\n cards: response.docs.map((item) => buildProductListingCard(item, options)),\n }\n}\n\nexport type ProductUpsertOptionSwatchInput = ProductUpsertSwatchInput\n\nexport type ProductUpsertOptionValueInput = {\n id?: string\n value: string\n slug?: string\n swatch?: ProductUpsertSwatchInput | null\n metadata?: unknown\n}\n\nexport type ProductUpsertOptionValuePayload = ProductUpsertOptionValueInput\n\nfunction rejectLegacyOptionValueSwatchColor(\n value: ProductUpsertOptionValueInput,\n): void {\n if (\n Object.prototype.hasOwnProperty.call(\n value as Record<string, unknown>,\n 'swatchColor',\n )\n ) {\n throw new TypeError(\n 'Product upsert option values no longer accept removed flat \"swatchColor\"; use nested \"swatch\" instead.',\n )\n }\n}\n\nfunction normalizeProductUpsertOptionValue(\n value: ProductUpsertOptionValueInput,\n): ProductUpsertOptionValuePayload {\n rejectLegacyOptionValueSwatchColor(value)\n return value\n}\n\nfunction normalizeProductUpsertParams(\n params: ProductUpsertParams,\n): ProductUpsertInput {\n const options = params.options ?? []\n const variants = params.variants ?? []\n if (!options.length) {\n return { ...params, options, variants } as ProductUpsertInput\n }\n return {\n ...params,\n options: options.map((option) => ({\n ...option,\n values: option.values.map((value) =>\n normalizeProductUpsertOptionValue(value),\n ),\n })),\n variants,\n } as ProductUpsertInput\n}\n\nexport type ProductUpsertOptionInput = {\n id?: string\n title: string\n slug?: string\n values: ProductUpsertOptionValueInput[]\n}\n\nexport type ProductUpsertVariantOptionValue =\n | string\n | {\n valueSlug?: string\n valueId?: string\n value?: string\n }\n\nexport type ProductUpsertVariantInput = {\n id?: string\n optionValues?: Record<string, ProductUpsertVariantOptionValue> | string[]\n sku?: string | null\n title?: string | null\n price: number\n compareAtPrice?: number | null\n stock?: number\n isUnlimited?: boolean\n inventoryPolicy?: 'deny' | 'continue'\n weight?: number | null\n requiresShipping?: boolean\n barcode?: string | null\n externalId?: string | null\n isActive?: boolean\n images?: string[]\n marketPrices?: Array<{\n market: string\n price: number\n compareAtPrice?: number | null\n }>\n metadata?: unknown\n}\n\nexport type ProductUpsertParams = ProductUpsertInput\n\n/** Console `POST /api/products/upsert` field allowlist error reasons. */\nexport const PRODUCT_UPSERT_UNKNOWN_FIELD_REASON = 'unknown_field' as const\nexport const PRODUCT_UPSERT_READONLY_FIELD_REASON =\n 'product_field_readonly' as const\nexport const PRODUCT_GRAPH_CONFLICT_REASON = 'graph_conflict' as const\nexport const PRODUCT_GRAPH_REVISION_REQUIRED_REASON =\n 'graph_revision_required' as const\n\nexport type ProductUpsertFieldValidationErrorReason =\n | typeof PRODUCT_UPSERT_UNKNOWN_FIELD_REASON\n | typeof PRODUCT_UPSERT_READONLY_FIELD_REASON\n\n/** 400 response body when upsert rejects unknown or server-managed product fields. */\nexport type ProductUpsertFieldValidationErrorBody = {\n error: string\n reason: ProductUpsertFieldValidationErrorReason\n field: string\n requestId?: string\n}\n\nexport function isProductUpsertFieldValidationErrorBody(\n value: unknown,\n): value is ProductUpsertFieldValidationErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n const reason = body.reason\n return (\n typeof body.error === 'string' &&\n typeof body.field === 'string' &&\n (reason === PRODUCT_UPSERT_UNKNOWN_FIELD_REASON ||\n reason === PRODUCT_UPSERT_READONLY_FIELD_REASON)\n )\n}\n\nexport type ProductUpsertGraphConflictErrorBody = {\n error: string\n reason: typeof PRODUCT_GRAPH_CONFLICT_REASON\n currentGraphRevision: string\n currentGraphUpdatedAt: string\n requestId?: string\n}\n\nexport function isProductUpsertGraphConflictErrorBody(\n value: unknown,\n): value is ProductUpsertGraphConflictErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n return (\n typeof body.error === 'string' &&\n body.reason === PRODUCT_GRAPH_CONFLICT_REASON &&\n typeof body.currentGraphRevision === 'string' &&\n typeof body.currentGraphUpdatedAt === 'string'\n )\n}\n\nexport type ProductUpsertGraphRevisionRequiredErrorBody = {\n error: string\n reason: typeof PRODUCT_GRAPH_REVISION_REQUIRED_REASON\n requestId?: string\n}\n\nexport function isProductUpsertGraphRevisionRequiredErrorBody(\n value: unknown,\n): value is ProductUpsertGraphRevisionRequiredErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n return (\n typeof body.error === 'string' &&\n body.reason === PRODUCT_GRAPH_REVISION_REQUIRED_REASON\n )\n}\n\nexport type ProductUpsertResponse =\n | { ok: true; product: PublicProduct; productProjectionStale: boolean }\n | {\n ok: false\n failedEntity: 'product' | 'option' | 'option-value' | 'variant'\n failedIndex?: number\n message: string\n }\n\nexport type ProductGraphRevisionParams = {\n productId: string\n locale?: 'ko' | 'en'\n}\n\nexport type ProductGraphRevisionResponse = {\n productId: string\n graphRevision: string\n}\n\nexport type VariantPricesUpdateInput = {\n graphRevision: string\n updates: Array<{ id: string; price: number }>\n}\n\nexport type VariantPricesUpdateParams = ProductGraphRevisionParams &\n VariantPricesUpdateInput\n\nexport type VariantPricesUpdateResponse = {\n ok: true\n productId: string\n updated: number\n deleted: number\n productProjectionStale: boolean\n}\n\nfunction assertPriceOperationObject(\n value: unknown,\n allowed: readonly string[],\n): asserts value is Record<string, unknown> {\n if (\n !value ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n Object.keys(value).some((key) => !allowed.includes(key))\n ) {\n throw createValidationError(\n 'Product price operations accept only their declared fields.',\n )\n }\n}\n\nfunction productGraphQuery(\n params: ProductGraphRevisionParams,\n): URLSearchParams {\n if (\n typeof params.productId !== 'string' ||\n !params.productId.trim() ||\n (params.locale !== undefined &&\n params.locale !== 'ko' &&\n params.locale !== 'en')\n ) {\n throw createValidationError(\n 'Provide a productId and, when specified, a ko or en content locale.',\n )\n }\n return new URLSearchParams(\n params.locale ? { locale: params.locale } : undefined,\n )\n}\n\nexport class ProductApi extends BaseApi {\n constructor(options: ProductApiOptions) {\n super('ProductApi', options)\n }\n\n /** Read a baseline before reviewing values in the same content locale. */\n async graphRevision(\n params: ProductGraphRevisionParams,\n ): Promise<ProductGraphRevisionResponse> {\n assertPriceOperationObject(params, ['productId', 'locale'])\n return this.requestEndpoint<ProductGraphRevisionResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.graphRevision,\n undefined,\n {\n pathParams: { id: params.productId },\n query: productGraphQuery(params),\n },\n )\n }\n\n /** Update existing base prices only; conflicts never trigger a rebase or full upsert. */\n async updateVariantPrices(\n params: VariantPricesUpdateParams,\n ): Promise<VariantPricesUpdateResponse> {\n assertPriceOperationObject(params, [\n 'productId',\n 'locale',\n 'graphRevision',\n 'updates',\n ])\n const query = productGraphQuery(params)\n if (\n typeof params.graphRevision !== 'string' ||\n !params.graphRevision.length ||\n !Array.isArray(params.updates) ||\n params.updates.length < 1 ||\n params.updates.length > 250\n ) {\n throw createValidationError(\n 'Provide graphRevision and between 1 and 250 price updates.',\n )\n }\n const updates = params.updates.map((row) => {\n assertPriceOperationObject(row, ['id', 'price'])\n if (\n typeof row.id !== 'string' ||\n !row.id.trim() ||\n typeof row.price !== 'number' ||\n !Number.isFinite(row.price)\n ) {\n throw createValidationError(\n 'Each price update requires an existing variant id and numeric price.',\n )\n }\n // Amount/currency validation remains server-owned. Never forward other fields.\n return { id: row.id, price: row.price }\n })\n return this.requestEndpoint<VariantPricesUpdateResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.variantsPatch,\n { graphRevision: params.graphRevision, updates },\n { pathParams: { id: params.productId }, query },\n )\n }\n\n /**\n * Check point-in-time stock availability for one or more product variants.\n * Results reflect available stock at the moment of the call and are not guaranteed\n * to remain available by the time an order is placed.\n */\n stockCheck(params: StockCheckParams): Promise<StockCheckResponse> {\n return this.requestEndpoint<StockCheckResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockCheck,\n params,\n )\n }\n\n stockSnapshot(params: StockSnapshotParams): Promise<StockSnapshotResponse> {\n return this.requestEndpoint<StockSnapshotResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockSnapshot,\n undefined,\n { query: stockSnapshotSearchParams(params) },\n )\n }\n\n listingGroups(\n params: ListingGroupsParams,\n ): Promise<ProductListingGroupsResponse> {\n return this.requestEndpoint<ProductListingGroupsResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroups,\n undefined,\n { query: listingGroupsSearchParams(params) },\n )\n }\n\n listingGroupsCatalog(\n params: ListingGroupsParams,\n ): Promise<ProductListingGroupsCatalogResponse> {\n return this.requestEndpoint<ProductListingGroupsCatalogResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,\n undefined,\n { query: listingGroupsSearchParams(params) },\n )\n }\n\n async listingPage(\n params?: ProductListingPageCatalogParams,\n ): Promise<ProductListingPageResult<ProductListingGroupsCatalogItem>>\n async listingPage(\n params: ProductListingPageFullParams,\n ): Promise<ProductListingPageResult<ProductListingGroupsItem>>\n async listingPage(\n params: ProductListingPageParams,\n ): Promise<\n | ProductListingPageResult<ProductListingGroupsCatalogItem>\n | ProductListingPageResult<ProductListingGroupsItem>\n >\n async listingPage(\n params: ProductListingPageParams = {},\n ): Promise<\n | ProductListingPageResult<ProductListingGroupsCatalogItem>\n | ProductListingPageResult<ProductListingGroupsItem>\n > {\n if (params.mode === 'full') {\n const request = buildProductListingPageRequest(params)\n const response = await this.requestEndpoint<\n PayloadFindResponse<ProductListingGroupsItem>\n >(request.operation, undefined, { query: request.query })\n return withProductListingCards(response, params)\n }\n\n const request = buildProductListingPageRequest(params)\n const response = await this.requestEndpoint<\n PayloadFindResponse<ProductListingGroupsCatalogItem>\n >(request.operation, undefined, { query: request.query })\n return withProductListingCards(response, params)\n }\n\n /**\n * Fetch full product detail by slug or id.\n * Returns a discriminated result so storefronts can distinguish missing,\n * unpublished, and feature-disabled products.\n *\n * Only product-detail 404 responses carrying one of those allowlisted reasons\n * are mapped to `{ found: false, reason }`. Unknown or uncoded 404s, plus\n * permission/auth errors such as tenant mismatch, continue to throw typed SDK\n * errors instead of being collapsed into a storefront absence result.\n */\n async detail(params: ProductDetailParams): Promise<ProductDetailResult> {\n try {\n const product = await this.requestEndpoint<ProductDetail>(\n COMMERCE_ENDPOINT_OPERATIONS.products.detail,\n undefined,\n { query: productDetailSearchParams(params) },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult) return notFoundResult\n throw err\n }\n }\n\n async detailCatalog(\n params: ProductDetailParams,\n ): Promise<ProductDetailCatalogResult> {\n try {\n const product = await this.requestEndpoint<ProductDetailCatalog>(\n COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,\n undefined,\n { query: productDetailSearchParams(params) },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult?.found === false) return notFoundResult\n throw err\n }\n }\n\n /**\n * Atomically create or update a product together with its options,\n * option-values, and variants in a single transaction. Mirrors Shopify's\n * `productSet` shape and is the canonical write path for the MCP\n * `product-upsert` tool.\n */\n upsert(params: ProductUpsertParams): Promise<ProductUpsertResponse> {\n return this.requestEndpoint<ProductUpsertResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.upsert,\n normalizeProductUpsertParams(params),\n )\n }\n}\n","import { CartApi } from '../api/cart-api'\nimport { CheckoutApi } from '../api/checkout-api'\nimport { PaymentSessionApi } from '../api/payment-session-api'\nimport { CustomerScopedApi } from '../api/customer-scoped-api'\nimport {\n COMMERCE_ENDPOINT_OPERATIONS,\n type CommerceEndpointDescriptor,\n} from '../api/endpoints'\nimport {\n buildProductListingPageRequest,\n productDetailResultFromError,\n withProductListingCards,\n} from '../api/product-api'\nimport {\n listingGroupsSearchParams,\n productDetailSearchParams,\n stockSnapshotSearchParams,\n} from '../internal/utils/query-string'\nimport type {\n CustomerAuth,\n CustomerOrderListOptions,\n} from '../customer/customer-auth'\nimport type {\n CreateCartParams,\n CreateCartResult,\n AddItemParams,\n UpdateItemParams,\n RemoveItemParams,\n UpdateDiscountCodesParams,\n UpdateCartAttributesParams,\n ClearCartParams,\n RetrieveCartParams,\n CartMergeParams,\n CartMergeResult,\n CartMineResult,\n CartMutationResult,\n PublicCart,\n} from '../api/cart-api'\nimport type {\n StockCheckParams,\n StockCheckResponse,\n StockSnapshotParams,\n StockSnapshotResponse,\n ListingGroupsParams,\n ProductListingGroupsCatalogItem,\n ProductListingGroupsCatalogResponse,\n ProductListingPageCatalogParams,\n ProductListingPageResult,\n ProductDetailParams,\n ProductDetailCatalog,\n ProductDetailCatalogResult,\n} from '../api/product-api'\nimport type {\n ValidateDiscountParams,\n ValidateDiscountResult,\n} from '../api/discount-api'\nimport type {\n CalculateShippingParams,\n CalculateShippingResult,\n} from '../api/shipping-api'\nimport type { PublicOrder } from '../api/order-api'\nimport type {\n CreateCheckoutParams,\n CreateCheckoutResult,\n PublicCheckout,\n RetrieveCheckoutParams,\n} from '../api/checkout-api'\nimport type {\n CancelBrowserPaymentSessionParams,\n CreatePortOnePaymentSessionParams,\n CreatePaymentSessionParams,\n PortOnePublicPaymentSession,\n PublicPaymentSession,\n RetrieveBrowserPaymentSessionParams,\n} from '../api/payment-session-api'\nimport type { PayloadFindResponse } from '../client/types'\n\nclass BrowserCommerceApi extends CustomerScopedApi {\n requestEndpoint<T>(\n endpoint: CommerceEndpointDescriptor,\n body?: unknown,\n options?: {\n query?: string | URLSearchParams\n headers?: Record<string, string>\n },\n ): Promise<T> {\n return super.requestEndpoint<T>(endpoint, body, options)\n }\n}\n\nexport interface CommerceClientOptions {\n publishableKey: string\n apiUrl?: string\n market?: string\n customerToken: () => string | null\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n customerAuth: CustomerAuth\n}\n\nexport class CommerceClient {\n private readonly market?: string\n\n readonly product: {\n stockCheck: (params: StockCheckParams) => Promise<StockCheckResponse>\n stockSnapshot: (\n params: StockSnapshotParams,\n ) => Promise<StockSnapshotResponse>\n listingGroups: (\n params: ListingGroupsParams,\n ) => Promise<ProductListingGroupsCatalogResponse>\n listingGroupsCatalog: (\n params: ListingGroupsParams,\n ) => Promise<ProductListingGroupsCatalogResponse>\n listingPage: {\n (\n params?: ProductListingPageCatalogParams,\n ): Promise<ProductListingPageResult<ProductListingGroupsCatalogItem>>\n }\n detail: (params: ProductDetailParams) => Promise<ProductDetailCatalogResult>\n detailCatalog: (\n params: ProductDetailParams,\n ) => Promise<ProductDetailCatalogResult>\n }\n\n readonly carts: {\n create: (params?: CreateCartParams) => Promise<CreateCartResult>\n retrieve: (params: RetrieveCartParams) => Promise<PublicCart>\n addItem: (params: AddItemParams) => Promise<CartMutationResult>\n updateItem: (params: UpdateItemParams) => Promise<CartMutationResult>\n removeItem: (params: RemoveItemParams) => Promise<CartMutationResult>\n updateDiscountCodes: (\n params: UpdateDiscountCodesParams,\n ) => Promise<CartMutationResult>\n updateAttributes: (\n params: UpdateCartAttributesParams,\n ) => Promise<CartMutationResult>\n clear: (params: ClearCartParams) => Promise<CartMutationResult>\n /**\n * Union/claim a pre-login guest cart into the authenticated customer's cart\n * (customer JWT required). Returns the resolved customer cart's `cartToken`\n * so the caller can persist it and keep operating the cart.\n */\n merge: (params: CartMergeParams) => Promise<CartMergeResult>\n /**\n * Load the authenticated customer's active cart by JWT (no `cartToken`\n * needed). `cart`/`cartToken` are both `null` when there is no active cart.\n */\n mine: () => Promise<CartMineResult>\n }\n\n readonly orders: {\n listMine: (\n options?: CustomerOrderListOptions,\n ) => Promise<PayloadFindResponse<PublicOrder>>\n }\n\n readonly checkouts: {\n create: (params: CreateCheckoutParams) => Promise<CreateCheckoutResult>\n retrieve: (params: RetrieveCheckoutParams) => Promise<PublicCheckout>\n }\n\n readonly paymentSessions: {\n create: (\n params: CreatePaymentSessionParams,\n ) => Promise<PublicPaymentSession>\n createPortOne: (\n params: CreatePortOnePaymentSessionParams,\n ) => Promise<PortOnePublicPaymentSession>\n retrieve: (\n params: RetrieveBrowserPaymentSessionParams,\n ) => Promise<PublicPaymentSession>\n retrievePortOne: (\n params: RetrieveBrowserPaymentSessionParams,\n ) => Promise<PortOnePublicPaymentSession>\n cancel: (\n params: CancelBrowserPaymentSessionParams,\n ) => Promise<PublicPaymentSession>\n cancelPortOne: (\n params: CancelBrowserPaymentSessionParams,\n ) => Promise<PortOnePublicPaymentSession>\n }\n\n readonly discounts: {\n validate: (\n params: ValidateDiscountParams,\n ) => Promise<ValidateDiscountResult>\n }\n\n readonly shipping: {\n calculate: (\n params: CalculateShippingParams,\n ) => Promise<CalculateShippingResult>\n }\n\n constructor(options: CommerceClientOptions) {\n this.market = options.market\n\n const cartApi = new CartApi({\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n const checkoutApi = new CheckoutApi({\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n const paymentSessionApi = new PaymentSessionApi({\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n const api = new BrowserCommerceApi('CommerceClient', {\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n\n this.product = {\n stockCheck: (params) =>\n api.requestEndpoint<StockCheckResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockCheck,\n params,\n ),\n stockSnapshot: (params) =>\n api.requestEndpoint<StockSnapshotResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockSnapshot,\n undefined,\n { query: stockSnapshotSearchParams(params) },\n ),\n listingGroups: (params) =>\n api.requestEndpoint<ProductListingGroupsCatalogResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,\n undefined,\n { query: listingGroupsSearchParams(this.withMarket(params)) },\n ),\n listingGroupsCatalog: (params) =>\n api.requestEndpoint<ProductListingGroupsCatalogResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,\n undefined,\n { query: listingGroupsSearchParams(this.withMarket(params)) },\n ),\n listingPage: async (params = {}) => {\n const catalogParams: ProductListingPageCatalogParams = {\n ...params,\n mode: 'catalog',\n }\n const request = buildProductListingPageRequest(\n this.withMarket(catalogParams),\n )\n const response = await api.requestEndpoint<\n PayloadFindResponse<ProductListingGroupsCatalogItem>\n >(request.operation, undefined, { query: request.query })\n return withProductListingCards(response, this.withMarket(catalogParams))\n },\n detail: async (params) => {\n try {\n const product = await api.requestEndpoint<ProductDetailCatalog>(\n COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,\n undefined,\n { query: productDetailSearchParams(this.withMarket(params)) },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult) return notFoundResult\n throw err\n }\n },\n detailCatalog: async (params) => {\n try {\n const product = await api.requestEndpoint<ProductDetailCatalog>(\n COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,\n undefined,\n { query: productDetailSearchParams(this.withMarket(params)) },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult?.found === false) return notFoundResult\n throw err\n }\n },\n }\n\n this.carts = {\n create: (params) => cartApi.create(this.withMarket(params ?? {})),\n retrieve: cartApi.retrieve.bind(cartApi),\n addItem: cartApi.addItem.bind(cartApi),\n updateItem: cartApi.updateItem.bind(cartApi),\n removeItem: cartApi.removeItem.bind(cartApi),\n updateDiscountCodes: cartApi.updateDiscountCodes.bind(cartApi),\n updateAttributes: cartApi.updateAttributes.bind(cartApi),\n clear: cartApi.clear.bind(cartApi),\n merge: cartApi.merge.bind(cartApi),\n mine: cartApi.mine.bind(cartApi),\n }\n\n this.orders = {\n listMine: (params) => options.customerAuth.getMyOrders(params),\n }\n\n this.checkouts = {\n create: checkoutApi.create.bind(checkoutApi),\n retrieve: checkoutApi.retrieve.bind(checkoutApi),\n }\n\n this.paymentSessions = {\n create: paymentSessionApi.create.bind(paymentSessionApi),\n createPortOne: paymentSessionApi.createPortOne.bind(paymentSessionApi),\n retrieve: (params) => paymentSessionApi.retrieve(params),\n retrievePortOne: (params) => paymentSessionApi.retrievePortOne(params),\n cancel: (params) => paymentSessionApi.cancel(params),\n cancelPortOne: (params) => paymentSessionApi.cancelPortOne(params),\n }\n\n this.discounts = {\n validate: (params) =>\n api.requestEndpoint<ValidateDiscountResult>(\n COMMERCE_ENDPOINT_OPERATIONS.discounts.validate,\n params,\n ),\n }\n\n this.shipping = {\n calculate: (params) =>\n api.requestEndpoint<CalculateShippingResult>(\n COMMERCE_ENDPOINT_OPERATIONS.shippingPolicies.calculate,\n params,\n ),\n }\n }\n\n getDefaultMarket(): string | undefined {\n return this.market\n }\n\n private withMarket<T extends { market?: string }>(params: T): T {\n const defaultMarket = this.market?.trim()\n if (!defaultMarket || params.market?.trim()) return params\n return { ...params, market: defaultMarket }\n }\n}\n","import { parseApiResponse } from '../api/parse-response'\nimport { SDKError } from '../internal/errors'\nimport { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\nimport {\n EVENTS_ENDPOINT_OPERATIONS,\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\n\nexport interface EventsClientOptions {\n publishableKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport type EventsDateParam = string | Date\n\nexport interface EventsRangeParams {\n start?: EventsDateParam\n end?: EventsDateParam\n limit?: number\n page?: number\n calendar?: string\n calendarSlug?: string\n category?: string | string[]\n categorySlug?: string | string[]\n tag?: string | string[]\n tagSlug?: string | string[]\n}\n\nexport interface EventsTaxonomyItem {\n id: string | number\n title?: string | null\n slug?: string | null\n description?: string | null\n color?: string | null\n}\n\nexport interface EventsCalendarItem extends EventsTaxonomyItem {\n timezone?: string | null\n visibility?: string | null\n}\n\nexport interface EventsLocation {\n type?: string | null\n name?: string | null\n address?: string | null\n onlineUrl?: string | null\n onlineNote?: string | null\n}\n\nexport interface EventsOccurrenceLocation {\n name?: string | null\n address?: string | null\n onlineUrl?: string | null\n note?: string | null\n}\n\nexport interface EventsExternalSource {\n provider?: string | null\n url?: string | null\n}\n\nexport interface EventsRangeEvent {\n id: string | number\n title?: string | null\n slug?: string | null\n description?: string | null\n startsAt?: string | null\n endsAt?: string | null\n timezone?: string | null\n isAllDay: boolean\n allDayStartDate?: string | null\n allDayEndDateExclusive?: string | null\n visibility?: string | null\n sourceType?: string | null\n registrationPolicy?: string | null\n externalRegistrationUrl?: string | null\n externalSource: EventsExternalSource | null\n location: EventsLocation | null\n calendar: EventsCalendarItem\n categories: EventsTaxonomyItem[]\n tags: EventsTaxonomyItem[]\n}\n\nexport interface EventsRangeOccurrence {\n id: string | number\n instanceKey?: string | null\n startsAt?: string | null\n endsAt?: string | null\n timezone?: string | null\n isAllDay: boolean\n allDayStartDate?: string | null\n allDayEndDateExclusive?: string | null\n status?: string | null\n capacity?: number\n registrationCount?: number\n waitlistCount?: number\n locationOverride: EventsOccurrenceLocation | null\n event: EventsRangeEvent\n}\n\nexport interface EventsRangeResponse {\n range: {\n start: string\n end: string\n }\n docs: EventsRangeOccurrence[]\n calendar: EventsCalendarItem | null\n events: EventsRangeEvent[]\n categories: EventsTaxonomyItem[]\n tags: EventsTaxonomyItem[]\n totalDocs: number\n limit: number\n page: number\n totalPages: number\n hasNextPage: boolean\n hasPrevPage: boolean\n}\n\nexport interface EventAdmissionAvailabilityParams {\n occurrence: string\n /** Active market handle or id; omitted uses the tenant's default market. */\n market?: string\n}\n\nexport interface EventAdmissionPricePresentment {\n amount: number\n compareAtPrice: number | null\n currency: string | null\n marketId: string | null\n}\n\nexport interface EventAdmissionAvailabilityType {\n id: string | number\n label?: string | null\n description?: string | null\n eventId: string | number\n occurrenceId: string | number\n productId: string | number | null\n variantId: string | number | null\n price: EventAdmissionPricePresentment | null\n remainingCapacityHint: number | null\n available: boolean\n}\n\nexport interface EventAdmissionAvailabilityResponse {\n occurrenceId: string | number\n eventId: string | number\n remainingCapacityHint: number | null\n admissionTypes: EventAdmissionAvailabilityType[]\n}\n\nexport interface EventRegistrationAttendeeInput {\n name?: string\n email?: string\n phone?: string\n}\n\nexport interface EventRegistrationAnswerInput {\n question: string\n answer?: string\n}\n\nexport interface EventRegistrationRegisterParams {\n event: string\n occurrence: string\n quantity?: number\n attendee?: EventRegistrationAttendeeInput\n answers?: EventRegistrationAnswerInput[]\n}\n\nexport interface EventRegistrationPublic {\n id?: string | number\n event?: unknown\n occurrence?: unknown\n registrationStatus?: string | null\n attendanceStatus?: string | null\n quantity?: number | null\n guestTokenExpiresAt?: string | null\n}\n\nexport interface EventGuestRegistration extends EventRegistrationPublic {\n attendee: {\n name: string | null\n email: string | null\n phone: string | null\n } | null\n attendeeEmail: string | null\n answers: Array<{ question: string; answer?: string }>\n}\n\nexport interface EventRegistrationRegisterResponse {\n registration: EventRegistrationPublic\n guestToken: string\n guestTokenExpiresAt: string\n}\n\nexport interface EventGuestRegistrationResponse {\n registration: EventGuestRegistration\n}\n\nexport interface EventMyRegistrationsParams {\n page?: number\n limit?: number\n}\n\nexport interface EventMyRegistration {\n id: string\n event: { id: string | null; title: string | null }\n occurrence: {\n id: string | null\n startsAt: string | null\n endsAt: string | null\n timezone: string | null\n isAllDay: boolean | null\n allDayStartDate: string | null\n allDayEndDateExclusive: string | null\n }\n registrationStatus: string | null\n attendanceStatus: string | null\n quantity: number | null\n createdAt: string | null\n}\n\nexport interface EventMyRegistrationsResponse {\n docs: EventMyRegistration[]\n totalDocs: number\n limit: number\n page: number\n totalPages: number\n hasNextPage: boolean\n hasPrevPage: boolean\n}\n\nexport interface EventGuestCancelParams {\n reason?: string\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\n\nexport class EventsClient {\n private readonly publishableKey: string\n private readonly apiUrl?: string\n private readonly customerToken?: string | (() => string | null)\n private readonly onUnauthorized?: () => Promise<string | null>\n private readonly onRequestId?: (id: string | null) => void\n\n constructor(options: EventsClientOptions) {\n const secretKey = (options as { secretKey?: string }).secretKey\n this.publishableKey = requirePublishableKeyForSecret(\n 'EventsClient',\n options.publishableKey,\n secretKey,\n )\n this.apiUrl = options.apiUrl\n this.customerToken = options.customerToken\n this.onUnauthorized = options.onUnauthorized\n this.onRequestId = options.onRequestId\n }\n\n getRange(params: EventsRangeParams): Promise<EventsRangeResponse> {\n return this.execute<EventsRangeResponse>(\n buildRangeEndpoint(params),\n resolveOperationMethod(EVENTS_ENDPOINT_OPERATIONS.occurrences.range),\n undefined,\n { useCustomerAuth: false },\n )\n }\n\n getAdmissionAvailability(\n params: EventAdmissionAvailabilityParams,\n ): Promise<EventAdmissionAvailabilityResponse> {\n return this.execute<EventAdmissionAvailabilityResponse>(\n buildAdmissionAvailabilityEndpoint(params),\n resolveOperationMethod(\n EVENTS_ENDPOINT_OPERATIONS.occurrences.admissionAvailability,\n ),\n undefined,\n { useCustomerAuth: false },\n )\n }\n\n listMyRegistrations(\n params: EventMyRegistrationsParams = {},\n ): Promise<EventMyRegistrationsResponse> {\n const query = new URLSearchParams()\n if (params.page !== undefined) query.set('page', String(params.page))\n if (params.limit !== undefined) query.set('limit', String(params.limit))\n const operation = EVENTS_ENDPOINT_OPERATIONS.registrations.listMine\n return this.execute<EventMyRegistrationsResponse>(\n resolveOperationPath(operation, { query }),\n resolveOperationMethod(operation),\n undefined,\n { useCustomerAuth: true, noStore: true },\n )\n }\n\n register(\n params: EventRegistrationRegisterParams,\n ): Promise<EventRegistrationRegisterResponse> {\n return this.execute<EventRegistrationRegisterResponse>(\n resolveOperationPath(EVENTS_ENDPOINT_OPERATIONS.registrations.register),\n resolveOperationMethod(EVENTS_ENDPOINT_OPERATIONS.registrations.register),\n buildRegistrationRequestBody(params),\n { useCustomerAuth: true },\n )\n }\n\n getGuestRegistration(token: string): Promise<EventGuestRegistrationResponse> {\n return this.execute<EventGuestRegistrationResponse>(\n resolveOperationPath(\n EVENTS_ENDPOINT_OPERATIONS.registrations.guestLookup,\n ),\n resolveOperationMethod(\n EVENTS_ENDPOINT_OPERATIONS.registrations.guestLookup,\n ),\n { token },\n { useCustomerAuth: false },\n )\n }\n\n cancelGuestRegistration(\n token: string,\n params: EventGuestCancelParams = {},\n ): Promise<EventGuestRegistrationResponse> {\n return this.execute<EventGuestRegistrationResponse>(\n resolveOperationPath(\n EVENTS_ENDPOINT_OPERATIONS.registrations.guestCancel,\n ),\n resolveOperationMethod(\n EVENTS_ENDPOINT_OPERATIONS.registrations.guestCancel,\n ),\n buildGuestCancelRequestBody(token, params),\n { useCustomerAuth: false },\n )\n }\n\n private async execute<T>(\n endpoint: string,\n method: HttpMethod,\n body?: unknown,\n options: { useCustomerAuth?: boolean; noStore?: boolean } = {},\n ): Promise<T> {\n const useCustomerAuth = options.useCustomerAuth === true\n const token = useCustomerAuth\n ? typeof this.customerToken === 'function'\n ? this.customerToken()\n : this.customerToken\n : undefined\n\n try {\n const response = await httpFetch(endpoint, {\n method,\n ...(options.noStore && { cache: 'no-store' as const }),\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n ...(useCustomerAuth && token ? { customerToken: token } : {}),\n ...(useCustomerAuth &&\n token &&\n this.onUnauthorized && { onUnauthorized: this.onUnauthorized }),\n ...(body !== undefined && { body: JSON.stringify(body) }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n}\n\nfunction buildRegistrationRequestBody(\n params: EventRegistrationRegisterParams,\n): EventRegistrationRegisterParams {\n return {\n event: params.event,\n occurrence: params.occurrence,\n ...(params.quantity !== undefined && { quantity: params.quantity }),\n ...(params.attendee !== undefined && { attendee: params.attendee }),\n ...(params.answers !== undefined && { answers: params.answers }),\n }\n}\n\nfunction buildGuestCancelRequestBody(\n token: string,\n params: EventGuestCancelParams,\n): { token: string; reason?: string } {\n return {\n token,\n ...(params.reason !== undefined && { reason: params.reason }),\n }\n}\n\nfunction buildRangeEndpoint(params: EventsRangeParams): string {\n const urlParams = new URLSearchParams()\n if (params.start !== undefined) {\n urlParams.set('start', formatDateParam(params.start))\n }\n if (params.end !== undefined) {\n urlParams.set('end', formatDateParam(params.end))\n }\n if (params.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params.page !== undefined) urlParams.set('page', String(params.page))\n appendValues(urlParams, 'calendar', params.calendar)\n appendValues(urlParams, 'calendarSlug', params.calendarSlug)\n appendValues(urlParams, 'category', params.category)\n appendValues(urlParams, 'categorySlug', params.categorySlug)\n appendValues(urlParams, 'tag', params.tag)\n appendValues(urlParams, 'tagSlug', params.tagSlug)\n return resolveOperationPath(EVENTS_ENDPOINT_OPERATIONS.occurrences.range, {\n query: urlParams,\n })\n}\n\nfunction buildAdmissionAvailabilityEndpoint(\n params: EventAdmissionAvailabilityParams,\n): string {\n const urlParams = new URLSearchParams()\n urlParams.set('occurrence', params.occurrence)\n const normalizedMarket = params.market?.trim()\n if (normalizedMarket) urlParams.set('market', normalizedMarket)\n return resolveOperationPath(\n EVENTS_ENDPOINT_OPERATIONS.occurrences.admissionAvailability,\n { query: urlParams },\n )\n}\n\nfunction formatDateParam(value: EventsDateParam): string {\n return value instanceof Date ? value.toISOString() : value\n}\n\nfunction appendValues(\n params: URLSearchParams,\n key: string,\n value: string | string[] | undefined,\n): void {\n if (value === undefined) return\n const values = Array.isArray(value) ? value : [value]\n for (const entry of values) {\n if (entry) params.append(key, entry)\n }\n}\n","import type { PublicMarket } from '../collection/types'\nimport type { PayloadFindResponse, Where } from '../client/types'\n\n/**\n * Client-safe market discovery shape (Shopify-like). Structural copy of the\n * private contracts package's `PublicMarketDTO` — the public SDK must not import\n * private contracts, so a parity `test-d` keeps the two in lockstep. The\n * `toMarketDTO` return annotation ties this shape back to the real `PublicMarket`\n * row (which the parity test alone cannot check).\n */\nexport type MarketDTO = {\n id: string\n handle: string\n name: string\n countryCode: string\n targetCountries: string[]\n currency: string\n isPrimary: boolean\n isActive: boolean\n}\n\n/**\n * Minimal reader the discovery helper depends on: the shape of\n * `collections.from('markets').find`. Kept narrow so the helper is\n * transport-agnostic and unit-testable against a mock.\n */\nexport type MarketRowReader = (options: {\n where: Where\n limit: number\n}) => Promise<PayloadFindResponse<PublicMarket>>\n\n/**\n * Allow-list mapper: selects only stable, client-safe fields, so server-only\n * fields (FX/adjustment/rounding/metadata) and `tenant`/timestamps are dropped\n * even when a secret-key read returns them. The explicit `: MarketDTO` return\n * annotation is the source-of-truth tie to the generated row shape.\n */\nexport function toMarketDTO(row: PublicMarket): MarketDTO {\n return {\n id: row.id,\n handle: row.handle,\n name: row.name,\n countryCode: row.countryCode,\n targetCountries: (row.targetCountries ?? []).map((c) => c.countryCode),\n currency: row.currency,\n isPrimary: row.isPrimary === true,\n isActive: row.isActive === true,\n }\n}\n\nexport interface MarketDiscoveryClient {\n /** List the tenant's active buyer markets. */\n list(): Promise<MarketDTO[]>\n /** Resolve the tenant's default (active primary) market, or `null`. */\n default(): Promise<MarketDTO | null>\n}\n\n/** Read-side helper for public market discovery. */\nexport class MarketDiscovery implements MarketDiscoveryClient {\n constructor(private readonly read: MarketRowReader) {}\n\n async list(): Promise<MarketDTO[]> {\n const res = await this.read({\n where: { isActive: { equals: true } },\n limit: 100,\n })\n if (res.hasNextPage) {\n console.warn(\n '[markets.list] more than 100 active markets; results truncated to 100.',\n )\n }\n return res.docs.map(toMarketDTO)\n }\n\n async default(): Promise<MarketDTO | null> {\n const res = await this.read({\n where: { isPrimary: { equals: true }, isActive: { equals: true } },\n limit: 1,\n })\n const row = res.docs[0]\n return row ? toMarketDTO(row) : null\n }\n}\n","import { CustomerBenefitVouchersApi } from '../api/customer-benefit-vouchers-api'\nimport { CustomerCreditsApi } from '../api/customer-credits-api'\nimport { ReadOnlyCollectionClient } from '../collection/collection-client'\nimport { CommunityClient } from '../community/community-client'\nimport { ContentClient } from '../content/content-client'\nimport { CustomerNamespace } from '../customer/customer-namespace'\nimport { CommerceClient } from '../commerce/commerce-client'\nimport { EventsClient } from '../events/events-client'\nimport { MarketDiscovery } from '../market/market-discovery'\nimport { CustomerScopedApi } from '../api/customer-scoped-api'\nimport { createConfigError } from '../internal/errors'\nimport { MEMBERSHIP_ENDPOINT_OPERATIONS } from '../api/endpoints'\nimport type {\n CancelMembershipParams,\n CancelMembershipResponse,\n CustomerMembershipView,\n} from '../api/membership-types'\nimport {\n type ClientConfig,\n type ClientState,\n type ClientMetadata,\n} from './types'\n\nclass BrowserMembershipApi extends CustomerScopedApi {\n me(): Promise<CustomerMembershipView | null> {\n return this.requestEndpoint<CustomerMembershipView | null>(\n MEMBERSHIP_ENDPOINT_OPERATIONS.me,\n )\n }\n\n cancel(params: CancelMembershipParams): Promise<CancelMembershipResponse> {\n const { id, immediate } = params\n return this.requestEndpoint<CancelMembershipResponse>(\n MEMBERSHIP_ENDPOINT_OPERATIONS.cancel,\n immediate !== undefined ? { immediate } : {},\n { pathParams: { id } },\n )\n }\n}\n\nexport default class Client {\n credits: Pick<CustomerCreditsApi, 'mine' | 'history'>\n benefitVouchers: Pick<CustomerBenefitVouchersApi, 'listMine'>\n commerce: CommerceClient\n community: CommunityClient\n content: ContentClient\n events: EventsClient\n customer: CustomerNamespace\n collections: ReadOnlyCollectionClient\n markets: MarketDiscovery\n memberships: {\n me: () => Promise<CustomerMembershipView | null>\n cancel: (\n params: CancelMembershipParams,\n ) => Promise<CancelMembershipResponse>\n }\n\n lastRequestId: string | null = null\n\n protected state: ClientState\n protected config: ClientConfig\n\n constructor(options: ClientConfig) {\n const publishableKey = options.publishableKey\n if (!publishableKey) {\n throw createConfigError('publishableKey is required.')\n }\n\n this.config = { ...options, publishableKey }\n\n const metadata: ClientMetadata = {\n timestamp: Date.now(),\n userAgent:\n typeof window !== 'undefined' ? window.navigator?.userAgent : 'Node.js',\n }\n\n this.state = { metadata }\n\n this.customer = new CustomerNamespace(\n this.config.publishableKey,\n options.customer,\n this.config.apiUrl,\n )\n\n const onUnauthorized = async (): Promise<string | null> => {\n try {\n const result = await this.customer.auth.refreshToken()\n return result.token ?? null\n } catch {\n return null\n }\n }\n\n const onRequestId = (id: string | null) => {\n this.lastRequestId = id\n }\n\n this.commerce = new CommerceClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n market: this.config.market,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n customerAuth: this.customer.auth,\n })\n\n this.community = new CommunityClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.content = new ContentClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n onRequestId,\n })\n\n this.events = new EventsClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.collections = new ReadOnlyCollectionClient(\n this.config.publishableKey,\n undefined,\n () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n this.config.apiUrl,\n )\n\n this.markets = new MarketDiscovery((options) =>\n this.collections.from('markets').find(options),\n )\n\n this.credits = new CustomerCreditsApi('CustomerCreditsApi', {\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.benefitVouchers = new CustomerBenefitVouchersApi(\n 'CustomerBenefitVouchersApi',\n {\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n },\n )\n\n const membershipApi = new BrowserMembershipApi('MembershipApi', {\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n this.memberships = {\n me: membershipApi.me.bind(membershipApi),\n cancel: membershipApi.cancel.bind(membershipApi),\n }\n }\n\n getState(): ClientState {\n return { ...this.state }\n }\n\n withMarket(market: string): Client {\n return new Client({\n ...this.config,\n customer:\n this.config.customer?.persist === false\n ? {\n ...this.config.customer,\n token: this.customer.auth.getToken() ?? undefined,\n refreshToken: this.customer.auth.getRefreshToken() ?? undefined,\n }\n : this.config.customer,\n market,\n })\n }\n\n getConfig(): ClientConfig {\n return { ...this.config }\n }\n}\n\n/**\n * Create an SDK client. Works in both browser and server environments.\n * Read-only collection queries + customer auth (cart, login, profile).\n * Use the server subpath when you need full CRUD with server credentials.\n */\nexport function createClient(options: ClientConfig): Client {\n return new Client(options)\n}\n","import type {\n ProductDetail,\n ProductDetailCatalog,\n ProductDetailVariant,\n} from '../api/product-api'\nimport type { StockSnapshotResponse } from '../api/product-api'\n\nexport type ProductDetailStockMergeStatus = 'complete' | 'partial'\n\nexport interface MergedProductDetailResult {\n stockMergeStatus: ProductDetailStockMergeStatus\n product: ProductDetail\n}\n\nexport function mergeProductDetailWithStock(\n catalog: ProductDetailCatalog,\n snapshot: StockSnapshotResponse,\n): MergedProductDetailResult {\n const snapshotByVariantId = new Map(\n snapshot.snapshots.map((item) => [item.variantId, item]),\n )\n\n let missingSnapshotCount = 0\n const variants: ProductDetailVariant[] = catalog.variants.map((variant) => {\n const snap = snapshotByVariantId.get(String(variant.id))\n if (!snap) {\n missingSnapshotCount += 1\n return { ...variant, stock: 0, reservedStock: 0 }\n }\n\n return {\n ...variant,\n stock: snap.isUnlimited ? 0 : snap.availableStock,\n reservedStock: 0,\n }\n })\n\n const trackedVariants = variants.filter((variant) => !variant.isUnlimited)\n const totalInventory =\n trackedVariants.length === 0\n ? null\n : trackedVariants.reduce(\n (sum, variant) =>\n sum + Math.max(0, (variant.stock ?? 0) - (variant.reservedStock ?? 0)),\n 0,\n )\n\n const availableForSale = snapshot.snapshots.some(\n (item) => item.status === 'available' && item.availableForSale,\n )\n const selectedVariantId =\n typeof catalog.selectedOrFirstAvailableVariant === 'object' &&\n catalog.selectedOrFirstAvailableVariant !== null\n ? String(catalog.selectedOrFirstAvailableVariant.id)\n : catalog.selectedOrFirstAvailableVariant != null\n ? String(catalog.selectedOrFirstAvailableVariant)\n : null\n const selectedOrFirstAvailableVariant =\n selectedVariantId != null\n ? (variants.find((variant) => String(variant.id) === selectedVariantId) ??\n selectedVariantId)\n : null\n\n return {\n stockMergeStatus: missingSnapshotCount === 0 ? 'complete' : 'partial',\n product: {\n ...catalog,\n product: { ...catalog.product, totalInventory },\n variants,\n availableForSale,\n selectedOrFirstAvailableVariant,\n },\n }\n}\n","export function isValidWebhookEventData(data: unknown): boolean {\n if (typeof data !== 'object' || data === null) return false\n const event = data as Record<string, unknown>\n return (\n typeof event.collection === 'string' &&\n typeof event.operation === 'string' &&\n event.operation.length > 0 &&\n typeof event.data === 'object' &&\n event.data !== null\n )\n}\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\nimport type { WebhookEvent, WebhookHandler } from './index'\nimport { isValidWebhookEventData } from './validation'\n\nexport interface SignedWebhookOptions {\n /** Nonblank HMAC-SHA256 signing secret for this receiver. */\n secret: string\n /**\n * Max accepted skew for signed webhook delivery timestamps. Default: 300s.\n * Must be a number between 0 and 86400 inclusive; anything else is a\n * configuration error, because an unbounded or effectively unbounded window\n * would accept an arbitrarily old replay.\n */\n toleranceSeconds?: number\n}\n\nasync function verifySignature(\n rawBody: Uint8Array,\n secret: string,\n signature: string,\n timestamp: string,\n deliveryId: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const signedPrefix = encoder.encode(`${timestamp}.${deliveryId}.`)\n const signedPayload = new Uint8Array(signedPrefix.length + rawBody.length)\n signedPayload.set(signedPrefix)\n signedPayload.set(rawBody, signedPrefix.length)\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['verify'],\n )\n if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {\n return false\n }\n const sigBytes = new Uint8Array(\n (signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16)),\n )\n return crypto.subtle.verify('HMAC', key, sigBytes, signedPayload)\n}\n\nfunction timestampIsFresh(\n timestamp: string,\n toleranceSeconds: number,\n): boolean {\n if (!/^\\d+$/.test(timestamp)) return false\n const timestampMs = Number(timestamp)\n if (!Number.isFinite(timestampMs)) return false\n const skewMs = Math.abs(Date.now() - timestampMs)\n return skewMs <= toleranceSeconds * 1000\n}\n\n/**\n * Upper bound for the signed replay window. A merely finite tolerance is not\n * enough: `Number.MAX_VALUE * 1000` overflows to `Infinity`, and even without\n * overflow a value of that size accepts an arbitrarily old capture. The sender's\n * retry and dead-letter lifecycle completes far inside a day, so anything beyond\n * this is a misconfiguration rather than clock-skew tolerance.\n */\nconst MAX_TOLERANCE_SECONDS = 86_400\n\n/**\n * A signed receiver's replay window must stay bounded. A non-finite, negative,\n * or over-bound tolerance would silently accept an old capture, so it is a\n * configuration error rather than a request-authentication failure.\n */\nfunction toleranceIsValid(\n toleranceSeconds: unknown,\n): toleranceSeconds is number {\n return (\n typeof toleranceSeconds === 'number' &&\n Number.isFinite(toleranceSeconds) &&\n toleranceSeconds >= 0 &&\n toleranceSeconds <= MAX_TOLERANCE_SECONDS\n )\n}\n\nasync function processWebhookRequest<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n verify?: (rawBody: Uint8Array) => Promise<Response | undefined>,\n): Promise<Response> {\n try {\n const rawBody = new Uint8Array(await request.arrayBuffer())\n const verificationFailure = await verify?.(rawBody)\n if (verificationFailure) return verificationFailure\n\n const body = JSON.parse(new TextDecoder().decode(rawBody))\n if (!isValidWebhookEventData(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T, TData>)\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n return new Response(JSON.stringify({ error: 'Internal server error' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n\nexport async function handleSignedWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n options: SignedWebhookOptions,\n): Promise<Response> {\n // Read each configuration value exactly once. Re-reading `options` would let\n // a getter return a valid secret to the guard and a different one to the\n // verifier, so the validated bytes are the only bytes this receiver uses.\n const secret: unknown = options?.secret\n const configuredTolerance: unknown = options?.toleranceSeconds\n // `??` so an absent or null tolerance keeps the documented default, exactly as\n // before this change; only a present, out-of-contract value is rejected.\n const toleranceSeconds = configuredTolerance ?? 300\n\n if (typeof secret !== 'string' || secret.trim().length === 0) {\n return new Response(\n JSON.stringify({ error: 'Webhook signing secret is not configured' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n // Reported separately so a tolerance mistake is not misdiagnosed as a bad secret.\n if (!toleranceIsValid(toleranceSeconds)) {\n return new Response(\n JSON.stringify({ error: 'Webhook signature tolerance is not valid' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n return processWebhookRequest(request, handler, async (rawBody) => {\n const signature = request.headers.get('x-webhook-signature') || ''\n const timestamp = request.headers.get('x-webhook-timestamp') || ''\n const deliveryId = request.headers.get('x-webhook-delivery-id') || ''\n const valid =\n Boolean(timestamp && deliveryId) &&\n timestampIsFresh(timestamp, toleranceSeconds) &&\n (await verifySignature(rawBody, secret, signature, timestamp, deliveryId))\n\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n })\n}\n\n/** Process a webhook only when its endpoint is intentionally unsigned. */\nexport async function handleUnsignedWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(request: Request, handler: WebhookHandler<T, TData>): Promise<Response> {\n return processWebhookRequest(request, handler)\n}\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\nimport { handleSignedWebhook as handleSignedWebhookInternal } from './receiver'\nimport { isValidWebhookEventData } from './validation'\n\nexport type WebhookOperation = string\n\n/**\n * Semantic event type for manual Admin Panel ordering changes.\n *\n * Order-change webhooks remain `operation: \"update\"` events for compatibility.\n * Do not filter on or emit `operation: \"reorder\"`; use this event type with\n * `isOrderChangedWebhookEvent()` to distinguish ordering from normal content\n * updates.\n */\nexport const ORDER_CHANGED_EVENT_TYPE = 'collection.orderChanged' as const\n\n/** Semantic event type for v1 commerce notification webhooks. */\nexport const COMMERCE_NOTIFICATION_EVENT_TYPE = 'commerce.notification' as const\n\n/** Collection webhook operations emitted for tenant collection writes. */\nexport type CollectionWebhookOperation = 'create' | 'update'\n\n/** Describes the ordered area affected by an order-change webhook. */\nexport type WebhookOrderScope =\n | { kind: 'collection'; collection: string }\n | { kind: 'join'; collection: string; field: string; id: string | number }\n\n/** Identifies the public moved document for the ordered scope. */\nexport type WebhookOrderMoved = {\n collection: string\n id: string | number\n relatedCollection?: string\n relatedId?: string | number\n}\n\n/** Metadata attached to `collection.orderChanged` webhook events. */\nexport type WebhookOrderChange = {\n type: 'order'\n source: 'payload-orderable'\n /**\n * Diagnostic Payload order field name.\n *\n * This may contain hidden implementation field names. Application routing\n * should use `change.scope` and `change.moved` instead.\n */\n orderableFieldName?: string\n previousOrder?: string | null\n nextOrder?: string | null\n scope: WebhookOrderScope\n moved: WebhookOrderMoved\n}\n\n/** Known semantic webhook change metadata. */\nexport type WebhookChange =\n | WebhookOrderChange\n | WebhookCommerceNotificationChange\n\nexport interface WebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> {\n collection: T\n operation: WebhookOperation\n data: TData\n eventType?: string\n change?: unknown\n timestamp?: string\n deliveryId?: string\n}\n\nexport type WebhookHandler<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = (event: WebhookEvent<T, TData>) => Promise<void> | void\n\n/** @deprecated Use the signed receiver options from `@01.software/sdk/webhook`. */\nexport interface WebhookOptions {\n /** Nonblank HMAC-SHA256 signing secret for this receiver. */\n secret: string\n /** Max accepted skew for signed webhook delivery timestamps. Default: 300s. */\n toleranceSeconds?: number\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n return isValidWebhookEventData(data)\n}\n\n/** Webhook event emitted when manual Admin Panel ordering changes. */\nexport type OrderChangedWebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = WebhookEvent<T, TData> & {\n operation: 'update'\n eventType: typeof ORDER_CHANGED_EVENT_TYPE\n change: WebhookOrderChange\n}\n\nexport const COMMERCE_NOTIFICATION_OPERATION = 'notification' as const\n\nexport const COMMERCE_NOTIFICATION_EVENTS = [\n 'orderPaid',\n 'orderCanceled',\n 'fulfillmentShipped',\n 'orderDelivered',\n 'returnRequested',\n 'returnApproved',\n 'returnRejected',\n 'returnCanceled',\n 'returnCompleted',\n 'paymentReconciliationRequired',\n 'paymentRefundRequiresAttention',\n 'membershipActivated',\n 'membershipPastDue',\n 'membershipExpired',\n 'membershipCancelled',\n] as const\n\nexport type CommerceNotificationEventName =\n (typeof COMMERCE_NOTIFICATION_EVENTS)[number]\n\nexport type CustomerCommerceNotificationEventName = Exclude<\n CommerceNotificationEventName,\n PaymentIncidentNotificationEventName | MembershipNotificationEventName\n>\n\nexport type CommerceNotificationSourceCollection =\n | 'orders'\n | 'fulfillments'\n | 'returns'\n | 'payment-sessions'\n | 'payment-refund-attempts'\n | 'customer-memberships'\n\nexport type CommerceNotificationSource = {\n collection: CommerceNotificationSourceCollection\n id: string | number\n}\n\nexport type PaymentIncidentNotificationEventName =\n | 'paymentReconciliationRequired'\n | 'paymentRefundRequiresAttention'\n\nexport type MembershipNotificationEventName =\n | 'membershipActivated'\n | 'membershipPastDue'\n | 'membershipExpired'\n | 'membershipCancelled'\n\nexport type MembershipNotificationData = {\n membershipId: string\n planId: string\n /** Tenant-scoped pseudonymous identifier; this is not a PII-free claim. */\n customerId: string\n fromStatus: string\n toStatus: 'active' | 'past_due' | 'expired' | 'cancelled'\n occurredAt: string\n}\n\nexport type PaymentIncidentNotificationSourceCollection =\n | 'payment-sessions'\n | 'payment-refund-attempts'\n\nexport type PaymentIncidentNotificationReason =\n | 'orderless_capture'\n | 'local_commit_ambiguous'\n\nexport type PaymentIncidentNotificationStatus =\n | 'reconciliation_required'\n | 'requires_attention'\n\nexport type PaymentIncidentProviderObject = {\n provider: string\n kind: 'payment' | 'refund'\n id: string\n}\n\nexport type PaymentIncidentMoney = {\n amountMinor: number\n currency: string\n}\n\ntype PaymentIncidentNotificationBase = {\n paymentSessionId: string\n checkoutId?: string\n orderId?: string\n providerObject: PaymentIncidentProviderObject\n money: PaymentIncidentMoney\n observedAt: string\n}\n\nexport type PaymentReconciliationRequiredNotificationData =\n PaymentIncidentNotificationBase & {\n source: {\n collection: 'payment-sessions'\n id: string\n }\n providerObject: PaymentIncidentProviderObject & { kind: 'payment' }\n status: 'reconciliation_required'\n reason: 'orderless_capture'\n refundAttemptId?: never\n }\n\nexport type PaymentRefundRequiresAttentionNotificationData =\n PaymentIncidentNotificationBase & {\n source: { collection: 'payment-refund-attempts'; id: string }\n refundAttemptId: string\n status: 'requires_attention'\n reason: 'local_commit_ambiguous'\n }\n\nexport type PaymentIncidentNotificationData =\n | PaymentReconciliationRequiredNotificationData\n | PaymentRefundRequiresAttentionNotificationData\n\nexport type CommerceNotificationData = {\n source?: CommerceNotificationSource\n orderId?: string | number\n orderNumber?: string\n status?: string\n totalAmount?: number\n currency?: string\n fulfillmentId?: string | number\n fulfillmentStatus?: string\n shippedAt?: string\n returnId?: string | number\n returnStatus?: string\n refundAmount?: number\n completedAt?: string\n paymentSessionId?: string\n checkoutId?: string\n refundAttemptId?: string\n providerObject?: PaymentIncidentProviderObject\n money?: PaymentIncidentMoney\n reason?: PaymentIncidentNotificationReason\n observedAt?: string\n membershipId?: string\n planId?: string\n customerId?: string\n fromStatus?: string\n toStatus?: string\n occurredAt?: string\n}\n\nexport type CommerceNotification = {\n event: CommerceNotificationEventName\n intentId: string\n dedupeKey: string\n orderId?: string\n fulfillmentId?: string\n returnId?: string\n paymentSessionId?: string\n refundAttemptId?: string\n membershipId?: string\n}\n\nexport type WebhookCommerceNotificationChange = {\n type: 'notification'\n source: 'commerce-notifications'\n event: CommerceNotificationEventName\n sourceCollection: CommerceNotificationSourceCollection\n sourceId: string | number\n}\n\n/** Webhook event emitted for v1 commerce notification deliveries. */\nexport type CommerceNotificationWebhookEvent = WebhookEvent<\n CommerceNotificationSourceCollection,\n CommerceNotificationData\n> & {\n operation: typeof COMMERCE_NOTIFICATION_OPERATION\n eventType: typeof COMMERCE_NOTIFICATION_EVENT_TYPE\n change?: WebhookCommerceNotificationChange\n notification: CommerceNotification\n}\n\nexport type CommerceEmailChannel = 'webhook' | 'provider'\n\nexport type CommerceEmailEventConfig = {\n enabled: boolean\n channel: CommerceEmailChannel\n template?: string\n}\n\nexport type CommerceEmailConfig = {\n version: 1\n commerceNotifications: Partial<\n Record<CustomerCommerceNotificationEventName, CommerceEmailEventConfig>\n >\n}\n\nexport type CommerceNotificationHandlerContext = {\n event: CommerceNotificationWebhookEvent\n idempotencyKey: string\n}\n\ntype MaybePromise<T> = T | Promise<T>\n\nexport type CommerceNotificationEventHandlers = Partial<\n Record<\n CommerceNotificationEventName,\n (context: CommerceNotificationHandlerContext) => MaybePromise<void>\n >\n> & {\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nexport type CommerceEmailHandlerContext = CommerceNotificationHandlerContext\n\nexport type CommerceEmailEventHandlers = Partial<\n Record<\n CustomerCommerceNotificationEventName,\n (context: CommerceEmailHandlerContext) => MaybePromise<void>\n >\n> & {\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isStringOrNumber(value: unknown): value is string | number {\n return typeof value === 'string' || typeof value === 'number'\n}\n\nfunction isWebhookOrderScope(value: unknown): value is WebhookOrderScope {\n if (!isRecord(value)) return false\n\n if (value.kind === 'collection') {\n return typeof value.collection === 'string'\n }\n\n if (value.kind === 'join') {\n return (\n typeof value.collection === 'string' &&\n typeof value.field === 'string' &&\n isStringOrNumber(value.id)\n )\n }\n\n return false\n}\n\nfunction isWebhookOrderMoved(value: unknown): value is WebhookOrderMoved {\n if (!isRecord(value)) return false\n\n return (\n typeof value.collection === 'string' &&\n isStringOrNumber(value.id) &&\n (value.relatedCollection === undefined ||\n typeof value.relatedCollection === 'string') &&\n (value.relatedId === undefined || isStringOrNumber(value.relatedId))\n )\n}\n\nfunction hasOptionalOrderValue(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return (\n value[key] === undefined ||\n value[key] === null ||\n typeof value[key] === 'string'\n )\n}\n\nfunction isWebhookOrderChange(value: unknown): value is WebhookOrderChange {\n if (!isRecord(value)) return false\n\n return (\n value.type === 'order' &&\n value.source === 'payload-orderable' &&\n (value.orderableFieldName === undefined ||\n typeof value.orderableFieldName === 'string') &&\n hasOptionalOrderValue(value, 'previousOrder') &&\n hasOptionalOrderValue(value, 'nextOrder') &&\n isWebhookOrderScope(value.scope) &&\n isWebhookOrderMoved(value.moved)\n )\n}\n\nfunction isCommerceNotificationEventName(\n value: unknown,\n): value is CommerceNotificationEventName {\n return (\n typeof value === 'string' &&\n (COMMERCE_NOTIFICATION_EVENTS as readonly string[]).includes(value)\n )\n}\n\nfunction isCommerceNotificationSourceCollection(\n value: unknown,\n): value is CommerceNotificationSourceCollection {\n return (\n value === 'orders' ||\n value === 'fulfillments' ||\n value === 'returns' ||\n value === 'payment-sessions' ||\n value === 'payment-refund-attempts' ||\n value === 'customer-memberships'\n )\n}\n\nfunction isCommerceNotificationData(\n value: unknown,\n): value is CommerceNotificationData {\n if (!isRecord(value)) return false\n if (\n value.source !== undefined &&\n (!isRecord(value.source) ||\n !isCommerceNotificationSourceCollection(value.source.collection) ||\n !isStringOrNumber(value.source.id))\n ) {\n return false\n }\n\n return (\n (value.orderId === undefined || isStringOrNumber(value.orderId)) &&\n (value.orderNumber === undefined ||\n typeof value.orderNumber === 'string') &&\n (value.status === undefined || typeof value.status === 'string') &&\n (value.totalAmount === undefined ||\n typeof value.totalAmount === 'number') &&\n (value.currency === undefined || typeof value.currency === 'string') &&\n (value.fulfillmentId === undefined ||\n isStringOrNumber(value.fulfillmentId)) &&\n (value.fulfillmentStatus === undefined ||\n typeof value.fulfillmentStatus === 'string') &&\n (value.shippedAt === undefined || typeof value.shippedAt === 'string') &&\n (value.returnId === undefined || isStringOrNumber(value.returnId)) &&\n (value.returnStatus === undefined ||\n typeof value.returnStatus === 'string') &&\n (value.refundAmount === undefined ||\n typeof value.refundAmount === 'number') &&\n (value.completedAt === undefined ||\n typeof value.completedAt === 'string') &&\n (value.paymentSessionId === undefined ||\n typeof value.paymentSessionId === 'string') &&\n (value.checkoutId === undefined || typeof value.checkoutId === 'string') &&\n (value.refundAttemptId === undefined ||\n typeof value.refundAttemptId === 'string') &&\n (value.reason === undefined || typeof value.reason === 'string') &&\n (value.observedAt === undefined || typeof value.observedAt === 'string') &&\n (value.providerObject === undefined ||\n (isRecord(value.providerObject) &&\n typeof value.providerObject.provider === 'string' &&\n (value.providerObject.kind === 'payment' ||\n value.providerObject.kind === 'refund') &&\n typeof value.providerObject.id === 'string')) &&\n (value.money === undefined ||\n (isRecord(value.money) &&\n Number.isSafeInteger(value.money.amountMinor) &&\n Number(value.money.amountMinor) > 0 &&\n typeof value.money.currency === 'string'))\n )\n}\n\nfunction isCommerceNotification(value: unknown): value is CommerceNotification {\n if (!isRecord(value)) return false\n return (\n isCommerceNotificationEventName(value.event) &&\n typeof value.intentId === 'string' &&\n value.intentId.length > 0 &&\n typeof value.dedupeKey === 'string' &&\n value.dedupeKey.length > 0 &&\n (value.orderId === undefined || typeof value.orderId === 'string') &&\n (value.fulfillmentId === undefined ||\n typeof value.fulfillmentId === 'string') &&\n (value.returnId === undefined || typeof value.returnId === 'string') &&\n (value.paymentSessionId === undefined ||\n typeof value.paymentSessionId === 'string') &&\n (value.refundAttemptId === undefined ||\n typeof value.refundAttemptId === 'string')\n )\n}\n\nfunction isPaymentIncidentNotificationData(\n value: CommerceNotificationData,\n event: PaymentIncidentNotificationEventName,\n): boolean {\n const reconciliation = event === 'paymentReconciliationRequired'\n const expectedCollection = reconciliation\n ? 'payment-sessions'\n : 'payment-refund-attempts'\n const expectedStatus = reconciliation\n ? 'reconciliation_required'\n : 'requires_attention'\n const expectedReason = reconciliation\n ? 'orderless_capture'\n : 'local_commit_ambiguous'\n\n return (\n value.source?.collection === expectedCollection &&\n typeof value.source.id === 'string' &&\n value.source.id.length > 0 &&\n typeof value.paymentSessionId === 'string' &&\n value.paymentSessionId.length > 0 &&\n isRecord(value.providerObject) &&\n typeof value.providerObject.provider === 'string' &&\n value.providerObject.provider.length > 0 &&\n (value.providerObject.kind === 'payment' ||\n value.providerObject.kind === 'refund') &&\n typeof value.providerObject.id === 'string' &&\n value.providerObject.id.length > 0 &&\n isRecord(value.money) &&\n Number.isSafeInteger(value.money.amountMinor) &&\n Number(value.money.amountMinor) > 0 &&\n typeof value.money.currency === 'string' &&\n value.money.currency.length > 0 &&\n value.status === expectedStatus &&\n value.reason === expectedReason &&\n typeof value.observedAt === 'string' &&\n value.observedAt.length > 0 &&\n !Number.isNaN(Date.parse(value.observedAt)) &&\n (value.checkoutId === undefined ||\n (typeof value.checkoutId === 'string' && value.checkoutId.length > 0)) &&\n (value.orderId === undefined ||\n (typeof value.orderId === 'string' && value.orderId.length > 0)) &&\n (reconciliation\n ? value.source.id === value.paymentSessionId &&\n value.providerObject.kind === 'payment' &&\n value.refundAttemptId === undefined\n : typeof value.refundAttemptId === 'string' &&\n value.refundAttemptId.length > 0 &&\n value.source.id === value.refundAttemptId)\n )\n}\n\nfunction isMembershipNotificationData(\n value: CommerceNotificationData,\n event: MembershipNotificationEventName,\n): boolean {\n const expectedStatus =\n event === 'membershipActivated'\n ? 'active'\n : event === 'membershipPastDue'\n ? 'past_due'\n : event === 'membershipExpired'\n ? 'expired'\n : 'cancelled'\n return (\n typeof value.membershipId === 'string' &&\n value.membershipId.length > 0 &&\n typeof value.planId === 'string' &&\n value.planId.length > 0 &&\n typeof value.customerId === 'string' &&\n value.customerId.length > 0 &&\n typeof value.fromStatus === 'string' &&\n value.fromStatus.length > 0 &&\n value.fromStatus !== value.toStatus &&\n value.toStatus === expectedStatus &&\n typeof value.occurredAt === 'string' &&\n !Number.isNaN(Date.parse(value.occurredAt))\n )\n}\n\nfunction isWebhookCommerceNotificationChange(\n value: unknown,\n): value is WebhookCommerceNotificationChange {\n if (!isRecord(value)) return false\n return (\n value.type === 'notification' &&\n value.source === 'commerce-notifications' &&\n isCommerceNotificationEventName(value.event) &&\n isCommerceNotificationSourceCollection(value.sourceCollection) &&\n isStringOrNumber(value.sourceId)\n )\n}\n\nfunction matchesOptionalId(\n actual: string | number | undefined,\n expected: string | number | undefined,\n): boolean {\n return actual === undefined || expected === undefined || actual === expected\n}\n\n/**\n * Returns true for semantic order-change webhooks emitted as update events.\n *\n * Use this guard with `ORDER_CHANGED_EVENT_TYPE` instead of filtering on\n * `operation: \"reorder\"`. Tenant order-change webhooks intentionally keep\n * `operation: \"update\"` for compatibility with existing webhook handlers.\n */\nexport function isOrderChangedWebhookEvent(\n event: unknown,\n): event is OrderChangedWebhookEvent<string, unknown> {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== 'update' ||\n event.eventType !== ORDER_CHANGED_EVENT_TYPE ||\n !isWebhookOrderChange(event.change)\n ) {\n return false\n }\n\n if (event.collection !== event.change.scope.collection) {\n return false\n }\n\n if (\n event.change.scope.kind === 'collection' &&\n event.change.moved.collection !== event.change.scope.collection\n ) {\n return false\n }\n\n return true\n}\n\n/**\n * Returns true for semantic commerce notification webhooks.\n *\n * Use `notification.intentId` and `notification.dedupeKey` for semantic\n * idempotency. `deliveryId`, when present, identifies a delivery attempt for\n * observability and is not the semantic notification identity.\n */\nexport function isCommerceNotificationWebhookEvent(\n event: unknown,\n): event is CommerceNotificationWebhookEvent {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== COMMERCE_NOTIFICATION_OPERATION ||\n event.eventType !== COMMERCE_NOTIFICATION_EVENT_TYPE ||\n !isCommerceNotificationData(event.data) ||\n !isCommerceNotification((event as { notification?: unknown }).notification)\n ) {\n return false\n }\n\n const notification = (event as unknown as CommerceNotificationWebhookEvent)\n .notification\n const data = event.data\n const change = event.change\n const sourceCollection = data.source?.collection ?? event.collection\n const sourceId = data.source?.id\n\n if (!isCommerceNotificationSourceCollection(sourceCollection)) return false\n if (\n data.source !== undefined &&\n event.collection !== data.source.collection\n ) {\n return false\n }\n\n if (change !== undefined) {\n if (!isWebhookCommerceNotificationChange(change)) return false\n if (change.sourceCollection !== sourceCollection) return false\n if (change.event !== notification.event) return false\n if (!matchesOptionalId(change.sourceId, sourceId)) return false\n }\n const changeSourceId = isWebhookCommerceNotificationChange(change)\n ? change.sourceId\n : undefined\n\n if (\n notification.event === 'paymentReconciliationRequired' ||\n notification.event === 'paymentRefundRequiresAttention'\n ) {\n if (!isPaymentIncidentNotificationData(data, notification.event)) {\n return false\n }\n const incidentData = data as PaymentIncidentNotificationData\n const expectedCollection =\n notification.event === 'paymentReconciliationRequired'\n ? 'payment-sessions'\n : 'payment-refund-attempts'\n const notificationSourceId =\n notification.event === 'paymentReconciliationRequired'\n ? notification.paymentSessionId\n : notification.refundAttemptId\n return (\n sourceCollection === expectedCollection &&\n typeof notification.paymentSessionId === 'string' &&\n notification.paymentSessionId === incidentData.paymentSessionId &&\n typeof notificationSourceId === 'string' &&\n notificationSourceId === incidentData.source.id &&\n matchesOptionalId(changeSourceId, incidentData.source.id)\n )\n }\n\n if (\n notification.event === 'membershipActivated' ||\n notification.event === 'membershipPastDue' ||\n notification.event === 'membershipExpired' ||\n notification.event === 'membershipCancelled'\n ) {\n return (\n sourceCollection === 'customer-memberships' &&\n isMembershipNotificationData(data, notification.event) &&\n typeof notification.membershipId === 'string' &&\n notification.membershipId === data.membershipId &&\n matchesOptionalId(changeSourceId, data.membershipId)\n )\n }\n\n if (\n notification.event === 'orderPaid' ||\n notification.event === 'orderCanceled' ||\n notification.event === 'orderDelivered'\n ) {\n return (\n sourceCollection === 'orders' &&\n typeof notification.orderId === 'string' &&\n notification.orderId.length > 0 &&\n matchesOptionalId(data.orderId, sourceId) &&\n matchesOptionalId(notification.orderId, sourceId) &&\n matchesOptionalId(data.orderId, notification.orderId) &&\n matchesOptionalId(changeSourceId, data.orderId ?? notification.orderId)\n )\n }\n\n if (notification.event === 'fulfillmentShipped') {\n return (\n sourceCollection === 'fulfillments' &&\n matchesOptionalId(data.fulfillmentId, sourceId) &&\n typeof notification.fulfillmentId === 'string' &&\n notification.fulfillmentId.length > 0 &&\n matchesOptionalId(notification.fulfillmentId, sourceId) &&\n matchesOptionalId(data.fulfillmentId, notification.fulfillmentId) &&\n matchesOptionalId(changeSourceId, notification.fulfillmentId)\n )\n }\n\n if (\n notification.event === 'returnRequested' ||\n notification.event === 'returnApproved' ||\n notification.event === 'returnRejected' ||\n notification.event === 'returnCanceled' ||\n notification.event === 'returnCompleted'\n ) {\n return (\n sourceCollection === 'returns' &&\n matchesOptionalId(data.returnId, sourceId) &&\n typeof notification.returnId === 'string' &&\n notification.returnId.length > 0 &&\n matchesOptionalId(notification.returnId, sourceId) &&\n matchesOptionalId(data.returnId, notification.returnId) &&\n matchesOptionalId(changeSourceId, notification.returnId)\n )\n }\n\n return false\n}\n\nexport function getCommerceNotificationIdempotencyKey(\n event: Pick<CommerceNotificationWebhookEvent, 'notification'>,\n): string {\n return `${event.notification.intentId}:${event.notification.dedupeKey}`\n}\n\nexport function defineCommerceEmailConfig<TConfig extends CommerceEmailConfig>(\n config: TConfig,\n): TConfig {\n return config\n}\n\nexport function createCommerceNotificationWebhookHandler(\n handlers: CommerceNotificationEventHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (!isCommerceNotificationWebhookEvent(event)) {\n await handlers.unhandled?.(event)\n return\n }\n\n const handler = handlers[event.notification.event]\n if (!handler) {\n await handlers.unhandled?.(event)\n return\n }\n\n await handler({\n event,\n idempotencyKey: getCommerceNotificationIdempotencyKey(event),\n })\n }\n}\n\nexport function createCommerceEmailWebhookHandler(\n handlers: CommerceEmailEventHandlers,\n): WebhookHandler<string, unknown> {\n return createCommerceNotificationWebhookHandler(handlers)\n}\n\n/** Narrows a webhook event to a specific collection. */\nexport function isWebhookCollection<TCollection extends string>(\n event: unknown,\n collection: TCollection,\n): event is WebhookEvent<TCollection, unknown> {\n return isValidWebhookEvent(event) && event.collection === collection\n}\n\n/** Narrows a webhook event to a specific operation. */\nexport function isWebhookOperation<TOperation extends string>(\n event: unknown,\n operation: TOperation,\n): event is WebhookEvent<string, unknown> & { operation: TOperation } {\n return isValidWebhookEvent(event) && event.operation === operation\n}\n\nexport const CUSTOMER_PASSWORD_RESET_OPERATION = 'password-reset' as const\n\nexport type WebhookKnownOperation =\n | CollectionWebhookOperation\n | typeof CUSTOMER_PASSWORD_RESET_OPERATION\n | typeof COMMERCE_NOTIFICATION_OPERATION\n\nexport interface CustomerPasswordResetWebhookData {\n customerId: string | number\n email: string\n name: string\n resetPasswordToken: string\n resetPasswordExpiresAt: string\n}\n\nexport type CustomerPasswordResetWebhookEvent = WebhookEvent<\n 'customers',\n CustomerPasswordResetWebhookData\n> & {\n operation: typeof CUSTOMER_PASSWORD_RESET_OPERATION\n}\n\nexport type CustomerAuthWebhookEvent = CustomerPasswordResetWebhookEvent\n\nexport interface CustomerAuthWebhookHandlers {\n passwordReset?: (\n data: CustomerPasswordResetWebhookData,\n event: CustomerPasswordResetWebhookEvent,\n ) => MaybePromise<void>\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction hasString(value: Record<string, unknown>, key: string): boolean {\n return typeof value[key] === 'string'\n}\n\nfunction hasStringOrNumber(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return typeof value[key] === 'string' || typeof value[key] === 'number'\n}\n\nexport function isCustomerPasswordResetWebhookEvent(\n event: WebhookEvent<string, unknown>,\n): event is CustomerPasswordResetWebhookEvent {\n if (\n event.collection !== 'customers' ||\n event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION ||\n !isRecord(event.data)\n ) {\n return false\n }\n\n return (\n hasStringOrNumber(event.data, 'customerId') &&\n hasString(event.data, 'email') &&\n hasString(event.data, 'name') &&\n hasString(event.data, 'resetPasswordToken') &&\n hasString(event.data, 'resetPasswordExpiresAt')\n )\n}\n\nexport function createCustomerAuthWebhookHandler(\n handlers: CustomerAuthWebhookHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (isCustomerPasswordResetWebhookEvent(event) && handlers.passwordReset) {\n await handlers.passwordReset(event.data, event)\n return\n }\n\n await handlers.unhandled?.(event)\n }\n}\n\n/**\n * @deprecated Import `handleSignedWebhook()` from `@01.software/sdk/webhook`.\n * This compatibility alias is signed and fails closed when its required secret\n * is missing or blank.\n */\nexport async function handleWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n options: WebhookOptions,\n): Promise<Response> {\n return handleSignedWebhookInternal(request, handler, options)\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(\n `Expected collection \"${collection}\", got \"${event.collection}\"`,\n )\n }\n return handler(event)\n }\n}\n","import type { Config } from '../../payload-types'\n\n/**\n * Internal collections that should not be exposed via SDK.\n * Includes Payload system collections and admin-only collections.\n */\nexport const INTERNAL_COLLECTIONS = [\n 'benefit-voucher-definitions',\n 'users',\n 'payload-kv',\n 'payload-locked-documents',\n 'payload-preferences',\n 'payload-migrations',\n 'payload-folders',\n 'field-configs',\n 'system-media',\n 'track-assets',\n 'audiences',\n 'email-logs',\n 'api-usage',\n 'tenant-mcp-usage-daily',\n 'subscriptions',\n 'billing-history',\n 'billing-consent-receipts',\n 'usage-rate-cards',\n 'usage-invoices',\n 'inventory-reservations',\n 'inventory-adjustments',\n 'payment-sessions',\n 'payment-event-inbox',\n 'payment-refund-attempts',\n 'portone-payment-interactions',\n 'commerce-payment-webhook-routes',\n 'commerce-notification-intents',\n 'commerce-idempotency-records',\n 'product-collection-items',\n 'order-status-logs',\n 'fulfillment-events',\n 'tenant-commerce-config',\n 'customer-oauth-clients',\n 'customer-consent-receipts',\n 'customer-group-grants',\n 'api-keys',\n 'personal-access-tokens',\n 'tenant-entitlements',\n 'tenant-purge-jobs',\n 'direct-upload-sessions',\n 'webhook-events',\n 'webhook-deliveries',\n 'webhook-outbox-deliveries',\n 'audit-logs',\n 'plans',\n 'webhooks',\n 'custom-field-definitions',\n 'event-registrations',\n 'event-admission-holds',\n 'event-admission-types',\n 'customer-payment-methods',\n 'tenant-payment-credentials',\n 'membership-unapplied-paid-evidence',\n 'commerce-payment-accounts',\n 'payment-provider-customer-aliases',\n] as const\n\nexport type InternalCollection = (typeof INTERNAL_COLLECTIONS)[number]\n\n/**\n * Array of browser-public collection names for runtime use (e.g., Zod enum validation).\n * This is the single source of truth for publishable-key collection discovery.\n */\nexport const COLLECTIONS = [\n 'tenant-metadata',\n 'products',\n 'product-variants',\n 'product-options',\n 'product-option-values',\n 'product-categories',\n 'product-tags',\n 'product-collections',\n 'markets',\n 'brands',\n 'customer-profiles',\n 'customer-profile-stats',\n 'shipping-policies',\n 'shipping-zones',\n 'documents',\n 'document-categories',\n 'document-types',\n 'articles',\n 'article-authors',\n 'article-categories',\n 'article-tags',\n 'playlists',\n 'playlist-categories',\n 'playlist-tags',\n 'tracks',\n 'track-categories',\n 'track-tags',\n 'galleries',\n 'gallery-categories',\n 'gallery-tags',\n 'gallery-items',\n 'links',\n 'link-categories',\n 'link-tags',\n 'canvases',\n 'canvas-node-types',\n 'canvas-edge-types',\n 'canvas-categories',\n 'canvas-tags',\n 'video-categories',\n 'video-tags',\n 'forms',\n // Community\n 'reaction-types',\n 'post-categories',\n 'post-tags',\n 'customer-profile-lists',\n // Events\n 'event-calendars',\n 'events',\n 'event-categories',\n 'event-occurrences',\n 'event-tags',\n 'membership-plans',\n 'membership-plan-prices',\n 'customer-memberships',\n] as const\n\n/**\n * Server-auth collection names for runtime use. These collections are safe for\n * secret-key/PAT SDK and MCP server tools, but must not appear in browser or\n * publishable-key collection discovery.\n */\nexport const SERVER_ONLY_COLLECTIONS = [\n // The tenant record itself denies reads without an authenticated user, so a\n // publishable key never reaches it; `tenant-metadata` is the browser-public\n // tenant identity surface.\n 'tenants',\n 'tenant-logos',\n 'brand-logos',\n 'images',\n 'videos',\n 'orders',\n 'order-tags',\n 'order-items',\n 'returns',\n 'return-items',\n 'refunds',\n 'refund-line-items',\n 'order-edit-sessions',\n 'order-staged-changes',\n 'fulfillment-orders',\n 'fulfillment-order-items',\n 'fulfillments',\n 'fulfillment-items',\n 'transactions',\n 'customers',\n 'customer-addresses',\n 'form-submissions',\n 'carts',\n 'cart-items',\n 'checkouts',\n 'checkout-items',\n // Raw discount definitions require a server credential. Browser discount\n // validation is exposed through the shaped POST /api/discounts/validate path.\n 'discounts',\n 'draft-orders',\n 'draft-order-items',\n 'posts',\n 'comments',\n 'reactions',\n 'bookmarks',\n 'live-streams',\n 'canvas-nodes',\n 'canvas-edges',\n 'customer-groups',\n 'reports',\n 'community-bans',\n 'order-export-profiles',\n 'membership-charges',\n] as const\n\n/**\n * Browser-public collections available for publishable-key SDK access.\n * Derived from the COLLECTIONS array (single source of truth).\n */\nexport type PublicCollection = (typeof COLLECTIONS)[number]\n\nexport type ServerOnlyCollection = (typeof SERVER_ONLY_COLLECTIONS)[number]\n\nexport const SERVER_COLLECTIONS = [\n ...COLLECTIONS,\n ...SERVER_ONLY_COLLECTIONS,\n] as const\n\nexport type ServerCollection = (typeof SERVER_COLLECTIONS)[number]\n\n/**\n * The published SDK collection universe is exactly the union of its three\n * existing addressability buckets. Generated Payload Config entries may also\n * contain Console-only collections that are intentionally outside this type.\n */\nexport type Collection =\n | PublicCollection\n | ServerOnlyCollection\n | InternalCollection\n\n/**\n * Compile-time classification checks: every published SDK collection belongs\n * to one of the three buckets, each bucket entry exists in generated Config,\n * and no collection is categorized more than once.\n */\ntype _Uncategorized = Exclude<\n Collection,\n PublicCollection | ServerOnlyCollection | InternalCollection\n>\nexport const _assertAllCategorized: [_Uncategorized] extends [never]\n ? true\n : _Uncategorized = true\n\ntype _UnknownGeneratedCollection = Exclude<\n Collection,\n keyof Config['collections']\n>\nexport const _assertAllSdkCollectionsExist: [\n _UnknownGeneratedCollection,\n] extends [never]\n ? true\n : _UnknownGeneratedCollection = true\n\ntype _Overcategorized =\n | Extract<PublicCollection, ServerOnlyCollection | InternalCollection>\n | Extract<ServerOnlyCollection, InternalCollection>\nexport const _assertNoDuplicateCategorization: [_Overcategorized] extends [\n never,\n]\n ? true\n : _Overcategorized = true\n","/**\n * Fetch-based SSE connection manager for real-time collection change events.\n * Uses fetch + ReadableStream to support custom auth headers (unlike native EventSource).\n */\n\nexport interface RealtimeEvent {\n collection: string\n operation: string\n id: string | null\n timestamp: string\n}\n\nexport type RealtimeListener = (event: RealtimeEvent) => void\n\nconst INITIAL_RECONNECT_DELAY = 1_000\nconst MAX_RECONNECT_DELAY = 30_000\nconst RECONNECT_BACKOFF_FACTOR = 2\nconst MAX_NO_TOKEN_RETRIES = 5\n\nexport class RealtimeConnection {\n private abortController: AbortController | null = null\n private reconnectAttempt = 0\n private noTokenAttempts = 0\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null\n private listeners = new Set<RealtimeListener>()\n private _connected = false\n\n constructor(\n private baseUrl: string,\n private publishableKey: string,\n private getToken: () => string | null,\n private collections?: string[],\n ) {}\n\n get connected(): boolean {\n return this._connected\n }\n\n addListener(fn: RealtimeListener): () => void {\n this.listeners.add(fn)\n return () => this.listeners.delete(fn)\n }\n\n connect(): void {\n if (this.abortController) return // Already connecting/connected\n\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }\n\n disconnect(): void {\n this._connected = false\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer)\n this.reconnectTimer = null\n }\n if (this.abortController) {\n this.abortController.abort()\n this.abortController = null\n }\n this.reconnectAttempt = 0\n this.noTokenAttempts = 0\n }\n\n private async startStream(signal: AbortSignal): Promise<void> {\n const token = this.getToken()\n if (!token) {\n this.noTokenAttempts++\n if (this.noTokenAttempts >= MAX_NO_TOKEN_RETRIES) {\n // Stop reconnecting — no token available after multiple attempts\n this._connected = false\n this.abortController = null\n return\n }\n this.scheduleReconnect()\n return\n }\n this.noTokenAttempts = 0\n\n const params = this.collections?.length\n ? `?collections=${this.collections.join(',')}`\n : ''\n const url = `${this.baseUrl}/api/events/stream${params}`\n\n try {\n const response = await fetch(url, {\n headers: {\n 'X-Publishable-Key': this.publishableKey,\n Authorization: `Bearer ${token}`,\n },\n signal,\n })\n\n if (!response.ok) {\n if (response.status === 401) {\n // Token expired — try reconnecting (will get fresh token)\n this.scheduleReconnect()\n return\n }\n throw new Error(`SSE connection failed: ${response.status}`)\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body')\n }\n\n this._connected = true\n this.reconnectAttempt = 0\n\n await this.readStream(response.body, signal)\n } catch {\n if (signal.aborted) return // Intentional disconnect\n this._connected = false\n this.scheduleReconnect()\n }\n }\n\n private async readStream(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n ): Promise<void> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent = ''\n let currentData = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done || signal.aborted) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? '' // Keep incomplete last line in buffer\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7)\n } else if (line.startsWith('data: ')) {\n currentData += (currentData ? '\\n' : '') + line.slice(6)\n } else if (line === '') {\n // Empty line = end of event\n if (currentEvent === 'collection:change' && currentData) {\n try {\n const event: RealtimeEvent = JSON.parse(currentData)\n for (const listener of this.listeners) {\n try {\n listener(event)\n } catch {\n // Listener error — ignore\n }\n }\n } catch {\n // Malformed JSON — ignore\n }\n }\n currentEvent = ''\n currentData = ''\n }\n // Ignore comment lines (: heartbeat)\n }\n }\n } catch {\n // Stream read error\n } finally {\n reader.releaseLock()\n this._connected = false\n if (!signal.aborted) {\n this.scheduleReconnect()\n }\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return\n\n const delay = Math.min(\n INITIAL_RECONNECT_DELAY *\n Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),\n MAX_RECONNECT_DELAY,\n )\n this.reconnectAttempt++\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }, delay)\n }\n}\n","/** Palette colors extracted from an image */\nexport interface ImagePalette {\n vibrant?: string | null\n muted?: string | null\n darkVibrant?: string | null\n darkMuted?: string | null\n lightVibrant?: string | null\n lightMuted?: string | null\n}\n\n/** Structural image size entry accepted by public image helpers. */\nexport interface ImageDataSizeEntry {\n url?: string | null\n width?: number | null\n height?: number | null\n}\n\n/** Structural image sizes accepted from Payload upload-like collections. */\nexport type ImageDataSizes = Partial<\n Record<string, ImageDataSizeEntry | null | undefined>\n>\n\n/** Common image data shape from Payload CMS upload collections */\nexport interface ImageData {\n url?: string | null\n width?: number | null\n height?: number | null\n alt?: string | null\n lqip?: string | null\n palette?: ImagePalette | null\n sizes?: ImageDataSizes\n}\n\n/** Pre-generated image size breakpoints (px), aligned with Payload Image.sizes. */\nexport const IMAGE_SIZES = [200, 400, 800, 1200, 1600] as const\n\n/** Numeric rendition keys from `IMAGE_SIZES` plus any numeric keys on the image. */\nfunction imageSizeCandidates(sizes: ImageDataSizes): number[] {\n const keys = new Set<number>(IMAGE_SIZES)\n for (const key of Object.keys(sizes)) {\n const value = Number(key)\n if (Number.isFinite(value) && value > 0) keys.add(value)\n }\n return [...keys].sort((a, b) => a - b)\n}\n\n/**\n * Returns the optimal image URL for a given display width.\n *\n * Picks the smallest pre-generated size whose width >= displayWidth × dpr.\n * Falls back to the original URL when no matching size exists.\n *\n * @param image - Payload image document\n * @param displayWidth - CSS pixel width the image will be displayed at\n * @param dpr - Device pixel ratio (default: 1)\n * @returns URL string, or empty string if no URL is available\n */\nexport function getImageUrl(\n image: ImageData,\n displayWidth: number,\n dpr: number = 1,\n): string {\n const target = displayWidth * dpr\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of imageSizeCandidates(sizes)) {\n if (size >= target) {\n const entry = sizes[`${size}`]\n if (entry?.url) return entry.url\n }\n }\n }\n\n return image.url ?? ''\n}\n\n/**\n * Generates an HTML `srcset` attribute string from pre-generated sizes.\n *\n * Includes all available sizes plus the original image.\n * Example output: `\"url-200 200w, url-400 400w, url-800 800w, url-1200 1200w, url-1600 1600w, url-original 2000w\"`\n *\n * @param image - Payload image document\n * @returns srcset string, or empty string if no URLs are available\n */\nexport function getImageSrcSet(image: ImageData): string {\n const parts: string[] = []\n const emittedWidths = new Set<number>()\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of imageSizeCandidates(sizes)) {\n const entry = sizes[`${size}`]\n if (entry?.url && entry.width && !emittedWidths.has(entry.width)) {\n emittedWidths.add(entry.width)\n parts.push(`${entry.url} ${entry.width}w`)\n }\n }\n }\n\n if (image.url && image.width && !emittedWidths.has(image.width)) {\n parts.push(`${image.url} ${image.width}w`)\n }\n\n return parts.join(', ')\n}\n\n/**\n * Returns the LQIP (Low Quality Image Placeholder) data URL for an image.\n *\n * @param image - Payload image document\n * @returns LQIP data URL string, or undefined if not available\n */\nexport function getImageLqip(image: ImageData): string | undefined {\n return image.lqip ?? undefined\n}\n\n/**\n * Returns the extracted color palette for an image.\n *\n * @param image - Payload image document\n * @returns ImagePalette object, or undefined if not available\n */\nexport function getImagePalette(image: ImageData): ImagePalette | undefined {\n return image.palette ?? undefined\n}\n\n/** Options for `getImagePlaceholderStyle` */\nexport interface ImagePlaceholderOptions {\n /** Placeholder strategy (default: 'blur') */\n type?: 'blur' | 'color' | 'none'\n /** Which palette color to use for 'color' strategy (default: 'muted') */\n paletteColor?: keyof ImagePalette\n}\n\n/**\n * Returns inline CSS styles for an image placeholder.\n *\n * - `blur`: uses LQIP as background, falls back to palette color, then empty\n * - `color`: uses palette color as background, falls back to empty\n * - `none`: always returns empty\n *\n * @param image - Payload image document\n * @param options - Placeholder options\n * @returns CSS style object compatible with React CSSProperties\n */\nexport function getImagePlaceholderStyle(\n image: ImageData,\n options?: ImagePlaceholderOptions,\n): Record<string, string> {\n const type = options?.type ?? 'blur'\n const paletteColor = options?.paletteColor ?? 'muted'\n\n if (type === 'none') return {}\n\n const color = image.palette?.[paletteColor]\n\n if (type === 'blur') {\n const lqip = image.lqip\n if (lqip) {\n return {\n backgroundImage: `url(${lqip})`,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }\n }\n // Cascade: fall back to color\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n }\n\n // type === 'color'\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n}\n","export const generateOrderNumber = () => {\n // YYMMDDRRRRRR\n const now = new Date()\n const year = now.getFullYear().toString().slice(-2)\n const month = (now.getMonth() + 1).toString().padStart(2, '0')\n const day = now.getDate().toString().padStart(2, '0')\n // Use crypto.getRandomValues for cryptographically secure randomness (works in both browser and Node.js)\n const array = new Uint32Array(1)\n globalThis.crypto.getRandomValues(array)\n const random = ((array[0] ?? 0) % 1000000).toString().padStart(6, '0')\n\n return `${year}${month}${day}${random}`\n}\n","import { Product } from '../../payload-types'\nimport { resolveRelation } from '../types'\n\ntype OrderItem = {\n product: Product | string | null | undefined\n}\n\nexport const formatOrderName = (items: OrderItem[]) => {\n if (items.length === 0) return ''\n\n const firstTitle = resolveRelation(items[0]?.product)?.title || ''\n\n return items.length === 1\n ? firstTitle\n : `${firstTitle} 외 ${items.length - 1}건`\n}\n","const MUX_IMAGE_BASE = 'https://image.mux.com'\nconst MUX_STREAM_BASE = 'https://stream.mux.com'\n\n// ── Thumbnail ──\n\nexport interface VideoThumbnailOptions {\n /** Width in pixels (default: 640) */\n width?: number\n /** Height in pixels (auto if omitted) */\n height?: number\n /** Time offset in seconds (default: 0) */\n time?: number\n /** Fit mode (default: 'smartcrop') */\n fitMode?: 'preserve' | 'stretch' | 'crop' | 'smartcrop' | 'pad'\n /** Flip horizontally */\n flipH?: boolean\n /** Flip vertically */\n flipV?: boolean\n /** Rotation in degrees (90, 180, 270) */\n rotate?: 90 | 180 | 270\n}\n\n/**\n * Returns a Mux thumbnail URL for a video.\n *\n * @example\n * ```ts\n * getVideoThumbnail('abc123')\n * // => 'https://image.mux.com/abc123/thumbnail.jpg?width=640'\n *\n * getVideoThumbnail('abc123', { width: 320, time: 5 })\n * // => 'https://image.mux.com/abc123/thumbnail.jpg?width=320&time=5'\n * ```\n */\nexport function getVideoThumbnail(\n playbackId: string,\n options?: VideoThumbnailOptions,\n): string {\n const params = new URLSearchParams()\n params.set('width', String(options?.width ?? 640))\n if (options?.height) params.set('height', String(options.height))\n if (options?.time != null) params.set('time', String(options.time))\n if (options?.fitMode) params.set('fit_mode', options.fitMode)\n if (options?.flipH) params.set('flip_h', 'true')\n if (options?.flipV) params.set('flip_v', 'true')\n if (options?.rotate) params.set('rotate', String(options.rotate))\n return `${MUX_IMAGE_BASE}/${playbackId}/thumbnail.jpg?${params}`\n}\n\n// ── Animated GIF ──\n\nexport interface VideoGifOptions {\n /** Width in pixels (default: 320) */\n width?: number\n /** Start time in seconds (default: 0) */\n start?: number\n /** End time in seconds (default: start + 5) */\n end?: number\n /** Frames per second (default: 15) */\n fps?: number\n}\n\n/**\n * Returns a Mux animated GIF URL for a video.\n *\n * @example\n * ```ts\n * getVideoGif('abc123')\n * // => 'https://image.mux.com/abc123/animated.gif?width=320'\n *\n * getVideoGif('abc123', { width: 240, start: 2, end: 6 })\n * // => 'https://image.mux.com/abc123/animated.gif?width=240&start=2&end=6'\n * ```\n */\nexport function getVideoGif(\n playbackId: string,\n options?: VideoGifOptions,\n): string {\n const params = new URLSearchParams()\n params.set('width', String(options?.width ?? 320))\n if (options?.start != null) params.set('start', String(options.start))\n if (options?.end != null) params.set('end', String(options.end))\n if (options?.fps) params.set('fps', String(options.fps))\n return `${MUX_IMAGE_BASE}/${playbackId}/animated.gif?${params}`\n}\n\n// ── Storyboard ──\n\n/**\n * Returns a Mux storyboard VTT URL for timeline hover previews.\n *\n * @example\n * ```ts\n * getVideoStoryboard('abc123')\n * // => 'https://image.mux.com/abc123/storyboard.vtt'\n * ```\n */\nexport function getVideoStoryboard(playbackId: string): string {\n return `${MUX_IMAGE_BASE}/${playbackId}/storyboard.vtt`\n}\n\n// ── Stream / Playback URLs ──\n\n/**\n * Returns the HLS stream URL for a video.\n *\n * @example\n * ```ts\n * getVideoStreamUrl('abc123')\n * // => 'https://stream.mux.com/abc123.m3u8'\n * ```\n */\nexport function getVideoStreamUrl(playbackId: string): string {\n return `${MUX_STREAM_BASE}/${playbackId}.m3u8`\n}\n\n/**\n * Returns a Mux MP4 download URL for a video.\n * Only available if the asset was created with `mp4_support` enabled.\n *\n * @example\n * ```ts\n * getVideoMp4Url('abc123', 'high')\n * // => 'https://stream.mux.com/abc123/high.mp4'\n * ```\n */\nexport function getVideoMp4Url(\n playbackId: string,\n resolution: 'high' | 'medium' | 'low' = 'high',\n): string {\n return `${MUX_STREAM_BASE}/${playbackId}/${resolution}.mp4`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAM,kBAAkB,uBAAO,IAAI,2BAA2B;AAC9D,IAAM,uBAAuB,uBAAO,IAAI,gCAAgC;AAiBxE,SAAS,oBAAoB,OAAuB;AAClD,SAAO,eAAe,OAAO,iBAAiB;AAAA,IAC5C,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,EACZ,CAAC;AACH;AAEA,SAAS,mBAAmB,OAAiB,MAA0B;AACrE,SAAO,eAAe,OAAO,sBAAsB;AAAA,IACjD,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,EACZ,CAAC;AACH;AAEO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAelC,YACE,MACA,SACA,QACA,SACA,aACA,YACA,WACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,wBAAoB,IAAI;AAExB,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,UAAU;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,iBAAyB;AACvB,WAAO,KAAK,eAAe,KAAK;AAAA,EAClC;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,SAAS,UAAa,EAAE,MAAM,KAAK,KAAK;AAAA,MACjD,GAAI,KAAK,WAAW,UAAa,EAAE,QAAQ,KAAK,OAAO;AAAA,MACvD,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,eAAe,UAAa,EAAE,YAAY,KAAK,WAAW;AAAA,IACrE;AAAA,EACF;AACF;AAOO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAqBA,IAAM,0BAA+C,IAAI;AAAA,EACvD;AACF;AACA,IAAM,+BAA+B,oBAAI,IAAI;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,cAAc,OAAkD;AACvE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAUA,SAAS,sBACP,OACA,kBACU;AACV,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,UAAU,2BAA2B,MAAM;AAAA,IAC7C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,2BACd,MACA,iBACuB;AACvB,MAAI,oBAAoB,QAAW;AACjC,UAAM,sBAAsB,2BAA2B;AAAA,EACzD;AACA,MAAI,gBAAgB,WAAW,GAAG;AAChC,UAAM,sBAAsB,yBAAyB;AAAA,EACvD;AACA,MAAI,CAAC,cAAc,IAAI,GAAG;AACxB,UAAM,sBAAsB,mBAAmB,eAAe;AAAA,EAChE;AACA,MAAI,OAAO,KAAK,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,6BAA6B,IAAI,GAAG,CAAC,GAAG;AAC3E,UAAM,sBAAsB,oBAAoB,eAAe;AAAA,EACjE;AACA,MACE,OAAO,KAAK,UAAU,YACtB,KAAK,MAAM,WAAW,KACtB,OAAO,KAAK,WAAW,YACvB,KAAK,OAAO,WAAW,KACvB,OAAO,KAAK,cAAc,YAC1B,KAAK,UAAU,WAAW,KACzB,KAAK,cAAc,UAAa,OAAO,KAAK,cAAc,aAC1D,KAAK,YAAY,UAAa,CAAC,cAAc,KAAK,OAAO,GAC1D;AACA,UAAM,sBAAsB,iBAAiB,eAAe;AAAA,EAC9D;AAEA,MAAI,oBAAoB,UAAa,oBAAoB,KAAK,WAAW;AACvE,UAAM,sBAAsB,uBAAuB,eAAe;AAAA,EACpE;AAEA,SAAO;AAAA,IACL,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,IACb,WAAW,KAAK;AAAA,IAChB,WAAW,KAAK,cAAc;AAAA,IAC9B,GAAI,KAAK,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;AAAA,EAChE;AACF;AAGO,SAAS,qBACd,OACA,MACA,iBACU;AACV,QAAM,WAAW,2BAA2B,MAAM,eAAe;AAEjE,QAAM,QAAQ,wBAAwB,IAAI,SAAS,MAAM;AACzD,SAAO,OAAO,OAAO;AAAA,IACnB,MAAM,SAAS;AAAA,IACf,MAAM;AAAA,IACN,QAAQ,QACH,SAAS,SACV;AAAA,IACJ,GAAI,QAAQ,CAAC,IAAI,EAAE,WAAW,SAAS,OAAO;AAAA,IAC9C,WAAW,SAAS;AAAA,IACpB,WAAW,SAAS;AAAA,IACpB,SAAS,SAAS;AAAA,EACpB,CAAC;AACD,SAAO;AACT;AAGO,SAAS,wBACd,OACA,QACU;AACV,MAAI,OAAO,WAAW,SAAU,QAAO,OAAO,OAAO,EAAE,WAAW,OAAO,CAAC;AAC1E,SAAO;AACT;AAMO,SAAS,kBAAkB,OAAqC;AACrE,MAAI,MAAM,SAAS,WAAY,QAAO,MAAM;AAC5C,SAAO,MAAM,WAAW,2BACpB,MAAM,YACN,MAAM;AACZ;AAEO,SAAS,mBAAmB,OAA2C;AAC5E,MAAI,CAAC,WAAW,KAAK,KAAK,MAAM,SAAS,WAAY,QAAO;AAC5D,MACE,OAAO,MAAM,cAAc,YAC3B,OAAO,MAAM,cAAc,aAC1B,MAAM,eAAe,WACnB,CAAC,OAAO,cAAc,MAAM,UAAU,KAAK,MAAM,aAAa,MACjE,OAAO,MAAM,WAAW,UACxB;AACA,WAAO;AAAA,EACT;AACA,SAAO,MAAM,WAAW,2BACpB,OAAO,MAAM,cAAc,WAC3B,wBAAwB,IAAI,MAAM,MAAM,KAAK,MAAM,cAAc;AACvE;AAEO,IAAM,eAAN,cAA2B,SAAS;AAAA,EACzC,YACE,SACA,QACA,SACA,aACA,YACA;AACA,UAAM,iBAAiB,SAAS,QAAQ,SAAS,aAAa,UAAU;AACxE,SAAK,OAAO;AACZ,uBAAmB,MAAM,cAAc;AAAA,EACzC;AACF;AAEO,IAAM,kBAAN,cAA8B,SAAS;AAAA,EAC5C,YACE,SACA,SACA,aACA,YACA,SAAS,KACT;AACA,UAAM,oBAAoB,SAAS,QAAQ,SAAS,aAAa,UAAU;AAC3E,SAAK,OAAO;AACZ,uBAAmB,MAAM,iBAAiB;AAAA,EAC5C;AACF;AAEO,IAAM,WAAN,cAAuB,SAAS;AAAA,EACrC,YACE,SACA,QACA,SACA,aACA,YACA,WACA;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,OAAO;AACZ,uBAAmB,MAAM,UAAU;AAAA,EACrC;AACF;AAEO,IAAM,cAAN,cAA0B,SAAS;AAAA,EACxC,YACE,SACA,SACA,aACA,YACA;AACA,UAAM,gBAAgB,SAAS,QAAW,SAAS,aAAa,UAAU;AAC1E,SAAK,OAAO;AACZ,uBAAmB,MAAM,aAAa;AAAA,EACxC;AACF;AAEO,IAAM,eAAN,cAA2B,SAAS;AAAA,EACzC,YACE,UAAU,sBACV,SACA,aACA,YACA;AACA,UAAM,iBAAiB,SAAS,KAAK,SAAS,aAAa,UAAU;AACrE,SAAK,OAAO;AACZ,uBAAmB,MAAM,cAAc;AAAA,EACzC;AACF;AAEO,IAAM,YAAN,cAAwB,SAAS;AAAA,EACtC,YACE,UAAU,kDACV,SACA,aACA,YACA;AACA,UAAM,cAAc,SAAS,KAAK,SAAS,aAAa,UAAU;AAClE,SAAK,OAAO;AACZ,uBAAmB,MAAM,WAAW;AAAA,EACtC;AACF;AAEO,IAAM,0BAAN,cAAsC,SAAS;AAAA,EAGpD,YACE,UAAU,oCACV,YACA,SACA,aACA,YACA;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,uBAAmB,MAAM,yBAAyB;AAAA,EACpD;AACF;AAEO,IAAM,kBAAN,cAA8B,SAAS;AAAA,EAG5C,YACE,SACA,OACA,SACA,aACA,YACA;AACA,UAAM,qBAAqB,SAAS,KAAK,SAAS,aAAa,UAAU;AACzE,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,uBAAmB,MAAM,iBAAiB;AAAA,EAC5C;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,GAAG,MAAM,OAAO;AAAA,MAChB,OAAO,KAAK;AAAA,IACd;AAAA,EACF;AACF;AAEO,IAAM,YAAN,cAAwB,SAAS;AAAA,EACtC,YACE,SACA,SACA,aACA,YACA,WACA;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,OAAO;AACZ,uBAAmB,MAAM,WAAW;AAAA,EACtC;AACF;AAEO,IAAM,kBAAN,cAA8B,SAAS;AAAA,EAC5C,YACE,SACA,SACA,aACA,YACA,WACA;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,OAAO;AACZ,uBAAmB,MAAM,iBAAiB;AAAA,EAC5C;AACF;AAEO,IAAM,gBAAN,cAA4B,SAAS;AAAA,EAC1C,YACE,SACA,SACA,aACA,YACA,WACA;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,OAAO;AACZ,uBAAmB,MAAM,eAAe;AAAA,EAC1C;AACF;AAEO,IAAM,gBAAN,cAA4B,SAAS;AAAA,EAC1C,YACE,SACA,SACA,aACA,YACA,WACA;AACA,UAAM,YAAY,SAAS,KAAK,SAAS,aAAa,YAAY,SAAS;AAC3E,SAAK,OAAO;AACZ,uBAAmB,MAAM,eAAe;AAAA,EAC1C;AACF;AAEO,IAAM,iBAAN,cAA6B,SAAS;AAAA,EAG3C,YACE,SACA,YACA,SACA,aACA,YACA,WACA;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,uBAAmB,MAAM,gBAAgB;AAAA,EAC3C;AACF;AAEA,SAAS,wBAAwB,OAAmC;AAClE,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AAExD,QAAM,YAAY;AAClB,SACE,UAAU,eAAe,MAAM,QAC/B,OAAO,UAAU,SAAS,YAC1B,OAAO,UAAU,SAAS,YAC1B,OAAO,UAAU,YAAY,aAC5B,UAAU,WAAW,UAAa,OAAO,UAAU,WAAW,cAC9D,UAAU,gBAAgB,UACzB,OAAO,UAAU,gBAAgB,cAClC,UAAU,eAAe,UACxB,OAAO,UAAU,eAAe,cACjC,UAAU,cAAc,UACvB,OAAO,UAAU,cAAc,cAChC,UAAU,SAAS,UAAa,UAAU,SAAS,gBACnD,UAAU,WAAW,UAAa,OAAO,UAAU,WAAW,cAC9D,UAAU,cAAc,UACvB,OAAO,UAAU,cAAc,cAChC,UAAU,cAAc,UACvB,OAAO,UAAU,cAAc,cAChC,UAAU,cAAc,UACvB,OAAO,UAAU,cAAc,eAChC,UAAU,eAAe,UACxB,OAAO,UAAU,eAAe,aAClC,OAAO,UAAU,mBAAmB,cACpC,OAAO,UAAU,WAAW;AAEhC;AAEA,SAAS,gBAAgB,OAAgB,MAA6B;AACpE,SACE,wBAAwB,KAAK,KAC5B,MAAkD,oBAAoB,MACrE;AAEN;AAEO,SAAS,WAAW,OAAmC;AAC5D,SAAO,iBAAiB,YAAY,wBAAwB,KAAK;AACnE;AAEO,SAAS,eAAe,OAAuC;AACpE,SAAO,iBAAiB,gBAAgB,gBAAgB,OAAO,cAAc;AAC/E;AAEO,SAAS,kBAAkB,OAA0C;AAC1E,MACE,iBAAiB,mBACjB,gBAAgB,OAAO,iBAAiB,GACxC;AACA,WAAO;AAAA,EACT;AACA,MAAI,SAAS,QAAQ,OAAO,UAAU,SAAU,QAAO;AAEvD,QAAM,YAAY;AAOlB,SACE,UAAU,SAAS,qBACnB,UAAU,SAAS,sBACnB,OAAO,UAAU,YAAY,YAC7B,OAAO,UAAU,mBAAmB,cACpC,OAAO,UAAU,WAAW;AAEhC;AAEO,SAAS,WAAW,OAAmC;AAC5D,SAAO,iBAAiB,YAAY,gBAAgB,OAAO,UAAU;AACvE;AAEO,SAAS,cAAc,OAAsC;AAClE,SAAO,iBAAiB,eAAe,gBAAgB,OAAO,aAAa;AAC7E;AAEO,SAAS,eAAe,OAAuC;AACpE,SAAO,iBAAiB,gBAAgB,gBAAgB,OAAO,cAAc;AAC/E;AAEO,SAAS,YAAY,OAAoC;AAC9D,SAAO,iBAAiB,aAAa,gBAAgB,OAAO,WAAW;AACzE;AAEO,SAAS,0BACd,OACkC;AAClC,SACE,iBAAiB,2BACjB,gBAAgB,OAAO,yBAAyB;AAEpD;AAEO,SAAS,kBAAkB,OAA0C;AAC1E,SACE,iBAAiB,mBACjB,gBAAgB,OAAO,iBAAiB;AAE5C;AAEO,SAAS,YAAY,OAAoC;AAC9D,SAAO,iBAAiB,aAAa,gBAAgB,OAAO,WAAW;AACzE;AAEO,SAAS,kBAAkB,OAA0C;AAC1E,SACE,iBAAiB,mBACjB,gBAAgB,OAAO,iBAAiB;AAE5C;AAEO,SAAS,gBAAgB,OAAwC;AACtE,SACE,iBAAiB,iBAAiB,gBAAgB,OAAO,eAAe;AAE5E;AAEO,SAAS,gBAAgB,OAAwC;AACtE,SACE,iBAAiB,iBAAiB,gBAAgB,OAAO,eAAe;AAE5E;AAEO,SAAS,iBAAiB,OAAyC;AACxE,SACE,iBAAiB,kBAAkB,gBAAgB,OAAO,gBAAgB;AAE9E;AAEO,IAAM,qBAAqB,CAChC,SACA,QACA,SACA,aACA,eACG,IAAI,aAAa,SAAS,QAAQ,SAAS,aAAa,UAAU;AAEhE,IAAM,wBAAwB,CACnC,SACA,SACA,aACA,YACA,WACG,IAAI,gBAAgB,SAAS,SAAS,aAAa,YAAY,MAAM;AAEnE,IAAM,iBAAiB,CAC5B,SACA,QACA,SACA,aACA,YACA,cACG,IAAI,SAAS,SAAS,QAAQ,SAAS,aAAa,YAAY,SAAS;AAEvE,IAAM,oBAAoB,CAC/B,SACA,SACA,aACA,eACG,IAAI,YAAY,SAAS,SAAS,aAAa,UAAU;AAEvD,IAAM,qBAAqB,CAChC,SACA,SACA,aACA,eACG,IAAI,aAAa,SAAS,SAAS,aAAa,UAAU;AAExD,IAAM,kBAAkB,CAC7B,SACA,SACA,aACA,eACG,IAAI,UAAU,SAAS,SAAS,aAAa,UAAU;AAErD,IAAM,gCAAgC,CAC3C,SACA,YACA,SACA,aACA,eAEA,IAAI;AAAA,EACF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEK,IAAM,wBAAwB,CACnC,SACA,OACA,SACA,aACA,eACG,IAAI,gBAAgB,SAAS,OAAO,SAAS,aAAa,UAAU;AAElE,IAAM,kBAAkB,CAC7B,SACA,SACA,aACA,YACA,cACG,IAAI,UAAU,SAAS,SAAS,aAAa,YAAY,SAAS;AAEhE,IAAM,wBAAwB,CACnC,SACA,SACA,aACA,YACA,cACG,IAAI,gBAAgB,SAAS,SAAS,aAAa,YAAY,SAAS;AAEtE,IAAM,sBAAsB,CACjC,SACA,SACA,aACA,YACA,cACG,IAAI,cAAc,SAAS,SAAS,aAAa,YAAY,SAAS;AAEpE,IAAM,sBAAsB,CACjC,SACA,SACA,aACA,YACA,cACG,IAAI,cAAc,SAAS,SAAS,aAAa,YAAY,SAAS;AAEpE,IAAM,uBAAuB,CAClC,SACA,YACA,SACA,aACA,YACA,cAEA,IAAI;AAAA,EACF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACr2BK,SAAS,+BACd,SACA,gBACA,WACQ;AACR,MAAI,aAAa,CAAC,gBAAgB;AAChC,UAAM;AAAA,MACJ,kCAAkC,OAAO;AAAA,IAE3C;AAAA,EACF;AAEA,SAAO,kBAAkB;AAC3B;;;ACbO,SAAS,cAAc,QAAyB;AACrD,MAAI,QAAQ;AACV,WAAO,OAAO,QAAQ,OAAO,EAAE;AAAA,EACjC;AAEA,MAAI,OAAO,YAAY,eAAe,QAAQ,KAAK;AACjD,UAAM,SACJ,QAAQ,IAAI,oBAAoB,QAAQ,IAAI;AAC9C,QAAI,QAAQ;AACV,aAAO,OAAO,QAAQ,OAAO,EAAE;AAAA,IACjC;AAAA,EACF;AACA,SAAO;AACT;;;ACSA,IAAM,kBAAkB;AACxB,IAAM,6BAA6B;AAGnC,IAAM,6BAA6B,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG;AAC3D,IAAM,yBAAyB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC5D,IAAM,eAAe,CAAC,OAAO,QAAQ,SAAS;AAC9C,IAAM,sBAAsB;AAC5B,IAAM,iCAAiC;AAGvC,IAAM,oCAAoC,IAAI;AAkB9C,SAAS,SACP,OACA,MACA,SACA,MACA;AACA,MAAI,CAAC,MAAO;AAEZ,QAAM,YACJ,UAAU,QACT,SAAS,aAAc,MAAsB,eAC7C,SAAS,cAAe,MAAsB,gBAC9C,SAAS,WAAY,MAAsB;AAE9C,MAAI,WAAW;AACb,YAAQ,MAAM,QAAQ,KAAK,YAAY,CAAC,KAAK,OAAO,EAAE;AACtD,QAAI,KAAM,SAAQ,IAAI,IAAI;AAC1B,YAAQ,SAAS;AAAA,EACnB;AACF;AAEA,SAAS,sBAAsB,OAAuB;AACpD,QAAM,SAAS,MAAM,YAAY,EAAE,WAAW,SAAS,IAAI,YAAY;AACvE,SAAO,MAAM,SAAS,KAAK,GAAG,MAAM,UAAU,MAAM,MAAM,EAAE,CAAC,KAAK;AACpE;AAEA,SAAS,uBAAuB,SAA0C;AACxE,QAAM,WAAW,OAAO,YAAY,QAAQ,QAAQ,CAAC;AACrD,MAAI,SAAS,eAAe;AAC1B,aAAS,gBAAgB,sBAAsB,SAAS,aAAa;AAAA,EACvE;AACA,MAAI,SAAS,iBAAiB,GAAG;AAC/B,aAAS,iBAAiB,IAAI;AAAA,MAC5B,SAAS,iBAAiB;AAAA,IAC5B;AAAA,EACF;AACA,MAAI,SAAS,4BAA4B,GAAG;AAC1C,aAAS,4BAA4B,IAAI;AAAA,MACvC,SAAS,4BAA4B;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,QAAoC;AAC9D,MAAI,WAAW;AACb,WAAO;AACT,MAAI,WAAW,IAAK,QAAO;AAC3B,MAAI,WAAW;AACb,WAAO;AACT,MAAI,WAAW,IAAK,QAAO;AAC3B,MAAI,WAAW,IAAK,QAAO;AAC3B,MAAI,UAAU,IAAK,QAAO;AAC1B,SAAO;AACT;AAEA,SAAS,6BAA6B,UAA6B;AACjE,MAAI,SAAS,WAAW,IAAK,QAAO;AAEpC,QAAM,QAAQ,SAAS,SAAS,QAAQ,IAAI,eAAe,KAAK,IAAI,EAAE;AACtE,QAAM,UAAU,SAAS,SAAS,QAAQ,IAAI,iBAAiB,KAAK,IAAI,EAAE;AAC1E,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,SAAS,OAAO,EAAG,QAAO;AAEjE,SAAO,SAAS,QAAQ,IAAI,kBAAkB,MAAM,UAAU,UAAU;AAC1E;AASA,eAAe,eAAe,UAY3B;AACD,QAAM,WAAW;AAAA,IACf,cAAc,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU;AAAA,IAC7D,aAAa,2BAA2B,SAAS,MAAM;AAAA,EACzD;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,SACJ,OAAO,KAAK,WAAW,WACnB,KAAK,SACL,OAAO,KAAK,SAAS,WACnB,KAAK,OACL;AACR,UAAM,qBAAqB,MAAM,QAAQ,KAAK,MAAM,IAChD,uBAAuB,KAAK,MAAM,IAClC;AACJ,UAAM,qBACJ,uBAAuB,SAAY,EAAE,mBAAmB,IAAI,CAAC;AAG/D,QAAI,KAAK,UAAU,MAAM,QAAQ,KAAK,MAAM,GAAG;AAG7C,YAAM,cAA2D,CAAC;AAClE,iBAAW,KAAK,KAAK,QAAQ;AAC3B,YACE,EAAE,MAAM,UACR,MAAM,QAAQ,EAAE,KAAK,MAAM,KAC3B,EAAE,KAAK,OAAO,SAAS,GACvB;AACA,qBAAW,MAAM,EAAE,KAAK,QAAQ;AAC9B,wBAAY,KAAK;AAAA,cACf,OAAO,GAAG,QAAQ,GAAG;AAAA,cACrB,SAAS,GAAG;AAAA,YACd,CAAC;AAAA,UACH;AAAA,QACF,WAAW,EAAE,SAAS,EAAE,SAAS;AAC/B,sBAAY,KAAK,EAAE,OAAO,EAAE,OAAO,SAAS,EAAE,QAAQ,CAAC;AAAA,QACzD;AAAA,MACF;AAEA,YAAM,WAAW,YAAY,SAAS,IAAI,cAAc,KAAK,QAC1D;AAAA,QAAI,CAAC,MACJ,EAAE,QAAQ,GAAG,EAAE,KAAK,KAAK,EAAE,OAAO,KAAK,EAAE;AAAA,MAC3C,EACC,OAAO,OAAO,EACd,KAAK,IAAI;AACZ,UAAI,SAAS;AACX,eAAO;AAAA,UACL,cAAc,QAAQ,SAAS,MAAM,KAAK,OAAO;AAAA,UACjD,aAAa;AAAA,UACb;AAAA,UACA,GAAG;AAAA,UACH;AAAA,UACA,QAAQ,YAAY,SAAS,IAAI,cAAc,KAAK;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,KAAK,UAAU,UAAU;AAClC,aAAO;AAAA,QACL,cAAc,QAAQ,SAAS,MAAM,KAAK,KAAK,KAAK;AAAA,QACpD,aAAa,KAAK;AAAA,QAClB;AAAA,QACA,GAAG;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,QAAI,KAAK,SAAS;AAChB,aAAO;AAAA,QACL,cAAc,QAAQ,SAAS,MAAM,KAAK,KAAK,OAAO;AAAA,QACtD,aAAa,KAAK;AAAA,QAClB;AAAA,QACA,GAAG;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,GAAG,UAAU,QAAQ,GAAG,oBAAoB,KAAK;AAAA,EAC5D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,uBAAuB,QAAuC;AACrE,QAAM,OAAQ,OAAO,CAAC,GAA6C;AACnE,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,MAAI,OAAO,WAAW,SAAU,QAAO;AACvC,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,SAAO;AACT;AAEA,SAAS,yBACP,QACA,QACoB;AACpB,MAAI,WAAW,OAAO,OAAO,WAAW,sBAAsB;AAC5D,WAAO;AAAA,EACT;AAEA,SAAO,mBAAmB,MAAM;AAClC;AAEA,eAAe,MAAM,IAA2B;AAC9C,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAGO,SAAS,gBACd,KACA,IACG;AACH,MAAI,GAAI,CAAC,IAAgC,YAAY;AACrD,SAAO;AACT;AAEO,SAAS,gBAAgB,UAG9B;AACA,QAAM,MAAM,SAAS,QAAQ,IAAI,aAAa;AAC9C,MAAI,CAAC,IAAK,QAAO,EAAE,uBAAuB,KAAK;AAE/C,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI;AACJ,MAAI,QAAQ,KAAK,OAAO,GAAG;AACzB,cAAU,OAAO,OAAO;AACxB,QAAI,CAAC,OAAO,cAAc,OAAO,GAAG;AAClC,aAAO,EAAE,uBAAuB,MAAM;AAAA,IACxC;AAAA,EACF,OAAO;AACL,UAAM,UAAU,KAAK,MAAM,OAAO;AAClC,QAAI,CAAC,OAAO,SAAS,OAAO,EAAG,QAAO,EAAE,uBAAuB,KAAK;AACpE,cAAU,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,KAAK,IAAI,KAAK,GAAI,CAAC;AAAA,EAChE;AAEA,SAAO;AAAA,IACL;AAAA,IACA,uBAAuB,WAAW;AAAA,EACpC;AACF;AAOA,SAAS,mBACP,QACA,QACA,SACA,WACA,YACA,wBACU;AACV,QAAM,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,GAAI,OAAO,UAAU,EAAE,QAAQ,OAAO,OAAO;AAAA,IAC7C,GAAI,CAAC,0BAA0B,OAAO,QAAQ,EAAE,MAAM,OAAO,KAAK;AAAA,EACpE;AACA,QAAM,aAAa,yBAAyB,QAAQ,MAAM;AAC1D,QAAM,WAAW,CAAC,UAA8B;AAC9C,UAAM,gBAAgB,gBAAgB,OAAO,SAAS;AACtD,QAAI,eAAe,QAAW;AAC5B,aAAO,OAAO,eAAe,EAAE,WAAW,CAAC;AAAA,IAC7C;AACA,WAAO,yBACH,qBAAqB,eAAe,OAAO,MAAM,SAAS,IAC1D;AAAA,MACE;AAAA,MACA,OAAO,UAAU,OAAO;AAAA,IAC1B;AAAA,EACN;AAEA,MAAI,WAAW,OAAO,WAAW,KAAK;AACpC,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,KAAK;AAClB,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,KAAK;AAClB,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,KAAK;AAClB,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,KAAK;AAClB,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,KAAK;AAClB,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,KAAK;AAGlB,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,KAAK;AAClB,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,MACE,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,UACpB,KACA,SACmB;AACnB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,gBAAgB;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI,WAAW,CAAC;AAEhB,QAAM,UAAU,cAAc,MAAM;AACpC,QAAM,UAAU,YAAY,UAAU,OAAO,YAAY;AACzD,QAAM,6BACJ,OAAO,WAAW,eAClB,CAAC,aACD,CAAC,iBACD,QAAQ,cAAc,KACtB,aAAa,SAAS,MAAM;AAE9B,QAAM,UACJ,kBAAkB,mBAAmB,6BACjC,6BACA;AAEN,QAAM,cAAc;AAAA,IAClB,YACE,OAAO,eACN,6BACG,iCACA;AAAA,IACN,mBAAmB,OAAO,qBAAqB;AAAA,IAC/C,YACE,OAAO,eACN,CAAC,YAAoB,KAAK,IAAI,MAAO,KAAK,SAAS,GAAK;AAAA,EAC7D;AAIA,MAAI;AACJ,MAAI,WAAW;AACb,gBAAY;AAAA,EACd,WAAW,eAAe;AACxB,gBAAY;AAAA,EACd;AAEA,MAAI;AACJ,MAAI,gBAAgB;AAEpB,WAAS,UAAU,GAAG,WAAW,YAAY,YAAY,WAAW;AAClE,QAAI;AACJ,QAAI;AACF,YAAM,UAAU,IAAI,QAAQ,YAAY,OAAO;AAE/C,UAAI,gBAAgB;AAClB,gBAAQ,IAAI,qBAAqB,cAAc;AAAA,MACjD;AAEA,UAAI,WAAW;AACb,gBAAQ,IAAI,iBAAiB,UAAU,SAAS,EAAE;AAAA,MACpD;AAEA,UACE,CAAC,QAAQ,IAAI,cAAc,KAC3B,YAAY,QACZ,EAAE,YAAY,gBAAgB,WAC9B;AACA,gBAAQ,IAAI,gBAAgB,kBAAkB;AAAA,MAChD;AAGA,YAAM,kBAAkB,uBAAuB,OAAO;AAEtD,eAAS,OAAO,WAAW,KAAK;AAAA,QAC9B,QAAQ,YAAY,UAAU;AAAA,QAC9B,SAAS;AAAA,QACT,SAAS,UAAU;AAAA,MACrB,CAAC;AAED,YAAM,aAAa,IAAI,gBAAgB;AACvC,YAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,OAAO;AAE9D,YAAM,WAAW,MAAM,MAAM,GAAG,OAAO,GAAG,GAAG,IAAI;AAAA,QAC/C,GAAG;AAAA,QACH;AAAA,QACA,QAAQ,WAAW;AAAA,MACrB,CAAC;AAED,mBAAa,SAAS;AAEtB,YAAM,YAAY,SAAS,QAAQ,IAAI,cAAc,KAAK;AAE1D,eAAS,OAAO,YAAY,KAAK;AAAA,QAC/B,QAAQ,SAAS;AAAA,QACjB,YAAY,SAAS;AAAA,QACrB,SAAS,uBAAuB,SAAS,OAAO;AAAA,MAClD,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAGhB,cAAM,SAAS,MAAM,eAAe,QAAQ;AAC5C,cAAM,yBACJ,gBAAgB,cACf,OAAO,OAAO,WAAW,YACxB,2BAA2B,SAAS,OAAO,MAAM,MAAM;AAC3D,cAAM,mBAAmB,yBACrB,2BAA2B,OAAO,MAAM,SAAS,IACjD;AAKJ,YAAI,6BAA6B,QAAQ,GAAG;AAC1C,gBAAM,QAAQ;AAAA,YACZ,SAAS,QAAQ,IAAI,eAAe,KAAK;AAAA,YACzC;AAAA,UACF;AACA,gBAAM,UAAU;AAAA,YACd,SAAS,QAAQ,IAAI,iBAAiB,KAAK;AAAA,YAC3C;AAAA,UACF;AACA,gBAAM,YAAY;AAAA,YAChB,SAAS,QAAQ,IAAI,mBAAmB,KAAK;AAAA,YAC7C;AAAA,UACF;AAEA,gBAAM,aAAa;AAAA,YACjB;AAAA,cACE,qCAAqC,QAAQ,eAAe,OAAO,CAAC,IAAI,MAAM,eAAe,OAAO,CAAC;AAAA,cACrG,EAAE,OAAO,SAAS,UAAU;AAAA,cAC5B;AAAA,gBACE;AAAA,gBACA,QAAQ,YAAY,UAAU;AAAA,gBAC9B,SAAS,UAAU;AAAA,cACrB;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,YACA;AAAA,UACF;AACA,gBAAM,yBACF,qBAAqB,YAAY,OAAO,MAAM,SAAS,IACvD,wBAAwB,YAAY,OAAO,MAAM;AAAA,QACvD;AAGA,YACE,SAAS,WAAW,OACpB,kBACA,iBACA,CAAC,kBACA,kBAAkB,UAAU,OAAO,YAAY,iBAChD;AACA,0BAAgB;AAChB,cAAI;AACF,kBAAM,WAAW,MAAM,eAAe;AACtC,gBACE,YACA,aAAa,UAAU,YAAY,UAAU,OAAO,YAAY,CAAC,GACjE;AACA,0BAAY;AAGZ;AACA;AAAA,YACF;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAEA,cAAM,UAAU;AAAA,UACd;AAAA,UACA,QAAQ,YAAY,UAAU;AAAA,UAC9B,SAAS,UAAU;AAAA,QACrB;AAEA,cAAM,aAAa,gBAAgB,QAAQ;AAC3C,cAAM,QAAQ;AAAA,UACZ,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAW;AAAA,UACX;AAAA,QACF;AAEA,cAAMC,WAAU,YAAY,UAAU,OAAO,YAAY;AAGzD,cAAM,aACJ,iBAAiB,kBAAkB,iBAAiB;AACtD,cAAM,sBAAsB,mBAAmB,KAAK,IAChD,MAAM,YACN;AACJ,YACE,UAAU,YAAY,cACtB,aAAa,SAASA,OAAM,KAC5B,CAAC,cACD,uBACA,WAAW,yBACX,CAAC,uBAAuB,SAAS,SAAS,MAAM,KAChD,YAAY,kBAAkB,SAAS,SAAS,MAAM,GACtD;AACA,sBAAY;AACZ,gBAAM,aAAa,KAAK;AAAA,YACtB,YAAY,WAAW,OAAO;AAAA,aAC7B,WAAW,WAAW,KAAK;AAAA,UAC9B;AACA,mBAAS,OAAO,SAAS,eAAe,UAAU,SAAS,KAAK;AAChE,gBAAM,MAAM,UAAU;AACtB;AAAA,QACF;AAEA,gCAAwB;AACxB,cAAM;AAAA,MACR;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,eAAS,OAAO,SAAS,KAAK,KAAK;AAInC,UAAI,yBAAyB,UAAU,uBAAuB;AAC5D,cAAM;AAAA,MACR;AAEA,YAAMA,WAAU,YAAY,UAAU,OAAO,YAAY;AACzD,YAAM,SAAS,aAAa,SAASA,OAAM;AAE3C,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,cAAM,eAAe;AAAA,UACnB,2BAA2B,OAAO;AAAA,UAClC,EAAE,KAAK,SAAS,SAAS,UAAU,EAAE;AAAA,UACrC;AAAA,UACA;AAAA,QACF;AAEA,YAAI,UAAU,UAAU,YAAY,YAAY;AAC9C,sBAAY;AACZ,gBAAM,MAAM,YAAY,WAAW,OAAO,CAAC;AAC3C;AAAA,QACF;AAEA,cAAM;AAAA,MACR;AAEA,UAAI,iBAAiB,WAAW;AAC9B,cAAM,eAAe;AAAA,UACnB;AAAA,UACA;AAAA,UACA,EAAE,KAAK,eAAe,MAAM,SAAS,SAAS,UAAU,EAAE;AAAA,UAC1D;AAAA,UACA;AAAA,QACF;AAEA,YAAI,UAAU,UAAU,YAAY,YAAY;AAC9C,sBAAY;AACZ,gBAAM,MAAM,YAAY,WAAW,OAAO,CAAC;AAC3C;AAAA,QACF;AAEA,cAAM;AAAA,MACR;AAEA,UAAI,iBAAiB,gBAAgB,iBAAiB,cAAc;AAClE,YACE,UACA,UAAU,YAAY,cACtB,MAAM,UACN,CAAC,uBAAuB,SAAS,MAAM,MAAM,KAC7C,YAAY,kBAAkB,SAAS,MAAM,MAAM,GACnD;AACA,sBAAY;AACZ,gBAAM,MAAM,YAAY,WAAW,OAAO,CAAC;AAC3C;AAAA,QACF;AAEA,cAAM;AAAA,MACR;AAGA,UAAI,iBAAiB,UAAU;AAC7B,cAAM;AAAA,MACR;AAEA,YAAM,eAAe;AAAA,QACnB,iBAAiB,QACb,MAAM,UACN;AAAA,QACJ;AAAA,QACA,EAAE,KAAK,eAAe,OAAO,SAAS,UAAU,EAAE;AAAA,QAClD;AAAA,QACA;AAAA,MACF;AAEA,UAAI,UAAU,UAAU,YAAY,YAAY;AAC9C,oBAAY;AACZ,cAAM,MAAM,YAAY,WAAW,OAAO,CAAC;AAC3C;AAAA,MACF;AAEA,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,aAAa,8BAA8B;AACpE;;;AC9tBA,SAAS,iBAAiB,OAA+C;AACvE,QAAM,SAAS,OAAO,KAAK;AAC3B,SAAO,UAAU;AACnB;AAOA,SAAS,gCACP,QACA,SACM;AACN,MAAI,SAAS,OAAQ,QAAO,IAAI,UAAU,QAAQ,MAAM;AACxD,MAAI,SAAS,mBAAmB,QAAW;AACzC,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,mBAAmB,QAAQ,SAAS,QAAQ;AAAA,IACtD;AAAA,EACF;AACF;AAEO,SAAS,0BACd,QAGQ;AACR,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,UAAU,QAAQ;AACpB,WAAO,IAAI,QAAQ,OAAO,IAAI;AAAA,EAChC,OAAO;AACL,WAAO,IAAI,MAAM,OAAO,EAAE;AAAA,EAC5B;AACA,QAAM,SAAS,iBAAiB,OAAO,MAAM;AAC7C,MAAI,OAAQ,QAAO,IAAI,UAAU,MAAM;AACvC,kCAAgC,QAAQ,MAAM;AAC9C,SAAO,OAAO,SAAS;AACzB;AAEO,SAAS,0BACd,QAIQ;AACR,QAAM,MAAM,OAAO,WAAW,IAAI,kBAAkB,EAAE,KAAK,GAAG;AAC9D,QAAM,SAAS,IAAI,gBAAgB;AACnC,QAAM,SAAS,iBAAiB,OAAO,MAAM;AAC7C,MAAI,OAAQ,QAAO,IAAI,UAAU,MAAM;AACvC,kCAAgC,QAAQ,MAAM;AAC9C,QAAM,QAAQ,OAAO,SAAS;AAC9B,SAAO,OAAO,GAAG,GAAG,QAAQ,IAAI,KAAK,KAAK,EAAE;AAC9C;AAYA,SAAS,qCACP,QACA,SACM;AACN,QAAM,SAAS,iBAAiB,SAAS,MAAM;AAC/C,MAAI,OAAQ,QAAO,IAAI,UAAU,MAAM;AACvC,kCAAgC,QAAQ,OAAO;AAC/C,MAAI,SAAS,QAAQ,KAAM,QAAO,IAAI,QAAQ,OAAO,QAAQ,IAAI,CAAC;AAClE,MAAI,SAAS,SAAS,KAAM,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AACrE,MAAI,SAAS,QAAQ,MAAM;AACzB,UAAM,OAAO,QAAQ;AACrB,WAAO,IAAI,QAAQ,MAAM,QAAQ,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI,IAAI;AAAA,EAChE;AACA,MAAI,SAAS,SAAS,MAAM;AAC1B,WAAO,IAAI,aAAa,KAAK,UAAU,QAAQ,KAAK,CAAC;AAAA,EACvD;AACF;AAGO,SAAS,wBACd,SACQ;AACR,QAAM,SAAS,IAAI,gBAAgB;AACnC,uCAAqC,QAAQ,OAAO;AACpD,SAAO,OAAO,SAAS;AACzB;AAEO,SAAS,0BAA0B,QAE/B;AACT,SAAO,cAAc,OAAO,WAAW,IAAI,kBAAkB,EAAE,KAAK,GAAG,CAAC;AAC1E;;;ACjFA,eAAsB,iBACpB,UACA,UACA,UAAwC,CAAC,GAC7B;AACZ,MACE,SAAS,WAAW,OACpB,SAAS,QAAQ,IAAI,gBAAgB,MAAM,KAC3C;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,SAAS,KAAK;AAAA,EAC/B,QAAQ;AACN,UAAM;AAAA,MACJ,8BAA8B,QAAQ;AAAA,MACtC,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAOA,MAAI,WAAW,QAAQ,OAAO,WAAW,UAAU;AACjD,WAAO;AAAA,EACT;AACA,QAAM,OAAO;AACb,QAAM,4BACJ,QAAQ,gBAAgB,cACxB,CAAC,SAAS,UAAU,aAAa,aAAa,SAAS,EAAE;AAAA,IAAK,CAAC,QAC7D,OAAO,UAAU,eAAe,KAAK,MAAM,GAAG;AAAA,EAChD;AAEF,MAAI,KAAK,SAAS,2BAA2B;AAC3C,UAAM,eACJ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAChD,UAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,UAAM,YAAY,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC1D,UAAM,aAAa,gBAAgB,QAAQ,EAAE;AAE7C,QAAI;AACJ,QAAI,WAAW,qBAAqB;AAClC,cAAQ,sBAAsB,cAAc,MAAM,YAAY;AAAA,IAChE,WACE,WAAW,mBACX,WAAW,mBACX,WAAW,2BACX,WAAW,4BACX,WAAW,iBACX,WAAW,eACX;AACA,cAAQ,gBAAgB,cAAc,MAAM,YAAY;AAAA,IAC1D,WAAW,WAAW,aAAa;AACjC,cAAQ,sBAAsB,cAAc,MAAM,YAAY;AAAA,IAChE,WAAW,WAAW,uBAAuB;AAC3C,cAAQ,qBAAqB,cAAc,YAAY,MAAM,YAAY;AAAA,IAC3E,WAAW,WAAW,aAAa;AACjC,cAAQ,oBAAoB,cAAc,MAAM,YAAY;AAAA,IAC9D,WAAW,WAAW,YAAY;AAChC,cAAQ,oBAAoB,cAAc,MAAM,YAAY;AAAA,IAC9D,OAAO;AACL,cAAQ;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,gBAAgB,gBAAgB,OAAO,SAAS;AACtD,QAAI,eAAe,OAAW,QAAO,OAAO,eAAe,EAAE,WAAW,CAAC;AACzE,UAAM,QAAQ,gBAAgB,aAC1B,qBAAqB,eAAe,MAAM,SAAS,IACnD,wBAAwB,eAAe,MAAM;AAAA,EACnD;AAEA,SAAO;AACT;;;ACxGA,IAAM,iBAAgC,uBAAO,oBAAoB;AAY1D,IAAM,kDACX;AAgBK,IAAM,qCACX;AAsBF,IAAM,YAAY,CAKhB,YACA,QACA,MACA,gBAEA,OAAO,OAAO;AAAA,EACZ,CAAC,cAAc,GAAG;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAI,eAAe,EAAE,YAAY;AACnC,CAAU;AAEZ,IAAM,0BAA0B,CAK9B,YACA,QACA,SACG,UAAU,YAAY,QAAQ,MAAM,UAAU;AAEnD,IAAM,6BAA6B,CAMjC,YACA,QACA,MACA,8BAEA,OAAO,OAAO;AAAA,EACZ,GAAG,UAAU,YAAY,QAAQ,IAAI;AAAA,EACrC,2BAA2B,OAAO,OAAO,CAAC,GAAG,yBAAyB,CAAC;AACzE,CAAU;AAEL,IAAM,+BAA+B;AAAA,EAC1C,UAAU;AAAA,IACR,QAAQ,UAAU,YAAY,OAAO,SAAS;AAAA,IAC9C,eAAe,UAAU,YAAY,OAAO,iBAAiB;AAAA,IAC7D,eAAe,UAAU,YAAY,OAAO,iBAAiB;AAAA,IAC7D,sBAAsB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,oBAAoB,UAAU,YAAY,QAAQ,uBAAuB;AAAA,IACzE,uBAAuB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,2BAA2B;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY,UAAU,YAAY,QAAQ,cAAc;AAAA,IACxD,eAAe,UAAU,YAAY,OAAO,QAAQ;AAAA,IACpD,QAAQ,UAAU,YAAY,QAAQ,SAAS;AAAA,IAC/C,eAAe,UAAU,YAAY,OAAO,qBAAqB;AAAA,IACjE,eAAe,UAAU,YAAY,SAAS,eAAe;AAAA,EAC/D;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ,UAAU,UAAU,QAAQ,SAAS;AAAA,IAC7C,QAAQ,UAAU,UAAU,QAAQ,SAAS;AAAA,IAC7C,gBAAgB,UAAU,UAAU,QAAQ,kBAAkB;AAAA,IAC9D,WAAW,UAAU,UAAU,OAAO,aAAa;AAAA,IACnD,QAAQ,UAAU,UAAU,QAAQ,SAAS;AAAA,IAC7C,qBAAqB;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,sCAAsC;AAAA,IACzC;AAAA,IACA,UAAU,wBAAwB,UAAU,QAAQ,WAAW;AAAA,IAC/D,mBAAmB,UAAU,UAAU,QAAQ,qBAAqB;AAAA,IACpE,mBAAmB,UAAU,UAAU,QAAQ,qBAAqB;AAAA,EACtE;AAAA,EACA,WAAW;AAAA,IACT,QAAQ,wBAAwB,aAAa,QAAQ,SAAS;AAAA,IAC9D,OAAO,wBAAwB,aAAa,QAAQ,QAAQ;AAAA,EAC9D;AAAA,EACA,aAAa;AAAA,IACX,WAAW,UAAU,gBAAgB,QAAQ,gBAAgB;AAAA,IAC7D,UAAU,UAAU,gBAAgB,QAAQ,eAAe;AAAA,IAC3D,UAAU,UAAU,gBAAgB,QAAQ,eAAe;AAAA,EAC7D;AAAA,EACA,cAAc;AAAA,IACZ,QAAQ,UAAU,gBAAgB,QAAQ,SAAS;AAAA,EACrD;AAAA,EACA,SAAS;AAAA,IACP,QAAQ,UAAU,WAAW,QAAQ,SAAS;AAAA,IAC9C,QAAQ,UAAU,WAAW,QAAQ,SAAS;AAAA,IAC9C,cAAc,UAAU,WAAW,QAAQ,gBAAgB;AAAA,EAC7D;AAAA,EACA,mBAAmB;AAAA,IACjB,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ,YAAY,UAAU,gBAAgB,QAAQ,cAAc;AAAA,EAC9D;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,wBAAwB,SAAS,QAAQ,SAAS;AAAA,IAC1D,UAAU,wBAAwB,SAAS,QAAQ,WAAW;AAAA,IAC9D,MAAM,wBAAwB,SAAS,QAAQ,OAAO;AAAA,IACtD,OAAO,wBAAwB,SAAS,QAAQ,QAAQ;AAAA,IACxD,SAAS,wBAAwB,SAAS,QAAQ,WAAW;AAAA,IAC7D,YAAY,wBAAwB,SAAS,QAAQ,cAAc;AAAA,IACnE,YAAY,wBAAwB,SAAS,QAAQ,cAAc;AAAA,IACnE,qBAAqB;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,kBAAkB;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,OAAO,wBAAwB,SAAS,QAAQ,QAAQ;AAAA,EAC1D;AAAA,EACA,iBAAiB;AAAA,IACf,QAAQ,wBAAwB,oBAAoB,QAAQ,SAAS;AAAA,IACrE,UAAU,wBAAwB,oBAAoB,QAAQ,WAAW;AAAA,IACzE,QAAQ,wBAAwB,oBAAoB,QAAQ,SAAS;AAAA,IACrE,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,aAAa;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,kBAAkB;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ,UAAU,UAAU,QAAQ,0BAA0B;AAAA,MAC9D,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,SAAS,UAAU,UAAU,QAAQ,kCAAkC;AAAA,IACzE;AAAA,EACF;AAAA,EACA,kBAAkB;AAAA,IAChB,WAAW,UAAU,qBAAqB,QAAQ,YAAY;AAAA,EAChE;AAAA,EACA,WAAW;AAAA,IACT,UAAU,UAAU,aAAa,QAAQ,WAAW;AAAA,EACtD;AACF;AAEA,IAAM,4CAA4C,oBAAI,IAAmB;AAAA,EACvE,6BAA6B,gBAAgB;AAAA,EAC7C,6BAA6B,gBAAgB;AAAA,EAC7C,6BAA6B,gBAAgB,OAAO;AAAA,EACpD,6BAA6B,gBAAgB,OAAO;AACtD,CAAC;AAeM,IAAM,iCAAiC;AAAA,EAC5C,WAAW,UAAU,MAAM,QAAQ,wBAAwB;AAAA,EAC3D,oBAAoB;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,gBAAgB,UAAU,MAAM,QAAQ,8BAA8B;AAAA,EACtE,QAAQ,UAAU,MAAM,QAAQ,yBAAyB;AAAA,EACzD,IAAI,UAAU,MAAM,OAAO,iBAAiB;AAAA,EAC5C,cAAc,UAAU,MAAM,QAAQ,gCAAgC;AAAA,EACtE,cAAc,UAAU,MAAM,QAAQ,gCAAgC;AAAA,EACtE,QAAQ,UAAU,MAAM,QAAQ,yBAAyB;AAC3D;AAGO,IAAM,4CAA4C;AAAA,EACvD,OAAO,UAAU,MAAM,QAAQ,+BAA+B;AAAA,EAC9D,KAAK,UAAU,MAAM,QAAQ,6BAA6B;AAAA,EAC1D,KAAK,UAAU,MAAM,QAAQ,6BAA6B;AAAA,EAC1D,SAAS,UAAU,MAAM,QAAQ,iCAAiC;AAAA,EAClE,QAAQ,UAAU,MAAM,QAAQ,gCAAgC;AAAA,EAChE,UAAU,UAAU,MAAM,QAAQ,kCAAkC;AACtE;AAGO,IAAM,8CAA8C;AAAA,EACzD,QAAQ,UAAU,MAAM,QAAQ,kCAAkC;AAAA,EAClE,KAAK,UAAU,MAAM,QAAQ,+BAA+B;AAAA,EAC5D,SAAS,UAAU,MAAM,QAAQ,mCAAmC;AAAA,EACpE,SAAS,UAAU,MAAM,QAAQ,mCAAmC;AACtE;AAGO,IAAM,6CAA6C;AAAA,EACxD,SAAS,UAAU,aAAa,QAAQ,yBAAyB;AAAA,EACjE,KAAK,UAAU,aAAa,QAAQ,qBAAqB;AAAA,EACzD,MAAM,UAAU,aAAa,QAAQ,sBAAsB;AAAA,EAC3D,QAAQ,UAAU,aAAa,QAAQ,wBAAwB;AAAA,EAC/D,sBAAsB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,oBAAoB;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGO,IAAM,sCAAsC;AAAA,EACjD,OAAO,UAAU,aAAa,QAAQ,yBAAyB;AAAA,EAC/D,KAAK,UAAU,aAAa,QAAQ,uBAAuB;AAAA,EAC3D,MAAM,UAAU,aAAa,QAAQ,wBAAwB;AAAA,EAC7D,QAAQ,UAAU,aAAa,QAAQ,0BAA0B;AAAA,EACjE,MAAM,UAAU,aAAa,QAAQ,wBAAwB;AAAA,EAC7D,UAAU,UAAU,aAAa,OAAO,sBAAsB;AAChE;AAIO,IAAM,sCAAsC;AAAA,EACjD,OAAO,wBAAwB,aAAa,QAAQ,gBAAgB;AAAA,EACpE,UAAU,wBAAwB,aAAa,QAAQ,oBAAoB;AAAA,EAC3E,YAAY,wBAAwB,aAAa,QAAQ,kBAAkB;AAAA,EAC3E,QAAQ,wBAAwB,aAAa,QAAQ,iBAAiB;AAAA,EACtE,MAAM,wBAAwB,aAAa,OAAO,aAAa;AAAA,EAC/D,SAAS,wBAAwB,aAAa,OAAO,qBAAqB;AAAA,EAC1E,WAAW;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGO,IAAM,qCAAqC;AAAA,EAChD,SAAS,UAAU,mBAAmB,OAAO,cAAc;AAAA,EAC3D,OAAO,UAAU,mBAAmB,QAAQ,oBAAoB;AAAA,EAChE,QAAQ,UAAU,mBAAmB,QAAQ,qBAAqB;AACpE;AAGO,IAAM,oCAAoC;AAAA,EAC/C,UAAU,UAAU,aAAa,QAAQ,WAAW;AAAA,EACpD,OAAO,UAAU,aAAa,QAAQ,QAAQ;AAAA,EAC9C,SAAS,UAAU,aAAa,QAAQ,UAAU;AAAA,EAClD,IAAI,UAAU,aAAa,OAAO,KAAK;AAAA,EACvC,eAAe,UAAU,aAAa,SAAS,KAAK;AAAA,EACpD,gBAAgB,UAAU,aAAa,QAAQ,kBAAkB;AAAA,EACjE,eAAe,UAAU,aAAa,QAAQ,iBAAiB;AAAA,EAC/D,gBAAgB,UAAU,aAAa,QAAQ,kBAAkB;AAAA,EAEjE,eAAe,UAAU,aAAa,QAAQ,iBAAiB;AAAA,EAC/D,UAAU,UAAU,aAAa,QAAQ,WAAW;AACtD;AAGO,IAAM,qCAAqC;AAAA,EAChD,MAAM,UAAU,WAAW,OAAO,qBAAqB;AAAA,EACvD,WAAW,UAAU,WAAW,SAAS,qBAAqB;AAAA,EAC9D,SAAS,UAAU,WAAW,UAAU,qBAAqB;AAC/D;AAGO,IAAM,6BAA6B;AAAA,EACxC,eAAe;AAAA,IACb,UAAU,UAAU,uBAAuB,QAAQ,WAAW;AAAA,IAC9D,aAAa,UAAU,uBAAuB,QAAQ,eAAe;AAAA,IACrE,kBAAkB,UAAU,uBAAuB,OAAO,eAAe;AAAA,IACzE,aAAa,UAAU,uBAAuB,QAAQ,eAAe;AAAA,IACrE,kBAAkB;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU,UAAU,uBAAuB,OAAO,KAAK;AAAA,EACzD;AAAA,EACA,QAAQ;AAAA,IACN,iBAAiB,UAAU,UAAU,QAAQ,eAAe;AAAA,EAC9D;AAAA,EACA,aAAa;AAAA,IACX,OAAO,UAAU,qBAAqB,OAAO,QAAQ;AAAA,IACrD,uBAAuB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,gCAAgC;AAAA,EAC3C,OAAO;AAAA,IACL,QAAQ,UAAU,SAAS,OAAO,SAAS;AAAA,EAC7C;AACF;AAGO,IAAM,8BAA8B;AAAA,EACzC,OAAO;AAAA,IACL,YAAY,UAAU,iBAAiB,OAAO,aAAa;AAAA,EAC7D;AACF;AAGO,IAAM,4BAA4B;AAAA,EACvC,UAAU,UAAU,UAAU,QAAQ,eAAe;AACvD;AAEO,SAAS,yBAAyB,YAAmC;AAC1E,SAAO,WAAW,aACd,QAAQ,WAAW,UAAU,GAAG,WAAW,IAAI,KAC/C,OAAO,WAAW,IAAI;AAC5B;AAEO,SAAS,qBACd,YACA,SAIQ;AACR,QAAM,OAAO,yBAAyB,UAAU,EAAE;AAAA,IAChD;AAAA,IACA,CAAC,GAAG,QAAQ;AACV,YAAM,QAAQ,SAAS,aAAa,GAAG;AACvC,UAAI,UAAU,QAAW;AACvB,cAAM,IAAI,UAAU,2BAA2B,GAAG,EAAE;AAAA,MACtD;AACA,aAAO,mBAAmB,KAAK;AAAA,IACjC;AAAA,EACF;AACA,QAAM,aAAa,KAAK,MAAM,0BAA0B;AACxD,MAAI,YAAY;AACd,UAAM,IAAI,UAAU,2BAA2B,WAAW,CAAC,CAAC,EAAE;AAAA,EAChE;AAEA,QAAM,QAAQ,SAAS,OAAO,SAAS,EAAE,QAAQ,OAAO,EAAE;AAC1D,SAAO,QAAQ,GAAG,IAAI,IAAI,KAAK,KAAK;AACtC;AAEO,SAAS,uBACd,YACoC;AACpC,SAAO,WAAW,OAAO,YAAY;AACvC;;;AC1YA,IAAM,iBAAiB,CAAC,eAA6C;AAE9D,SAAS,4BACd,YACwB;AACxB,SAAO,WAAW;AACpB;AAQO,IAAM,qBAAqB;AAAA,EAChC,UAAU;AAAA,IACR,QAAQ,eAAe,6BAA6B,SAAS,MAAM;AAAA,IACnE,eAAe;AAAA,MACb,6BAA6B,SAAS;AAAA,IACxC;AAAA,IACA,eAAe;AAAA,MACb,6BAA6B,SAAS;AAAA,IACxC;AAAA,IACA,sBAAsB;AAAA,MACpB,6BAA6B,SAAS;AAAA,IACxC;AAAA;AAAA;AAAA,IAGA,oBAAoB;AAAA,MAClB,6BAA6B,SAAS;AAAA,IACxC;AAAA,IACA,2BAA2B;AAAA,MACzB,6BAA6B,SAAS;AAAA,IACxC;AAAA,IACA,YAAY;AAAA,MACV,6BAA6B,SAAS;AAAA,IACxC;AAAA,IACA,eAAe;AAAA,MACb,6BAA6B,SAAS;AAAA,IACxC;AAAA,IACA,QAAQ,eAAe,6BAA6B,SAAS,MAAM;AAAA,EACrE;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ,eAAe,6BAA6B,OAAO,MAAM;AAAA,IACjE,WAAW,eAAe,6BAA6B,OAAO,SAAS;AAAA,IACvE,QAAQ,eAAe,6BAA6B,OAAO,MAAM;AAAA,IACjE,qBAAqB;AAAA,MACnB,6BAA6B,OAAO;AAAA,IACtC;AAAA,IACA,mBAAmB;AAAA,MACjB,6BAA6B,OAAO;AAAA,IACtC;AAAA,IACA,mBAAmB;AAAA,MACjB,6BAA6B,OAAO;AAAA,IACtC;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,QAAQ,eAAe,6BAA6B,OAAO,QAAQ;AAAA,IACnE,UAAU,eAAe,6BAA6B,UAAU,MAAM;AAAA,IACtE,QAAQ;AAAA,MACN,QAAQ,eAAe,6BAA6B,OAAO,QAAQ;AAAA,MACnE,UAAU,eAAe,6BAA6B,UAAU,MAAM;AAAA,MACtE,OAAO,eAAe,6BAA6B,UAAU,KAAK;AAAA,IACpE;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,QAAQ,eAAe,6BAA6B,QAAQ,MAAM;AAAA,IAClE,QAAQ,eAAe,6BAA6B,QAAQ,MAAM;AAAA,IAClE,cAAc;AAAA,MACZ,6BAA6B,QAAQ;AAAA,IACvC;AAAA,EACF;AAAA,EACA,mBAAmB;AAAA,IACjB,SAAS;AAAA,MACP,6BAA6B,kBAAkB;AAAA,IACjD;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ,YAAY;AAAA,MACV,6BAA6B,aAAa;AAAA,IAC5C;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,eAAe,6BAA6B,MAAM,MAAM;AAAA,IAChE,UAAU,eAAe,6BAA6B,MAAM,QAAQ;AAAA,IACpE,MAAM,eAAe,6BAA6B,MAAM,IAAI;AAAA,IAC5D,OAAO,eAAe,6BAA6B,MAAM,KAAK;AAAA,IAC9D,QAAQ;AAAA;AAAA;AAAA,MAGN,QAAQ,eAAe,6BAA6B,MAAM,MAAM;AAAA,MAChE,UAAU,eAAe,6BAA6B,MAAM,QAAQ;AAAA,MACpE,MAAM,eAAe,6BAA6B,MAAM,IAAI;AAAA,MAC5D,OAAO,eAAe,6BAA6B,MAAM,KAAK;AAAA,MAC9D,SAAS,eAAe,6BAA6B,MAAM,OAAO;AAAA,MAClE,YAAY,eAAe,6BAA6B,MAAM,UAAU;AAAA,MACxE,YAAY,eAAe,6BAA6B,MAAM,UAAU;AAAA,MACxE,qBAAqB;AAAA,QACnB,6BAA6B,MAAM;AAAA,MACrC;AAAA,MACA,kBAAkB;AAAA,QAChB,6BAA6B,MAAM;AAAA,MACrC;AAAA,MACA,OAAO,eAAe,6BAA6B,MAAM,KAAK;AAAA,IAChE;AAAA,IACA,SAAS,eAAe,6BAA6B,MAAM,OAAO;AAAA,IAClE,YAAY,eAAe,6BAA6B,MAAM,UAAU;AAAA,IACxE,YAAY,eAAe,6BAA6B,MAAM,UAAU;AAAA,IACxE,qBAAqB;AAAA,MACnB,6BAA6B,MAAM;AAAA,IACrC;AAAA,IACA,kBAAkB;AAAA,MAChB,6BAA6B,MAAM;AAAA,IACrC;AAAA,IACA,OAAO,eAAe,6BAA6B,MAAM,KAAK;AAAA,EAChE;AAAA,EACA,iBAAiB;AAAA,IACf,QAAQ,eAAe,6BAA6B,gBAAgB,MAAM;AAAA,IAC1E,UAAU;AAAA,MACR,6BAA6B,gBAAgB;AAAA,IAC/C;AAAA,IACA,QAAQ,eAAe,6BAA6B,gBAAgB,MAAM;AAAA,IAC1E,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN,6BAA6B,gBAAgB,OAAO;AAAA,MACtD;AAAA,MACA,UAAU;AAAA,QACR,6BAA6B,gBAAgB,OAAO;AAAA,MACtD;AAAA,MACA,SAAS;AAAA,QACP,6BAA6B,gBAAgB,OAAO;AAAA,MACtD;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN,6BAA6B,gBAAgB,OAAO;AAAA,MACtD;AAAA,MACA,UAAU;AAAA,QACR,6BAA6B,gBAAgB,OAAO;AAAA,MACtD;AAAA,MACA,QAAQ;AAAA,QACN,6BAA6B,gBAAgB,OAAO;AAAA,MACtD;AAAA,MACA,SAAS;AAAA,QACP,6BAA6B,gBAAgB,OAAO;AAAA,MACtD;AAAA,MACA,aAAa;AAAA,QACX,6BAA6B,gBAAgB,OAAO;AAAA,MACtD;AAAA,MACA,kBAAkB;AAAA,QAChB,6BAA6B,gBAAgB,OAAO;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAAA,EACA,kBAAkB;AAAA,IAChB,WAAW;AAAA,MACT,6BAA6B,iBAAiB;AAAA,IAChD;AAAA,EACF;AACF;;;ACpLA,IAAM,0BAAN,MAA8B;AAAA,EAQ5B,YAAY,SAAiB,SAAmC;AAC9D,QACE,QAAQ,uBAAuB,SAC/B,CAAC,QAAQ,aACT,CAAC,QAAQ,eACT;AACA,YAAM;AAAA,QACJ,qDAAqD,OAAO;AAAA,MAC9D;AAAA,IACF;AAEA,SAAK,iBAAiB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AACA,SAAK,YAAY,QAAQ;AACzB,SAAK,SAAS,QAAQ;AACtB,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,cAAc,QAAQ;AAAA,EAC7B;AAAA,EAEA,MAAM,QACJ,UACA,SACY;AACZ,UAAM,QACJ,OAAO,KAAK,kBAAkB,aAC1B,KAAK,cAAc,IACnB,KAAK;AAEX,QAAI;AACF,YAAM,WAAW,MAAM,UAAU,UAAU;AAAA,QACzC,QAAQ,QAAQ;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,gBAAgB,KAAK;AAAA,QACrB,WAAW,KAAK;AAAA,QAChB,eAAe,SAAS;AAAA,QACxB,GAAI,SACF,KAAK,kBAAkB,EAAE,gBAAgB,KAAK,eAAe;AAAA,QAC/D,GAAI,QAAQ,SAAS,UAAa;AAAA,UAChC,MAAM,KAAK,UAAU,QAAQ,IAAI;AAAA,QACnC;AAAA,QACA,GAAI,QAAQ,WAAW,EAAE,SAAS,QAAQ,QAAQ;AAAA,QAClD,GAAI,QAAQ,eAAe,EAAE,aAAa,QAAQ,YAAY;AAAA,MAChE,CAAC;AAED,WAAK,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK,IAAI;AAC/D,aAAO,iBAAoB,UAAU,UAAU;AAAA,QAC7C,aAAa,QAAQ;AAAA,MACvB,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,KAAK,eAAe,WAAY,IAAI,aAAa,OAAQ;AAC/D,WAAK,cAAc,EAAE;AACrB,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAGO,IAAM,oBAAN,MAAwB;AAAA,EAG7B,YAAY,SAAiB,SAAmC;AAC9D,SAAK,YAAY,IAAI,wBAAwB,SAAS,OAAO;AAAA,EAC/D;AAAA,EAEU,gBACR,UACA,MACA,SACY;AACZ,WAAO,KAAK,UAAU,QAAW,qBAAqB,UAAU,OAAO,GAAG;AAAA,MACxE,QAAQ,uBAAuB,QAAQ;AAAA,MACvC;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,aAAa,4BAA4B,QAAQ;AAAA,IACnD,CAAC;AAAA,EACH;AACF;AAGO,IAAM,uBAAN,MAA2B;AAAA,EAGhC,YAAY,SAAiB,SAAmC;AAC9D,SAAK,YAAY,IAAI,wBAAwB,SAAS,OAAO;AAAA,EAC/D;AAAA,EAEU,QACR,UACA,SACY;AACZ,WAAO,KAAK,UAAU,QAAW,UAAU,OAAO;AAAA,EACpD;AACF;;;ACxIO,IAAM,+BAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA8FO,SAAS,gCAAuC;AACrD,QAAM,eAAe,oCAAoC,GAAG;AAC9D;AACA,SAAS,OAAO,OAAgB,MAAyC;AACvE,MACE,CAAC,SACD,OAAO,UAAU,YACjB,MAAM,QAAQ,KAAK,KACnB,OAAO,KAAK,KAAK,EAAE,WAAW,KAAK,UACnC,KAAK,KAAK,CAAC,QAAQ,EAAE,OAAO,MAAM;AAElC,kCAA8B;AAChC,SAAO;AACT;AACA,IAAM,OAAO,CAAC,MACZ,OAAO,MAAM,aACZ,6EAA6E;AAAA,EAC5E;AACF,KACE,MAAM,0CACN,EAAE,YAAY,MAAM;AACxB,IAAM,OAAO,CAAC,MACZ,OAAO,MAAM,YACb,sBAAsB,KAAK,CAAC,KAC5B,OAAO,SAAS,KAAK,MAAM,CAAC,CAAC,KAC7B,IAAI,KAAK,KAAK,MAAM,CAAC,CAAC,EAAE,YAAY,MAAM;AAC5C,IAAM,QAAQ,CAAC,MACb,OAAO,MAAM,YAAY,sCAAsC,KAAK,CAAC;AAShE,SAAS,oBACd,OACA,OAAO,OACkC;AACzC,QAAM,IAAI,OAAO,OAAO;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OACA,CAAC,UAAU,IACX,CAAC,cAAc,gBAAgB,UAAU,QAAQ;AAAA,EACvD,CAAC;AACD,MACE,CAAC,KAAK,EAAE,EAAE,KACV,OAAO,EAAE,SAAS,YAClB,CAAC,EAAE,KAAK,UACR,EAAE,KAAK,SAAS,OACf,EAAE,gBAAgB,SAChB,OAAO,EAAE,gBAAgB,YAAY,EAAE,YAAY,SAAS,QAC/D,CAAC,CAAC,UAAU,YAAY,WAAW,QAAQ,EAAE,SAAS,EAAE,KAAe,KACvE,CAAC,KAAK,EAAE,QAAQ,KAChB,CAAC,KAAK,EAAE,SAAS;AAEjB,kCAA8B;AAChC,MAAI,MAAM;AACR,QAAI,EAAE,aAAa,QAAQ,CAAC,KAAK,EAAE,QAAQ;AACzC,oCAA8B;AAAA,EAClC,OAAO;AACL,QAAI,CAAC,KAAK,EAAE,UAAU,KAAK,CAAC,KAAK,EAAE,YAAY;AAC7C,oCAA8B;AAChC,UAAM,SAAS,OAAO,EAAE,QAAQ,CAAC,aAAa,KAAK,CAAC;AACpD,QACE,OAAO,OAAO,cAAc,YAC5B,CAAC,sCAAsC,KAAK,OAAO,SAAS,KAC5D,OAAO,OAAO,QAAQ,YACtB,CAAC,OAAO,IAAI,UACZ,OAAO,IAAI,SAAS;AAEpB,oCAA8B;AAChC,QAAI,EAAE,WAAW,MAAM;AACrB,YAAM,SAAS,OAAO,EAAE,QAAQ;AAAA,QAC9B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD,YAAM,YAAY,OAAO,OAAO,OAAO,CAAC,QAAQ,IAAI,CAAC;AACrD,UACE,CAAC,KAAK,OAAO,EAAE,KACf,CAAC,KAAK,UAAU,EAAE,KAClB,CAAC,CAAC,UAAU,SAAS,EAAE,SAAS,OAAO,OAAiB,KACxD,CAAC,CAAC,qBAAqB,UAAU,EAAE,SAAS,UAAU,IAAc,KACnE,OAAO,aAAa,QAAQ,CAAC,MAAM,OAAO,QAAQ,KAClD,OAAO,eAAe,QACrB,CAAC,6BAA6B,SAAS,OAAO,UAAmB;AAEnE,sCAA8B;AAAA,IAClC;AAAA,EACF;AACA,SAAO;AACT;AASO,SAAS,wBACd,OACA,OAAO,OACsD;AAC7D,QAAM,IAAI,OAAO,OAAO,CAAC,YAAY,cAAc,aAAa,CAAC;AACjE,MACE,CAAC,MAAM,QAAQ,EAAE,QAAQ,KACzB,EAAE,SAAS,SAAS,OACpB,CAAC,KAAK,EAAE,WAAW,KAClB,EAAE,eAAe,SACf,OAAO,EAAE,eAAe,YACvB,CAAC,EAAE,WAAW,UACd,EAAE,WAAW,SAAS;AAE1B,kCAA8B;AAChC,aAAW,OAAO,EAAE,UAAU;AAC5B,QAAI,KAAM,qBAAoB,KAAK,IAAI;AAAA,QAClC,qBAAoB,GAAG;AAAA,EAC9B;AACA,SAAO;AACT;;;AC9NO,IAAM,6BAAN,cAAyC,kBAAkB;AAAA,EAChE,MAAM,SACJ,SAAuC,CAAC,GACA;AACxC,UAAM,QAAQ,IAAI,gBAAgB;AAClC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM;AAC9C,UAAI,UAAU,OAAW,OAAM,IAAI,KAAK,OAAO,KAAK,CAAC;AACvD,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,QACT,oCAAoC;AAAA,QACpC;AAAA,QACA,EAAE,MAAM;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AC2EA,SAAS,UAAiB;AACxB,QAAM,eAAe,oCAAoC,GAAG;AAC9D;AACA,SAASC,QACP,OACA,MACyB;AACzB,MACE,CAAC,SACD,OAAO,UAAU,YACjB,MAAM,QAAQ,KAAK,KACnB,OAAO,KAAK,KAAK,EAAE,WAAW,KAAK,UACnC,KAAK,KAAK,CAAC,QAAQ,CAAC,OAAO,UAAU,eAAe,KAAK,OAAO,GAAG,CAAC;AAEpE,YAAQ;AACV,SAAO;AACT;AACA,SAAS,MAAM,OAAiC;AAC9C,SAAO,OAAO,UAAU,YAAY,oBAAoB,KAAK,KAAK;AACpE;AACA,SAASC,MAAK,OAAiC;AAC7C,SACE,OAAO,UAAU,YACjB,yJAAyJ;AAAA,IACvJ;AAAA,EACF;AAEJ;AACA,SAASC,MAAK,OAAiC;AAC7C,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,QACJ,+DAA+D,KAAK,KAAK;AAC3E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,CAAC,EAAE,MAAM,OAAO,KAAK,MAAM,QAAQ,SAAS,GAAG,IAAI;AACzD,QAAM,IAAI,OAAO,IAAI,GACnB,IAAI,OAAO,KAAK,GAChB,IAAI,OAAO,GAAG;AAChB,QAAM,OAAO;AAAA,IACX;AAAA,IACA,IAAI,MAAM,MAAM,IAAI,QAAQ,KAAK,IAAI,QAAQ,KAAK,KAAK;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SACE,KAAK,KACL,KAAK,MACL,KAAK,KACL,KAAK,KAAK,IAAI,CAAC,KACf,OAAO,IAAI,IAAI,MACf,OAAO,MAAM,IAAI,MACjB,OAAO,MAAM,IAAI;AAErB;AACA,IAAM,SAAS,CAAC,aAAa,QAAQ,SAAS,WAAW,SAAS;AAClE,SAAS,SAAS,OAAsB;AACtC,QAAM,OAAOF,QAAO,OAAO,MAAM;AACjC,MAAI,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,EAAG,SAAQ;AACvD;AACA,SAAS,KAAK,OAAsC;AAClD,MACE,MAAM,aAAa,SACnB,CAACE,MAAK,MAAM,WAAW,KACvB,CAAC,OAAO,cAAc,MAAM,IAAI,KAC/B,MAAM,OAAkB,KACzB,OAAO,MAAM,gBAAgB;AAE7B,YAAQ;AACZ;AAoDO,SAAS,uBACd,OAC2B;AAC3B,QAAM,OAAOC,QAAO,OAAO;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,OAAK,IAAI;AACT,WAAS,KAAK,QAAQ;AACtB,MACE,CAAC,MAAM,KAAK,OAAO,KACnB,CAAC,MAAM,QAAQ,KAAK,OAAO,KAC3B,KAAK,QAAQ,SAAS;AAEtB,YAAQ;AACV,aAAWC,UAAS,KAAK,SAAS;AAChC,UAAM,SAASD,QAAOC,QAAO;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QACE,CAACC,MAAK,OAAO,EAAE,KACf,CAACA,MAAK,OAAO,OAAO,KACpB,CAAC,CAAC,YAAY,OAAO,EAAE,SAAS,OAAO,IAAc,KACrD,CAACC,MAAK,OAAO,SAAS,KACtB,CAACA,MAAK,OAAO,SAAS,KACtB,OAAO,OAAO,cAAc;AAE5B,cAAQ;AACV,aAAS,OAAO,QAAQ;AAAA,EAC1B;AACA,SAAO;AACT;AACO,SAAS,6BACd,OACiC;AACjC,QAAM,OAAOH,QAAO,OAAO;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,OAAK,IAAI;AACT,MAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,KAAK,KAAK,QAAQ,SAAS,GAAI,SAAQ;AACtE,aAAWC,UAAS,KAAK,SAAS;AAChC,UAAM,QAAQD,QAAOC,QAAO;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QACE,CAACC,MAAK,MAAM,EAAE,KACd,CAACA,MAAK,MAAM,OAAO,KACnB,CAAC,MAAM,MAAM,MAAM,KACnB,CAACC,MAAK,MAAM,SAAS,KACrB,CAAC;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,SAAS,MAAM,IAAc,KAC9B,MAAM,cAAc,QACnB,CAAC,OAAO,SAAS,MAAM,SAAkB,KAC1C,MAAM,YAAY,QAAQ,CAAC,OAAO,SAAS,MAAM,OAAgB;AAElE,cAAQ;AAAA,EACZ;AACA,SAAO;AACT;;;AC3SO,IAAM,qBAAN,cAAiC,kBAAkB;AAAA,EACxD,MAAM,KACJ,SAAmC,CAAC,GACA;AACpC,UAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAI,OAAO,SAAS,OAAW,OAAM,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC;AACpE,WAAO;AAAA,MACL,MAAM,KAAK,gBAAyB,oCAAW,MAAM,QAAW;AAAA,QAC9D;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EACA,MAAM,QACJ,SAAyC,CAAC,GACA;AAC1C,UAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAI,OAAO,SAAS,OAAW,OAAM,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC;AACpE,WAAO;AAAA,MACL,MAAM,KAAK,gBAAyB,oCAAW,SAAS,QAAW;AAAA,QACjE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ACnCA,oBAA0B;AAoB1B,SAAS,cAAc,OAA0C;AAC/D,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,UAAU;AACd,WAAS,MAAM,OAAgB,OAAe,KAAoB;AAChE,QAAI,QAAQ,IAAI;AACd,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA,QAAI,UAAU,SAAS,QAAQ,YAAY,QAAQ,eAAe;AAChE,gBAAU;AACV;AAAA,IACF;AACA,QAAI,SAAS,MAAM;AACjB,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAI,MAAM,WAAW,GAAG;AACtB,cAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA,UAAI,MAAM,SAAS,KAAM;AACvB,cAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA,iBAAW,QAAQ,MAAO,OAAM,MAAM,QAAQ,CAAC;AAAA,IACjD,WAAW,OAAO,UAAU,YAAY,EAAE,iBAAiB,OAAO;AAChE,YAAM,SAAS,OAAO,QAAQ,KAAK;AACnC,UAAI,OAAO,WAAW,GAAG;AACvB,cAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA,iBAAW,CAACC,MAAK,IAAI,KAAK,OAAQ,OAAM,MAAM,QAAQ,GAAGA,IAAG;AAAA,IAC9D;AAAA,EACF;AACA,QAAM,OAAO,CAAC;AACd,SAAO;AACT;AAEO,IAAM,aAAN,MAAiB;AAAA,EAQtB,YACE,gBACA,WACA,kBACA,gBACA,aACA,QACA;AACA,SAAK,iBAAiB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,YAAY;AACjB,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAc,iBAA+B;AAC3C,UAAM,OAAqB;AAAA,MACzB,QAAQ,KAAK;AAAA,MACb,gBAAgB,KAAK;AAAA,MACrB,WAAW,KAAK;AAAA,IAClB;AACA,UAAM,QAAQ,KAAK,mBAAmB;AACtC,QAAI,OAAO;AACT,WAAK,gBAAgB;AACrB,UAAI,KAAK,gBAAgB;AACvB,aAAK,iBAAiB,KAAK;AAAA,MAC7B;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAgB,kBAAkB,KAAa,MAAuC;AACpF,QAAI;AACF,YAAM,WAAW,MAAM,UAAU,KAAK,IAAI;AAC1C,WAAK,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK,IAAI;AAC/D,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAM,KAAK,eAAe,WAAY,IAAI,aAAa,OAAQ;AAC/D,WAAK,cAAc,EAAE;AACrB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEU,SAAS,UAAkB,SAAmC;AACtE,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,UAAM,eACJ,mBAAmB,SACf,OACA;AAAA,MACE,GAAG;AAAA,MACH,mBACE,mBAAmB,QAAQ,SAAS;AAAA,IACxC;AAGN,UAAM,iBAAiB,cAAc,aAAa,KAAK,IACnD,EAAE,GAAG,cAAc,OAAO,KAAK,UAAU,aAAa,KAAK,EAAE,IAC7D;AACJ,UAAM,kBAAc,yBAAU,gBAAgB,EAAE,gBAAgB,KAAK,CAAC;AACtE,WAAO,cAAc,GAAG,QAAQ,GAAG,WAAW,KAAK;AAAA,EACrD;AAAA,EAEU,mBAAmB,UAA0B;AACrD,UAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AACvD,QAAI,CAAC,aAAa,SAAS,kBAAkB,GAAG;AAC9C,YAAM,eAAe,mCAAmC,SAAS,QAAQ;AAAA,QACvE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAgB,kBACd,UACiC;AACjC,UAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AAEvD,QAAI;AACF,WAAK,mBAAmB,QAAQ;AAEhC,YAAM,WAAW,MAAM,SAAS,KAAK;AAGrC,UAAI,SAAS,SAAS,QAAW;AAC/B,cAAM,eAAe,0BAA0B,SAAS,QAAQ;AAAA,UAC9D;AAAA,QACF,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL,MAAM,SAAS;AAAA,QACf,WAAW,SAAS,aAAa;AAAA,QACjC,OAAO,SAAS,SAAS;AAAA,QACzB,YAAY,SAAS,cAAc;AAAA,QACnC,MAAM,SAAS,QAAQ;AAAA,QACvB,eAAe,SAAS,iBAAiB;AAAA,QACzC,aAAa,SAAS,eAAe;AAAA,QACrC,aAAa,SAAS,eAAe;AAAA,QACrC,UAAU,SAAS,YAAY;AAAA,QAC/B,UAAU,SAAS,YAAY;AAAA,MACjC;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAU,OAAM;AACrC,YAAM,eAAe,6BAA6B,SAAS,QAAQ;AAAA,QACjE;AAAA,QACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAgB,sBACd,UACqC;AACrC,UAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AAEvD,QAAI;AACF,WAAK,mBAAmB,QAAQ;AAEhC,YAAM,WAAW,MAAM,SAAS,KAAK;AAGrC,UAAI,SAAS,QAAQ,QAAW;AAC9B,cAAM,eAAe,8BAA8B,SAAS,QAAQ;AAAA,UAClE;AAAA,QACF,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL,SAAS,SAAS,WAAW;AAAA,QAC7B,KAAK,SAAS;AAAA,QACd,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAU,OAAM;AACrC,YAAM,eAAe,6BAA6B,SAAS,QAAQ;AAAA,QACjE;AAAA,QACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAgB,sBAAyB,UAAgC;AACvE,UAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AAEvD,QAAI;AACF,WAAK,mBAAmB,QAAQ;AAEhC,YAAM,WAAW,MAAM,SAAS,KAAK;AACrC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAU,OAAM;AACrC,YAAM,eAAe,6BAA6B,SAAS,QAAQ;AAAA,QACjE;AAAA,QACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ACzOO,SAAS,gBAAmB,KAAwB;AACzD,MACE,OAAO,QAAQ,YACf,OAAO,QAAQ,YACf,QAAQ,QACR,QAAQ;AAER,WAAO;AACT,SAAO;AACT;;;ACWA,IAAM,0BACJ;AACF,IAAM,0BACJ;AACF,IAAM,6BACJ;AAEF,SAAS,6BACP,SACwB;AACxB,QAAM,aAAa;AAEnB,MAAI,YAAY,UAAU,UAAa,WAAW,UAAU,GAAG;AAC7D,UAAM,sBAAsB,uBAAuB;AAAA,EACrD;AACA,MAAI,YAAY,UAAU,UAAa,WAAW,UAAU,OAAO;AACjE,UAAM,sBAAsB,uBAAuB;AAAA,EACrD;AACA,MAAI,YAAY,aAAa,QAAW;AACtC,UAAM,sBAAsB,0BAA0B;AAAA,EACxD;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,SAAS,SAAS;AAAA,IACzB,OAAO,SAAS,SAAS;AAAA,EAC3B;AACF;AAgBO,IAAM,iCAAN,MAAiE;AAAA,EACtE,YACU,KACA,YACR;AAFQ;AACA;AAAA,EACP;AAAA,EAEH,MAAM,KACJ,SACiD;AACjD,WAAO,KAAK,IAAI;AAAA,MACd,QAAQ,OAAO,KAAK,UAAU,CAAC;AAAA,MAC/B,6BAA6B,OAAO;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,SACJ,IACA,SAC4B;AAC5B,WAAO,KAAK,IAAI;AAAA,MACd,QAAQ,OAAO,KAAK,UAAU,CAAC,IAAI,OAAO,EAAE,CAAC;AAAA,MAC7C,6BAA6B,OAAO;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,MACJ,SACgC;AAChC,WAAO,KAAK,IAAI;AAAA,MACd,QAAQ,OAAO,KAAK,UAAU,CAAC;AAAA,MAC/B,6BAA6B,OAAO;AAAA,IACtC;AAAA,EACF;AACF;;;ACkJO,IAAM,2BAAN,cAAuC,WAAW;AAAA,EACvD,KAAiC,YAAwC;AACvE,WAAO,IAAI,+BAA+B,MAAM,UAAU;AAAA,EAC5D;AAAA,EAEA,MAAM,YACJ,UACA,SACiC;AACjC,UAAM,MAAM,KAAK,SAAS,UAAU,OAAO;AAC3C,UAAM,WAAW,MAAM,KAAK,kBAAkB,KAAK;AAAA,MACjD,GAAG,KAAK;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,KAAK,kBAAqB,QAAQ;AAAA,EAC3C;AAAA,EAEA,MAAM,oBACJ,UACA,MACiC;AACjC,UAAM,WAAW,MAAM,KAAK,kBAAkB,UAAU;AAAA,MACtD,GAAG,KAAK;AAAA,MACR,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AACD,WAAO,KAAK,kBAAqB,QAAQ;AAAA,EAC3C;AAAA,EAEA,MAAM,uBACJ,UACiC;AACjC,UAAM,WAAW,MAAM,KAAK,kBAAkB,UAAU;AAAA,MACtD,GAAG,KAAK;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,KAAK,kBAAqB,QAAQ;AAAA,EAC3C;AAAA,EAEA,MAAM,gBACJ,UACA,SACY;AACZ,UAAM,MAAM,KAAK,SAAS,UAAU,OAAO;AAC3C,UAAM,WAAW,MAAM,KAAK,kBAAkB,KAAK;AAAA,MACjD,GAAG,KAAK;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,KAAK,sBAAyB,QAAQ;AAAA,EAC/C;AAAA,EAEA,MAAM,aACJ,UACA,SACgC;AAChC,UAAM,MAAM,KAAK,SAAS,UAAU,OAAO;AAC3C,UAAM,WAAW,MAAM,KAAK,kBAAkB,KAAK;AAAA,MACjD,GAAG,KAAK;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,KAAK,sBAA6C,QAAQ;AAAA,EACnE;AACF;;;ACrIA,IAAM,yBAAgD;AACtD,IAAM,4BAAsD;AAE5D,SAAS,iBAAoB,OAA0B;AACrD,MAAI,SAAS,OAAO,UAAU,YAAY,SAAS,OAAO;AACxD,WAAQ,MAAqB;AAAA,EAC/B;AACA,SAAO;AACT;AAEA,SAAS,2BAA2B,OAA+B;AACjE,SAAO,kBAAkB,KAAK,MAAM;AACtC;AAEO,IAAM,kBAAN,cAA8B,qBAAqB;AAAA,EAGxD,YAAY,SAAiC;AAC3C,UAAM,mBAAmB,EAAE,GAAG,SAAS,oBAAoB,MAAM,CAAC;AAClE,SAAK,6BAA6B,CAAC,QAAQ;AAAA,EAC7C;AAAA,EAEQ,WACN,QACQ;AACR,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,UAAU,OAAO,QAAQ,MAAM,EAClC,OAAO,CAAC,MAAsC,EAAE,CAAC,MAAM,MAAS,EAChE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;AACjC,WAAO,QAAQ,SAAS,IAAI,IAAI,gBAAgB,OAAO,EAAE,SAAS,CAAC,KAAK;AAAA,EAC1E;AAAA,EAEQ,2BAA2B,OAAuB;AACxD,QAAI,CAAC,KAAK,2BAA4B,QAAO;AAC7C,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,wBAAwB,MAAM,MAAM,CAAC,CAAC;AAAA,EAC/C;AAAA,EAEQ,4BAA4B,QAGzB;AACT,QAAI,CAAC,KAAK,4BAA4B;AACpC,aAAO,KAAK,WAAW,MAAM;AAAA,IAC/B;AAEA,UAAM,cAA+C,CAAC;AACtD,QAAI,QAAQ,SAAS,OAAW,aAAY,OAAO,OAAO;AAC1D,QAAI,QAAQ,UAAU,OAAW,aAAY,QAAQ,OAAO;AAE5D,WAAO,KAAK,2BAA2B,KAAK,WAAW,WAAW,CAAC;AAAA,EACrE;AAAA,EAEQ,oBAAoB,QAMjB;AACT,UAAM,YAAY,IAAI,gBAAgB;AACtC,UAAM,OAAO,QAAQ,QAAQ;AAC7B,cAAU,IAAI,QAAQ,IAAI;AAC1B,QAAI,QAAQ,UAAU;AACpB,gBAAU,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAC7C,QAAI,QAAQ,SAAS,OAAW,WAAU,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC;AACzE,QAAI,QAAQ,eAAe,QAAW;AACpC,gBAAU,IAAI,yBAAyB,OAAO,UAAU;AAAA,IAC1D;AACA,QAAI,QAAQ,UAAU,QAAW;AAC/B,gBAAU,IAAI,mBAAmB,OAAO,KAAK;AAAA,IAC/C;AACA,WAAO,qBAAqB,UAAU,SAAS,CAAC;AAAA,EAClD;AAAA,EAEQ,uBAAuB,QAQpB;AACT,UAAM,YAAY,IAAI,gBAAgB;AACtC,UAAM,OAAO,OAAO,QAAQ;AAC5B,cAAU,IAAI,QAAQ,IAAI;AAC1B,QAAI,OAAO,WAAW,QAAW;AAC/B,gBAAU,IAAI,uBAAuB,OAAO,MAAM;AAAA,IACpD;AACA,QAAI,OAAO,aAAa,QAAW;AACjC,gBAAU,IAAI,yBAAyB,OAAO,QAAQ;AAAA,IACxD;AACA,QAAI,OAAO,gBAAgB,QAAW;AACpC,gBAAU,IAAI,8BAA8B,OAAO,WAAW;AAAA,IAChE;AACA,QAAI,OAAO,cAAc;AACvB,gBAAU,IAAI,yBAAyB,OAAO;AAAA,IAChD;AACA,QAAI,OAAO,UAAU,OAAW,WAAU,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAC3E,QAAI,OAAO,SAAS,OAAW,WAAU,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC;AACxE,WAAO,wBAAwB,UAAU,SAAS,CAAC;AAAA,EACrD;AAAA,EAEA,MAAc,QACZ,UACA,QACA,MACY;AACZ,WAAO,KAAK,QAAW,UAAU,EAAE,QAAQ,KAAK,CAAC;AAAA,EACnD;AAAA,EAEA,MAAc,WACZ,UACA,QACA,MACY;AACZ,UAAM,WAAW,MAAM,KAAK,QAAwB,UAAU,QAAQ,IAAI;AAC1E,WAAO,iBAAiB,QAAQ;AAAA,EAClC;AAAA,EAEA,WAAW,QAKgC;AACzC,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,QAMoC;AAC5C,WAAO,KAAK;AAAA,MACV,KAAK,oBAAoB,MAAM;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,QAA2D;AACvE,UAAM,QAAQ,IAAI,gBAAgB,EAAE,QAAQ,OAAO,OAAO,CAAC;AAC3D,QAAI;AACF,aAAO,MAAM,KAAK;AAAA,QAChB,qBAAqB,8BAA8B,MAAM,QAAQ;AAAA,UAC/D;AAAA,QACF,CAAC;AAAA,QACD,uBAAuB,8BAA8B,MAAM,MAAM;AAAA,MACnE;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,iBAAiB,2BAA2B,KAAK,GAAG;AACvE,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,mBAAmB,QAGmC;AACpD,WAAO,KAAK;AAAA,MACV,uBAAuB,KAAK,4BAA4B,MAAM,CAAC;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,aAAa,QAGoC;AAC/C,WAAO,KAAK;AAAA,MACV,iBAAiB,KAAK,4BAA4B,MAAM,CAAC;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,QAGmC;AAC5C,WAAO,KAAK;AAAA,MACV,gBAAgB,KAAK,WAAW,MAAM,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY,QAKkC;AAC5C,WAAO,KAAK;AAAA,MACV,sBAAsB,KAAK,WAAW,MAAM,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,QAA4D;AACxE,WAAO,KAAK;AAAA,MACV,cAAc,OAAO,MAAM;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,QAIuB;AAChC,UAAM,EAAE,QAAQ,GAAG,KAAK,IAAI;AAC5B,WAAO,KAAK;AAAA,MACV,cAAc,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,cAAc,QAIgC;AAC5C,UAAM,EAAE,QAAQ,UAAU,MAAM,YAAY,IAAI;AAChD,UAAM,OAAgC,EAAE,MAAM,QAAQ,MAAM,YAAY;AACxE,QAAI,aAAa,QAAW;AAC1B,WAAK,SAAS;AAAA,IAChB;AACA,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,aAAa,QAOoC;AAC/C,UAAM,EAAE,QAAQ,MAAAC,OAAM,OAAO,aAAa,cAAc,KAAK,IAAI;AACjE,WAAO,KAAK;AAAA,MACV,KAAK,uBAAuB;AAAA,QAC1B;AAAA,QACA,MAAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,YAAY,QAKqC;AAC/C,UAAM,EAAE,WAAW,MAAAA,OAAM,OAAO,KAAK,IAAI;AACzC,WAAO,KAAK;AAAA,MACV,KAAK,uBAAuB;AAAA,QAC1B,UAAU;AAAA,QACV,MAAAA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,QAGgC;AAC5C,UAAM,EAAE,WAAW,KAAK,IAAI;AAC5B,WAAO,KAAK;AAAA,MACV,iBAAiB,SAAS;AAAA,MAC1B;AAAA,MACA,EAAE,KAAK;AAAA,IACT;AAAA,EACF;AAAA,EAEA,cAAc,QAEgC;AAC5C,WAAO,KAAK;AAAA,MACV,iBAAiB,OAAO,SAAS;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,QAIoB;AAChC,UAAM,EAAE,WAAW,GAAG,KAAK,IAAI;AAC/B,WAAO,KAAK;AAAA,MACV,iBAAiB,SAAS;AAAA,MAC1B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,YAAY,QAKmC;AAC7C,UAAM,EAAE,QAAQ,UAAU,KAAK,IAAI;AACnC,UAAM,eAAe,YAAY;AACjC,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,QAGmB;AAChC,UAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,WAAO,KAAK;AAAA,MACV,cAAc,MAAM,eAAe,mBAAmB,IAAI,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,mBAAmB,QAK4B;AAC7C,UAAM,EAAE,WAAW,UAAU,KAAK,IAAI;AACtC,UAAM,eAAe,YAAY;AACjC,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,sBAAsB,QAGY;AAChC,UAAM,EAAE,WAAW,KAAK,IAAI;AAC5B,WAAO,KAAK;AAAA,MACV,iBAAiB,SAAS,eAAe,mBAAmB,IAAI,CAAC;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,mBAAmB,QAAsD;AACvE,WAAO,KAAK;AAAA,MACV,cAAc,OAAO,MAAM;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,0BAA0B,QAEG;AAC3B,WAAO,KAAK;AAAA,MACV,iBAAiB,OAAO,SAAS;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,mBAA6D;AAC3D,WAAO,KAAK;AAAA,MACV,sBAAsB,KAAK,4BAA4B,EAAE,OAAO,IAAI,CAAC,CAAC;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,YAAY,QAEmC;AAC7C,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,QACE,MAAM,OAAO;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,QAA2D;AACxE,WAAO,KAAK;AAAA,MACV,cAAc,OAAO,MAAM;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,QAG0B;AACvC,WAAO,KAAK;AAAA,MACV,oBAAoB,KAAK,WAAW,MAAM,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,iBAAiB,QAGwD;AACvE,WAAO,KAAK;AAAA,MAGV,8BAA8B,KAAK,4BAA4B,MAAM,CAAC;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,QAC0D;AAC1D,UAAM,QACJ,UAAU,SACN,wBAAwB,mBAAmB,OAAO,IAAI,CAAC,aACvD,sBAAsB,mBAAmB,OAAO,EAAE,CAAC;AACzD,UAAM,MAAM,MAAM,KAAK;AAAA,MAGrB,8BAA8B,KAAK,2BAA2B,KAAK,CAAC;AAAA,MACpE;AAAA,IACF;AACA,WAAO,IAAI,KAAK,CAAC,KAAK;AAAA,EACxB;AAAA,EAEA,oBAAoB,MAM6B;AAC/C,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AC5jBA,IAAM,mBAAN,cAA+B,qBAAqB;AAAA,EAClD,IAAO,UAA8B;AACnC,WAAO,KAAK,QAAW,UAAU,EAAE,QAAQ,MAAM,CAAC;AAAA,EACpD;AAAA,EAEA,aAAgB,SAAwD;AACtE,UAAMC,aAAY,4BAA4B,MAAM;AACpD,WAAO,KAAK;AAAA,MACV,qBAAqBA,YAAW;AAAA,QAC9B,OAAO,sBAAsB,OAAO;AAAA,MACtC,CAAC;AAAA,MACD,EAAE,QAAQ,uBAAuBA,UAAS,EAAE;AAAA,IAC9C;AAAA,EACF;AACF;AAEA,SAAS,mBACP,QACA,SACA,aACM;AACN,SAAO,IAAI,QAAQ,SAAS,QAAQ,WAAW;AAC/C,MAAI,SAAS,QAAQ,KAAM,QAAO,IAAI,QAAQ,OAAO,QAAQ,IAAI,CAAC;AAClE,MAAI,SAAS,SAAS,KAAM,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AACvE;AAEA,SAAS,cAAc,SAA8C;AACnE,QAAM,SAAS,IAAI,gBAAgB;AACnC,qBAAmB,QAAQ,SAAS,yBAAyB;AAC7D,MAAI,SAAS,WAAY,QAAO,IAAI,cAAc,QAAQ,UAAU;AACpE,MAAI,SAAS,cAAc;AACzB,WAAO,IAAI,gBAAgB,QAAQ,YAAY;AAAA,EACjD;AACA,MAAI,SAAS,MAAO,QAAO,IAAI,SAAS,QAAQ,KAAK;AACrD,MAAI,SAAS,QAAS,QAAO,IAAI,WAAW,QAAQ,OAAO;AAC3D,MAAI,SAAS,YAAY;AACvB,WAAO,IAAI,YAAY,OAAO,QAAQ,QAAQ,CAAC;AACjD,SAAO,yBAAyB,MAAM;AACxC;AAEA,SAAS,sBACP,SACiB;AACjB,QAAM,SAAS,IAAI,gBAAgB;AACnC,qBAAmB,QAAQ,SAAS,QAAQ;AAC5C,MAAI,SAAS,UAAW,QAAO,IAAI,aAAa,QAAQ,SAAS;AACjE,MAAI,SAAS,YAAa,QAAO,IAAI,eAAe,QAAQ,WAAW;AACvE,SAAO;AACT;AAEO,IAAM,gBAAN,MAAoB;AAAA,EAazB,YAAY,SAA+B;AACzC,UAAM,MAAM,IAAI,iBAAiB,iBAAiB;AAAA,MAChD,gBAAgB,QAAQ;AAAA,MACxB,QAAQ,QAAQ;AAAA,MAChB,aAAa,QAAQ;AAAA,MACrB,oBAAoB;AAAA,IACtB,CAAC;AAED,SAAK,QAAQ;AAAA,MACX,MAAM,CAAC,WACL,IAAI,IAAyC,cAAc,MAAM,CAAC;AAAA,IACtE;AAEA,SAAK,eAAe;AAAA,MAClB,MAAM,CAAC,WACL,IAAI,aAAyD,MAAM;AAAA,IACvE;AAAA,EACF;AACF;;;AClMA,IAAM,gBAAgB,CAAC,UAAU,aAAa,WAAW;AACzD,IAAM,yBAAyB;AAC/B,IAAM,iCAAiC;AACvC,IAAM,8BAA8B;AACpC,IAAM,4BAA4B;AAClC,IAAM,4BAA4B;AAClC,IAAM,kCAAkC;AACxC,IAAM,sCAAsC;AAC5C,IAAM,kCAAkC;AACxC,IAAM,iCAAiC;AACvC,IAAM,gCAAgC;AACtC,IAAM,2BAA2B;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,6BAA6B;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,8BAA8B,CAAC,eAAe,WAAW;AAC/D,IAAM,iCAAiC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,oBAAoB,CAAC,QAAQ,UAAU,WAAW;AACxD,IAAM,oBAAoB,CAAC,WAAW,YAAY,UAAU;AAG5D,SAAS,wBAGP,WAEW;AACX,SAAO;AACT;AAEA,IAAM,oBAAoB,wBAAwB;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AACF,CAAU;AAMV,IAAM,0BAA0B;AAAA,EAC9B,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AACV;AAGA,IAAM,mCAAmC;AAGzC,IAAM,8BACJ;AACF,IAAM,4BAA4B;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAaA,IAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,yBACd,UACA,SACO;AACP,QAAM;AAAA,IACJ,qBAAqB,QAAQ;AAAA,IAC7B;AAAA,IACA,EAAE,UAAU,GAAG,QAAQ;AAAA,IACvB,uCAAuC,QAAQ;AAAA,IAC/C;AAAA,EACF;AACF;AAEA,SAAS,KAAK,UAAkB,MAAc,UAAyB;AACrE,2BAAyB,UAAU,EAAE,MAAM,SAAS,CAAC;AACvD;AAEA,SAAS,iBACP,UACA,UACA,QACAC,YACO;AACP,QAAM,SAAS,wBAAwB,MAAM;AAC7C,MAAIA,eAAc,YAAY,WAAW,MAAM;AAC7C,UAAM;AAAA,MACJ,aAAa,QAAQ,yCAAyC,QAAQ,cAAc,MAAM;AAAA,MAC1F;AAAA,MACA,EAAE,UAAU,MAAM,cAAc,UAAU,OAAO;AAAA,MACjD,4CAA4C,MAAM,gDAAgD,QAAQ;AAAA,MAC1G,aAAa,MAAM;AAAA,IACrB;AAAA,EACF;AACA,2BAAyB,UAAU;AAAA,IACjC,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,SAAS,OAAO,OAAgB,UAAkB,MAA2B;AAC3E,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,SAAK,UAAU,MAAM,QAAQ;AAAA,EAC/B;AACA,SAAO;AACT;AAEA,SAAS,MACP,OACA,UACA,UACA,UACA,MACM;AACN,aAAW,OAAO,UAAU;AAC1B,QAAI,EAAE,OAAO,OAAQ,MAAK,UAAU,GAAG,IAAI,IAAI,GAAG,IAAI,gBAAgB;AAAA,EACxE;AACA,QAAM,UAAU,oBAAI,IAAI,CAAC,GAAG,UAAU,GAAG,QAAQ,CAAC;AAClD,QAAM,aAAa,OAAO,KAAK,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,IAAI,GAAG,CAAC;AACrE,MAAI,WAAY,MAAK,UAAU,GAAG,IAAI,IAAI,UAAU,IAAI,mBAAmB;AAC7E;AAIA,SAAS,sBACP,OACA,MACA,UACA,MACU;AACV,MAAI,CAAC,KAAK,KAAK,CAAC,QAAQ,OAAO,UAAU,eAAe,KAAK,OAAO,GAAG,CAAC;AACtE,WAAO,CAAC;AACV;AAAA,IACE,MAAM;AAAA,IACN,CAAC,YAAY,QAAQ;AAAA,IACrB;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,SAAO,CAAC,GAAG,IAAI;AACjB;AAEA,SAAS,OAAO,OAAgB,UAAkB,MAAsB;AACtE,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,SAAK,UAAU,MAAM,kBAAkB;AAAA,EACzC;AACA,SAAO;AACT;AAEA,SAAS,cACP,OACA,WACA,UACA,MACA,aAAa,OACL;AACR,MACE,OAAO,UAAU,YAChB,CAAC,cAAc,MAAM,WAAW,KACjC,MAAM,SAAS,WACf;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,GAAG,aAAa,KAAK,YAAY,qBAAqB,SAAS;AAAA,IACjE;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,eAAe,OAAgB,UAAkB,MAAoB;AAC5E,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,SAAK,UAAU,MAAM,gBAAgB;AAAA,EACvC;AACF;AAEA,SAAS,uBACP,OACA,UACA,MACM;AACN,MAAI,UAAU,KAAM,QAAO,OAAO,UAAU,IAAI;AAClD;AAgCA,SAAS,iBACP,OACA,UACA,MACQ;AACR,QAAM,WAAW,gBAAgB,OAAO,UAAU,IAAI;AACtD,MAAI,WAAW,wBAAwB;AACrC,SAAK,UAAU,MAAM,yBAAyB,sBAAsB,EAAE;AAAA,EACxE;AACA,SAAO;AACT;AAEA,SAAS,QAAQ,OAAgB,UAAkB,MAAoB;AACrE,MAAI,OAAO,UAAU,UAAW,MAAK,UAAU,MAAM,SAAS;AAChE;AAEA,SAAS,UAAU,OAAgB,UAAkB,MAAsB;AACzE,MAAI,CAAC,OAAO,cAAc,KAAK,KAAM,QAAmB,GAAG;AACzD,SAAK,UAAU,MAAM,2BAA2B;AAAA,EAClD;AACA,SAAO;AACT;AAEA,SAAS,gBACP,OACA,UACA,MACQ;AACR,MAAI,CAAC,OAAO,cAAc,KAAK,KAAM,SAAoB,GAAG;AAC1D,SAAK,UAAU,MAAM,uBAAuB;AAAA,EAC9C;AACA,SAAO;AACT;AAEA,SAAS,UACP,OACA,QACA,UACA,MACQ;AACR,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,SAAK,UAAU,MAAM,OAAO,KAAK,KAAK,CAAC;AAAA,EACzC;AACA,SAAO;AACT;AAEA,SAAS,UAAU,OAAgB,UAAkB,MAAoB;AACvE,MACE,OAAO,UAAU,YACjB,CAAC,8CAA8C,KAAK,KAAK,KACzD,CAAC,OAAO,SAAS,KAAK,MAAM,KAAK,CAAC,GAClC;AACA,SAAK,UAAU,MAAM,gCAAgC;AAAA,EACvD;AACF;AAEA,SAAS,SAAS,OAAgB,UAAkB,MAAoB;AACtE,MAAI,OAAO,UAAU,YAAY,CAAC,aAAa,KAAK,KAAK,GAAG;AAC1D,SAAK,UAAU,MAAM,sCAAsC;AAAA,EAC7D;AACF;AAEA,SAAS,MAAM,OAAgB,UAAkB,MAAyB;AACxE,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,MAAK,UAAU,MAAM,OAAO;AACvD,SAAO;AACT;AAEA,SAAS,uBACP,OACA,UACA,MACM;AACN,MAAI,UAAU,UAAa,UAAU,QAAQ,OAAO,UAAU,UAAU;AACtE,SAAK,UAAU,MAAM,gBAAgB;AAAA,EACvC;AACF;AAEA,SAAS,kBAAkB,OAAgB,UAAkB,MAAc;AACzE,QAAM,OAAO,OAAO,OAAO,UAAU,IAAI;AACzC;AAAA,IACE;AAAA,IACA,CAAC;AAAA,IACD,CAAC,SAAS,UAAU,YAAY,YAAY,KAAK;AAAA,IACjD;AAAA,IACA;AAAA,EACF;AACA,yBAAuB,KAAK,OAAO,UAAU,GAAG,IAAI,QAAQ;AAC5D,yBAAuB,KAAK,QAAQ,UAAU,GAAG,IAAI,SAAS;AAC9D,aAAW,OAAO,CAAC,YAAY,YAAY,KAAK,GAAY;AAC1D,QAAI,KAAK,GAAG,MAAM;AAChB,qBAAe,KAAK,GAAG,GAAG,UAAU,GAAG,IAAI,IAAI,GAAG,EAAE;AAAA,EACxD;AACF;AAEA,SAAS,cAAc,OAAgB,UAAkB,MAAoB;AAC3E,MAAI,OAAO,UAAU,SAAU;AAC/B,QAAM,QAAQ,OAAO,OAAO,UAAU,IAAI;AAC1C;AAAA,IACE;AAAA,IACA,CAAC;AAAA,IACD,CAAC,MAAM,OAAO,SAAS,UAAU,YAAY,YAAY,OAAO,OAAO;AAAA,IACvE;AAAA,IACA;AAAA,EACF;AACA,MACE,MAAM,OAAO,UACb,MAAM,OAAO,QACb,OAAO,MAAM,OAAO,YACpB,OAAO,MAAM,OAAO,UACpB;AACA,SAAK,UAAU,GAAG,IAAI,OAAO,yBAAyB;AAAA,EACxD;AACA,aAAW,OAAO,CAAC,OAAO,YAAY,YAAY,KAAK,GAAY;AACjE,QAAI,MAAM,GAAG,MAAM;AACjB,qBAAe,MAAM,GAAG,GAAG,UAAU,GAAG,IAAI,IAAI,GAAG,EAAE;AAAA,EACzD;AACA,yBAAuB,MAAM,OAAO,UAAU,GAAG,IAAI,QAAQ;AAC7D,yBAAuB,MAAM,QAAQ,UAAU,GAAG,IAAI,SAAS;AAC/D,MAAI,MAAM,UAAU,QAAW;AAC7B,UAAM,QAAQ,OAAO,MAAM,OAAO,UAAU,GAAG,IAAI,QAAQ;AAC3D,WAAO,QAAQ,KAAK,EAAE;AAAA,MAAQ,CAAC,CAAC,KAAK,IAAI,MACvC,kBAAkB,MAAM,UAAU,GAAG,IAAI,UAAU,GAAG,EAAE;AAAA,IAC1D;AAAA,EACF;AACF;AAEA,SAAS,kBACP,OACA,UACA,MACM;AACN,QAAM,MAAM,OAAO,OAAO,UAAU,IAAI;AACxC,QAAM,KAAK,CAAC,MAAM,SAAS,UAAU,OAAO,GAAG,CAAC,GAAG,UAAU,IAAI;AACjE,SAAO,IAAI,IAAI,UAAU,GAAG,IAAI,KAAK;AACrC,SAAO,IAAI,OAAO,UAAU,GAAG,IAAI,QAAQ;AAC3C,MAAI,IAAI,WAAW,KAAM,QAAO,IAAI,QAAQ,UAAU,GAAG,IAAI,SAAS;AACtE,MAAI,IAAI,UAAU,KAAM,eAAc,IAAI,OAAO,UAAU,GAAG,IAAI,QAAQ;AAC5E;AAEA,SAAS,kBACP,OACA,UACA,MACM;AACN,QAAM,YAAY,OAAO,OAAO,UAAU,IAAI;AAC9C;AAAA,IACE;AAAA,IACA,CAAC,WAAW,gBAAgB,iBAAiB;AAAA,IAC7C,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,SAAO,UAAU,SAAS,UAAU,GAAG,IAAI,UAAU;AACrD,SAAO,UAAU,cAAc,UAAU,GAAG,IAAI,eAAe;AAC/D,SAAO,UAAU,iBAAiB,UAAU,GAAG,IAAI,kBAAkB;AACvE;AAEA,SAAS,kBAAkB,MAAmB,OAA4B;AACxE,aAAW,SAAS,CAAC,WAAW,gBAAgB,iBAAiB,GAAY;AAC3E,QAAK,KAAK,KAAK,IAAgB,MAAM,KAAK,EAAc,QAAO;AAC/D,QAAK,KAAK,KAAK,IAAgB,MAAM,KAAK,EAAc,QAAO;AAAA,EACjE;AACA,SAAO;AACT;AAEA,SAAS,mBACP,OACA,UACA,MACM;AACN,QAAM,aAAa,MAAM,OAAO,UAAU,IAAI;AAC9C,MAAI,WAAW,SAAS,GAAI,MAAK,UAAU,MAAM,uBAAuB;AACxE,MAAI;AACJ,aAAW,QAAQ,CAAC,WAAW,UAAU;AACvC,sBAAkB,WAAW,UAAU,GAAG,IAAI,IAAI,KAAK,GAAG;AAC1D,UAAM,OAAO;AACb,UAAM,aAAa,QAAQ,kBAAkB,MAAM,KAAK,IAAI;AAC5D,QAAI,eAAe,UAAa,cAAc,GAAG;AAC/C,WAAK,UAAU,GAAG,IAAI,IAAI,KAAK,KAAK,oCAAoC;AAAA,IAC1E;AACA,YAAQ;AAAA,EACV,CAAC;AACH;AAEA,SAAS,mBACP,OACA,UACA,MACM;AACN,QAAM,aAAa,MAAM,OAAO,UAAU,IAAI;AAC9C,MAAI,WAAW,SAAS,GAAI,MAAK,UAAU,MAAM,uBAAuB;AACxE,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,CAACC,QAAO,UAAU;AACnC,UAAM,WAAW,GAAG,IAAI,IAAI,KAAK;AACjC,UAAM,YAAY,OAAOA,QAAO,UAAU,QAAQ;AAClD,UAAM,WAAW,CAAC,OAAO,OAAO,GAAG,CAAC,GAAG,UAAU,QAAQ;AACzD,UAAM,MAAM,OAAO,UAAU,KAAK,UAAU,GAAG,QAAQ,MAAM;AAC7D,QAAI,IAAI,SAAS,MAAM,IAAI,WAAW,IAAI,KAAK,KAAK,IAAI,GAAG,GAAG;AAC5D;AAAA,QACE;AAAA,QACA,GAAG,QAAQ;AAAA,QACX;AAAA,MACF;AAAA,IACF;AACA,SAAK,IAAI,GAAG;AACZ,QAAI,OAAO,UAAU,UAAU,YAAY,UAAU,MAAM,SAAS,KAAK;AACvE,WAAK,UAAU,GAAG,QAAQ,UAAU,kCAAkC;AAAA,IACxE;AAAA,EACF,CAAC;AACH;AAEA,SAAS,iBACP,OACA,UACA,MACM;AACN,QAAM,WAAW,OAAO,OAAO,UAAU,IAAI;AAC7C,QAAM,UAAU,CAAC,OAAO,GAAG,CAAC,QAAQ,OAAO,GAAG,UAAU,IAAI;AAC5D,QAAM,QAAQ;AAAA,IACZ,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AAEA,MACE,CAAC,iGAAiG;AAAA,IAChG;AAAA,EACF,GACA;AACA,SAAK,UAAU,GAAG,IAAI,UAAU,eAAe;AAAA,EACjD;AACA,MAAI,SAAS,SAAS;AACpB;AAAA,MACE,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,GAAG,IAAI;AAAA,IACT;AACF,MAAI,SAAS,UAAU;AACrB;AAAA,MACE,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,GAAG,IAAI;AAAA,IACT;AACJ;AAEA,SAAS,wBACP,OACA,UACA,MACM;AACN,QAAM,UAAU,OAAO,OAAO,UAAU,IAAI;AAC5C;AAAA,IACE;AAAA,IACA,CAAC,iBAAiB,SAAS,cAAc,WAAW,eAAe;AAAA,IACnE,CAAC,eAAe,cAAc,iBAAiB;AAAA,IAC/C;AAAA,IACA;AAAA,EACF;AACA;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,aAAW,OAAO,CAAC,WAAW,eAAe,GAAY;AACvD;AAAA,MACE,QAAQ,GAAG;AAAA,MACX;AAAA,MACA;AAAA,MACA,GAAG,IAAI,IAAI,GAAG;AAAA,IAChB;AAAA,EACF;AACA,MAAI,QAAQ,gBAAgB,QAAW;AACrC,QACE,OAAO,QAAQ,gBAAgB,YAC/B,QAAQ,YAAY,KAAK,EAAE,WAAW,GACtC;AACA,WAAK,UAAU,GAAG,IAAI,gBAAgB,yBAAyB;AAAA,IACjE;AAAA,EACF;AACA,MAAI,QAAQ,eAAe,QAAW;AACpC,QACE,OAAO,QAAQ,eAAe,YAC9B,QAAQ,WAAW,KAAK,EAAE,WAAW,KACrC,QAAQ,WAAW,KAAK,EAAE,SAAS,IACnC;AACA;AAAA,QACE;AAAA,QACA,GAAG,IAAI;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,oBAAoB,QAAW;AACzC;AAAA,MACE,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,uBACP,OACA,UACA,MACM;AACN,QAAM,QAAQ,OAAO,OAAO,UAAU,IAAI;AAC1C,QAAM,OAAO,CAAC,MAAM,aAAa,GAAG,CAAC,GAAG,UAAU,IAAI;AACtD,SAAO,MAAM,IAAI,UAAU,GAAG,IAAI,KAAK;AACvC,SAAO,MAAM,aAAa,UAAU,GAAG,IAAI,cAAc;AAC3D;AAEA,SAAS,4BACP,OACA,UACA,MACM;AACN,QAAM,WAAW,OAAO,OAAO,UAAU,IAAI;AAC7C,MAAI,OAAO,KAAK,QAAQ,EAAE,SAAS;AACjC,SAAK,UAAU,MAAM,oBAAoB;AAC3C,SAAO,QAAQ,QAAQ,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACjD,QAAI,CAAC,OAAO,IAAI,SAAS,MAAM,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,GAAG;AACrE,WAAK,UAAU,GAAG,IAAI,IAAI,GAAG,IAAI,oBAAoB;AAAA,IACvD;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,SAAS,KAAK;AACnD,WAAK,UAAU,GAAG,IAAI,IAAI,GAAG,IAAI,kCAAkC;AAAA,IACrE;AAAA,EACF,CAAC;AACH;AAEA,SAAS,iBACP,OACA,UACA,MACM;AACN,QAAM,OAAO,OAAO,OAAO,UAAU,IAAI;AACzC;AAAA,IACE;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK,IAAI,UAAU,GAAG,IAAI,KAAK;AACtC,oBAAkB,KAAK,SAAS,UAAU,GAAG,IAAI,UAAU;AAC3D,oBAAkB,KAAK,SAAS,UAAU,GAAG,IAAI,UAAU;AAC3D,qBAAmB,KAAK,YAAY,UAAU,GAAG,IAAI,aAAa;AAClE,mBAAiB,KAAK,UAAU,UAAU,GAAG,IAAI,WAAW;AAC5D,QAAM,YAAY;AAAA,IAChB,KAAK;AAAA,IACL;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW;AAAA,IACf,KAAK;AAAA,IACL;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,qBAAqB;AAAA,IACzB,KAAK;AAAA,IACL;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW,KAAK;AACtB,QAAM,oBACJ,OAAO,SAAS,IAAI,OAAO,QAAQ,IAAI,OAAO,QAAQ;AACxD,MACE,oBAAoB,MACpB,OAAO,kBAAkB,MAAM,mBAC/B;AACA;AAAA,MACE;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACA,UAAQ,KAAK,kBAAkB,UAAU,GAAG,IAAI,mBAAmB;AACrE;AAEO,SAAS,mBAAsB,OAAgB,WAAW,QAAW;AAC1E,QAAM,OAAO,OAAO,OAAO,UAAU,GAAG;AACxC;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,QACD;AAAA,QACA,CAAC,kBAAkB,iBAAiB,YAAY;AAAA,QAChD;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK,IAAI,UAAU,MAAM;AAChC,YAAU,KAAK,QAAQ,eAAe,UAAU,UAAU;AAC1D,YAAU,KAAK,UAAU,UAAU,YAAY;AAC/C,WAAS,KAAK,UAAU,UAAU,YAAY;AAC9C,QAAM,SAAS,OAAO,KAAK,QAAQ,UAAU,UAAU;AACvD,QAAM,QAAQ,CAAC,MAAM,UAAU,MAAM,GAAG,CAAC,GAAG,UAAU,UAAU;AAChE,aAAW,OAAO,CAAC,MAAM,UAAU,MAAM;AACvC,WAAO,OAAO,GAAG,GAAG,UAAU,YAAY,GAAG,EAAE;AACjD,QAAM,WAAW,UAAU,KAAK,eAAe,UAAU,iBAAiB;AAC1E,QAAM,WAAW,UAAU,KAAK,eAAe,UAAU,iBAAiB;AAC1E,QAAM,iBAAiB;AAAA,IACrB,KAAK;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACA,QAAM,KAAK,eAAe,UAAU,iBAAiB,EAAE;AAAA,IACrD,CAACA,QAAO,UAAU;AAChB,YAAM,WAAW,mBAAmB,KAAK;AACzC,YAAM,OAAO,OAAOA,QAAO,UAAU,QAAQ;AAC7C,YAAM,MAAM,CAAC,QAAQ,YAAY,GAAG,CAAC,GAAG,UAAU,QAAQ;AAC1D;AAAA,QACE,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,GAAG,QAAQ;AAAA,MACb;AACA,cAAQ,KAAK,YAAY,UAAU,GAAG,QAAQ,aAAa;AAAA,IAC7D;AAAA,EACF;AACA,qBAAmB,KAAK,YAAY,UAAU,cAAc;AAC5D,QAAM,QAAQ,MAAM,KAAK,OAAO,UAAU,SAAS;AACnD,QAAM;AAAA,IAAQ,CAAC,MAAM,UACnB,iBAAiB,MAAM,UAAU,WAAW,KAAK,GAAG;AAAA,EACtD;AACA,QAAM,mBAAmB,MAAM,OAAe,CAAC,OAAOA,WAAU;AAC9D,UAAM,OAAOA;AACb,WACE,QACA,OAAO,KAAK,cAAwB,IAAI,OAAO,KAAK,QAAkB;AAAA,EAE1E,GAAG,EAAE;AACL,QAAM,mBAAmB,MAAM,OAAe,CAAC,OAAOA,WAAU;AAC9D,UAAM,OAAOA;AACb,WAAO,QAAQ,OAAO,KAAK,aAAuB;AAAA,EACpD,GAAG,EAAE;AACL,MAAI,OAAO,QAAQ,MAAM,kBAAkB;AACzC,SAAK,UAAU,mBAAmB,sCAAsC;AAAA,EAC1E;AACA,MAAI,OAAO,QAAQ,MAAM,kBAAkB;AACzC,SAAK,UAAU,mBAAmB,4BAA4B;AAAA,EAChE;AACA,MACE,mBAAmB,OAAO,QAAQ,IAAI,MACtC,OAAO,cAAc,MAAM,mBAAmB,OAAO,QAAQ,GAC7D;AACA,SAAK,UAAU,yBAAyB,+BAA+B;AAAA,EACzE;AACA,MAAI,oBAAoB,MAAM;AAC5B,UAAM,WAAW,UAAU,KAAK,eAAe,UAAU,iBAAiB;AAC1E,UAAM,QAAQ,UAAU,KAAK,YAAY,UAAU,cAAc;AACjE,QAAI,OAAO,KAAK,MAAM,OAAO,cAAc,IAAI,OAAO,QAAQ,GAAG;AAC/D,WAAK,UAAU,gBAAgB,qCAAqC;AAAA,IACtE;AAAA,EACF;AACA,YAAU,KAAK,WAAW,UAAU,aAAa;AACjD,YAAU,KAAK,WAAW,UAAU,aAAa;AACjD,YAAU,KAAK,WAAW,UAAU,aAAa;AACjD,SAAO;AACT;AAEA,SAAS,iBACP,OACA,UACA,MACM;AACN,QAAM,OAAO,UAAU,IAAI,EAAE,QAAQ,CAACA,QAAO,UAAU;AACrD,UAAM,WAAW,GAAG,IAAI,IAAI,KAAK;AACjC,UAAM,UAAU,OAAOA,QAAO,UAAU,QAAQ;AAChD,UAAM,SAAS,CAAC,QAAQ,WAAW,QAAQ,GAAG,CAAC,GAAG,UAAU,QAAQ;AACpE,cAAU,QAAQ,MAAM,oBAAoB,UAAU,GAAG,QAAQ,OAAO;AACxE,WAAO,QAAQ,SAAS,UAAU,GAAG,QAAQ,UAAU;AACvD,WAAO,QAAQ,QAAQ,UAAU,GAAG,QAAQ,SAAS;AAAA,EACvD,CAAC;AACH;AAEO,SAAS,2BAA8B,OAAmB;AAC/D,QAAM,SAAS,OAAO,OAAO,wBAAwB,GAAG;AACxD,QAAM,QAAQ,CAAC,QAAQ,UAAU,GAAG,CAAC,GAAG,wBAAwB,GAAG;AACnE,qBAAmB,OAAO,IAAI;AAC9B,mBAAiB,OAAO,UAAU,wBAAwB,YAAY;AACtE,SAAO;AACT;AAEO,SAAS,yBAA4B,OAAmB;AAC7D,QAAM,SAAS,OAAO,OAAO,sBAAsB,GAAG;AACtD;AAAA,IACE;AAAA,IACA,CAAC,QAAQ,YAAY,WAAW;AAAA,IAChC,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,QAAM,OAAO,OAAO,OAAO,MAAM,sBAAsB,QAAQ;AAC/D,qBAAmB,IAAI;AACvB,MAAI,KAAK,aAAa,GAAG;AACvB,SAAK,sBAAsB,mBAAmB,4BAA4B;AAAA,EAC5E;AACA,mBAAiB,OAAO,UAAU,sBAAsB,YAAY;AACpE;AAAA,IACE,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,uBAA0B,OAAmB;AAC3D,QAAM,SAAS,OAAO,OAAO,oBAAoB,GAAG;AACpD,QAAM,QAAQ,CAAC,QAAQ,WAAW,GAAG,CAAC,GAAG,oBAAoB,GAAG;AAChE,MAAI,OAAO,SAAS,QAAQ,OAAO,cAAc,MAAM;AACrD,QAAI,OAAO,SAAS,QAAQ,OAAO,cAAc,MAAM;AACrD,WAAK,oBAAoB,KAAK,sCAAsC;AAAA,IACtE;AAAA,EACF,OAAO;AACL,uBAAmB,OAAO,IAAI;AAC9B;AAAA,MACE,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,wBAA2B,OAAmB;AAC5D,QAAM,SAAS,OAAO,OAAO,qBAAqB,GAAG;AACrD;AAAA,IACE;AAAA,IACA,CAAC,QAAQ,YAAY,aAAa,cAAc,UAAU,SAAS;AAAA,IACnE,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,qBAAmB,OAAO,IAAI;AAC9B,mBAAiB,OAAO,UAAU,qBAAqB,YAAY;AACnE;AAAA,IACE,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,aAAa;AAAA,IACjB,OAAO;AAAA,IACP,CAAC,aAAa,WAAW,QAAQ;AAAA,IACjC;AAAA,IACA;AAAA,EACF;AACA,UAAQ,OAAO,QAAQ,qBAAqB,UAAU;AACtD,UAAQ,OAAO,SAAS,qBAAqB,WAAW;AACxD,QAAM,WACJ,eAAe,WACX,CAAC,MAAM,KAAK,IACZ,eAAe,YACb,CAAC,OAAO,IAAI,IACZ,CAAC,OAAO,KAAK;AACrB,MAAI,OAAO,WAAW,SAAS,CAAC,KAAK,OAAO,YAAY,SAAS,CAAC,GAAG;AACnE,SAAK,qBAAqB,KAAK,4CAA4C;AAAA,EAC7E;AACA,SAAO;AACT;AAEA,SAAS,wBACP,OACA,UACA,MACM;AACN,QAAM,OAAO,OAAO,OAAO,UAAU,IAAI;AACzC;AAAA,IACE;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK,IAAI,UAAU,GAAG,IAAI,KAAK;AACtC,MAAI,KAAK,YAAY,MAAM;AACzB,sBAAkB,KAAK,SAAS,UAAU,GAAG,IAAI,UAAU;AAAA,EAC7D;AACA,MAAI,KAAK,YAAY,MAAM;AACzB,sBAAkB,KAAK,SAAS,UAAU,GAAG,IAAI,UAAU;AAAA,EAC7D;AACA,SAAO,KAAK,cAAc,UAAU,GAAG,IAAI,eAAe;AAC1D,yBAAuB,KAAK,cAAc,UAAU,GAAG,IAAI,eAAe;AAC1E,yBAAuB,KAAK,KAAK,UAAU,GAAG,IAAI,MAAM;AACxD,qBAAmB,KAAK,YAAY,UAAU,GAAG,IAAI,aAAa;AAGlE,QAAM,WAAW,gBAAgB,KAAK,UAAU,UAAU,GAAG,IAAI,WAAW;AAC5E,QAAM,YAAY;AAAA,IAChB,KAAK;AAAA,IACL;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW;AAAA,IACf,KAAK;AAAA,IACL;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,YAAY;AAAA,IAChB,KAAK;AAAA,IACL;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW,OAAO,SAAS,IAAI,OAAO,QAAQ,IAAI,OAAO,QAAQ;AACvE,MAAI,WAAW,MAAM,OAAO,SAAS,MAAM,UAAU;AACnD;AAAA,MACE;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACA,UAAQ,KAAK,kBAAkB,UAAU,GAAG,IAAI,mBAAmB;AACrE;AAEA,SAAS,sBACP,OACA,UACA,MACM;AACN,QAAM,QAAQ,OAAO,OAAO,UAAU,IAAI;AAC1C;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,QACD;AAAA,QACA,CAAC,kBAAkB,UAAU,QAAQ;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,MAAI,oBAAoB,OAAO;AAC7B;AAAA,MACE,MAAM;AAAA,MACN,CAAC,OAAO,OAAO,UAAU,OAAO,UAAU,WAAW;AAAA,MACrD;AAAA,MACA,GAAG,IAAI;AAAA,IACT;AACA,QAAI,MAAM,mBAAmB,YAAY;AACvC,UAAI,MAAM,WAAW;AACnB,aAAK,UAAU,GAAG,IAAI,WAAW,mBAAmB;AAAA,IACxD,OAAO;AACL,YAAM,SAAS,OAAO,MAAM,QAAQ,UAAU,GAAG,IAAI,SAAS;AAC9D;AAAA,QACE;AAAA,QACA,CAAC,UAAU,WAAW,YAAY;AAAA,QAClC,CAAC;AAAA,QACD;AAAA,QACA,GAAG,IAAI;AAAA,MACT;AACA;AAAA,QACE,OAAO;AAAA,QACP,CAAC,WAAW,oBAAoB,aAAa,UAAU;AAAA,QACvD;AAAA,QACA,GAAG,IAAI;AAAA,MACT;AACA,iBAAW,OAAO,CAAC,WAAW,YAAY,GAAY;AACpD,YAAI,OAAO,GAAG,MAAM;AAClB,oBAAU,OAAO,GAAG,GAAG,UAAU,GAAG,IAAI,WAAW,GAAG,EAAE;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AACA,SAAO,MAAM,IAAI,UAAU,GAAG,IAAI,KAAK;AACvC,SAAO,MAAM,aAAa,UAAU,GAAG,IAAI,cAAc;AAEzD,QAAM,UAAU,OAAO,MAAM,SAAS,UAAU,GAAG,IAAI,UAAU;AACjE;AAAA,IACE;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC;AAAA,IACD;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,WAAS,QAAQ,UAAU,UAAU,GAAG,IAAI,mBAAmB;AAC/D,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,QAAQ;AAAA,IACZ,QAAQ;AAAA,IACR;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,UAAU;AAAA,IACd,QAAQ;AAAA,IACR;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,gBAAgB,OAAO,QAAQ,IAAI,OAAO,QAAQ,IAAI,OAAO,QAAQ;AAC3E,MAAI,gBAAgB,MAAM,OAAO,KAAK,MAAM,eAAe;AACzD;AAAA,MACE;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,KAAK,IAAI,OAAO,QAAQ,IAAI,MAAM,YAAY,QAAQ,UAAU;AACzE;AAAA,MACE;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,WAAW,MAAM;AACzB,UAAM,SAAS,OAAO,MAAM,QAAQ,UAAU,GAAG,IAAI,SAAS;AAC9D,UAAM,QAAQ,CAAC,MAAM,UAAU,MAAM,GAAG,CAAC,GAAG,UAAU,GAAG,IAAI,SAAS;AACtE,eAAW,OAAO,CAAC,MAAM,UAAU,MAAM,GAAY;AACnD,aAAO,OAAO,GAAG,GAAG,UAAU,GAAG,IAAI,WAAW,GAAG,EAAE;AAAA,IACvD;AAAA,EACF;AACA,mBAAiB,MAAM,kBAAkB,UAAU,GAAG,IAAI,mBAAmB;AAC7E,MAAI,MAAM,oBAAoB,MAAM;AAClC;AAAA,MACE,MAAM;AAAA,MACN;AAAA,MACA,GAAG,IAAI;AAAA,IACT;AAAA,EACF;AACA,qBAAmB,MAAM,YAAY,UAAU,GAAG,IAAI,aAAa;AAEnE,QAAM,QAAQ,MAAM,MAAM,OAAO,UAAU,GAAG,IAAI,QAAQ;AAC1D,MAAI,MAAM,WAAW,EAAG,MAAK,UAAU,GAAG,IAAI,UAAU,iBAAiB;AACzE,QAAM;AAAA,IAAQ,CAAC,MAAM,UACnB,wBAAwB,MAAM,UAAU,GAAG,IAAI,UAAU,KAAK,GAAG;AAAA,EACnE;AACA,QAAM,mBAAmB,MAAM,OAAe,CAAC,KAAKA,WAAU;AAC5D,UAAM,OAAOA;AACb,WACE,MACA,OAAO,KAAK,cAAwB,IAAI,OAAO,KAAK,QAAkB;AAAA,EAE1E,GAAG,EAAE;AACL,QAAM,mBAAmB,MAAM,OAAe,CAAC,KAAKA,WAAU;AAC5D,UAAM,OAAOA;AACb,WAAO,MAAM,OAAO,KAAK,aAAuB;AAAA,EAClD,GAAG,EAAE;AACL,MAAI,OAAO,QAAQ,MAAM,kBAAkB;AACzC,SAAK,UAAU,GAAG,IAAI,0BAA0B,uBAAuB;AAAA,EACzE;AACA,MAAI,OAAO,QAAQ,MAAM,kBAAkB;AACzC,SAAK,UAAU,GAAG,IAAI,0BAA0B,uBAAuB;AAAA,EACzE;AAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,YAAU,MAAM,UAAU,UAAU,GAAG,IAAI,WAAW;AACtD,YAAU,MAAM,WAAW,UAAU,GAAG,IAAI,YAAY;AACxD,YAAU,MAAM,WAAW,UAAU,GAAG,IAAI,YAAY;AAC1D;AAOA,SAAS,wBACP,OACA,UACA,MACM;AACN,MAAI,UAAU,KAAM,iBAAgB,OAAO,UAAU,IAAI;AAC3D;AAEO,SAAS,wBAA2B,OAAmB;AAC5D,QAAM,WAAW;AACjB,QAAM,SAAS,OAAO,OAAO,UAAU,GAAG;AAC1C;AAAA,IACE;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,QAAM,OAAO,MAAM,UAAU,QAAQ,EAAE;AAAA,IAAQ,CAAC,OAAO,UACrD,sBAAsB,OAAO,UAAU,UAAU,KAAK,GAAG;AAAA,EAC3D;AACA,YAAU,OAAO,WAAW,UAAU,aAAa;AACnD,kBAAgB,OAAO,OAAO,UAAU,SAAS;AACjD,YAAU,OAAO,YAAY,UAAU,cAAc;AACrD,kBAAgB,OAAO,MAAM,UAAU,QAAQ;AAC/C,kBAAgB,OAAO,eAAe,UAAU,iBAAiB;AACjE,UAAQ,OAAO,aAAa,UAAU,eAAe;AACrD,UAAQ,OAAO,aAAa,UAAU,eAAe;AACrD,0BAAwB,OAAO,UAAU,UAAU,YAAY;AAC/D,0BAAwB,OAAO,UAAU,UAAU,YAAY;AAC/D,SAAO;AACT;AAEA,SAAS,qBACP,OACA,UACA,MACM;AACN,QAAM,OAAO,OAAO,OAAO,UAAU,IAAI;AACzC;AAAA,IACE;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK,IAAI,UAAU,GAAG,IAAI,KAAK;AACtC,oBAAkB,KAAK,SAAS,UAAU,GAAG,IAAI,UAAU;AAC3D,oBAAkB,KAAK,SAAS,UAAU,GAAG,IAAI,UAAU;AAC3D,SAAO,KAAK,cAAc,UAAU,GAAG,IAAI,eAAe;AAC1D,yBAAuB,KAAK,cAAc,UAAU,GAAG,IAAI,eAAe;AAC1E,yBAAuB,KAAK,KAAK,UAAU,GAAG,IAAI,MAAM;AACxD,qBAAmB,KAAK,YAAY,UAAU,GAAG,IAAI,aAAa;AAClE,mBAAiB,KAAK,UAAU,UAAU,GAAG,IAAI,WAAW;AAC5D,QAAM,YAAY;AAAA,IAChB,KAAK;AAAA,IACL;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW;AAAA,IACf,KAAK;AAAA,IACL;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,YAAY;AAAA,IAChB,KAAK;AAAA,IACL;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,oBACJ,OAAO,SAAS,IAAI,OAAO,KAAK,QAAkB,IAAI,OAAO,QAAQ;AACvE,MAAI,oBAAoB,MAAM,OAAO,SAAS,MAAM,mBAAmB;AACrE;AAAA,MACE;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACA,UAAQ,KAAK,kBAAkB,UAAU,GAAG,IAAI,mBAAmB;AACrE;AAEA,SAAS,wBACP,OACA,UACA,MACM;AACN,QAAM,UAAU,OAAO,OAAO,UAAU,IAAI;AAC5C;AAAA,IACE;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,WAAS,QAAQ,UAAU,UAAU,GAAG,IAAI,WAAW;AACvD,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,QAAM,QAAQ,UAAU,QAAQ,YAAY,UAAU,GAAG,IAAI,aAAa;AAC1E,MACE,OAAO,KAAK,MACZ,OAAO,QAAQ,IAAI,OAAO,QAAQ,IAAI,OAAO,QAAQ,GACrD;AACA;AAAA,MACE;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,gCACP,OACA,UACA,MACM;AACN,QAAM,UAAU,OAAO,OAAO,UAAU,IAAI;AAC5C,QAAM,SAAS,CAAC,MAAM,YAAY,gBAAgB,GAAG,CAAC,GAAG,UAAU,IAAI;AACvE,SAAO,QAAQ,IAAI,UAAU,GAAG,IAAI,KAAK;AACzC,YAAU,QAAQ,UAAU,mBAAmB,UAAU,GAAG,IAAI,WAAW;AAC3E;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACF;AAEA,SAAS,oBACP,QACA,WAIA;AACA,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,WAAW,OAAQ,QAAO,EAAE,UAAU,MAAM,UAAU,CAAC,EAAE;AAC7D,MAAI,WAAW,aAAa;AAC1B,WAAO;AAAA,MACL,UAAU,CAAC,GAAG,MAAM,eAAe,iBAAiB;AAAA,MACpD,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AACA,SAAO,cAAc,iBACjB;AAAA,IACE,UAAU;AAAA,MACR,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU,CAAC;AAAA,EACb,IACA,EAAE,UAAU,CAAC,GAAG,MAAM,UAAU,GAAG,UAAU,CAAC,EAAE;AACtD;AAEA,SAAS,qBACP,OACA,UACA,MACA,QACM;AACN,QAAM,WAAW,OAAO,OAAO,UAAU,GAAG;AAC5C,QAAM,SAAS;AAAA,IACb,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,OAAO,oBAAoB,QAAQ,SAAS,SAAS;AAC3D,OAAK,SAAS;AAAA,IACZ,GAAG;AAAA,MACD;AAAA,MACA,CAAC,kBAAkB,QAAQ;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,oBAAoB;AACtB,cAAU,SAAS,QAAQ,CAAC,OAAO,WAAW,GAAG,UAAU,UAAU;AACvE,OAAK,SAAS,KAAK,SAAS;AAC5B,MAAI,MAAM;AACR,SAAK,WAAW,KAAK,SAAS;AAAA,MAC5B,CAAC,QAAQ,CAAC,CAAC,SAAS,mBAAmB,YAAY,EAAE,SAAS,GAAG;AAAA,IACnE;AACA,SAAK,SAAS,KAAK,mBAAmB;AAAA,EACxC,WAAW,QAAQ;AACjB,SAAK,SAAS,KAAK,qBAAqB,qBAAqB;AAAA,EAC/D;AACA,QAAM,UAAU,KAAK,UAAU,KAAK,UAAU,UAAU,GAAG;AAC3D,SAAO,SAAS,IAAI,UAAU,MAAM;AACpC,0BAAwB,SAAS,SAAS,UAAU,WAAW;AAC/D,MAAI,OAAO,UAAU,eAAe,KAAK,UAAU,SAAS,GAAG;AAC7D,UAAM,UAAU,OAAO,SAAS,SAAS,UAAU,WAAW;AAC9D;AAAA,MACE;AAAA,MACA,CAAC,gBAAgB,uBAAuB;AAAA,MACxC,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF;AACA,UAAM,SAAS;AAAA,MACb,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACA,UAAM,WAAW;AAAA,MACf,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACA,UAAM,UAAU,SAAS;AACzB,QACE,OAAO,MAAM,IAAI,OAAO,QAAQ,MAC9B,OAAO,QAAQ,UAAoB,KACpC,SAAS,KAAK,QAAQ,aAAa;AAEpC;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,EACJ;AACA,MAAI,CAAC,MAAM;AACT,UAAM,QAAQ,MAAM,SAAS,OAAO,UAAU,SAAS;AACvD,QAAI,MAAM,WAAW,EAAG,MAAK,UAAU,WAAW,iBAAiB;AACnE,UAAM;AAAA,MAAQ,CAAC,MAAM,UACnB,qBAAqB,MAAM,UAAU,WAAW,KAAK,GAAG;AAAA,IAC1D;AACA,UAAM,mBAAmB,MAAM,OAAe,CAAC,OAAOC,WAAU;AAC9D,YAAM,OAAOA;AACb,aACE,QACA,OAAO,KAAK,cAAwB,IAAI,OAAO,KAAK,QAAkB;AAAA,IAE1E,GAAG,EAAE;AACL,UAAM,mBAAmB,MAAM,OAAe,CAAC,OAAOA,WAAU;AAC9D,YAAM,OAAOA;AACb,aAAO,QAAQ,OAAO,KAAK,aAAuB;AAAA,IACpD,GAAG,EAAE;AACL,UAAM,UAAU,SAAS;AACzB,QAAI,OAAO,QAAQ,aAAuB,MAAM,kBAAkB;AAChE;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,OAAO,QAAQ,aAAuB,MAAM,kBAAkB;AAChE;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,SAAS,oBAAoB,MAAM;AACrC;AAAA,QACE,SAAS;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,uBAAmB,SAAS,YAAY,UAAU,cAAc;AAAA,EAClE;AACA,mBAAiB,SAAS,kBAAkB,UAAU,oBAAoB;AAC1E,YAAU,SAAS,WAAW,UAAU,aAAa;AACrD,YAAU,SAAS,WAAW,UAAU,aAAa;AACrD,YAAU,SAAS,WAAW,UAAU,aAAa;AAErD,QAAM,eAAe,OAAO,SAAS,cAAc,UAAU,gBAAgB;AAC7E,QAAM,cAAc,CAAC,sBAAsB,GAAG,CAAC,GAAG,UAAU,gBAAgB;AAC5E,MAAI,WAAW,QAAQ;AACrB,QAAI,aAAa,yBAAyB,MAAM;AAC9C;AAAA,QACE,aAAa;AAAA,QACb;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,SAAS,UAAU;AACrB,WAAK,UAAU,WAAW,wBAAwB;AAAA,EACtD,OAAO;AACL,QAAI,aAAa,yBAAyB,MAAM;AAC9C;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,WAAW,UAAU;AACvB,gBAAU,SAAS,UAAU,UAAU,YAAY;AACnD,6BAAuB,SAAS,OAAO,UAAU,SAAS;AAC1D,UACE,SAAS,cAAc,UACvB,SAAS,cAAc,gBACvB;AACA,aAAK,UAAU,eAAe,cAAc;AAAA,MAC9C;AACA,UAAI,SAAS,cAAc,gBAAgB;AACzC,kBAAU,SAAS,aAAa,UAAU,eAAe;AACzD;AAAA,UACE,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,gBAAU,SAAS,aAAa,UAAU,eAAe;AACzD;AAAA,QACE,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,SAAS,UAAU;AACrB,aAAK,UAAU,WAAW,6BAA6B;AAAA,IAC3D;AAAA,EACF;AACA,MAAI,QAAQ,QAAQ;AAClB,QAAI,SAAS,sBAAsB,MAAM;AACvC;AAAA,QACE,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI;AACF;AAAA,MACE,SAAS;AAAA,MACT;AAAA,MACA;AAAA,IACF;AACJ;AAEO,SAAS,uBAA0B,OAAmB;AAC3D,uBAAqB,OAAO,YAAY,OAAO,KAAK;AACpD,SAAO;AACT;AAEO,SAAS,uBAA0B,OAAmB;AAC3D,uBAAqB,OAAO,mBAAmB,OAAO,IAAI;AAC1D,SAAO;AACT;AAEO,SAAS,6BACd,OACA,QACG;AACH,QAAM,WAAW,SACb,kCACA;AACJ,QAAM,SAAS,OAAO,OAAO,UAAU,GAAG;AAC1C,QAAM,QAAQ,CAAC,YAAY,eAAe,GAAG,CAAC,GAAG,UAAU,GAAG;AAC9D,MAAI,OAAQ,wBAAuB,OAAO,QAAQ;AAAA,MAC7C,wBAAuB,OAAO,QAAQ;AAC3C;AAAA,IACE,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,4BAA+B,OAAmB;AAChE,QAAM,SAAS,OAAO,OAAO,yBAAyB,GAAG;AACzD;AAAA,IACE;AAAA,IACA,CAAC,QAAQ,WAAW,YAAY;AAAA,IAChC,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACA,QAAM,OAAO,MAAM,yBAAyB,QAAQ,EAAE;AAAA,IAAQ,CAAC,SAC7D,qBAAqB,MAAM,sBAAsB,MAAM,KAAK;AAAA,EAC9D;AACA,UAAQ,OAAO,SAAS,yBAAyB,WAAW;AAC5D,MAAI,OAAO,eAAe;AACxB;AAAA,MACE,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACF,MAAI,OAAO,YAAY,QAAQ,OAAO,eAAe,MAAM;AACzD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAAgB,UAAkB,MAAoB;AAC3E,QAAMC,SAAQ,OAAO,OAAO,UAAU,IAAI;AAC1C,QAAMA,QAAO,CAAC,eAAe,UAAU,GAAG,CAAC,GAAG,UAAU,IAAI;AAC5D,YAAUA,OAAM,aAAa,UAAU,GAAG,IAAI,cAAc;AAC5D,WAASA,OAAM,UAAU,UAAU,GAAG,IAAI,WAAW;AACvD;AAqPA,SAAS,wBACP,OACA,UACA,MACM;AACN,QAAM,WAAW,OAAO,OAAO,UAAU,IAAI;AAC7C,QAAM,UAAU,CAAC,eAAe,YAAY,YAAY,GAAG,CAAC,GAAG,UAAU,IAAI;AAC7E,YAAU,SAAS,aAAa,UAAU,GAAG,IAAI,cAAc;AAC/D,WAAS,SAAS,UAAU,UAAU,GAAG,IAAI,WAAW;AACxD,YAAU,SAAS,YAAY,UAAU,GAAG,IAAI,aAAa;AAC/D;AAEA,SAAS,yBACP,OACA,UACA,MACM;AACN,QAAM,iBAAiB,OAAO,OAAO,UAAU,IAAI;AACnD,QAAM,gBAAgB,CAAC,QAAQ,GAAG,CAAC,GAAG,UAAU,IAAI;AACpD,MAAI,eAAe,WAAW,OAAQ,MAAK,UAAU,GAAG,IAAI,WAAW,MAAM;AAC/E;AAEA,SAAS,+BACP,OACA,SACA,UACA,MACM;AACN,QAAM,iBAAiB,OAAO,OAAO,UAAU,IAAI;AACnD,QAAM,gBAAgB,CAAC,UAAU,SAAS,GAAG,CAAC,GAAG,UAAU,IAAI;AAC/D,MAAI,eAAe,WAAW;AAC5B,SAAK,UAAU,GAAG,IAAI,WAAW,UAAU;AAC7C,QAAM,UAAU,MAAM,eAAe,SAAS,UAAU,GAAG,IAAI,UAAU;AACzE,MAAI,QAAQ,WAAW,EAAG,MAAK,UAAU,GAAG,IAAI,YAAY,iBAAiB;AAC7E,MAAI,WAAW;AACf,UAAQ,QAAQ,CAAC,QAAQ,UAAU;AACjC,UAAM,UAAU,QAAQ,QAAQ,MAAgB;AAChD,QAAI,UAAU,KAAK,WAAW,UAAU;AACtC;AAAA,QACE;AAAA,QACA,GAAG,IAAI,YAAY,KAAK;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AACA,eAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,mBACP,OACA,UACA,UACA,MACM;AACN,QAAM,SAAS,OAAO,OAAO,UAAU,IAAI;AAC3C,MAAI,aAAa,UAAU;AACzB;AAAA,MACE;AAAA,MACA,CAAC,QAAQ,gBAAgB,kBAAkB,WAAW;AAAA,MACtD,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF;AACA,QAAI,OAAO,SAAS;AAClB,WAAK,UAAU,GAAG,IAAI,SAAS,wBAAwB;AACzD,UAAM,eAAe;AAAA,MACnB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,GAAG,IAAI;AAAA,IACT;AACA,QAAI,CAAC,wCAAwC,KAAK,YAAY,GAAG;AAC/D;AAAA,QACE;AAAA,QACA,GAAG,IAAI;AAAA,QACP;AAAA,MACF;AAAA,IACF;AACA,UAAM,iBAAiB;AAAA,MACrB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,GAAG,IAAI;AAAA,IACT;AACA,QAAI,CAAC,kCAAkC,KAAK,cAAc,GAAG;AAC3D,WAAK,UAAU,GAAG,IAAI,mBAAmB,wBAAwB;AAAA,IACnE;AACA,UAAM,YAAY;AAAA,MAChB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,GAAG,IAAI;AAAA,IACT;AACA,QACE,CAAC,iCAAiC,KAAK,SAAS,KAChD,CAAC,4BAA4B,KAAK,SAAS,GAC3C;AACA;AAAA,QACE;AAAA,QACA,GAAG,IAAI;AAAA,QACP;AAAA,MACF;AAAA,IACF;AACA,QAAI;AACF,YAAM,SAAS,IAAI,IAAI,SAAS;AAChC,YAAM,WACJ,OAAO,aAAa,YACnB,OAAO,aAAa,eAAe,OAAO,aAAa;AAC1D,UACG,CAAC,YAAY,OAAO,aAAa,YAClC,OAAO,YACP,OAAO;AAEP,cAAM,IAAI,MAAM,mBAAmB;AAAA,IACvC,QAAQ;AACN;AAAA,QACE;AAAA,QACA,GAAG,IAAI;AAAA,QACP;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,aAAa,WAAW;AAC1B,QAAI,OAAO,SAAS,eAAe;AACjC,YAAM,gBAAgB,gBAAgB;AACtC,YAAM,iBAAiB,iBAAiB;AACxC,UAAI,kBAAkB,gBAAgB;AACpC;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,QACE;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,UACA,GAAI,gBAAgB,CAAC,cAAc,aAAa,IAAI,CAAC;AAAA,UACrD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,CAAC;AAAA,QACD;AAAA,QACA;AAAA,MACF;AACA,UAAI,OAAO,YAAY,KAAM,MAAK,UAAU,GAAG,IAAI,YAAY,IAAI;AACnE,UAAI,iBAAiB,OAAO,eAAe;AACzC,aAAK,UAAU,GAAG,IAAI,eAAe,OAAO;AAC9C,UAAI,kBAAkB,OAAO,gBAAgB,oBAAoB;AAC/D,aAAK,UAAU,GAAG,IAAI,gBAAgB,kBAAkB;AAAA,MAC1D;AACA,iBAAW,OAAO,CAAC,WAAW,YAAY,GAAY;AACpD,sBAAc,OAAO,GAAG,GAAG,KAAK,UAAU,GAAG,IAAI,IAAI,GAAG,EAAE;AAAA,MAC5D;AACA,YAAM,YAAY;AAAA,QAChB,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,GAAG,IAAI;AAAA,MACT;AACA,UAAI,CAAC,sBAAsB,KAAK,SAAS,GAAG;AAC1C;AAAA,UACE;AAAA,UACA,GAAG,IAAI;AAAA,UACP;AAAA,QACF;AAAA,MACF;AACA;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,GAAG,IAAI;AAAA,MACT;AACA,sBAAgB,OAAO,aAAa,UAAU,GAAG,IAAI,cAAc;AACnE,UAAI,OAAO,aAAa,gBAAgB;AACtC,aAAK,UAAU,GAAG,IAAI,aAAa,cAAc;AAAA,MACnD;AACA,UAAI,OAAO,cAAc;AACvB,aAAK,UAAU,GAAG,IAAI,cAAc,MAAM;AAC5C,YAAM,cAAc;AAAA,QAClB,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,GAAG,IAAI;AAAA,MACT;AACA,UAAI;AACF,cAAM,SAAS,IAAI,IAAI,WAAW;AAClC,cAAM,WACJ,OAAO,aAAa,YACnB,OAAO,aAAa,eAAe,OAAO,aAAa;AAC1D,YACG,CAAC,YAAY,OAAO,aAAa,YAClC,OAAO,YACP,OAAO;AAEP,gBAAM,IAAI,MAAM,qBAAqB;AAAA,MACzC,QAAQ;AACN;AAAA,UACE;AAAA,UACA,GAAG,IAAI;AAAA,UACP;AAAA,QACF;AAAA,MACF;AACA,UAAI,CAAC,eAAe;AAClB,eAAO,aAAa;AACpB,eAAO,cAAc;AAAA,MACvB;AACA;AAAA,IACF;AACA,UAAM,QAAQ,CAAC,QAAQ,aAAa,GAAG,CAAC,GAAG,UAAU,IAAI;AACzD,QAAI,OAAO,SAAS,oBAAoB;AACtC,WAAK,UAAU,GAAG,IAAI,SAAS,gCAAgC;AAAA,IACjE;AACA,UAAM,cAAc;AAAA,MAClB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,GAAG,IAAI;AAAA,IACT;AACA,QAAI;AACF,YAAM,SAAS,IAAI,IAAI,WAAW;AAClC,UACE,OAAO,aAAa,YACpB,OAAO,aAAa,MACpB,OAAO,aAAa,IACpB;AACA,cAAM,IAAI,MAAM,qBAAqB;AAAA,MACvC;AAAA,IACF,QAAQ;AACN;AAAA,QACE;AAAA,QACA,GAAG,IAAI;AAAA,QACP;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB,eAAe;AAAA,IAChC;AAAA,IACA;AAAA,EACF;AACA,MAAI,OAAO,SAAS;AAClB,SAAK,UAAU,GAAG,IAAI,SAAS,aAAa;AAC9C,aAAW,OAAO;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAY;AACV,kBAAc,OAAO,GAAG,GAAG,KAAK,UAAU,GAAG,IAAI,IAAI,GAAG,EAAE;AAAA,EAC5D;AACA,SAAO,OAAO,iBAAiB,UAAU,GAAG,IAAI,kBAAkB;AAClE,SAAO,OAAO,qBAAqB,UAAU,GAAG,IAAI,sBAAsB;AAC1E;AAAA,IACE,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AACA,MAAI,CAAC,wBAAwB,KAAK,OAAO,eAAyB,GAAG;AACnE,SAAK,UAAU,GAAG,IAAI,oBAAoB,8BAA8B;AAAA,EAC1E;AACA,MACE,OAAO,wBAAwB,eAC/B,CAAC,yEAAyE;AAAA,IACxE,OAAO;AAAA,EACT,GACA;AACA,SAAK,UAAU,GAAG,IAAI,wBAAwB,qBAAqB;AAAA,EACrE;AACA,MAAI,OAAO,iBAAiB;AAC1B;AAAA,MACE,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,GAAG,IAAI;AAAA,IACT;AACF,MAAI,OAAO,kBAAkB;AAC3B,qBAAiB,EAAE,OAAO,OAAO,cAAc,GAAG,UAAU,IAAI;AACpE;AAEO,SAAS,6BACd,OACA,kBACAC,YACG;AACH,QAAM,WAAW;AACjB,QAAM,UAAU,OAAO,OAAO,UAAU,GAAG;AAC3C,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,SAAS;AAAA,IACb,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,WAAqB,CAAC;AAC5B,MAAI,WAAW,6BAA6B,WAAW;AACrD,aAAS,KAAK,YAAY;AAAA,WACnB,WAAW,WAAY,QAAO,KAAK,kBAAkB;AAAA,WACrD,WAAW,SAAU,QAAO,KAAK,SAAS;AAAA,WAC1C,WAAW,WAAY,QAAO,KAAK,oBAAoB;AAChE,QAAM,SAAS,QAAQ,UAAU,UAAU,GAAG;AAC9C,SAAO,QAAQ,IAAI,UAAU,MAAM;AACnC,gBAAc,QAAQ,OAAO,UAAU,SAAS;AAChD,MAAI,QAAQ,cAAc;AACxB,cAAU,QAAQ,WAAW,UAAU,aAAa;AAEtD,MAAI,WAAW,6BAA6B,WAAW,mBAAmB;AACxE,QAAI,QAAQ,gBAAgB,UAAU;AACpC,UACE,QAAQ,uBAAuB,gBAC/B,QAAQ,uBAAuB,aAC/B;AACA,aAAK,UAAU,KAAK,mCAAmC;AAAA,MACzD;AACA,UAAI,EAAE,gBAAgB;AACpB,aAAK,UAAU,gBAAgB,gBAAgB;AACjD;AAAA,QACE,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,WAAW,QAAQ,gBAAgB,YAAY;AAC7C,UACE,QAAQ,uBAAuB,gBAC/B,QAAQ,uBAAuB,aAC/B;AACA,aAAK,UAAU,KAAK,qCAAqC;AAAA,MAC3D;AACA,UAAI,gBAAgB;AAClB,aAAK,UAAU,gBAAgB,6BAA6B;AAAA,IAChE,MAAO,MAAK,UAAU,iBAAiB,mBAAmB;AAC1D;AAAA,MACE,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ,UAAU,KAAM,MAAK,UAAU,WAAW,MAAM;AAAA,EAC9D,WACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,SAAS,MAAM,GACjB;AACA;AAAA,MACE,QAAQ;AAAA,MACR,CAAC,UAAU,UAAU;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AACA,QACE,QAAQ,uBAAuB,gBAC/B,QAAQ,uBAAuB,aAC/B;AACA,WAAK,UAAU,KAAK,4BAA4B;AAAA,IAClD;AACA;AAAA,MACE,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ,UAAU,KAAM,MAAK,UAAU,WAAW,MAAM;AAAA,EAC9D,WAAW,WAAW,WAAW;AAC/B;AAAA,MACE,QAAQ;AAAA,MACR,CAAC,UAAU,UAAU;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AACA,QACE,QAAQ,uBAAuB,gBAC/B,QAAQ,uBAAuB,aAC/B;AACA,WAAK,UAAU,KAAK,4BAA4B;AAAA,IAClD;AACA;AAAA,MACE,QAAQ;AAAA,MACR,CAAC,0BAA0B;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ,UAAU,KAAM,MAAK,UAAU,WAAW,MAAM;AAAA,EAC9D,WAAW,WAAW,YAAY;AAChC;AAAA,MACE,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ,uBAAuB;AACjC,WAAK,UAAU,wBAAwB,YAAY;AACrD,QAAI,QAAQ,uBAAuB,WAAW;AAC5C;AAAA,QACE,QAAQ;AAAA,QACR,CAAC,uBAAuB,UAAU;AAAA,QAClC;AAAA,QACA;AAAA,MACF;AACA,UAAI,QAAQ,UAAU;AACpB,aAAK,UAAU,WAAW,+BAA+B;AAC3D,YAAM,iBAAiB;AAAA,QACrB,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF;AACA,UAAI,eAAe,WAAW;AAC5B,iCAAyB,gBAAgB,UAAU,kBAAkB;AAAA;AAErE;AAAA,UACE;AAAA,UACA;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,IACJ,WAAW,QAAQ,uBAAuB,aAAa;AACrD,6BAAuB,QAAQ,OAAO,UAAU,SAAS;AACzD,YAAM,iBAAiB;AAAA,QACrB,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF;AACA,UAAI,eAAe,WAAW,QAAQ;AACpC;AAAA,UACE,QAAQ;AAAA,UACR,CAAC,aAAa,YAAY;AAAA,UAC1B;AAAA,UACA;AAAA,QACF;AACA,iCAAyB,gBAAgB,UAAU,kBAAkB;AAAA,MACvE,OAAO;AACL;AAAA,UACE,QAAQ;AAAA,UACR,CAAC,aAAa,UAAU;AAAA,UACxB;AAAA,UACA;AAAA,QACF;AACA;AAAA,UACE;AAAA,UACA;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,MAAO,MAAK,UAAU,wBAAwB,qBAAqB;AAAA,EACrE,WAAW,WAAW,UAAU;AAC9B,QACE,QAAQ,gBAAgB,gBACxB,QAAQ,uBAAuB,gBAC/B,QAAQ,uBAAuB,eAC/B,QAAQ,UAAU,MAClB;AACA,WAAK,UAAU,KAAK,oCAAoC;AAAA,IAC1D;AACA;AAAA,MACE,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACA,UAAM,UAAU,OAAO,QAAQ,SAAS,UAAU,WAAW;AAC7D,UAAM,SAAS,CAAC,QAAQ,GAAG,CAAC,SAAS,GAAG,UAAU,WAAW;AAC7D;AAAA,MACE,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ,YAAY;AACtB,aAAO,QAAQ,SAAS,UAAU,mBAAmB;AAAA,EACzD,OAAO;AACL,QACE,QAAQ,gBAAgB,gBACxB,QAAQ,uBAAuB,gBAC/B,QAAQ,uBAAuB,eAC/B,QAAQ,UAAU,MAClB;AACA,WAAK,UAAU,KAAK,sCAAsC;AAAA,IAC5D;AACA;AAAA,MACE,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACA;AAAA,MACE,QAAQ;AAAA,MACR,CAAC,WAAW,YAAY,YAAY,UAAU;AAAA,MAC9C;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,qBAAqB,UAAa,aAAa,kBAAkB;AACnE,QACEA,eAAc,YACd,wBAAwB,QAAQ,MAAM,QACtC,WAAW,eACX,WAAW,YACX;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,qBAAiB,UAAU,kBAAkB,UAAUA,UAAS;AAAA,EAClE;AACA,SAAO;AACT;;;AC72EA,IAAMC,mBAAkB;AAaxB,IAAM,uBAAuBA,mBAAkB;AAkB/C,IAAM,yBAAyB;AA2B/B,IAAM,mBAAmB,uBAAO,kBAAkB;AA+BlD,SAAS,qBAAqB,QAAwB;AACpD,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,WAAO,GAAG,IAAI,SAAS,YAAY,CAAC,KAAK,IAAI,KAAK,YAAY,CAAC,GAAG,IAAI,SAAS,QAAQ,QAAQ,EAAE,CAAC;AAAA,EACpG,QAAQ;AACN,WAAO,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,QAAQ,EAAE;AAAA,EACvD;AACF;AAOA,SAAS,qBACP,QACA,gBACA,YACQ;AACR,SAAO,oCAAoC,qBAAqB,MAAM,CAAC,IAAI,cAAc,IAAI,UAAU;AACzG;AAQA,SAAS,0BAAuD;AAC9D,MAAI;AACF,QAAI,OAAO,cAAc,YAAa,QAAO;AAC7C,UAAM,QAAS,UAAkD;AACjE,QAAI,CAAC,SAAS,OAAO,MAAM,YAAY,WAAY,QAAO;AAC1D,WAAO,CAAC,MAAM,SAAS,aACrB,MAAM;AAAA,MAAQ;AAAA,MAAM;AAAA,MAAS,MAC3B,SAAS;AAAA,IACX;AAAA,EACJ,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,mBAAmB,KAAmC;AAC7D,MAAI;AACF,UAAM,SAAkB,KAAK,MAAM,GAAG;AACtC,QAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAClD,UAAM,YAAY;AAElB,QAAI,UAAU,MAAM,uBAAwB,QAAO;AACnD,QAAI,OAAO,UAAU,QAAQ,YAAY,CAAC,OAAO,SAAS,UAAU,GAAG,GAAG;AACxE,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,UAAU;AACxB,UAAM,eAAe,UAAU;AAC/B,QAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,QAAI,iBAAiB,QAAQ,OAAO,iBAAiB,SAAU,QAAO;AACtE,WAAO;AAAA,MACL,GAAG;AAAA,MACH,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAqBA,SAAS,kBACP,WACA,WACA,kBACyC;AACzC,MAAI;AACJ,MAAI;AACF,UAAM,aAAa,QAAQ,SAAS;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,MAAM;AAChB,UAAM,SAAS,mBAAmB,GAAG;AACrC,WAAO,SAAS,EAAE,QAAQ,QAAQ,QAAQ,KAAK,IAAI;AAAA,EACrD;AACA,MAAI;AACF,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,KAAK;AAAA,QACL,OAAO,aAAa,QAAQ,SAAS;AAAA,QACrC,cAAc,aAAa,QAAQ,gBAAgB;AAAA,MACrD;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,IAAM,eAAN,MAAmB;AAAA,EAkBxB,YACE,gBACA,SACA,QACA;AAfF,SAAQ,iBAA0D;AAElE;AAAA,SAAQ,mBAAkC;AAE1C;AAAA,SAAQ,mBAAkC;AAC1C,SAAQ,0BAAyC;AAEjD;AAAA,SAAQ,kBAAiC;AAEzC;AAAA,SAAQ,aAAa;AAOnB,SAAK,iBAAiB;AACtB,SAAK,UAAU,cAAc,MAAM;AAEnC,UAAM,UAAU,SAAS,WAAW;AACpC,QAAI,SAAS;AACX,YAAM,MAAM,OAAO,YAAY,WAAW,UAAU;AACpD,YAAM,YAAY,OAAO,WAAW;AACpC,WAAK,QAAQ;AACb,WAAK,oBAAoB;AACzB,UAAI,WAAW;AACb,aAAK,mBAAmB,GAAG,GAAG;AAC9B,aAAK,mBAAmB;AACxB,aAAK,0BAA0B,GAAG,GAAG;AACrC,aAAK,kBAAkB;AAAA,UACrB,KAAK;AAAA,UACL;AAAA,UACA;AAAA,QACF;AACA,aAAK,yBAAyB;AAAA,MAChC;AAAA,IACF,OAAO;AACL,WAAK,QAAQ,SAAS,SAAS;AAC/B,WAAK,oBAAoB,SAAS,gBAAgB;AAClD,WAAK,gBAAgB,SAAS;AAC9B,WAAK,uBAAuB,SAAS;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SACJ,MACmC;AACnC,WAAO,KAAK;AAAA,MACV,qBAAqB,kCAAkC,QAAQ;AAAA,MAC/D;AAAA,QACE,QAAQ;AAAA,UACN,kCAAkC;AAAA,QACpC;AAAA,QACA,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,MAAwD;AAClE,UAAM,SAA+B,MAAM,KAAK;AAAA,MAC9C,qBAAqB,kCAAkC,KAAK;AAAA,MAC5D;AAAA,QACE,QAAQ,uBAAuB,kCAAkC,KAAK;AAAA,QACtE,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B;AAAA,IACF;AAEA,QAAI,OAAO,aAAc,MAAK,WAAW,OAAO,OAAO,OAAO,YAAY;AAAA,QACrE,MAAK,SAAS,OAAO,KAAK;AAC/B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,eAAiD;AACrD,SAAK,yBAAyB;AAC9B,QAAI,CAAC,KAAK,qBAAqB,CAAC,KAAK,OAAO;AAC1C,YAAM,IAAI,SAAS,qBAAqB,GAAG;AAAA,IAC7C;AAEA,QAAI,KAAK,eAAgB,QAAO,KAAK;AAErC,UAAM,WAAW,KAAK,aAAa;AACnC,SAAK,iBAAiB,KAAK,qBAAqB,QAAQ;AACxD,QAAI;AACF,aAAO,MAAM,KAAK;AAAA,IACpB,UAAE;AACA,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,2BAAiC;AACvC,UAAM,YAAY,KAAK,qBAAqB;AAC5C,QAAI,cAAc,kBAAkB;AAClC,WAAK,mBAAmB;AACxB;AAAA,IACF;AACA,QAAI,CAAC,UAAW;AAChB,SAAK,aAAa,UAAU,OAAO;AACnC,SAAK,QAAQ,UAAU,OAAO;AAC9B,SAAK,oBAAoB,UAAU,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGQ,uBAGoB;AAC1B,QACE,CAAC,KAAK,oBACN,CAAC,KAAK,oBACN,CAAC,KAAK,yBACN;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBQ,uBACN,QACA,SACS;AACT,UAAM,YAAY,KAAK;AACvB,UAAM,YAAY,KAAK;AACvB,UAAM,mBAAmB,KAAK;AAC9B,UAAM,YAAY,KAAK,qBAAqB;AAC5C,QAAI,cAAc,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,kBAAkB;AACvE,aAAO;AAAA,IACT;AACA,QAAI,cAAc,kBAAkB;AAClC,WAAK,mBAAmB;AACxB,aAAO;AAAA,IACT;AAGA,UAAM,UAAU,UAAU;AAC1B,QACE,SAAS,sBACT,CAAC,QAAQ,SACT,CAAC,QAAQ,cACT;AACA,aAAO;AAAA,IACT;AAEA,UAAM,OAAsB;AAAA,MAC1B,GAAG;AAAA,MACH,KAAK,QAAQ,MAAM;AAAA,MACnB,OAAO,WAAW,SAAU,OAAO,SAAS,OAAQ,QAAQ;AAAA,MAC5D,cACE,kBAAkB,SACb,OAAO,gBAAgB,OACxB,QAAQ;AAAA,IAChB;AACA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKE,UAAU,UACV,KAAK,UAAU,QAAQ,SACvB,KAAK,iBAAiB,QAAQ;AAAA,MAC9B;AACA,WAAK,aAAa,QAAQ;AAC1B,WAAK,QAAQ,QAAQ;AACrB,WAAK,oBAAoB,QAAQ;AACjC,aAAO;AAAA,IACT;AACA,QAAI;AACF,mBAAa,QAAQ,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACtD,QAAQ;AAEN,WAAK,mBAAmB;AACxB,aAAO;AAAA,IACT;AACA,SAAK,aAAa,KAAK;AACvB,SAAK,QAAQ,KAAK;AAClB,SAAK,oBAAoB,KAAK;AAI9B,QAAI;AAMF,mBAAa,WAAW,gBAAgB;AAAA,IAC1C,QAAQ;AAGN,aAAO;AAAA,IACT;AACA,QAAI;AACF,UAAI,KAAK,MAAO,cAAa,QAAQ,WAAW,KAAK,KAAK;AAAA,UACrD,cAAa,WAAW,SAAS;AAAA,IACxC,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,qBAA2B;AACjC,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,0BAA0B;AAC/B,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,uBAAuB,UAA4C;AACzE,QAAI,CAAC,KAAK,iBAAkB,QAAO;AACnC,SAAK,yBAAyB;AAE9B,QAAI,CAAC,KAAK,iBAAkB,QAAO;AAEnC,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,kBAAmB,QAAO;AACnD,QAAI,SAAS,iBAAiB,MAAM;AAIlC,aAAO,KAAK,sBAAsB,SAAS,eACvC,YACA;AAAA,IACN;AAGA,WAAO,KAAK,UAAU,SAAS,SAAS,CAAC,KAAK,oBAC1C,YACA;AAAA,EACN;AAAA;AAAA,EAGQ,cAAc,OAAwC;AAC5D,WAAO;AAAA,MACL;AAAA,MACA,GAAI,KAAK,oBACL,EAAE,cAAc,KAAK,kBAAkB,IACvC,CAAC;AAAA,IACP;AAAA,EACF;AAAA;AAAA,EAGQ,eAAiC;AACvC,WAAO,EAAE,OAAO,KAAK,OAAO,cAAc,KAAK,kBAAkB;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,sBAAsB,YAA0B;AACtD,SAAK,yBAAyB;AAC9B,QAAI,KAAK,UAAU,WAAY;AAC/B,SAAK,SAAS,IAAI;AAAA,EACpB;AAAA;AAAA,EAGQ,WACN,OACA,cACA,SACS;AACT,SAAK,QAAQ;AACb,SAAK,oBAAoB;AACzB,UAAM,YAAY,KAAK;AAAA,MACrB,EAAE,OAAO,aAAa;AAAA,MACtB;AAAA,IACF;AACA,QAAI,CAAC,UAAW,QAAO;AACvB,SAAK,gBAAgB,KAAK,KAAK;AAC/B,SAAK,uBAAuB,KAAK,iBAAiB;AAClD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,qBACZ,UACkC;AAClC,UAAM,WAAW,KAAK;AACtB,UAAM,cAAc,WAAW,wBAAwB,IAAI;AAC3D,QAAI,CAAC,YAAY,CAAC,aAAa;AAC7B,aAAO,KAAK,yBAAyB,QAAQ;AAAA,IAC/C;AAEA,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,oBAAoB;AACvE,QAAI,UAAU;AACd,QAAI;AACF,aAAO,MAAM;AAAA,QACX;AAAA,QACA,EAAE,QAAQ,WAAW,OAAO;AAAA,QAC5B,YAAY;AACV,oBAAU;AACV,iBAAO,KAAK,yBAAyB,QAAQ;AAAA,QAC/C;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AAEd,UAAI,QAAS,OAAM;AAGnB,aAAO,KAAK,yBAAyB,QAAQ;AAAA,IAC/C,UAAE;AAGA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,yBACZ,UACkC;AAClC,QAAI,QAAQ;AAGZ,aAAS,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG;AAC/C,YAAM,QAAQ,KAAK,uBAAuB,KAAK;AAE/C,UAAI,UAAU,UAAW,OAAM,IAAI,SAAS,qBAAqB,GAAG;AACpE,UAAI,UAAU,UAAW,QAAO,KAAK,gBAAgB,KAAK;AAG1D,UAAI,KAAK,MAAO,QAAO,KAAK,cAAc,KAAK,KAAK;AAGpD,cAAQ,KAAK,aAAa;AAAA,IAC5B;AACA,UAAM,IAAI,SAAS,qBAAqB,GAAG;AAAA,EAC7C;AAAA,EAEA,MAAc,gBACZ,UACkC;AAClC,UAAM,OAAoB,SAAS,eAC/B;AAAA,MACE,QAAQ;AAAA,QACN,kCAAkC;AAAA,MACpC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,cAAc,SAAS,aAAa,CAAC;AAAA,IAC9D,IACA;AAAA,MACE,QAAQ;AAAA,QACN,kCAAkC;AAAA,MACpC;AAAA,MACA,SAAS,EAAE,eAAe,UAAU,SAAS,KAAe,GAAG;AAAA,IACjE;AACJ,UAAM,SAAkC,MAAM,KAAK;AAAA,MACjD,qBAAqB,kCAAkC,OAAO;AAAA,MAC9D;AAAA,IACF;AAKA,UAAM,QAAQ,KAAK,uBAAuB,QAAQ;AAElD,QAAI,UAAU,UAAW,OAAM,IAAI,SAAS,qBAAqB,GAAG;AACpE,QAAI,UAAU,cAAc;AAG1B,UAAI,KAAK,MAAO,QAAO,KAAK,cAAc,KAAK,KAAK;AACpD,YAAM,IAAI,SAAS,qBAAqB,GAAG;AAAA,IAC7C;AAOA,UAAM,sBACJ,KAAK,UAAU,QAAQ,KAAK,UAAU,SAAS,QAAQ,KAAK,QAAQ;AACtE,UAAM,YAAY,uBAAuB,OAAO;AAChD,UAAM,cAAc,OAAO,gBAAgB;AAG3C,QACE,CAAC,KAAK,WAAW,WAAW,aAAa,EAAE,oBAAoB,KAAK,CAAC,GACrE;AACA,YAAM,IAAI,SAAS,qBAAqB,GAAG;AAAA,IAC7C;AACA,WAAO;AAAA,MACL,OAAO;AAAA,MACP,GAAI,cAAc,EAAE,cAAc,YAAY,IAAI,CAAC;AAAA,IACrD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAe;AAEb,SAAK,WAAW,MAAM,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAA6B;AACjC,SAAK,yBAAyB;AAC9B,UAAM,eAAe,KAAK;AAC1B,SAAK,OAAO;AACZ,QAAI,CAAC,aAAc;AAEnB,UAAMC,aAAY,kCAAkC;AACpD,UAAM,KAAK,YAAY,qBAAqBA,UAAS,GAAG;AAAA,MACtD,QAAQ,uBAAuBA,UAAS;AAAA,MACxC,MAAM,KAAK,UAAU,EAAE,aAAa,CAAC;AAAA,IACvC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,SAAS,iBAA4D;AACzE,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,CAAC,MAAO,OAAM,IAAI,SAAS,qBAAqB,GAAG;AACvD,UAAMA,aAAY,kCAAkC;AACpD,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB,qBAAqBA,UAAS;AAAA,MAC9B;AAAA,QACE,QAAQ,uBAAuBA,UAAS;AAAA,QACxC,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,QAC5C,MAAM,KAAK,UAAU,EAAE,gBAAgB,CAAC;AAAA,MAC1C;AAAA,IACF;AACA,QACE,CAAC,UACD,OAAO,OAAO,gBAAgB,YAC9B,CAAC,OAAO,SAAS,KAAK,MAAM,OAAO,WAAW,CAAC;AAE/C,YAAM,IAAI,SAAS,wCAAwC,GAAG;AAChE,SAAK,OAAO;AACZ,WAAO,EAAE,aAAa,OAAO,YAAY;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAsC;AAC1C,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,CAAC,MAAO,QAAO;AAEnB,QAAI;AACF,YAAM,OAAO,MAAM,KAAK;AAAA,QACtB,qBAAqB,kCAAkC,EAAE;AAAA,QACzD;AAAA,UACE,QAAQ,uBAAuB,kCAAkC,EAAE;AAAA,UACnE,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,QAC9C;AAAA,MACF;AACA,aAAO,KAAK,YAAY;AAAA,IAC1B,SAAS,OAAO;AACd,UAAI,iBAAiB,YAAY,MAAM,WAAW,KAAK;AACrD,aAAK,sBAAsB,KAAK;AAChC,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,OAA8B;AACjD,UAAM,KAAK;AAAA,MACT,qBAAqB,kCAAkC,cAAc;AAAA,MACrE;AAAA,QACE,QAAQ;AAAA,UACN,kCAAkC;AAAA,QACpC;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,OAAe,UAAiC;AAClE,UAAM,KAAK;AAAA,MACT,qBAAqB,kCAAkC,aAAa;AAAA,MACpE;AAAA,QACE,QAAQ;AAAA,UACN,kCAAkC;AAAA,QACpC;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,MAAmD;AACrE,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,CAAC,MAAO,OAAM,IAAI,SAAS,qBAAqB,GAAG;AAEvD,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB,qBAAqB,kCAAkC,aAAa;AAAA,MACpE;AAAA,QACE,QAAQ;AAAA,UACN,kCAAkC;AAAA,QACpC;AAAA,QACA,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,QAC5C,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B;AAAA,IACF;AACA,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eACJ,iBACA,aACe;AACf,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,CAAC,MAAO,OAAM,IAAI,SAAS,qBAAqB,GAAG;AAEvD,UAAM,KAAK;AAAA,MACT,qBAAqB,kCAAkC,cAAc;AAAA,MACrE;AAAA,QACE,QAAQ;AAAA,UACN,kCAAkC;AAAA,QACpC;AAAA,QACA,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,QAC5C,MAAM,KAAK,UAAU,EAAE,iBAAiB,YAAY,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YACJ,SAC2C;AAC3C,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,CAAC,MAAO,OAAM,IAAI,SAAS,qBAAqB,GAAG;AAEvD,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,SAAS,KAAM,QAAO,IAAI,QAAQ,OAAO,QAAQ,IAAI,CAAC;AAC1D,QAAI,SAAS,MAAO,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AAC7D,QAAI,SAAS,iBAAiB;AAC5B,aAAO,IAAI,mBAAmB,QAAQ,eAAe;AAAA,IACvD;AACA,QAAI,SAAS,mBAAmB;AAC9B,aAAO,IAAI,qBAAqB,QAAQ,iBAAiB;AAAA,IAC3D;AACA,QAAI,SAAS,aAAc,QAAO,IAAI,gBAAgB,QAAQ,YAAY;AAC1E,QAAI,SAAS,oBAAoB;AAC/B,aAAO,IAAI,sBAAsB,QAAQ,kBAAkB;AAAA,IAC7D;AACA,QAAI,SAAS,sBAAsB;AACjC,aAAO,IAAI,wBAAwB,QAAQ,oBAAoB;AAAA,IACjE;AACA,UAAM,KAAK,OAAO,SAAS;AAC3B,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB,2BAA2B,KAAK,IAAI,EAAE,KAAK,EAAE;AAAA,MAC7C;AAAA,QACE,QAAQ;AAAA,QACR,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,MAC9C;AAAA,IACF;AACA,WAAO,wBAA0D,MAAM;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAA0B;AACxB,SAAK,yBAAyB;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAiC;AAC/B,SAAK,yBAAyB;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,OAA4B;AACnC,SAAK,QAAQ;AAEb,SAAK,uBAAuB,EAAE,MAAM,CAAC;AACrC,SAAK,gBAAgB,KAAK;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,cAAmC;AACjD,SAAK,oBAAoB;AAEzB,SAAK,uBAAuB,EAAE,aAAa,CAAC;AAC5C,SAAK,uBAAuB,YAAY;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,kBAA2B;AACzB,WAAO,KAAK,SAAS,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YACZ,MACA,MACY;AACZ,UAAM,UAAU,IAAI,QAAQ,KAAK,OAAO;AACxC,YAAQ,IAAI,qBAAqB,KAAK,cAAc;AACpD,QAAI,CAAC,QAAQ,IAAI,cAAc,KAAK,KAAK,MAAM;AAC7C,cAAQ,IAAI,gBAAgB,kBAAkB;AAAA,IAChD;AAEA,UAAM,WAAW,MAAM,UAAU,MAAM;AAAA,MACrC,GAAG;AAAA,MACH,QAAQ,KAAK;AAAA,MACb,gBAAgB,KAAK;AAAA,MACrB;AAAA,MACA,SAASD;AAAA,MACT,OAAO,EAAE,YAAY,EAAE;AAAA,IACzB,CAAC;AAED,WAAO,iBAAoB,UAAU,IAAI;AAAA,EAC3C;AACF;;;ACj7BA,IAAM,iBAAiB,CAAC,UAAU,WAAW,OAAO;AACpD,IAAME,mBAAkB;AA+CxB,SAAS,UAAU,QAAgB,MAAsB;AACvD,QAAM,OAAO,cAAc,MAAM;AACjC,SAAO,IAAI,IAAI,MAAM,KAAK,SAAS,GAAG,IAAI,OAAO,GAAG,IAAI,GAAG,EAAE,SAAS;AACxE;AAEA,SAAS,gBAAgB,OAAuB;AAC9C,QAAM,SAAS,IAAI,WAAW,KAAK;AACnC,SAAO,gBAAgB,MAAM;AAE7B,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,cAAU,OAAO,aAAa,KAAK;AAAA,EACrC;AAEA,SAAO,KAAK,MAAM,EACf,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,QAAQ,EAAE;AACvB;AAEA,eAAe,gBAAgB,OAAgC;AAC7D,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAC3C,QAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI;AAEzD,MAAI,SAAS;AACb,aAAW,QAAQ,IAAI,WAAW,MAAM,GAAG;AACzC,cAAU,OAAO,aAAa,IAAI;AAAA,EACpC;AAEA,SAAO,KAAK,MAAM,EACf,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,QAAQ,EAAE;AACvB;AAEA,SAAS,eAAe,MAAoD;AAC1E,MAAI,KAAK,eAAe,UAAU;AAChC,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AAEA,SAAO;AAAA,IACL,aAAa,KAAK;AAAA,IAClB,WAAW,KAAK,IAAI,IAAI,KAAK,aAAa;AAAA,IAC1C,WAAW,KAAK;AAAA,IAChB,GAAI,KAAK,WAAW,EAAE,SAAS,KAAK,SAAS,IAAI,CAAC;AAAA,IAClD,cAAc,KAAK;AAAA,IACnB,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IAC1C,WAAW;AAAA,EACb;AACF;AAEO,IAAM,gBAAN,MAAoB;AAAA,EAKzB,YAAY,QAA6B;AACvC,QAAI,CAAC,OAAO,SAAU,OAAM,IAAI,MAAM,qCAAqC;AAC3E,QAAI,CAAC,OAAO,OAAQ,OAAM,IAAI,MAAM,mCAAmC;AAEvE,SAAK,WAAW,OAAO;AACvB,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO,WAAWA;AAAA,EACnC;AAAA,EAEA,MAAM,uBACJ,OACyC;AACzC,UAAM,eAAe,gBAAgB,EAAE;AACvC,UAAM,gBAAgB,MAAM,gBAAgB,YAAY;AACxD,UAAM,QAAQ,gBAAgB,EAAE;AAChC,UAAM,QAAQ,gBAAgB,EAAE;AAChC,UAAM,SAAS,MAAM,UAAU;AAC/B,UAAM,MAAM,IAAI,IAAI,UAAU,KAAK,QAAQ,0BAA0B,CAAC;AAEtE,QAAI,aAAa,IAAI,iBAAiB,MAAM;AAC5C,QAAI,aAAa,IAAI,aAAa,KAAK,QAAQ;AAC/C,QAAI,aAAa,IAAI,gBAAgB,MAAM,WAAW;AACtD,QAAI,aAAa,IAAI,SAAS,OAAO,KAAK,GAAG,CAAC;AAC9C,QAAI,aAAa,IAAI,SAAS,KAAK;AACnC,QAAI,aAAa,IAAI,SAAS,KAAK;AACnC,QAAI,aAAa,IAAI,kBAAkB,aAAa;AACpD,QAAI,aAAa,IAAI,yBAAyB,MAAM;AAEpD,WAAO;AAAA,MACL,kBAAkB,IAAI,SAAS;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,MAAM,YAAY;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cACE,aACA,SAC6B;AAC7B,UAAM,MAAM,IAAI,IAAI,WAAW;AAC/B,UAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAE1C,QAAI,OAAO;AACT,YAAM,IAAI;AAAA,QACR,IAAI,aAAa,IAAI,mBAAmB,KAAK,gBAAgB,KAAK;AAAA,MACpE;AAAA,IACF;AAEA,UAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,UAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAE1C,QAAI,CAAC,QAAQ,CAAC,MAAO,OAAM,IAAI,MAAM,sCAAsC;AAC3E,QAAI,UAAU,QAAQ,cAAe,OAAM,IAAI,MAAM,sBAAsB;AAE3E,WAAO,EAAE,MAAM,MAAM;AAAA,EACvB;AAAA,EAEA,MAAM,aAAa,OAIgB;AACjC,UAAM,OAAO,IAAI,gBAAgB;AAAA,MAC/B,WAAW,KAAK;AAAA,MAChB,MAAM,MAAM;AAAA,MACZ,eAAe,MAAM;AAAA,MACrB,YAAY;AAAA,MACZ,cAAc,MAAM;AAAA,IACtB,CAAC;AAED,WAAO,KAAK,aAAa,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,QAAQ,OAEqB;AACjC,UAAM,OAAO,IAAI,gBAAgB;AAAA,MAC/B,WAAW,KAAK;AAAA,MAChB,YAAY;AAAA,MACZ,eAAe,MAAM;AAAA,IACvB,CAAC;AAED,WAAO,KAAK,aAAa,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,OAAO,OAG2C;AACtD,UAAM,OAA+B,EAAE,WAAW,KAAK,SAAS;AAEhE,QAAI,MAAM,aAAc,MAAK,gBAAgB,MAAM;AACnD,QAAI,MAAM,uBAAuB;AAC/B,WAAK,2BAA2B,MAAM;AAAA,IACxC;AAEA,UAAM,WAAW,MAAM,UAAU,0BAA0B;AAAA,MACzD,QAAQ,KAAK;AAAA,MACb,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,IAAI;AAAA,MACzB,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,SAAS,KAAK;AAAA,MACd,OAAO,EAAE,YAAY,EAAE;AAAA,IACzB,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,gBAAuB;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,aACZ,MACgC;AAChC,UAAM,WAAW,MAAM,UAAU,6BAA6B;AAAA,MAC5D,QAAQ,KAAK;AAAA,MACb,QAAQ;AAAA,MACR;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,SAAS,KAAK;AAAA,MACd,OAAO,EAAE,YAAY,EAAE;AAAA,IACzB,CAAC;AAED,WAAO;AAAA,MACL,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACjPO,IAAM,oBAAN,MAAwB;AAAA,EAI7B,YACE,gBACA,SACA,QACA;AACA,SAAK,OAAO,IAAI,aAAa,gBAAgB,SAAS,MAAM;AAC5D,QAAI,SAAS,OAAO;AAClB,WAAK,QAAQ,IAAI,cAAc,QAAQ,KAAK;AAAA,IAC9C;AAAA,EACF;AACF;;;ACpBA,IAAM,kBACJ;AACF,IAAM,6BAA6B;AAE5B,SAAS,yBAAyB,OAAiC;AACxE,SACE,OAAO,UAAU,YACjB,MAAM,UAAU,QACf,gBAAgB,KAAK,KAAK,KAAK,2BAA2B,KAAK,KAAK;AAEzE;AAEO,SAAS,6BACd,OACyB;AACzB,MAAI,yBAAyB,KAAK,EAAG;AACrC,QAAM;AAAA,IACJ;AAAA,IACA,EAAE,OAAO,iBAAiB;AAAA,EAC5B;AACF;AAGO,SAAS,+BAAuC;AACrD,SAAO,WAAW,OAAO,WAAW;AACtC;;;ACHO,IAAM,2BAA2B;AAiLjC,IAAM,UAAN,cAAsB,kBAAkB;AAAA,EAG7C,YAAY,SAAyB;AACnC,UAAM,WAAW,EAAE,GAAG,SAAS,oBAAoB,MAAM,CAAC;AAC1D,SAAK,kBAAkB,QAAQ,QAAQ,SAAS;AAAA,EAClD;AAAA,EAEQ,SACN,KAC4B;AAC5B,WAAO,KAAK,kBACR,mBAAmB,MAAM,OAAO,GAAG,IACnC,mBAAmB,MAAM,GAAG;AAAA,EAClC;AAAA,EAEQ,QACN,UACA,MACA,gBACkB;AAClB,WAAO,KAAK,gBAAyB,UAAU,MAAM;AAAA,MACnD,GAAI,kBAAkB;AAAA,QACpB,SAAS,EAAE,qBAAqB,eAAe;AAAA,MACjD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,SAA2B,CAAC,GAA8B;AAC/D,WAAO,KAAK,QAAQ,KAAK,SAAS,QAAQ,GAAG,MAAM,EAAE;AAAA,MAAK,CAAC,UACzD,yBAA2C,KAAK;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,SAAS,QAAiD;AACxD,WAAO,KAAK,QAAQ,KAAK,SAAS,UAAU,GAAG,MAAM,EAAE;AAAA,MAAK,CAAC,UAC3D,mBAA+B,KAAK;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,KACE,SAAgD,CAAC,GACxB;AACzB,UAAM,WAAW,KAAK,SAAS,MAAM;AACrC,WAAO,KAAK,QAAQ,UAAU,MAAM,EAAE;AAAA,MAAK,CAAC,UAC1C,uBAAuC,KAAK;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,MACE,QAC0B;AAC1B,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,iCAA6B,cAAc;AAC3C,UAAM,WAAW,KAAK,SAAS,OAAO;AACtC,WAAO,KAAK,QAAQ,UAAU,MAAM,cAAc,EAAE;AAAA,MAAK,CAAC,UACxD,wBAAyC,KAAK;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,QACE,QAC6B;AAC7B,WAAO,KAAK,OAAO,KAAK,SAAS,SAAS,GAAG,MAAM;AAAA,EACrD;AAAA,EAEQ,OACN,UACA,QAC6B;AAC7B,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,iCAA6B,cAAc;AAC3C,WAAO,KAAK,QAAQ,UAAU,MAAM,cAAc,EAAE;AAAA,MAAK,CAAC,UACxD,2BAA+C,KAAK;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,WACE,QAC6B;AAC7B,WAAO,KAAK,OAAO,KAAK,SAAS,YAAY,GAAG,MAAM;AAAA,EACxD;AAAA,EAEA,WAAW,QAAuD;AAChE,WAAO,KAAK,OAAO,KAAK,SAAS,YAAY,GAAG,MAAM;AAAA,EACxD;AAAA,EAEA,MAAM,QAAsD;AAC1D,WAAO,KAAK,OAAO,KAAK,SAAS,OAAO,GAAG,MAAM;AAAA,EACnD;AAAA,EAEA,oBACE,QAC6B;AAC7B,WAAO,KAAK,OAAO,KAAK,SAAS,qBAAqB,GAAG,MAAM;AAAA,EACjE;AAAA,EAEA,iBACE,QAC6B;AAC7B,WAAO,KAAK,OAAO,KAAK,SAAS,kBAAkB,GAAG,MAAM;AAAA,EAC9D;AACF;;;AC7EO,IAAM,cAAN,cAA0B,kBAAkB;AAAA,EACjD,YAAY,SAA6B;AACvC,UAAM,eAAe,EAAE,GAAG,SAAS,oBAAoB,MAAM,CAAC;AAAA,EAChE;AAAA,EAEQ,KACN,UACA,MACA,gBACkB;AAClB,WAAO,KAAK,gBAAyB,UAAU,MAAM;AAAA,MACnD,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,GAAI,kBAAkB,EAAE,qBAAqB,eAAe;AAAA,MAC9D;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,eACZ,QACyB;AACzB,WAAO,uBAAuC,MAAM,MAAM;AAAA,EAC5D;AAAA,EAEA,MAAc,eACZ,QACyB;AACzB,WAAO,uBAAuC,MAAM,MAAM;AAAA,EAC5D;AAAA,EAEA,MAAc,aACZ,QACA,cAC+B;AAC/B,UAAM,SAAS;AAAA,MACb,MAAM;AAAA,MACN;AAAA,IACF;AACA,SAAK,sBAAsB,OAAO,UAAU,YAAY;AACxD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,mBACZ,QACA,cACqC;AACrC,UAAM,SAAS;AAAA,MACb,MAAM;AAAA,MACN;AAAA,IACF;AACA,SAAK,sBAAsB,OAAO,UAAU,YAAY;AACxD,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,QAAkC;AAC1D,QAAI,WAAW,WAAc,CAAC,OAAO,cAAc,MAAM,KAAK,UAAU;AACtE,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,EACJ;AAAA,EAEQ,sBACN,UACA,WACM;AACN,QAAI,cAAc,UAAa,SAAS,SAAS,iBAAiB;AAChE,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,EAAE,UAAU,YAAY,MAAM,YAAY;AAAA,QAC1C;AAAA,QACA;AAAA,MACF;AAAA,EACJ;AAAA,EAEA,OAAO,QAA6D;AAClE,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,iCAA6B,cAAc;AAC3C,SAAK,kBAAkB,KAAK,YAAY;AACxC,WAAO,KAAK;AAAA,MACV,KAAK,KAAK,mBAAmB,UAAU,QAAQ,MAAM,cAAc;AAAA,MACnE,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,aACE,QACqC;AACrC,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,iCAA6B,cAAc;AAC3C,SAAK,kBAAkB,KAAK,YAAY;AACxC,WAAO,KAAK;AAAA,MACV,KAAK;AAAA,QACH,mBAAmB,UAAU,OAAO;AAAA,QACpC;AAAA,QACA;AAAA,MACF;AAAA,MACA,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,SAAS,QAAyD;AAChE,WAAO,KAAK;AAAA,MACV,KAAK,KAAK,mBAAmB,UAAU,UAAU,MAAM;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,eACE,QACyB;AACzB,WAAO,KAAK;AAAA,MACV,KAAK,KAAK,mBAAmB,UAAU,OAAO,UAAU,MAAM;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,SAA8B,CAAC,GAAiC;AAC1E,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB,mBAAmB,UAAU,OAAO;AAAA,MACpC;AAAA,IACF;AACA,WAAO,4BAAiD,MAAM;AAAA,EAChE;AACF;;;ACiJO,IAAM,oBAAN,cAAgC,kBAAkB;AAAA,EAGvD,YAAY,SAAmC;AAC7C,UAAM,qBAAqB,EAAE,GAAG,SAAS,oBAAoB,MAAM,CAAC;AACpE,SAAK,kBAAkB,QAAQ,QAAQ,SAAS;AAAA,EAClD;AAAA,EAEQ,KACN,UACA,MACA,gBACA,sCAAsC,OACpB;AAClB,UAAM,UAAU;AAAA,MACd,GAAI,kBAAkB,EAAE,qBAAqB,eAAe;AAAA,MAC5D,GAAI,uCAAuC;AAAA,QACzC,QAAQ;AAAA,MACV;AAAA,IACF;AACA,WAAO,KAAK,gBAAyB,UAAU,MAAM;AAAA,MACnD,GAAI,OAAO,KAAK,OAAO,EAAE,SAAS,KAAK,EAAE,QAAQ;AAAA,IACnD,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,eACZ,QACA,kBACAC,YACY;AACZ,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACAA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OACE,QAC+B;AAC/B,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,iCAA6B,cAAc;AAC3C,WAAO,KAAK;AAAA,MACV,KAAK;AAAA,QACH,KAAK,kBACD,mBAAmB,gBAAgB,OAAO,SAC1C,mBAAmB,gBAAgB;AAAA,QACvC;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cACE,QAGsC;AACtC,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,iCAA6B,cAAc;AAC3C,WAAO,KAAK;AAAA,MACV,KAAK;AAAA,QACH,KAAK,kBACD,mBAAmB,gBAAgB,OAAO,SAC1C,mBAAmB,gBAAgB;AAAA,QACvC;AAAA,QACA;AAAA,QACA,KAAK,gBAAgB,YAAY;AAAA,MACnC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SACE,QAG+B;AAC/B,UAAM,WAAW,KAAK,kBAClB,mBAAmB,gBAAgB,OAAO,WAC1C,mBAAmB,gBAAgB;AACvC,WAAO,KAAK;AAAA,MACV,KAAK,KAAK,UAAU,MAAM;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,gBACE,QAGsC;AACtC,UAAM,WAAW,KAAK,kBAClB,mBAAmB,gBAAgB,OAAO,WAC1C,mBAAmB,gBAAgB;AACvC,WAAO,KAAK;AAAA,MACV,KAAK,KAAK,UAAU,QAAQ,QAAW,IAAI;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OACE,QAG+B;AAC/B,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,iCAA6B,cAAc;AAC3C,UAAM,WAAW,KAAK,kBAClB,mBAAmB,gBAAgB,OAAO,SAC1C,mBAAmB,gBAAgB;AACvC,WAAO,KAAK;AAAA,MACV,KAAK,KAAK,UAAU,MAAM,cAAc;AAAA,MACxC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cACE,QAGsC;AACtC,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,iCAA6B,cAAc;AAC3C,UAAM,WAAW,KAAK,kBAClB,mBAAmB,gBAAgB,OAAO,SAC1C,mBAAmB,gBAAgB;AACvC,WAAO,KAAK;AAAA,MACV,KAAK,KAAK,UAAU,MAAM,cAAc;AAAA,MACxC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QACE,QAC+B;AAC/B,UAAM,EAAE,gBAAgB,GAAG,KAAK,IAAI;AACpC,iCAA6B,cAAc;AAC3C,WAAO,KAAK;AAAA,MACV,KAAK;AAAA,QACH,mBAAmB,gBAAgB,OAAO;AAAA,QAC1C;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AC3nBO,SAAS,0BACd,QACe;AACf,MAAI,CAAC,UAAU,OAAO,SAAS,QAAS,QAAO;AAC/C,QAAM,KAAK,OAAO;AAClB,MAAI,MAAM,QAAQ,OAAO,GAAI,QAAO;AACpC,SAAO,OAAO,EAAE;AAClB;AAkEA,SAAS,WAAW,OAA+B;AACjD,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,WAAO,OAAO,KAAK;AAAA,EACrB;AAEA,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,QAAQ,OAAO;AAChE,UAAM,KAAM,MAA8B;AAC1C,QAAI,OAAO,OAAO,YAAY,OAAO,OAAO,SAAU,QAAO,OAAO,EAAE;AAAA,EACxE;AAEA,SAAO;AACT;AAEA,SAAS,YACP,OACe;AACf,SAAO,WAAW,KAAK;AACzB;AAEA,SAAS,WAAmB,OAA8C;AACxE,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MAAM,OAAO,CAAC,UAA2B,SAAS,IAAI;AAC/D;AAEA,SAAS,uBACP,SACA,OACU;AACV,QAAM,SAAS,oBAAI,IAAoB;AAEvC,aAAW,QAAQ,OAAO;AACxB,UAAM,KAAK,WAAW,IAAI;AAC1B,UAAM,MAAM,MAAM,UAAU,OAAO,IAAI;AACvC,QAAI,CAAC,OAAO,IAAI,GAAG,EAAG,QAAO,IAAI,KAAK,IAAI;AAAA,EAC5C;AAEA,MAAI,SAAS;AACX,UAAM,YAAY,WAAW,OAAO;AACpC,UAAM,WAAW,oBAAI,IAAoB;AACzC,UAAM,aAAa,aAAa;AAChC,aAAS,IAAI,YAAY,OAAO;AAEhC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG;AAC3C,UAAI,CAAC,SAAS,IAAI,GAAG,EAAG,UAAS,IAAI,KAAK,KAAK;AAAA,IACjD;AAEA,WAAO,MAAM,KAAK,SAAS,OAAO,CAAC;AAAA,EACrC;AAEA,SAAO,MAAM,KAAK,OAAO,OAAO,CAAC;AACnC;AAEA,SAAS,cAAsB,MAAqC;AAClE,QAAM,WAAW,oBAAI,IAAoB;AAEzC,aAAW,QAAQ,MAAM;AACvB,UAAM,KAAK,WAAW,IAAI;AAC1B,QAAI,GAAI,UAAS,IAAI,IAAI,IAAI;AAAA,EAC/B;AAEA,SAAO;AACT;AAEA,SAAS,yBACP,SACA,UACU;AACV,MAAI,CAAC,WAAW,CAAC,MAAM,QAAQ,QAAQ,MAAM,EAAG,QAAO,CAAC;AAExD,QAAM,WAAqB,CAAC;AAE5B,aAAW,SAAS,QAAQ,QAAQ;AAClC,QAAI,SAAS,KAAM;AAEnB,QAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,YAAM,SAAS,SAAS,IAAI,OAAO,KAAK,CAAC;AACzC,UAAI,OAAQ,UAAS,KAAK,MAAM;AAChC;AAAA,IACF;AAEA,UAAM,UAAU,WAAW,KAAK;AAChC,QAAI,SAAS;AACX,YAAM,SAAS,SAAS,IAAI,OAAO;AACnC,UAAI,QAAQ;AACV,iBAAS,KAAK,MAAM;AAAA,MACtB;AACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,2BACP,sBAIA,UACe;AACf,MAAI,CAAC,sBAAsB,OAAQ,QAAO;AAE1C,aAAW,eAAe,sBAAsB;AAC9C,UAAM,SAAS,aAAa;AAC5B,UAAM,gBAAgB,0BAA0B,MAAM;AACtD,QAAI,eAAe;AACjB,YAAM,SAAS,SAAS,IAAI,aAAa;AACzC,UAAI,OAAQ,QAAO;AAAA,IACrB;AAEA,UAAM,SAAS,QAAQ;AACvB,QAAI,UAAU,QAAQ,OAAO,WAAW,UAAU;AAChD,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,6BACd,OAC4C;AAC5C,QAAM,OAAO,WAAW,MAAM,gBAAgB;AAC9C,QAAM,WAAW,cAAc,IAAI;AAEnC,QAAM,wBAAwB;AAAA,IAC5B,MAAM;AAAA,IACN;AAAA,EACF;AAEA,MAAI,sBAAsB,SAAS,GAAG;AACpC,UAAM,eAAe,sBAAsB,CAAC,KAAK;AAEjD,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,uBAAuB,cAAc,qBAAqB;AAAA,MAClE,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MACE,MAAM,mBAAmB,SACxB,MAAM,kBAAkB,UAAU,KAAK,GACxC;AACA,UAAM,uBAAiC,CAAC;AAExC,eAAW,mBAAmB,MAAM,oBAAoB,CAAC,GAAG;AAC1D,2BAAqB;AAAA,QACnB,GAAG,yBAAyB,iBAAiB,QAAQ;AAAA,MACvD;AAAA,IACF;AAEA,QAAI,qBAAqB,SAAS,GAAG;AACnC,YAAM,eAAe,qBAAqB,CAAC,KAAK;AAEhD,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,uBAAuB,cAAc,oBAAoB;AAAA,QACjE,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,QAAM,sBAAsB;AAAA,IAC1B,MAAM;AAAA,IACN;AAAA,EACF;AAEA,MAAI,qBAAqB;AACvB,WAAO;AAAA,MACL,cAAc;AAAA,MACd,QAAQ,CAAC,mBAAmB;AAAA,MAC5B,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AAAA,IACL,cAAc;AAAA,IACd,QAAQ,CAAC;AAAA,IACT,QAAQ;AAAA,EACV;AACF;AAEO,SAAS,2BACd,OAC0C;AAC1C,QAAM,OAAO,WAAW,MAAM,gBAAgB;AAC9C,QAAM,WAAW,cAAc,IAAI;AAEnC,QAAM,uBAAuB,YAAY,MAAM,aAAa;AAC5D,MAAI,sBAAsB;AACxB,UAAM,gBAAgB,SAAS,IAAI,oBAAoB;AACvD,QAAI,eAAe;AACjB,aAAO;AAAA,QACL,cAAc;AAAA,QACd,QAAQ,uBAAuB,eAAe,IAAI;AAAA,QAClD,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,UAAM,qBAAqB,KAAK,CAAC,KAAK;AAEtC,QAAI,oBAAoB;AACtB,aAAO;AAAA,QACL,cAAc;AAAA,QACd,QAAQ,uBAAuB,oBAAoB,IAAI;AAAA,QACvD,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,cAAc;AAAA,IACd,QAAQ,CAAC;AAAA,IACT,QAAQ;AAAA,EACV;AACF;AASO,SAAS,4BACd,OACe;AACf,QAAM,OAAO,WAAW,MAAM,gBAAgB;AAC9C,QAAM,kBAAkB,WAAW,MAAM,eAAe;AACxD,MACE,mBACA,MAAM,mBAAmB,kBACzB,MAAM,mBAAmB,QACzB;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,cAAc,IAAI;AACnC,QAAM,uBAAuB,WAAW,MAAM,aAAa;AAC3D,MAAI,wBAAwB,SAAS,IAAI,oBAAoB,GAAG;AAC9D,WAAO;AAAA,EACT;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,UAAM,cAAc,WAAW,KAAK,CAAC,CAAC;AACtC,QAAI,YAAa,QAAO;AAAA,EAC1B;AAEA,SAAO;AACT;;;AC/SA,SAAS,sBACP,QACmD;AACnD,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,WAAW,OAAO;AACxB,QAAM,cACJ,YAAY,QACZ,OAAO,aAAa,YACpB,SAAS,YACT,OAAQ,SAA+B,QAAQ,WAC1C,WACD;AACN,SAAO;AAAA,IACL,MAAM,OAAO,QAAQ;AAAA,IACrB,OAAO,OAAO,SAAS;AAAA,IACvB,aAAa,gBAAgB,QAAQ;AAAA,IACrC;AAAA,EACF;AACF;AAiOA,IAAM,qCACJ;AAEF,SAAS,+BACP,MACyB;AACzB,SAAO,QAAQ;AACjB;AAEA,SAAS,+BACP,QACA,QACA,UACA,SACS;AACT,QAAM,SAAS,OAAO,WAAW,IAAI,QAAQ;AAC7C,QAAM,QAAQ,OAAO,UAAU,IAAI,OAAO;AAC1C,MAAI,CAAC,QAAQ,QAAQ,CAAC,OAAO,KAAM,QAAO;AAE1C,QAAM,cAAc,OAAO,OAAO;AAAA,IAChC,CAAC,cAAc,UAAU,SAAS,MAAM;AAAA,EAC1C;AACA,MAAI,YAAY,WAAW,EAAG,QAAO;AAErC,SAAO,OAAO,OAAO,OAAO,IAAI,IAAI,MAAM,IAAI;AAC9C,SAAO;AACT;AAEA,SAAS,8BACP,QACA,UACA,SACM;AACN,SAAO,OAAO,OAAO,QAAQ,IAAI,OAAO;AAC1C;AA2EO,IAAM,6BAAN,cAAyC,MAAM;AAAA,EAGpD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AAHf,gBAAO;AAIL,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,cAAc,OAA8C;AACnE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAClD,MAAI,SAAS,OAAO,UAAU,YAAY,QAAQ,OAAO;AACvD,UAAM,KAAK,MAAM;AACjB,QAAI,OAAO,OAAO,SAAU,QAAO;AACnC,QAAI,OAAO,OAAO,SAAU,QAAO,OAAO,EAAE;AAAA,EAC9C;AACA,SAAO;AACT;AAMA,SAAS,eAAe,MAAc,OAAuB;AAC3D,MAAI,OAAO,MAAO,QAAO;AACzB,MAAI,OAAO,MAAO,QAAO;AACzB,SAAO;AACT;AAEA,SAAS,aACP,MACA,OACQ;AACR,SAAO,eAAe,QAAQ,IAAI,SAAS,EAAE;AAC/C;AAEA,SAAS,wBACP,OACkC;AAClC,SACE,OAAO,UAAU,YACjB,UAAU,QACV,QAAQ,UACP,WAAW,SAAS,UAAU;AAEnC;AAEA,SAAS,gBAAgB,OAAoC;AAC3D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAClD,MAAI,SAAS,OAAO,UAAU,YAAY,QAAQ,OAAO;AACvD,QAAI,OAAO,MAAM,OAAO,SAAU,QAAO,MAAM;AAC/C,QAAI,OAAO,MAAM,OAAO,SAAU,QAAO,OAAO,MAAM,EAAE;AAAA,EAC1D;AACA,SAAO;AACT;AAEA,SAAS,gBACP,QACiB;AACjB,MAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO;AAEnC,aAAW,SAAS,QAAQ;AAC1B,UAAM,KAAK,gBAAgB,KAAK;AAChC,QAAI,MAAM,KAAM,QAAO;AAAA,EACzB;AAEA,SAAO;AACT;AAEA,SAAS,mBACP,SACA,SACiB;AACjB,MAAI,WAAW,KAAM,QAAO;AAC5B,QAAM,SAAS,MAAM,QAAQ,SAAS,MAAM,IAAI,QAAQ,SAAS,CAAC;AAClE,aAAW,SAAS,QAAQ;AAC1B,QAAI,gBAAgB,KAAK,MAAM,QAAS,QAAO;AAAA,EACjD;AACA,SAAO;AACT;AAEA,SAAS,uBACP,SACiB;AACjB,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,gBAAgB,QAAQ,SAAS,KAAK,gBAAgB,QAAQ,MAAM;AAC7E;AAEA,SAAS,kCACP,SACA,iBACA,gBACiB;AACjB,SAAO,4BAA4B;AAAA,IACjC,kBAAkB,SAAS,UAAU,CAAC;AAAA,IACtC,eAAe,SAAS,iBAAiB;AAAA,IACzC;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,SAAS,qCACP,UACiB;AACjB,QAAM,kBAAkB,CAAC,GAAG,QAAQ,EAAE,KAAK,mBAAmB;AAE9D,aAAW,WAAW,iBAAiB;AACrC,QAAI,CAAC,0BAA0B,OAAO,EAAG;AACzC,UAAM,QAAQ,uBAAuB,OAAO;AAC5C,QAAI,SAAS,KAAM,QAAO;AAAA,EAC5B;AAEA,SAAO;AACT;AAEA,SAAS,kCACP,QAK0B;AAC1B,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,OAAO,WAAW,SAAU,QAAO;AAEvC,QAAM,MAAM;AACZ,QAAM,cAAc,gBAAgB,IAAI,WAAyB;AACjE,QAAM,QAAQ,OAAO,IAAI,UAAU,WAAW,IAAI,MAAM,KAAK,IAAI;AACjE,QAAM,WAAW,MAAM,SAAS;AAEhC,MAAI,IAAI,SAAS,WAAY,eAAe,IAAI,SAAS,SAAU;AACjE,QAAI,CAAC,eAAe,SAAU,QAAO;AACrC,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,IAAI,SAAS,WAAW,UAAU;AACpC,QAAI,eAAe,CAAC,SAAU,QAAO;AACrC,WAAO,EAAE,MAAM,SAAS,OAAO,aAAa,KAAK;AAAA,EACnD;AAEA,SAAO;AACT;AAEA,SAAS,qBACP,OACA,kBACA,oBAC0B;AAC1B,SAAO;AAAA,IACL,IAAI,OAAO,MAAM,EAAE;AAAA,IACnB,UAAU,cAAc,MAAM,MAAM,KAAK;AAAA,IACzC,YAAY;AAAA,IACZ,OAAO,MAAM,SAAS,MAAM,QAAQ,OAAO,MAAM,EAAE;AAAA,IACnD,MAAM,MAAM,QAAQ;AAAA,IACpB,QAAQ,kCAAkC,MAAM,MAAM;AAAA,IACtD,OAAO,MAAM,UAAU,MAAM,qCAAqC,KAAK;AAAA,EACzE;AACF;AAEA,SAAS,6BACP,SACA,YACA,iBACA,WACsC;AACtC,QAAM,wBAAwB,oBAAI,IAAoB;AACtD,QAAM,0BAA0B,oBAAI,IAAoB;AAExD,aAAW,YAAY,MAAM,QAAQ,QAAQ,YAAY,IACrD,QAAQ,eACR,CAAC,GAAG;AACN,UAAM,UAAU,cAAc,QAA6B;AAC3D,QAAI,CAAC,QAAS;AAEd,UAAM,WACJ,gBAAgB,IAAI,OAAO,MAC1B,wBAAwB,QAAQ,IAC7B,cAAc,SAAS,MAAM,IAC7B;AACN,QAAI,CAAC,YAAY,sBAAsB,IAAI,QAAQ,EAAG;AAEtD,0BAAsB,IAAI,UAAU,OAAO;AAC3C,UAAM,aAAa,WAAW,IAAI,QAAQ,GAAG;AAC7C,QAAI,cAAc,CAAC,wBAAwB,IAAI,UAAU,GAAG;AAC1D,8BAAwB,IAAI,YAAY,OAAO;AAAA,IACjD;AAAA,EACF;AAEA,QAAM,iBAAiB,UACpB,IAAI,CAAC,aAAa,sBAAsB,IAAI,QAAQ,CAAC,EACrD,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAE1D,SAAO;AAAA,IACL,IAAI,OAAO,QAAQ,EAAE;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV;AACF;AAEO,SAAS,yBAEd;AAAA,EACA;AAAA,EACA,WAAW,CAAC;AACd,GAGkC;AAChC,QAAM,oBAAoB,QACvB,IAAI,CAAC,WAAW;AACf,UAAM,aAAa,oBAAI,IAAsC;AAC7D,UAAM,aAAa,OAAO,QAAQ,OAAO,OAAO,EAAE;AAElD,eAAW,YAAY,OAAO,QAAQ,QAAQ,CAAC,GAAG;AAChD,UAAI,CAAC,wBAAwB,QAAQ,EAAG;AAExC,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA,OAAO,OAAO,EAAE;AAAA,QAChB;AAAA,MACF;AACA,iBAAW,IAAI,gBAAgB,IAAI,eAAe;AAAA,IACpD;AAEA,WAAO;AAAA,MACL,IAAI,OAAO,OAAO,EAAE;AAAA,MACpB,OAAO,OAAO,SAAS,OAAO,OAAO,EAAE;AAAA,MACvC,MAAM;AAAA,MACN,OAAO,OAAO,UAAU,OAAO,gCAAgC,KAAK;AAAA,MACpE,QAAQ,MAAM,KAAK,WAAW,OAAO,CAAC,EAAE;AAAA,QAAK,CAAC,MAAM,UAClD,aAAa,KAAK,OAAO,MAAM,KAAK;AAAA,MACtC;AAAA,IACF;AAAA,EACF,CAAC,EACA,KAAK,CAAC,MAAM,UAAU,aAAa,KAAK,OAAO,MAAM,KAAK,CAAC;AAE9D,QAAM,aAAa,IAAI;AAAA,IACrB,kBAAkB,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC;AAAA,EACvD;AACA,QAAM,eAAe,IAAI;AAAA,IACvB,kBAAkB,IAAI,CAAC,WAAW,CAAC,OAAO,MAAM,MAAM,CAAC;AAAA,EACzD;AACA,QAAM,YAAY,oBAAI,IAAsC;AAC5D,QAAM,kBAAkB,oBAAI,IAAoB;AAChD,QAAM,oBAAoB,oBAAI,IAAoB;AAElD,aAAW,UAAU,mBAAmB;AACtC,eAAW,SAAS,OAAO,QAAQ;AACjC,gBAAU,IAAI,MAAM,IAAI,KAAK;AAC7B,sBAAgB,IAAI,MAAM,IAAI,OAAO,EAAE;AACvC,wBAAkB,IAAI,MAAM,IAAI,OAAO,IAAI;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,YAAY,kBAAkB,IAAI,CAAC,WAAW,OAAO,EAAE;AAC7D,QAAM,cAAc,kBAAkB,IAAI,CAAC,WAAW,OAAO,IAAI;AACjE,QAAM,qBAAqB,SAAS;AAAA,IAAI,CAAC,YACvC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,YAAY,OAAuB;AAC1C,SAAO,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG;AACtC;AAEO,SAAS,mCAGd,QACgE;AAChE,QAAM,oBAAoB,OAAO,QAAQ,IAAI,CAAC,QAAQ,iBAAiB;AAAA,IACrE,IAAI,OAAO,OAAO,EAAE;AAAA,IACpB,OAAO,OAAO,SAAS,OAAO,OAAO,EAAE;AAAA,IACvC,MAAM,OAAO;AAAA,IACb,OAAO,YAAY,WAAW;AAAA,IAC9B,QAAQ,OAAO,OAAO,IAAI,CAAC,OAAO,gBAAgB;AAAA,MAChD,IAAI,OAAO,MAAM,EAAE;AAAA,MACnB,UAAU,OAAO,OAAO,EAAE;AAAA,MAC1B,YAAY,OAAO;AAAA,MACnB,OAAO,MAAM,SAAS,MAAM,QAAQ,OAAO,MAAM,EAAE;AAAA,MACnD,MAAM,MAAM;AAAA,MACZ,QAAQ,kCAAkC,MAAM,MAAM;AAAA,MACtD,OAAO,YAAY,UAAU;AAAA,IAC/B,EAAE;AAAA,EACJ,EAAE;AAEF,QAAM,aAAa,IAAI;AAAA,IACrB,kBAAkB,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC;AAAA,EACvD;AACA,QAAM,eAAe,IAAI;AAAA,IACvB,kBAAkB,IAAI,CAAC,WAAW,CAAC,OAAO,MAAM,MAAM,CAAC;AAAA,EACzD;AACA,QAAM,YAAY,oBAAI,IAAsC;AAC5D,QAAM,kBAAkB,oBAAI,IAAoB;AAChD,QAAM,oBAAoB,oBAAI,IAAoB;AAElD,aAAW,UAAU,mBAAmB;AACtC,eAAW,SAAS,OAAO,QAAQ;AACjC,gBAAU,IAAI,MAAM,IAAI,KAAK;AAC7B,sBAAgB,IAAI,MAAM,IAAI,OAAO,EAAE;AACvC,wBAAkB,IAAI,MAAM,IAAI,OAAO,IAAI;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,YAAY,kBAAkB,IAAI,CAAC,WAAW,OAAO,EAAE;AAC7D,QAAM,cAAc,kBAAkB,IAAI,CAAC,WAAW,OAAO,IAAI;AACjE,QAAM,qBAAqB,OAAO,SAAS,IAAI,CAAC,YAAY;AAC1D,UAAM,wBAAwB,oBAAI,IAAoB;AACtD,UAAM,0BAA0B,oBAAI,IAAoB;AAExD,eAAW,YAAY,QAAQ,cAAc;AAC3C,YAAM,WAAW,OAAO,SAAS,QAAQ;AACzC,YAAM,UAAU,OAAO,SAAS,OAAO;AACvC,YAAM,aAAa,SAAS;AAC5B,UAAI,CAAC,WAAW,IAAI,QAAQ,EAAG;AAC/B,UAAI,gBAAgB,IAAI,OAAO,MAAM,SAAU;AAC/C,UAAI,sBAAsB,IAAI,QAAQ,EAAG;AACzC,4BAAsB,IAAI,UAAU,OAAO;AAC3C,UAAI,cAAc,CAAC,wBAAwB,IAAI,UAAU,GAAG;AAC1D,gCAAwB,IAAI,YAAY,OAAO;AAAA,MACjD;AAAA,IACF;AAEA,UAAM,iBAAiB,UACpB,IAAI,CAAC,aAAa,sBAAsB,IAAI,QAAQ,CAAC,EACrD,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAE1D,WAAO;AAAA,MACL,IAAI,OAAO,QAAQ,EAAE;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ;AACF;AAEO,SAAS,2BAGd,QACA,kBACqB;AACrB,QAAM,mBAAmB,oBAAI,IAAoB;AAEjD,aAAW,YAAY,kBAAkB;AACvC,UAAM,UAAU,cAAc,QAA6B;AAC3D,QAAI,CAAC,QAAS;AAEd,UAAM,WAAW,OAAO,gBAAgB,IAAI,OAAO;AACnD,QAAI,CAAC,YAAY,iBAAiB,IAAI,QAAQ,EAAG;AAEjD,qBAAiB,IAAI,UAAU,OAAO;AAAA,EACxC;AAEA,SAAO;AACT;AAEO,SAAS,0BAGd,QACA,kBACU;AACV,QAAM,mBAAmB,2BAA2B,QAAQ,gBAAgB;AAE5E,SAAO,OAAO,UACX,IAAI,CAAC,aAAa,iBAAiB,IAAI,QAAQ,CAAC,EAChD,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAC5D;AAEO,SAAS,yBAGd,QACA,UACA,kBAC4B;AAC5B,QAAM,SAAS,OAAO,WAAW,IAAI,QAAQ;AAC7C,MAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,MAAI,OAAO,SAAS,WAAW,GAAG;AAChC,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,mBAAmB,2BAA2B,QAAQ,gBAAgB;AAC5E,mBAAiB,OAAO,QAAQ;AAEhC,QAAM,mBAAmB,OAAO,SAAS;AAAA,IAAO,CAAC,YAC/C,MAAM,KAAK,iBAAiB,QAAQ,CAAC,EAAE;AAAA,MACrC,CAAC,CAAC,kBAAkB,eAAe,MACjC,QAAQ,sBAAsB,IAAI,gBAAgB,MAAM;AAAA,IAC5D;AAAA,EACF;AAEA,QAAM,oBAAoB,IAAI;AAAA,IAC5B,iBACG,OAAO,CAAC,YAAY,QAAQ,OAAO,aAAa,KAAK,EACrD,IAAI,CAAC,YAAY,QAAQ,sBAAsB,IAAI,QAAQ,CAAC,EAC5D,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAAA,EAC5D;AAEA,SAAO,OAAO,OAAO,OAAO,CAAC,UAAU,kBAAkB,IAAI,MAAM,EAAE,CAAC;AACxE;AAEO,SAAS,2BAGd,QACA,kBACkD;AAClD,QAAM,mBAAmB,2BAA2B,QAAQ,gBAAgB;AAC5E,MAAI,iBAAiB,SAAS,OAAO,UAAU,QAAQ;AACrD,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,SAAS;AAAA,IAAK,CAAC,YAC3B,OAAO,UAAU;AAAA,MACf,CAAC,aACC,QAAQ,sBAAsB,IAAI,QAAQ,MAC1C,iBAAiB,IAAI,QAAQ;AAAA,IACjC;AAAA,EACF;AACF;AAEA,SAAS,oBACP,QACA,WACiE;AACjE,MAAI,aAAa,KAAM,QAAO;AAC9B,QAAM,KAAK,OAAO,SAAS;AAC3B,SAAO,OAAO,SAAS,KAAK,CAAC,YAAY,QAAQ,OAAO,EAAE;AAC5D;AAEA,SAAS,qBAAqB,WAA2C;AACvE,SAAO;AAAA,IACL,UAAU,aAAa,QACvB,UAAU,UACV,UAAU,YACV,OAAO,KAAK,UAAU,cAAc,CAAC,CAAC,EAAE,SAAS,KACjD,OAAO,KAAK,UAAU,gBAAgB,CAAC,CAAC,EAAE,SAAS;AAAA,EACrD;AACF;AAEA,SAAS,oBACP,QACA,oBACA,UACA,SACS;AACT,MAAI,WAAW,KAAM,QAAO;AAC5B,QAAM,oBAAoB,OAAO,OAAO;AACxC,MAAI,OAAO,gBAAgB,IAAI,iBAAiB,MAAM,SAAU,QAAO;AACvE,qBAAmB,IAAI,UAAU,iBAAiB;AAClD,SAAO;AACT;AAEA,SAAS,kCACP,QACA,oBACA,UACA,WACS;AACT,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,SAAS,OAAO,WAAW,IAAI,QAAQ;AAC7C,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,SAAS,OAAO,OAAO;AAAA,IAC3B,CAAC,cAAc,UAAU,SAAS;AAAA,EACpC;AACA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,IAAI;AAAA,MACR,2CAA2C,SAAS,iBAAiB,QAAQ;AAAA,IAC/E;AAAA,EACF;AACA,QAAM,QAAQ,OAAO,CAAC;AACtB,MAAI,CAAC,MAAO,QAAO;AACnB,qBAAmB,IAAI,UAAU,MAAM,EAAE;AACzC,SAAO;AACT;AAEA,SAAS,oCACP,QACA,oBACA,YACA,WACS;AACT,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,SAAS,OAAO,aAAa,IAAI,UAAU;AACjD,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,SAAS,OAAO,OAAO;AAAA,IAC3B,CAAC,cAAc,UAAU,SAAS;AAAA,EACpC;AACA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,IAAI;AAAA,MACR,2CAA2C,SAAS,iBAAiB,UAAU;AAAA,IACjF;AAAA,EACF;AACA,QAAM,QAAQ,OAAO,CAAC;AACtB,MAAI,CAAC,MAAO,QAAO;AACnB,qBAAmB,IAAI,OAAO,IAAI,MAAM,EAAE;AAC1C,SAAO;AACT;AAEA,SAAS,eACP,QACiB;AACjB,MAAI,CAAC,OAAQ,QAAO,IAAI,gBAAgB;AACxC,MAAI,kBAAkB,gBAAiB,QAAO,IAAI,gBAAgB,MAAM;AACxE,MAAI,kBAAkB,IAAK,QAAO,IAAI,gBAAgB,OAAO,YAAY;AAEzE,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,CAAC,QAAS,QAAO,IAAI,gBAAgB;AAEzC,MAAI;AACF,QAAI,2BAA2B,KAAK,OAAO,GAAG;AAC5C,aAAO,IAAI,IAAI,OAAO,EAAE;AAAA,IAC1B;AAAA,EACF,QAAQ;AACN,WAAO,IAAI,gBAAgB;AAAA,EAC7B;AAEA,SAAO,IAAI;AAAA,IACT,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAAA,EAC/C;AACF;AAEA,SAAS,SAAS,OAAuB;AACvC,SAAO,MACJ,KAAK,EACL,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE;AAC3B;AAEA,SAAS,iCACP,QACA,QACA;AACA,QAAM,qBAAqB,oBAAI,IAAY;AAC3C,QAAM,kBAAkB,OAAO,IAAI,SAAS;AAC5C,QAAM,kBAAkB,MAAM,KAAK,OAAO,KAAK,CAAC,EAAE;AAAA,IAAK,CAAC,QACtD,IAAI,WAAW,MAAM;AAAA,EACvB;AAEA,MAAI,mBAAmB,iBAAiB;AACtC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,aAAW,UAAU,OAAO,SAAS;AACnC,uBAAmB,IAAI,SAAS,OAAO,IAAI,CAAC;AAC5C,uBAAmB,IAAI,SAAS,OAAO,KAAK,CAAC;AAC7C,eAAW,SAAS,OAAO,QAAQ;AACjC,UAAI,MAAM,KAAM,oBAAmB,IAAI,SAAS,MAAM,IAAI,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG;AAC3C,QAAI,IAAI,WAAW,MAAM,GAAG;AAC1B,YAAM,cAAc,IAAI,MAAM,CAAC;AAC/B,UACE,CAAC,eACA,CAAC,OAAO,aAAa,IAAI,WAAW,KACnC,CAAC,OAAO,WAAW,IAAI,WAAW,GACpC;AACA,cAAM,IAAI;AAAA,UACR,8CAA8C,GAAG;AAAA,QACnD;AAAA,MACF;AACA,UAAI,CAAC,OAAO;AACV,cAAM,IAAI;AAAA,UACR,sCAAsC,GAAG;AAAA,QAC3C;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW;AACrB,UAAI,CAAC,OAAO;AACV,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,UAAI,CAAC,oBAAoB,QAAQ,KAAK,GAAG;AACvC,cAAM,IAAI;AAAA,UACR,sCAAsC,KAAK;AAAA,QAC7C;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,WAAW,SAAS,GAAG;AAC7B,QACE,mBAAmB,IAAI,QAAQ,KAC9B,UAAU,MAAM,mBAAmB,IAAI,QAAQ,GAChD;AACA,YAAM,IAAI;AAAA,QACR,gDAAgD,GAAG;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,+BACP,SACA,OACA;AACA,MAAI;AACF,QAAI,SAAS,8BAA8B;AACzC,cAAQ,6BAA6B,KAAK;AAC1C;AAAA,IACF;AACA,aAAS,wBAAwB,KAAK;AAAA,EACxC,QAAQ;AAAA,EAER;AACF;AAEA,SAAS,sBACP,QACA,oBACA,QACA,SACe;AACf,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,SAAS,eAAe,MAAM;AACpC,mCAAiC,QAAQ,MAAM;AAE/C,QAAM,eAAe,OAAO,IAAI,SAAS;AACzC,MAAI,gBAAgB,MAAM;AACxB,UAAM,mBAAmB,oBAAoB,QAAQ,YAAY;AACjE,QAAI,CAAC,kBAAkB;AACrB,YAAM,IAAI;AAAA,QACR,sCAAsC,YAAY;AAAA,MACpD;AAAA,IACF;AACA,eAAW,CAAC,UAAU,OAAO,KAAK,iBAAiB,uBAAuB;AACxE,yBAAmB,IAAI,UAAU,OAAO;AAAA,IAC1C;AACA,WAAO,iBAAiB;AAAA,EAC1B;AAEA,aAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,GAAG;AAChD,QAAI,CAAC,IAAI,WAAW,MAAM,EAAG;AAC7B,UAAM,cAAc,IAAI,MAAM,CAAC;AAE/B,UAAM,aAAa,OAAO,WAAW,IAAI,WAAW;AACpD,QAAI,YAAY;AACd,UACE;AAAA,QACE;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF,GACA;AACA;AAAA,MACF;AAEA,YAAM,SAAS,mBAAmB,IAAI,WAAW,EAAE;AACnD,UACE;AAAA,QACE;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF,KACA,mBAAmB,IAAI,WAAW,EAAE,MAAM,QAC1C;AACA,uCAA+B,SAAS;AAAA,UACtC,UAAU,WAAW;AAAA,UACrB,YAAY,WAAW;AAAA,UACvB,WAAW;AAAA,UACX,aAAa;AAAA,QACf,CAAC;AACD;AAAA,MACF;AAEA,YAAM,IAAI;AAAA,QACR,oCAAoC,UAAU,iBAAiB,WAAW;AAAA,MAC5E;AAAA,IACF;AAEA,UAAM,eAAe,OAAO,aAAa,IAAI,WAAW;AACxD,QAAI,cAAc;AAChB,UACE;AAAA,QACE;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb;AAAA,MACF,GACA;AACA;AAAA,MACF;AAEA,UAAI,OAAO,UAAU,IAAI,UAAU,GAAG;AACpC,cAAM,IAAI;AAAA,UACR,oCAAoC,UAAU,iBAAiB,WAAW;AAAA,QAC5E;AAAA,MACF;AAEA,YAAM,IAAI;AAAA,QACR,oCAAoC,UAAU,iBAAiB,WAAW;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,0BACd,QACA,YAAmC,CAAC,GACpC,SAC4B;AAC5B,QAAM,SAAS,mCAAmC,MAAM;AACxD,SAAO,oCAAoC,QAAQ,WAAW,OAAO;AACvE;AAEO,SAAS,oCACd,QACA,YAAmC,CAAC,GACpC,SAC4B;AAC5B,QAAM,qBAAqB,oBAAI,IAAoB;AACnD,QAAM,mBAAmB,oBAAoB,QAAQ,UAAU,SAAS;AACxE,QAAM,YAAY,kBAAkB,MAAM;AAE1C,MAAI,kBAAkB;AACpB,eAAW,CAAC,UAAU,OAAO,KAAK,iBAAiB,uBAAuB;AACxE,yBAAmB,IAAI,UAAU,OAAO;AAAA,IAC1C;AAAA,EACF;AAEA,aAAW,cAAc,UAAU,YAAY,CAAC,GAAG;AACjD,UAAM,UAAU,cAAc,UAA+B;AAC7D,QAAI,CAAC,QAAS;AACd,UAAM,WAAW,OAAO,gBAAgB,IAAI,OAAO;AACnD,QAAI,CAAC,SAAU;AACf,uBAAmB,IAAI,UAAU,OAAO;AAAA,EAC1C;AAEA,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,EACF;AAEA,aAAW,CAAC,aAAa,YAAY,KAAK,OAAO;AAAA,IAC/C,UAAU,cAAc,CAAC;AAAA,EAC3B,GAAG;AACD,UAAM,WAAW,OAAO,WAAW;AACnC,QAAI,CAAC,OAAO,WAAW,IAAI,QAAQ,EAAG;AAEtC,QACE,gBACA,OAAO,iBAAiB,YACxB,aAAa,gBACb,aAAa,WAAW,MACxB;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa;AAAA,MACf;AACA;AAAA,IACF;AAEA,QAAI,OAAO,iBAAiB,YAAY,OAAO,iBAAiB,UAAU;AACxE,0BAAoB,QAAQ,oBAAoB,UAAU,YAAY;AACtE;AAAA,IACF;AAEA,QACE,gBACA,OAAO,iBAAiB,YACxB,eAAe,cACf;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,aAAW,CAAC,eAAe,YAAY,KAAK,OAAO;AAAA,IACjD,UAAU,gBAAgB,CAAC;AAAA,EAC7B,GAAG;AACD,UAAM,aAAa,OAAO,aAAa;AACvC,QAAI,CAAC,OAAO,aAAa,IAAI,UAAU,EAAG;AAE1C,QACE,gBACA,OAAO,iBAAiB,YACxB,aAAa,gBACb,aAAa,WAAW,MACxB;AACA,YAAM,SAAS,OAAO,aAAa,IAAI,UAAU;AACjD,UAAI,QAAQ;AACV;AAAA,UACE;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP,aAAa;AAAA,QACf;AAAA,MACF;AACA;AAAA,IACF;AAEA,QACE,gBACA,OAAO,iBAAiB,YACxB,eAAe,cACf;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa;AAAA,MACf;AACA;AAAA,IACF;AAEA,QAAI,OAAO,iBAAiB,YAAY,OAAO,iBAAiB,UAAU;AACxE;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,YAAY;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,OAAO;AAAA,IACxB,OAAO,UACJ,IAAI,CAAC,aAAa,CAAC,UAAU,mBAAmB,IAAI,QAAQ,CAAC,CAAC,EAC9D,OAAO,CAAC,UAAqC,QAAQ,MAAM,CAAC,CAAC,CAAC;AAAA,EACnE;AACA,QAAM,eAAe,OAAO;AAAA,IAC1B,OAAO,QACJ,IAAI,CAAC,WAAW;AACf,YAAM,UAAU,mBAAmB,IAAI,OAAO,EAAE;AAChD,YAAM,QAAQ,UAAU,OAAO,UAAU,IAAI,OAAO,IAAI;AACxD,aAAO,CAAC,OAAO,MAAM,OAAO,QAAQ,MAAS;AAAA,IAC/C,CAAC,EACA,OAAO,CAAC,UAAqC,QAAQ,MAAM,CAAC,CAAC,CAAC;AAAA,EACnE;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,OAAO,UACd,IAAI,CAAC,aAAa,WAAW,QAAQ,CAAC,EACtC,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAAA,IAC1D,WAAW,mBAAmB;AAAA,EAChC;AACF;AAEO,SAAS,sBACd,QACA,QACA,SAC4B;AAC5B,SAAO,0BAA0B,QAAQ,EAAE,OAAO,GAAG,OAAO;AAC9D;AAEO,SAAS,0BACd,QACA,YAAmC,CAAC,GACpC,SACQ;AACR,QAAM,SAAS,mCAAmC,MAAM;AACxD,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,SAAS,IAAI,gBAAgB;AAEnC,MAAI,qBAAqB,SAAS,GAAG;AACnC,UAAM,mBAAmB,0BAA0B,QAAQ,UAAU;AACrE,UAAM,eAAe;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,cAAc;AAChB,aAAO,IAAI,WAAW,aAAa,EAAE;AACrC,aAAO,OAAO,SAAS;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,OAAO,+BAA+B,SAAS,IAAI;AAEzD,aAAW,YAAY,OAAO,WAAW;AACvC,UAAM,UAAU,WAAW,WAAW,QAAQ;AAC9C,QAAI,CAAC,QAAS;AACd,QAAI,CAAC,OAAO,WAAW,IAAI,QAAQ,KAAK,CAAC,OAAO,UAAU,IAAI,OAAO,GAAG;AACtE;AAAA,IACF;AAEA,QAAI,SAAS,eAAe;AAC1B,UAAI,+BAA+B,QAAQ,QAAQ,UAAU,OAAO,GAAG;AACrE;AAAA,MACF;AAAA,IACF;AAEA,kCAA8B,QAAQ,UAAU,OAAO;AAAA,EACzD;AAEA,SAAO,OAAO,SAAS;AACzB;AAEO,SAAS,4BACd,QACA,SAMA;AACA,SAAO;AAAA,IACL,OAAO,CAAC,WAAW,sBAAsB,QAAQ,QAAQ,OAAO;AAAA,IAChE,WAAW,CAAC,YAAY,CAAC,MACvB,0BAA0B,QAAQ,WAAW,OAAO;AAAA,EACxD;AACF;AAEA,SAAS,gBACP,WACyB;AACzB,SAAO,OAAO,QAAQ,UAAU,UAAU;AAC5C;AAEA,SAAS,0BACP,QACA,WACuD;AACvD,QAAM,UAAU,gBAAgB,SAAS;AACzC,MAAI,QAAQ,WAAW,EAAG,QAAO,OAAO;AAExC,SAAO,OAAO,SAAS;AAAA,IAAO,CAAC,YAC7B,QAAQ;AAAA,MACN,CAAC,CAAC,UAAU,OAAO,MACjB,QAAQ,sBAAsB,IAAI,QAAQ,MAAM;AAAA,IACpD;AAAA,EACF;AACF;AAEA,SAAS,qBACP,UACuD;AACvD,SAAO,SAAS,OAAO,CAAC,YAAY,QAAQ,OAAO,aAAa,KAAK;AACvE;AAEA,SAAS,6BACP,QACA,WACA,kBAC4D;AAC5D,MAAI,OAAO,UAAU,WAAW,GAAG;AACjC,WACE,oBAAoB,QAAQ,UAAU,SAAS,MAC9C,iBAAiB,WAAW,IAAK,iBAAiB,CAAC,KAAK,OAAQ;AAAA,EAErE;AAEA,QAAM,qBAAqB,OAAO,UAAU;AAAA,IAAM,CAAC,aACjD,QAAQ,UAAU,WAAW,QAAQ,CAAC;AAAA,EACxC;AACA,MAAI,CAAC,mBAAoB,QAAO;AAEhC,SACE,iBAAiB;AAAA,IAAK,CAAC,YACrB,OAAO,UAAU;AAAA,MACf,CAAC,aACC,QAAQ,sBAAsB,IAAI,QAAQ,MAC1C,UAAU,WAAW,QAAQ;AAAA,IACjC;AAAA,EACF,KAAK;AAET;AAEA,SAAS,kCACP,QACA,oBACA,WAC4B;AAC5B,QAAM,aAAa,OAAO;AAAA,IACxB,OAAO,UACJ,IAAI,CAAC,aAAa,CAAC,UAAU,mBAAmB,IAAI,QAAQ,CAAC,CAAC,EAC9D,OAAO,CAAC,UAAqC,QAAQ,MAAM,CAAC,CAAC,CAAC;AAAA,EACnE;AACA,QAAM,eAAe,OAAO;AAAA,IAC1B,OAAO,QACJ,IAAI,CAAC,WAAW;AACf,YAAM,UAAU,mBAAmB,IAAI,OAAO,EAAE;AAChD,YAAM,QAAQ,UAAU,OAAO,UAAU,IAAI,OAAO,IAAI;AACxD,aAAO,CAAC,OAAO,MAAM,OAAO,QAAQ,MAAS;AAAA,IAC/C,CAAC,EACA,OAAO,CAAC,UAAqC,QAAQ,MAAM,CAAC,CAAC,CAAC;AAAA,EACnE;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,OAAO,UACd,IAAI,CAAC,aAAa,WAAW,QAAQ,CAAC,EACtC,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAAA,IAC1D;AAAA,EACF;AACF;AAEA,SAAS,+BACP,QACA,qBACA,sBAC4B;AAC5B,QAAM,qBAAqB,IAAI;AAAA,IAC7B,OAAO,QAAQ,oBAAoB,UAAU;AAAA,EAC/C;AAEA,MAAI,OAAO,UAAU,MAAM,CAAC,aAAa,mBAAmB,IAAI,QAAQ,CAAC,GAAG;AAC1E,UAAM,YACJ,oBAAoB,aACpB,qCAAqC,QAAQ,kBAAkB;AACjE,QAAI,cAAc,oBAAoB,WAAW;AAC/C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,aAAW,UAAU,OAAO,SAAS;AACnC,QAAI,mBAAmB,IAAI,OAAO,EAAE,EAAG;AACvC,QAAI,OAAO,OAAO,WAAW,GAAG;AAC9B,yBAAmB,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,EAAG,EAAE;AAAA,IACxD;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,MAAM,CAAC,aAAa,mBAAmB,IAAI,QAAQ,CAAC,GAAG;AAC1E,UAAM,YACJ,oBAAoB,aACpB,qCAAqC,QAAQ,kBAAkB;AACjE,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,EACtB;AACA,QAAM,yBAAyB;AAAA,IAC7B;AAAA,IACA;AAAA,EACF;AACA,QAAM,iBAAiB,CAAC,GAAG,sBAAsB,EAAE;AAAA,IAAK,CAAC,MAAM,UAC7D,oBAAoB,KAAK,QAAQ,MAAM,MAAM;AAAA,EAC/C;AAEA,QAAM,gBACJ,wBAAwB,OAAO,OAAO,oBAAoB,IAAI;AAChE,QAAM,cACJ,iBAAiB,OACb,eAAe,KAAK,CAAC,UAAU,MAAM,OAAO,aAAa,IACzD;AACN,QAAM,iBAAiB,eAAe;AAAA,IAAK,CAAC,UAC1C,0BAA0B,MAAM,MAAM;AAAA,EACxC;AACA,QAAM,cAAc,eAAe,kBAAkB,eAAe,CAAC;AAErE,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,aAAW,YAAY,OAAO,WAAW;AACvC,QAAI,mBAAmB,IAAI,QAAQ,EAAG;AACtC,UAAM,UAAU,YAAY,sBAAsB,IAAI,QAAQ;AAC9D,QAAI,QAAS,oBAAmB,IAAI,UAAU,OAAO;AAAA,EACvD;AAEA,QAAM,kBAAkB,OAAO,UAAU;AAAA,IAAM,CAAC,aAC9C,mBAAmB,IAAI,QAAQ;AAAA,EACjC,IACK,qCAAqC,QAAQ,kBAAkB,KAChE,YAAY,KACZ,oBAAoB;AAExB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,qCACP,QACA,oBACe;AACf,MAAI,CAAC,OAAO,UAAU,MAAM,CAAC,aAAa,mBAAmB,IAAI,QAAQ,CAAC,GAAG;AAC3E,WAAO;AAAA,EACT;AAEA,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,yBAAyB,0BAA0B,QAAQ,UAAU;AAC3E,SACE,6BAA6B,QAAQ,YAAY,sBAAsB,GACnE,MAAM;AAEd;AAEA,SAAS,oBACP,UACqC;AACrC,QAAM,EAAE,KAAK,IAAI,IAAI;AAAA,IACnB,SAAS,IAAI,CAAC,YAAY,QAAQ,eAAe,UAAU,QAAQ,KAAK;AAAA,EAC1E;AACA,QAAM,EAAE,KAAK,cAAc,KAAK,aAAa,IAAI;AAAA,IAC/C,SAAS;AAAA,MACP,CAAC,YACC,QAAQ,eAAe,kBAAkB,QAAQ;AAAA,IACrD;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACxD;AACF;AAEA,SAAS,eAAe,OAAgD;AACtE,SAAO,SAAS;AAClB;AAEA,SAASC,YACP,QACsB;AACtB,MAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AACpC,SAAO,OAAO,OAAO,cAAc;AACrC;AAEA,SAAS,oBACP,QAIA,iBACA,kBACA,gBACqC;AACrC,QAAM,cAAcA,YAAW,OAAO,MAAM;AAC5C,QAAM,gBAAgB,6BAAiD;AAAA,IACrE,kBAAkB;AAAA,IAClB,iBAAiB,kBACb;AAAA,MACE,IAAI,gBAAgB;AAAA,MACpB,QAAQ,gBAAgB;AAAA,IAC1B,IACA;AAAA,IACJ,kBAAkB,iBAAiB,IAAI,CAAC,aAAa;AAAA,MACnD,IAAI,QAAQ;AAAA,MACZ,QAAQ,QAAQ;AAAA,IAClB,EAAE;AAAA,IACF,sBAAsB,eAAe,IAAI,CAAC,WAAW;AAAA,MACnD,IAAI,MAAM;AAAA,MACV,QAAQ,sBAAsB,MAAM,MAAM;AAAA,IAC5C,EAAE;AAAA,EACJ,CAAC;AACD,MAAI,cAAc,WAAW,QAAQ;AACnC,WAAO;AAAA,MACL,cAAc,cAAc;AAAA,MAC5B,QAAQ,cAAc;AAAA,MACtB,QAAQ,cAAc;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,eAAe,2BAA+C;AAAA,IAClE,kBAAkB;AAAA,IAClB,eAAe,OAAO,iBAAiB;AAAA,EACzC,CAAC;AACD,MAAI,aAAa,WAAW,QAAQ;AAClC,WAAO;AAAA,MACL,cAAc,aAAa;AAAA,MAC3B,QAAQ,aAAa;AAAA,MACrB,QAAQ,aAAa;AAAA,IACvB;AAAA,EACF;AAEA,SAAO,EAAE,cAAc,MAAM,QAAQ,CAAC,GAAG,QAAQ,OAAO;AAC1D;AAEA,SAAS,oBACP,iBACA,kBACqC;AACrC,MAAI,iBAAiB;AACnB,UAAM,iBAAiB,yBAAyB,eAAe;AAC/D,WAAO;AAAA,MACL,kBAAkB,2BAA2B,eAAe;AAAA,MAC5D,aAAa,gBAAgB;AAAA,MAC7B,OAAO,WAAW,kBAAkB,gBAAgB,QAAQ;AAAA,MAC5D,eACE,mBAAmB,kBACf,gBAAgB,gBAChB;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,kBAAkB,iBAAiB,KAAK,yBAAyB;AAAA,IACjE,aAAa,iBAAiB,KAAK,CAAC,YAAY,QAAQ,WAAW;AAAA,IACnE,OAAO;AAAA,IACP,eAAe;AAAA,IACf,gBAAgB;AAAA,EAClB;AACF;AAEA,SAAS,yBACP,UAIA;AACA,QAAM,iBAAiB,SAAS;AAAA,IAC9B,CAAC,YAAY,QAAQ,aAAa;AAAA,EACpC;AACA,QAAM,cAAc,eAAe,KAAK,CAAC,YAAY,QAAQ,WAAW;AACxE,QAAM,iBAAiB,cACnB,OACA,eAAe;AAAA,IACb,CAAC,KAAK,YAAY,OAAO,yBAAyB,OAAO,KAAK;AAAA,IAC9D;AAAA,EACF;AAEJ,SAAO;AAAA,IACL,kBAAkB,eAAe,KAAK,yBAAyB;AAAA,IAC/D;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,oCACP,aACA,gBACA,UACA,WACA,OAIgC;AAChC,SAAO;AAAA,IACL,SAAS,YAAY;AAAA,IACrB,OAAO,YAAY;AAAA,IACnB,OAAO,YAAY;AAAA,IACnB,MAAM,YAAY,QAAQ;AAAA,IAC1B;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,GAAG;AAAA,IACH,QAAQ,YAAY,UAAU;AAAA,EAChC;AACF;AAEA,SAAS,6BACP,QACA,UACA,SACA,kBAC2B;AAC3B,QAAM,mBAAmB,2BAA2B,QAAQ,gBAAgB;AAC5E,mBAAiB,IAAI,UAAU,OAAO;AAEtC,SAAO,OAAO,SACX;AAAA,IAAO,CAAC,YACP,MAAM,KAAK,iBAAiB,QAAQ,CAAC,EAAE;AAAA,MACrC,CAAC,CAAC,kBAAkB,eAAe,MACjC,QAAQ,sBAAsB,IAAI,gBAAgB,MAClD;AAAA,IACJ;AAAA,EACF,EACC,IAAI,CAAC,YAAY,QAAQ,MAAM;AACpC;AAEA,SAAS,qBAAqB,SAM5B;AACA,SAAO;AAAA,IACL,eAAe,SAAS,iBAAiB,SAAS,QAAQ;AAAA,IAC1D,QAAQ,SAAS,UAAU,SAAS,QAAQ,UAAU,CAAC;AAAA,IACvD,iCACE,SAAS,mCACT,SAAS,QAAQ;AAAA,EACrB;AACF;AAEO,SAAS,kCACd,QACA,YAAmC,CAAC,GACpC,SACA,SAC4B;AAC5B,QAAM,EAAE,eAAe,QAAQ,gCAAgC,IAC7D,qBAAqB,OAAO;AAC9B,QAAM,uBAAuB,cAAc,+BAA+B;AAC1E,QAAM,qBACJ,qBAAqB,SAAS,KAAK,wBAAwB,OACvD,YACA,EAAE,GAAG,WAAW,WAAW,qBAAqB;AACtD,MAAI,sBAAsB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,SAAS,cAAc;AACzB,0BAAsB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,yBAAyB;AAAA,IAC7B;AAAA,IACA;AAAA,EACF;AACA,QAAM,+BAA+B;AAAA,IACnC;AAAA,EACF;AACA,QAAM,uBAAuB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,kBAAkB,sBAAsB,UAAU;AACxD,QAAM,mBAAmB,6BAA6B;AAAA,IACpD,CAAC,YAAY,QAAQ;AAAA,EACvB;AACA,QAAM,iBAAiB,OAAO,UAC3B,IAAI,CAAC,aAAa,oBAAoB,WAAW,QAAQ,CAAC,EAC1D,IAAI,CAAC,YAAa,UAAU,OAAO,UAAU,IAAI,OAAO,IAAI,MAAU,EACtE,OAAO,CAAC,UAA6C,UAAU,MAAS;AAC3E,QAAM,4BAA4B,OAAO;AAAA,IACvC,OAAO,QAAQ,IAAI,CAAC,WAAW;AAC7B,YAAM,oBAAoB,IAAI;AAAA,QAC5B;AAAA,UACE;AAAA,UACA,OAAO;AAAA,UACP,oBAAoB;AAAA,QACtB,EAAE,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,MAC3B;AACA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,OAAO,OAAO;AAAA,UAAI,CAAC,UACjB;AAAA,YACE;AAAA,YACA;AAAA,YACA,oBAAoB,WAAW,OAAO,EAAE,MAAM,MAAM;AAAA,YACpD,kBAAkB,IAAI,MAAM,EAAE;AAAA,YAC9B;AAAA,cACE;AAAA,gBACE;AAAA,gBACA,OAAO;AAAA,gBACP,MAAM;AAAA,gBACN,oBAAoB;AAAA,cACtB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACA,QAAM,8BAA8B,OAAO;AAAA,IACzC,OAAO,QAAQ,IAAI,CAAC,WAAW;AAAA,MAC7B,OAAO;AAAA,MACP,0BAA0B,OAAO,EAAE,KAAK,CAAC;AAAA,IAC3C,CAAC;AAAA,EACH;AACA,QAAM,qBAAqB,OAAO,UAAU;AAAA,IAAM,CAAC,aACjD,QAAQ,oBAAoB,WAAW,QAAQ,CAAC;AAAA,EAClD;AACA,QAAM,gBAAgB,kBAAkB,CAAC,eAAe,IAAI;AAE5D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,kBAAkB,CAAC,IAAI;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,oBAAoB,aAAa;AAAA,IACxC,OAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,OAAO,oBAAoB,iBAAiB,gBAAgB;AAAA,EAC9D;AACF;AAEO,SAAS,wBACd,QACA,YAAmC,CAAC,GACpC,SACuE;AACvE,QAAM,SAAS,mCAAmC,MAAM;AACxD,SAAO,kCAAkC,QAAQ,WAAW,SAAS;AAAA,IACnE;AAAA,EACF,CAAC;AACH;AAEO,SAAS,WACd,QACA,UAAiC,CAAC,GAClC,YACA,WACA,SAC4B;AAC5B,QAAM,SAAS,mCAAmC,MAAM;AACxD,QAAM,uBAAuB;AAAA,IAC3B,OAAO;AAAA,EACT;AACA,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,aAAa,IAAI,UAAU;AACjD,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,eAAe,OAAO,OAAO;AAAA,IACjC,CAAC,cAAc,UAAU,SAAS;AAAA,EACpC;AACA,MAAI,aAAa,WAAW,EAAG,QAAO;AACtC,QAAM,iBAAiB,aAAa,CAAC,EAAG;AAExC,QAAM,uBAAuB,MAAkC;AAC7D,UAAM,qBAAqB,oBAAI,IAAoB;AACnD,uBAAmB,IAAI,OAAO,IAAI,cAAc;AAEhD,eAAW,iBAAiB,OAAO,WAAW;AAC5C,UAAI,kBAAkB,OAAO,GAAI;AACjC,YAAM,eAAe,kBAAkB,WAAW,aAAa;AAC/D,UAAI,CAAC,aAAc;AAEnB,YAAM,gBAAgB;AAAA,QACpB;AAAA,QACA,MAAM,KAAK,mBAAmB,OAAO,CAAC;AAAA,MACxC;AACA,YAAM,YAAY;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,UAAU,KAAK,CAAC,cAAc,UAAU,OAAO,YAAY,GAAG;AAChE,2BAAmB,IAAI,eAAe,YAAY;AAAA,MACpD;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA,kCAAkC,QAAQ,oBAAoB,IAAI;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,qBAAqB,MAAkC;AAC3D,UAAM,qBAAqB,IAAI;AAAA,MAC7B,OAAO,QAAQ,kBAAkB,UAAU;AAAA,IAC7C;AACA,uBAAmB,OAAO,OAAO,EAAE;AAEnC,WAAO;AAAA,MACL;AAAA,MACA,kCAAkC,QAAQ,oBAAoB,IAAI;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB,qBAAqB;AAC3C,QAAM,mBAAmB;AAAA,IACvB;AAAA,IACA,IAAI,IAAI,OAAO,QAAQ,cAAc,UAAU,CAAC;AAAA,EAClD;AAEA,QAAM,gBAAgB,OAAO,QAAQ,kBAAkB,UAAU,EAC9D,OAAO,CAAC,CAAC,aAAa,MAAM,kBAAkB,OAAO,EAAE,EACvD,IAAI,CAAC,CAAC,EAAE,OAAO,MAAM,OAAO;AAE/B,QAAM,4BACJ,cAAc,WAAW,KACzB,yBAAyB,QAAQ,OAAO,IAAI,aAAa,EAAE;AAAA,IACzD,CAAC,cAAc,UAAU,OAAO;AAAA,EAClC;AAEF,MAAI,oBAAoB,MAAM;AAC5B,UAAM,oBAAoB,kBAAkB,WAAW,OAAO,EAAE;AAChE,QAAI,qBAAqB,QAAQ,sBAAsB,gBAAgB;AACrE,aAAO;AAAA,IACT;AACA,QAAI,2BAA2B;AAC7B,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO,mBAAmB;AAC5B;AAOA,SAAS,0BACP,OACkC;AAClC,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,eAAe,OAA+C;AACrE,MAAI,MAAM,MAAM,KAAM,QAAO,MAAM,OAAO,MAAM,EAAE,CAAC;AACnD,MAAI,MAAM,IAAK,QAAO,OAAO,MAAM,GAAG;AACtC,SAAO;AACT;AAEO,SAAS,0BACd,YAC2B;AAC3B,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAoC,CAAC;AAC3C,QAAM,aAAa;AAAA,IACjB,WAAW,MAAM;AAAA,IACjB,GAAG,WAAW,MAAM;AAAA,EACtB,EAAE,OAAO,yBAAyB;AAElC,aAAW,aAAa,YAAY;AAClC,UAAM,MAAM,eAAe,SAAS;AACpC,QAAI,OAAO,KAAK,IAAI,GAAG,EAAG;AAC1B,QAAI,IAAK,MAAK,IAAI,GAAG;AACrB,WAAO,KAAK,SAAS;AAAA,EACvB;AAEA,SAAO;AACT;AAqCA,SAAS,mBAAmB,SAAqC;AAC/D,MAAI,aAAa,WAAW,QAAQ,SAAS,MAAM;AACjD,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACA,MAAI,UAAU,WAAW,QAAQ,KAAM,QAAO,QAAQ;AACtD,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,gBACP,UACA,MACA,eACA;AACA,QAAM,OAAO,SAAS,QAAQ,QAAQ,EAAE;AACxC,QAAM,cAAc,mBAAmB,IAAI;AAC3C,SAAO,GAAG,IAAI,IAAI,WAAW,GAAG,gBAAgB,MAAM,EAAE;AAC1D;AAEA,SAAS,6BACP,OACA,QAC8B;AAC9B,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,MAAM,aAAa,KAAM,QAAO,EAAE,WAAW,MAAM,UAAU;AAEjE,QAAM,WACJ,MAAM,YAAY,OACd,OAAO,MAAM,QAAQ,IACrB,MAAM,aACJ,QAAQ,aAAa,IAAI,MAAM,UAAU,GAAG,KAC5C;AACR,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,SAAS,QAAQ,WAAW,IAAI,QAAQ;AAC9C,QAAM,gBACJ,MAAM,iBAAiB,OACnB,OAAO,MAAM,aAAa,IAC1B,MAAM,mBAAmB,SACvB,OAAO,OAAO,KAAK,CAAC,UAAU,MAAM,SAAS,MAAM,eAAe,GAC9D,KACJ;AAER,MAAI,CAAC,cAAe,QAAO;AAC3B,SAAO,EAAE,YAAY,EAAE,CAAC,QAAQ,GAAG,cAAc,EAAE;AACrD;AAEA,SAAS,2BACP,SAC0C;AAC1C,SAAO,QAAQ,QAAQ,OAAO,EAAE,MAAM,QAAQ,KAAK,IAAI;AACzD;AAEA,SAAS,gCACP,QACA,OACA,gBACA,SACS;AACT,QAAM,OAAO,+BAA+B,QAAQ,IAAI;AACxD,QAAM,aAAa,eAAe,cAAc,CAAC;AACjD,QAAM,UAAU,OAAO,QAAQ,UAAU;AACzC,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,aAAW,CAAC,UAAU,OAAO,KAAK,SAAS;AACzC,UAAM,aACJ,OAAO,cACP,QAAQ,QAAQ,WAAW,IAAI,QAAQ,GAAG,QAC1C;AACF,UAAM,YACJ,OAAO,mBACP,QAAQ,QAAQ,UAAU,IAAI,OAAO,OAAO,CAAC,GAAG,QAChD;AAEF,QACE,SAAS,iBACT,cACA,aACA,QAAQ,WAAW,GACnB;AACA,aAAO,IAAI,OAAO,UAAU,IAAI,SAAS;AACzC,aAAO;AAAA,IACT;AAEA,QACE,SAAS,iBACT,QAAQ,UACR;AAAA,MACE;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,OAAO,OAAO;AAAA,IAChB,GACA;AACA;AAAA,IACF;AACA,kCAA8B,QAAQ,UAAU,OAAO,OAAO,CAAC;AAAA,EACjE;AAEA,SAAO,OAAO,OAAO;AACvB;AAEA,SAAS,0CACP,OACA,SAC8B;AAC9B,MAAI,CAAC,QAAQ,8BAA+B,QAAO;AACnD,MAAI,OAAO,iBAAiB,QAAQ,OAAO,gBAAiB,QAAO;AAEnE,QAAM,gBAAgB,OAAO,SAAS;AACtC,MAAI,iBAAiB,KAAM,QAAO;AAElC,SAAO,EAAE,WAAW,cAAc;AACpC;AAEO,SAAS,iBACd,SACA,OACA,UAA8B,CAAC,GACvB;AACR,QAAM,OAAO;AAAA,IACX,QAAQ,YAAY;AAAA,IACpB,mBAAmB,OAAO;AAAA,IAC1B,QAAQ,iBAAiB;AAAA,EAC3B;AACA,QAAM,SAAS,IAAI,gBAAgB;AAEnC,MAAI,QAAQ,UAAU,QAAQ,WAAW;AACvC,UAAM,YAAY;AAAA,MAChB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,2BAA2B,OAAO;AAAA,IACpC;AACA,WAAO,YAAY,GAAG,IAAI,IAAI,SAAS,KAAK;AAAA,EAC9C;AAEA,QAAM,yBAAyB;AAAA,IAC7B;AAAA,IACA;AAAA,EACF;AACA,MAAI,wBAAwB;AAC1B,QAAI,QAAQ,QAAQ;AAClB,YAAM,YAAY;AAAA,QAChB,QAAQ;AAAA,QACR;AAAA,QACA,2BAA2B,OAAO;AAAA,MACpC;AACA,aAAO,YAAY,GAAG,IAAI,IAAI,SAAS,KAAK;AAAA,IAC9C;AACA,QAAI,uBAAuB,aAAa,MAAM;AAC5C,aAAO,IAAI,WAAW,OAAO,uBAAuB,SAAS,CAAC;AAC9D,aAAO,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,iBAAiB,6BAA6B,OAAO,QAAQ,MAAM;AACzE,MAAI,gBAAgB;AAClB,QAAI,QAAQ,QAAQ;AAClB,YAAM,YAAY;AAAA,QAChB,QAAQ;AAAA,QACR;AAAA,QACA,2BAA2B,OAAO;AAAA,MACpC;AACA,aAAO,YAAY,GAAG,IAAI,IAAI,SAAS,KAAK;AAAA,IAC9C;AACA,QAAI,eAAe,aAAa,MAAM;AACpC,aAAO,IAAI,WAAW,OAAO,eAAe,SAAS,CAAC;AACtD,aAAO,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC;AAAA,IACrC;AACA,QACE,gCAAgC,QAAQ,OAAO,gBAAgB,OAAO,GACtE;AACA,aAAO,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC;AAAA,IACrC;AAAA,EACF;AAEA,MAAI,OAAO,iBAAiB;AAC1B,UAAM,aACJ,MAAM,eACL,MAAM,YAAY,OACf,QAAQ,QAAQ,WAAW,IAAI,OAAO,MAAM,QAAQ,CAAC,GAAG,OACxD;AACN,QAAI,YAAY;AACd,aAAO,IAAI,OAAO,UAAU,IAAI,MAAM,eAAe;AAAA,IACvD;AAAA,EACF;AAEA,SAAO,OAAO,OAAO,IAAI,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC,KAAK;AAC5D;AAEA,SAAS,oBAAoB,GAAwB,GAAwB;AAC3E,QAAM,SAAS,OAAO,EAAE,UAAU,OAAO,gBAAgB;AACzD,QAAM,SAAS,OAAO,EAAE,UAAU,OAAO,gBAAgB;AAEzD,MAAI,OAAO,SAAS,MAAM,KAAK,OAAO,SAAS,MAAM,KAAK,WAAW,QAAQ;AAC3E,WAAO,SAAS;AAAA,EAClB;AAEA,QAAM,MAAM,OAAO,cAAc,EAAE,EAAE,KAAK,EAAE;AAC5C,QAAM,MAAM,OAAO,cAAc,EAAE,EAAE,KAAK,EAAE;AAC5C,SAAO,eAAe,KAAK,GAAG;AAChC;AAUO,SAAS,2BACd,SACS;AACT,MAAI,QAAQ,aAAa,MAAO,QAAO;AACvC,MAAI,OAAO,QAAQ,qBAAqB,WAAW;AACjD,WAAO,QAAQ;AAAA,EACjB;AACA,MAAI,QAAQ,YAAa,QAAO;AAEhC,MAAI,QAAQ,oBAAoB,WAAY,QAAO;AACnD,UAAQ,QAAQ,SAAS,MAAM,QAAQ,iBAAiB,KAAK;AAC/D;AAQO,SAAS,yBACd,SACe;AACf,MAAI,QAAQ,YAAa,QAAO;AAChC,SAAO,KAAK,IAAI,IAAI,QAAQ,SAAS,MAAM,QAAQ,iBAAiB,EAAE;AACxE;AAEA,SAAS,0BAA0B,SAA8B;AAC/D,SAAO,2BAA2B,OAAO;AAC3C;AAEA,SAAS,8BACP,UACuB;AACvB,QAAM,kBAAkB,CAAC,GAAG,QAAQ,EAAE,KAAK,mBAAmB;AAC9D,QAAM,iBAAiB,gBAAgB;AAAA,IACrC,CAAC,YAAY,QAAQ,aAAa;AAAA,EACpC;AACA,QAAM,oBAAoB,eAAe,OAAO,yBAAyB;AACzE,QAAM,4BAA4B,eAAe;AAAA,IAC/C,CAAC,YAAY,CAAC,0BAA0B,OAAO;AAAA,EACjD;AAEA,SAAO,CAAC,GAAG,mBAAmB,GAAG,yBAAyB;AAC5D;AAEA,SAAS,oBACP,SACA,kBACS;AACT,MAAI,CAAC,SAAS,QAAQ,OAAQ,QAAO;AACrC,SAAO,QAAQ,OAAO,KAAK,CAAC,UAAU;AACpC,UAAM,UAAU,cAAc,KAAK;AACnC,WAAO;AAAA,MACL,WACA,iBAAiB,KAAK,CAAC,aAAa,cAAc,QAAQ,MAAM,OAAO;AAAA,IACzE;AAAA,EACF,CAAC;AACH;AAEA,SAAS,UAAU,QAA0C;AAC3D,QAAM,UAAU,OAAO;AAAA,IACrB,CAAC,UAA2B,OAAO,UAAU;AAAA,EAC/C;AACA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,EAAE,KAAK,MAAM,KAAK,KAAK;AAAA,EAChC;AAEA,SAAO;AAAA,IACL,KAAK,KAAK,IAAI,GAAG,OAAO;AAAA,IACxB,KAAK,KAAK,IAAI,GAAG,OAAO;AAAA,EAC1B;AACF;AAEO,SAAS,mCACd,SACA,UAC+B;AAC/B,QAAM,kBAAkB,CAAC,GAAG,QAAQ,EAAE,KAAK,mBAAmB;AAC9D,QAAM,iBAAiB,gBAAgB;AAAA,IACrC,CAAC,YAAY,QAAQ,aAAa;AAAA,EACpC;AACA,QAAM,oBAAoB,eAAe,OAAO,yBAAyB;AACzE,QAAM,uBAAuB,kBAAkB,CAAC,KAAK,eAAe,CAAC,KAAK;AAE1E,QAAM,EAAE,KAAK,UAAU,KAAK,SAAS,IAAI;AAAA,IACvC,eAAe,IAAI,CAAC,YAAY,QAAQ,KAAK;AAAA,EAC/C;AACA,QAAM,EAAE,KAAK,mBAAmB,KAAK,kBAAkB,IAAI;AAAA,IACzD,eAAe,IAAI,CAAC,YAAY,QAAQ,cAAc;AAAA,EACxD;AAEA,QAAM,mBAAmB,SAAS,UAAU,CAAC;AAC7C,QAAM,4BAA4B;AAAA,IAChC;AAAA,IACA;AAAA,EACF;AACA,QAAM,yBAAyB,8BAA8B,QAAQ;AACrE,QAAM,uBAAuB,6BAAyC;AAAA,IACpE;AAAA,IACA,iBACE,wBAAwB,4BACpB;AAAA,MACE,IAAI,qBAAqB;AAAA,MACzB,QAAQ,qBAAqB;AAAA,IAC/B,IACA;AAAA,IACN,kBAAkB,4BAA4B,CAAC,IAAI;AAAA,EACrD,CAAC;AAED,SAAO;AAAA,IACL,sBAAsB,cAAc,sBAAsB,EAAE,KAAK;AAAA,IACjE,cAAc;AAAA,MACZ;AAAA,MACA,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cACE,aAAa,QAAQ,aAAa,OAAO,aAAa,WAAW;AAAA,IACnE,kBAAkB,kBAAkB,SAAS;AAAA,EAC/C;AACF;AAEO,SAAS,wBACd,MACA,UAAqC,CAAC,GAClB;AACpB,QAAM,UAAU,KAAK;AACrB,QAAM,SAAS,KAAK;AACpB,QAAM,WAAW,8BAA8B,IAAI;AACnD,QAAM,mBAAmB,mCAAmC,SAAS,QAAQ;AAC7E,QAAM,uBACJ,cAAc,QAAQ,+BAA+B,KACrD,iBAAiB;AACnB,QAAM,wBAAwB;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AAEA,QAAM,mBAAmBA,YAAW,QAAQ,MAAM;AAKlD,QAAM,kBAAkB,cAAc,QAAQ,aAAa;AAC3D,QAAM,wBAAwB,kBAC1B,iBAAiB,KAAK,CAACC,UAAS,cAAcA,KAAI,MAAM,eAAe,IACvE;AACJ,QAAM,sBACJ,yBACA,QAAQ,iBACR,iBAAiB,CAAC,KAClB;AAEF,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,mBACJ,QAAQ,oBAAoB,OACxB,QAAQ,mBACR,OAAO,SAAS,IACd,OAAO,KAAK,CAAC,UAAU,MAAM,QAAQ,gBAAgB,IACrD,iBAAiB;AAEzB,QAAM,WACJ,OAAO,SAAS,IACZ,OAAO,IAAI,CAAC,UAAU,mBAAmB,SAAS,OAAO,OAAO,CAAC,IACjE,CAAC;AAEP,SAAO;AAAA,IACL,IAAI,OAAO,QAAQ,EAAE;AAAA,IACrB,MAAM;AAAA,MACJ,EAAE,MAAM,QAAQ,KAAK;AAAA,MACrB,EAAE,SAAS,EAAE,qBAAqB,EAAE;AAAA,MACpC;AAAA,IACF;AAAA,IACA,OAAO,QAAQ,SAAS;AAAA,IACxB;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,8BACP,MAC2C;AAC3C,QAAM,kBAAkB,KAAK,QAAQ,UAAU;AAC/C,MAAI,MAAM,QAAQ,eAAe,KAAK,gBAAgB,SAAS,GAAG;AAChE,WAAO;AAAA,EACT;AAEA,QAAM,WAAsD,CAAC;AAC7D,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,SAAS,KAAK,QAAQ;AAC/B,eAAW,WAAW,MAAM,UAAU;AACpC,YAAM,KAAK,cAAc,QAAQ,EAAE;AACnC,UAAI,MAAM,KAAK,IAAI,EAAE,EAAG;AACxB,UAAI,GAAI,MAAK,IAAI,EAAE;AACnB,eAAS,KAAK,OAAO;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,qCACP,UACA,yBACgD;AAChD,MAAI,2BAA2B,KAAM,QAAO;AAC5C,SACE,SAAS;AAAA,IACP,CAAC,YAAY,cAAc,QAAQ,EAAE,MAAM;AAAA,EAC7C,KAAK;AAET;AAGO,SAAS,sBAAsB,SAMpC;AACA,SAAO;AAAA,IACL,iBAAiB,EAAE,QAAQ,QAAQ,YAAY,KAAK;AAAA,IACpD,iBAAiB,EAAE,QAAQ,QAAQ,YAAY,KAAK;AAAA,EACtD;AACF;AAEA,SAAS,6BACP,YAMA;AACA,SACE,YAAY,iBAAiB,UAAU,QACvC,YAAY,iBAAiB,UAAU;AAE3C;AAEA,SAAS,6BACP,SACA,kBACA,QAC8B;AAC9B,MAAI,6BAA6B,QAAQ,UAAU,GAAG;AACpD,UAAM,aACJ,OAAO,SAAS,IAAI,2BAA2B,MAAM,IAAI;AAC3D,UAAM,oBACJ,QAAQ,qBAAqB,iBAAiB,UAC9C,YAAY,qBACZ;AACF,UAAM,oBACJ,QAAQ,qBAAqB,iBAAiB,UAC9C,YAAY,qBACZ;AAEF,WAAO;AAAA,MACL,UAAU,QAAQ,WAAW,gBAAgB;AAAA,MAC7C,UAAU,QAAQ,WAAW,gBAAgB;AAAA,MAC7C;AAAA,MACA;AAAA,MACA,cACE,QAAQ,WAAW,gBACnB,QAAQ,WAAW,gBAAgB,WACjC,QAAQ,WAAW,gBAAgB;AAAA,IACzC;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO,2BAA2B,MAAM;AAAA,EAC1C;AAEA,SAAO;AAAA,IACL,UAAU,iBAAiB;AAAA,IAC3B,UAAU,iBAAiB;AAAA,IAC3B,mBAAmB,iBAAiB;AAAA,IACpC,mBAAmB,iBAAiB;AAAA,IACpC,cAAc,iBAAiB;AAAA,EACjC;AACF;AAEA,SAAS,2BACP,QAC8B;AAC9B,QAAM,WAAW,cAAc,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,QAAQ,CAAC;AACpE,QAAM,WAAW,cAAc,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,QAAQ,CAAC;AACpE,QAAM,oBAAoB;AAAA,IACxB,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,iBAAiB;AAAA,EAC/C;AACA,QAAM,oBAAoB;AAAA,IACxB,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,iBAAiB;AAAA,EAC/C;AACA,QAAM,eACJ,aAAa,QAAQ,aAAa,QAAQ,aAAa;AACzD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBACP,SACA,OACA,SACsB;AACtB,SAAO;AAAA,IACL,UAAU,MAAM;AAAA,IAChB,eAAe,MAAM;AAAA,IACrB,OAAO,MAAM;AAAA,IACb,QAAQ,MAAM,qBAAqB;AAAA,IACnC,MAAM;AAAA,MACJ,EAAE,MAAM,QAAQ,KAAK;AAAA,MACrB;AAAA,QACE,UAAU,MAAM;AAAA,QAChB,YAAY,MAAM;AAAA,QAClB,eAAe,MAAM;AAAA,QACrB,iBAAiB,MAAM;AAAA,QACvB,SAAS,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF;AAAA,IACA,kBAAkB,MAAM,QAAQ;AAAA,EAClC;AACF;AAEA,SAAS,cAAc,QAA6C;AAClE,QAAM,UAAU,OAAO,OAAO,CAAC,MAAmB,MAAM,IAAI;AAC5D,SAAO,QAAQ,WAAW,IAAI,OAAO,KAAK,IAAI,GAAG,OAAO;AAC1D;AAEA,SAAS,cAAc,QAA6C;AAClE,QAAM,UAAU,OAAO,OAAO,CAAC,MAAmB,MAAM,IAAI;AAC5D,SAAO,QAAQ,WAAW,IAAI,OAAO,KAAK,IAAI,GAAG,OAAO;AAC1D;AAoBO,IAAM,2BAA4C;AAAA,EACvD,OAAO;AAAA,IACL,UAAU,EAAE,OAAO,KAAK,MAAM,SAAS;AAAA,IACvC,SAAS,EAAE,OAAO,IAAI,MAAM,SAAS;AAAA,EACvC;AACF;AAaO,SAAS,6BAEd,SAA+C;AAC/C,QAAM,gBACJ,QAAQ,iBAAiB,OACrB,QAAQ,gBACR,QAAQ,QAAQ,KAAK,CAAC,UAAU,SAAS,IAAI;AAGnD,SAAO,EAAE,GAAG,SAAS,cAAc;AACrC;AASO,SAAS,kCAEd,MAKkC;AAClC,QAAM,kBAAkB,KAAK,mBAAmB;AAChD,MAAI,CAAC,gBAAiB,QAAO,CAAC;AAE9B,QAAM,SAAS,yBAAyB;AAAA,IACtC,SAAS,KAAK;AAAA,IACd,UAAU,KAAK;AAAA,EACjB,CAAC;AACD,QAAM,gBAAgB,OAAO,WAAW,IAAI,eAAe;AAC3D,MAAI,CAAC,cAAe,QAAO,CAAC;AAE5B,SAAO,cAAc,OAAO,QAAQ,CAAC,UAAU;AAC7C,UAAM,WAAW,OAAO,SACrB;AAAA,MACC,CAAC,YACC,QAAQ,sBAAsB,IAAI,cAAc,EAAE,MAAM,MAAM;AAAA,IAClE,EACC,IAAI,CAAC,YAAY,QAAQ,MAAM;AAElC,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,cAAc,mCAAmC,QAAW,QAAQ;AAC1E,UAAM,mBAAmB,sBAAsB,MAAM,MAAM;AAC3D,UAAM,gBACJ,kBAAkB,eAAe,OAC7B,OACA,OAAO,iBAAiB,WAAW;AACzC,UAAM,oBACJ,mBAAmB,KAAK,SAAS,aAAa,KAC9C;AAAA,MACE,KAAK;AAAA,MACL,qCAAqC,QAAQ;AAAA,IAC/C,KACA,gBAAgB,KAAK,SAAS,MAAM;AAEtC,WAAO;AAAA,MACL;AAAA,QACE,UAAU,cAAc;AAAA,QACxB,aAAa,cAAc;AAAA,QAC3B,YAAY,cAAc;AAAA,QAC1B,eAAe,MAAM;AAAA,QACrB,kBAAkB,MAAM;AAAA,QACxB,iBAAiB,MAAM;AAAA,QACvB,mBAAmB,MAAM,UAAU;AAAA,QACnC,YAAY,SAAS,IAAI,CAAC,YAAY,OAAO,QAAQ,EAAE,CAAC;AAAA,QACxD,cAAc,SAAS;AAAA,QACvB;AAAA,QACA,SAAS;AAAA,UACP,GAAG;AAAA,UACH,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AC5oEA,IAAM,qCAAqC,oBAAI,IAAY;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,6BACd,OACiC;AACjC,MAAI,EAAE,iBAAiB,aAAa,MAAM,WAAW,IAAK,QAAO;AAEjE,QAAM,SAAS,kBAAkB,KAAK;AACtC,MAAI,CAAC,UAAU,CAAC,mCAAmC,IAAI,MAAM;AAC3D,WAAO;AAET,SAAO,EAAE,OAAO,OAAO,OAAiD;AAC1E;AAGA,IAAM,yCACJ;AACF,IAAM,+BAA+B,oBAAI,IAAI;AAAA,EAC3C;AAAA,EACA;AACF,CAAC;AAED,SAAS,SAAS,QAAoD;AACpE,SAAO,QAAQ,SAAS,SAAS;AACnC;AAEA,SAAS,6BACP,QACqC;AACrC,QAAM,UAAqC,CAAC;AAC5C,QAAM,SAAS,OAAO,QAAQ,KAAK;AACnC,MAAI,QAAQ;AACV,YAAQ,KAAK;AAAA,MACX,IAAI;AAAA,QACF,EAAE,OAAO,EAAE,MAAM,OAAO,EAAE;AAAA,QAC1B,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE;AAAA,QACzB,EAAE,QAAQ,EAAE,MAAM,OAAO,EAAE;AAAA,MAC7B;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,OAAO;AACvB,QAAM,MAAM,SAAS,SAAS,GAAG;AACjC,MAAI,IAAK,SAAQ,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;AACzC,QAAM,QAAQ,SAAS,SAAS,KAAK;AACrC,MAAI,MAAO,SAAQ,KAAK,EAAE,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;AAC/C,QAAM,UAAU,SAAS,SAAS,OAAO;AACzC,MAAI,QAAS,SAAQ,KAAK,EAAE,QAAQ,EAAE,IAAI,QAAQ,EAAE,CAAC;AACrD,QAAM,cAAc,SAAS,SAAS,WAAW;AACjD,MAAI,YAAa,SAAQ,KAAK,EAAE,YAAY,EAAE,IAAI,YAAY,EAAE,CAAC;AACjE,QAAM,SAAS,SAAS,SAAS,MAAM;AACvC,MAAI,OAAQ,SAAQ,KAAK,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;AAEjD,QAAM,WAAW,SAAS,OAAO;AACjC,MAAI,YAAY,MAAM;AACpB,YAAQ,KAAK;AAAA,MACX,qCAAqC,EAAE,oBAAoB,SAAS;AAAA,IACtE,CAAC;AAAA,EACH;AACA,QAAM,WAAW,SAAS,OAAO;AACjC,MAAI,YAAY,MAAM;AACpB,YAAQ,KAAK;AAAA,MACX,qCAAqC,EAAE,iBAAiB,SAAS;AAAA,IACnE,CAAC;AAAA,EACH;AAEA,MAAI,SAAS,oBAAoB,MAAM;AACrC,YAAQ,KAAK;AAAA,MACX,kBAAkB,EAAE,QAAQ,QAAQ,iBAAiB;AAAA,IACvD,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC;AAC1C,SAAO,EAAE,KAAK,QAAQ;AACxB;AAEA,SAAS,oCACP,MACS;AACT,QAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO,OAAO,CAAC,IAAI,IAAI,CAAC;AAC7D,SAAO,OAAO;AAAA,IAAK,CAAC,UAClB,6BAA6B,IAAI,OAAO,KAAK,EAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,EAClE;AACF;AAEA,SAAS,sCACP,QACM;AACN,MAAI,CAAC,OAAO,QAAQ,KAAK,EAAG;AAC5B,QAAM,cAAc,OAAO,SAAS;AACpC,MACE,aAAa,OAAO,QACpB,aAAa,OAAO,QACpB,oCAAoC,OAAO,IAAI,GAC/C;AACA,UAAM,IAAI,UAAU,sCAAsC;AAAA,EAC5D;AACF;AAEO,SAAS,+BACd,QAMA;AACA,wCAAsC,MAAM;AAC5C,QAAM,UAAU;AAAA,IACd,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,IACf,gBAAgB,OAAO;AAAA,IACvB,MAAM,OAAO;AAAA,IACb,OAAO,OAAO;AAAA,IACd,MAAM,OAAO;AAAA,IACb,OAAO,6BAA6B,MAAM;AAAA,EAC5C;AAEA,SAAO;AAAA,IACL,WACE,OAAO,SAAS,SACZ,6BAA6B,SAAS,wBACtC,6BAA6B,SAAS;AAAA,IAC5C,OAAO,wBAAwB,OAAO;AAAA,EACxC;AACF;AAYO,SAAS,wBAGd,UACA,SACiC;AACjC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,SAAS,KAAK,IAAI,CAAC,SAAS,wBAAwB,MAAM,OAAO,CAAC;AAAA,EAC3E;AACF;AAkGO,IAAM,sCAAsC;AAC5C,IAAM,uCACX;AAiBK,SAAS,wCACd,OACgD;AAChD,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,OAAO;AACb,QAAM,SAAS,KAAK;AACpB,SACE,OAAO,KAAK,UAAU,YACtB,OAAO,KAAK,UAAU,aACrB,WAAW,uCACV,WAAW;AAEjB;;;AC3tBA,IAAM,qBAAN,cAAiC,kBAAkB;AAAA,EACjD,gBACE,UACA,MACA,SAIY;AACZ,WAAO,MAAM,gBAAmB,UAAU,MAAM,OAAO;AAAA,EACzD;AACF;AAYO,IAAM,iBAAN,MAAqB;AAAA,EA+F1B,YAAY,SAAgC;AAC1C,SAAK,SAAS,QAAQ;AAEtB,UAAM,UAAU,IAAI,QAAQ;AAAA,MAC1B,gBAAgB,QAAQ;AAAA,MACxB,QAAQ,QAAQ;AAAA,MAChB,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ;AAAA,MACxB,aAAa,QAAQ;AAAA,IACvB,CAAC;AACD,UAAM,cAAc,IAAI,YAAY;AAAA,MAClC,gBAAgB,QAAQ;AAAA,MACxB,QAAQ,QAAQ;AAAA,MAChB,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ;AAAA,MACxB,aAAa,QAAQ;AAAA,IACvB,CAAC;AACD,UAAM,oBAAoB,IAAI,kBAAkB;AAAA,MAC9C,gBAAgB,QAAQ;AAAA,MACxB,QAAQ,QAAQ;AAAA,MAChB,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ;AAAA,MACxB,aAAa,QAAQ;AAAA,IACvB,CAAC;AACD,UAAM,MAAM,IAAI,mBAAmB,kBAAkB;AAAA,MACnD,gBAAgB,QAAQ;AAAA,MACxB,QAAQ,QAAQ;AAAA,MAChB,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ;AAAA,MACxB,aAAa,QAAQ;AAAA,IACvB,CAAC;AAED,SAAK,UAAU;AAAA,MACb,YAAY,CAAC,WACX,IAAI;AAAA,QACF,6BAA6B,SAAS;AAAA,QACtC;AAAA,MACF;AAAA,MACF,eAAe,CAAC,WACd,IAAI;AAAA,QACF,6BAA6B,SAAS;AAAA,QACtC;AAAA,QACA,EAAE,OAAO,0BAA0B,MAAM,EAAE;AAAA,MAC7C;AAAA,MACF,eAAe,CAAC,WACd,IAAI;AAAA,QACF,6BAA6B,SAAS;AAAA,QACtC;AAAA,QACA,EAAE,OAAO,0BAA0B,KAAK,WAAW,MAAM,CAAC,EAAE;AAAA,MAC9D;AAAA,MACF,sBAAsB,CAAC,WACrB,IAAI;AAAA,QACF,6BAA6B,SAAS;AAAA,QACtC;AAAA,QACA,EAAE,OAAO,0BAA0B,KAAK,WAAW,MAAM,CAAC,EAAE;AAAA,MAC9D;AAAA,MACF,aAAa,OAAO,SAAS,CAAC,MAAM;AAClC,cAAM,gBAAiD;AAAA,UACrD,GAAG;AAAA,UACH,MAAM;AAAA,QACR;AACA,cAAM,UAAU;AAAA,UACd,KAAK,WAAW,aAAa;AAAA,QAC/B;AACA,cAAM,WAAW,MAAM,IAAI,gBAEzB,QAAQ,WAAW,QAAW,EAAE,OAAO,QAAQ,MAAM,CAAC;AACxD,eAAO,wBAAwB,UAAU,KAAK,WAAW,aAAa,CAAC;AAAA,MACzE;AAAA,MACA,QAAQ,OAAO,WAAW;AACxB,YAAI;AACF,gBAAM,UAAU,MAAM,IAAI;AAAA,YACxB,6BAA6B,SAAS;AAAA,YACtC;AAAA,YACA,EAAE,OAAO,0BAA0B,KAAK,WAAW,MAAM,CAAC,EAAE;AAAA,UAC9D;AACA,iBAAO,EAAE,OAAO,MAAM,QAAQ;AAAA,QAChC,SAAS,KAAK;AACZ,gBAAM,iBAAiB,6BAA6B,GAAG;AACvD,cAAI,eAAgB,QAAO;AAC3B,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,eAAe,OAAO,WAAW;AAC/B,YAAI;AACF,gBAAM,UAAU,MAAM,IAAI;AAAA,YACxB,6BAA6B,SAAS;AAAA,YACtC;AAAA,YACA,EAAE,OAAO,0BAA0B,KAAK,WAAW,MAAM,CAAC,EAAE;AAAA,UAC9D;AACA,iBAAO,EAAE,OAAO,MAAM,QAAQ;AAAA,QAChC,SAAS,KAAK;AACZ,gBAAM,iBAAiB,6BAA6B,GAAG;AACvD,cAAI,gBAAgB,UAAU,MAAO,QAAO;AAC5C,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,QAAQ;AAAA,MACX,QAAQ,CAAC,WAAW,QAAQ,OAAO,KAAK,WAAW,UAAU,CAAC,CAAC,CAAC;AAAA,MAChE,UAAU,QAAQ,SAAS,KAAK,OAAO;AAAA,MACvC,SAAS,QAAQ,QAAQ,KAAK,OAAO;AAAA,MACrC,YAAY,QAAQ,WAAW,KAAK,OAAO;AAAA,MAC3C,YAAY,QAAQ,WAAW,KAAK,OAAO;AAAA,MAC3C,qBAAqB,QAAQ,oBAAoB,KAAK,OAAO;AAAA,MAC7D,kBAAkB,QAAQ,iBAAiB,KAAK,OAAO;AAAA,MACvD,OAAO,QAAQ,MAAM,KAAK,OAAO;AAAA,MACjC,OAAO,QAAQ,MAAM,KAAK,OAAO;AAAA,MACjC,MAAM,QAAQ,KAAK,KAAK,OAAO;AAAA,IACjC;AAEA,SAAK,SAAS;AAAA,MACZ,UAAU,CAAC,WAAW,QAAQ,aAAa,YAAY,MAAM;AAAA,IAC/D;AAEA,SAAK,YAAY;AAAA,MACf,QAAQ,YAAY,OAAO,KAAK,WAAW;AAAA,MAC3C,UAAU,YAAY,SAAS,KAAK,WAAW;AAAA,IACjD;AAEA,SAAK,kBAAkB;AAAA,MACrB,QAAQ,kBAAkB,OAAO,KAAK,iBAAiB;AAAA,MACvD,eAAe,kBAAkB,cAAc,KAAK,iBAAiB;AAAA,MACrE,UAAU,CAAC,WAAW,kBAAkB,SAAS,MAAM;AAAA,MACvD,iBAAiB,CAAC,WAAW,kBAAkB,gBAAgB,MAAM;AAAA,MACrE,QAAQ,CAAC,WAAW,kBAAkB,OAAO,MAAM;AAAA,MACnD,eAAe,CAAC,WAAW,kBAAkB,cAAc,MAAM;AAAA,IACnE;AAEA,SAAK,YAAY;AAAA,MACf,UAAU,CAAC,WACT,IAAI;AAAA,QACF,6BAA6B,UAAU;AAAA,QACvC;AAAA,MACF;AAAA,IACJ;AAEA,SAAK,WAAW;AAAA,MACd,WAAW,CAAC,WACV,IAAI;AAAA,QACF,6BAA6B,iBAAiB;AAAA,QAC9C;AAAA,MACF;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,mBAAuC;AACrC,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,WAA0C,QAAc;AAC9D,UAAM,gBAAgB,KAAK,QAAQ,KAAK;AACxC,QAAI,CAAC,iBAAiB,OAAO,QAAQ,KAAK,EAAG,QAAO;AACpD,WAAO,EAAE,GAAG,QAAQ,QAAQ,cAAc;AAAA,EAC5C;AACF;;;AC5GO,IAAM,eAAN,MAAmB;AAAA,EAOxB,YAAY,SAA8B;AACxC,UAAM,YAAa,QAAmC;AACtD,SAAK,iBAAiB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACF;AACA,SAAK,SAAS,QAAQ;AACtB,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,cAAc,QAAQ;AAAA,EAC7B;AAAA,EAEA,SAAS,QAAyD;AAChE,WAAO,KAAK;AAAA,MACV,mBAAmB,MAAM;AAAA,MACzB,uBAAuB,2BAA2B,YAAY,KAAK;AAAA,MACnE;AAAA,MACA,EAAE,iBAAiB,MAAM;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,yBACE,QAC6C;AAC7C,WAAO,KAAK;AAAA,MACV,mCAAmC,MAAM;AAAA,MACzC;AAAA,QACE,2BAA2B,YAAY;AAAA,MACzC;AAAA,MACA;AAAA,MACA,EAAE,iBAAiB,MAAM;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,oBACE,SAAqC,CAAC,GACC;AACvC,UAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAI,OAAO,SAAS,OAAW,OAAM,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC;AACpE,QAAI,OAAO,UAAU,OAAW,OAAM,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AACvE,UAAMC,aAAY,2BAA2B,cAAc;AAC3D,WAAO,KAAK;AAAA,MACV,qBAAqBA,YAAW,EAAE,MAAM,CAAC;AAAA,MACzC,uBAAuBA,UAAS;AAAA,MAChC;AAAA,MACA,EAAE,iBAAiB,MAAM,SAAS,KAAK;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,SACE,QAC4C;AAC5C,WAAO,KAAK;AAAA,MACV,qBAAqB,2BAA2B,cAAc,QAAQ;AAAA,MACtE,uBAAuB,2BAA2B,cAAc,QAAQ;AAAA,MACxE,6BAA6B,MAAM;AAAA,MACnC,EAAE,iBAAiB,KAAK;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,qBAAqB,OAAwD;AAC3E,WAAO,KAAK;AAAA,MACV;AAAA,QACE,2BAA2B,cAAc;AAAA,MAC3C;AAAA,MACA;AAAA,QACE,2BAA2B,cAAc;AAAA,MAC3C;AAAA,MACA,EAAE,MAAM;AAAA,MACR,EAAE,iBAAiB,MAAM;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,wBACE,OACA,SAAiC,CAAC,GACO;AACzC,WAAO,KAAK;AAAA,MACV;AAAA,QACE,2BAA2B,cAAc;AAAA,MAC3C;AAAA,MACA;AAAA,QACE,2BAA2B,cAAc;AAAA,MAC3C;AAAA,MACA,4BAA4B,OAAO,MAAM;AAAA,MACzC,EAAE,iBAAiB,MAAM;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,MAAc,QACZ,UACA,QACA,MACA,UAA4D,CAAC,GACjD;AACZ,UAAM,kBAAkB,QAAQ,oBAAoB;AACpD,UAAM,QAAQ,kBACV,OAAO,KAAK,kBAAkB,aAC5B,KAAK,cAAc,IACnB,KAAK,gBACP;AAEJ,QAAI;AACF,YAAM,WAAW,MAAM,UAAU,UAAU;AAAA,QACzC;AAAA,QACA,GAAI,QAAQ,WAAW,EAAE,OAAO,WAAoB;AAAA,QACpD,QAAQ,KAAK;AAAA,QACb,gBAAgB,KAAK;AAAA,QACrB,GAAI,mBAAmB,QAAQ,EAAE,eAAe,MAAM,IAAI,CAAC;AAAA,QAC3D,GAAI,mBACF,SACA,KAAK,kBAAkB,EAAE,gBAAgB,KAAK,eAAe;AAAA,QAC/D,GAAI,SAAS,UAAa,EAAE,MAAM,KAAK,UAAU,IAAI,EAAE;AAAA,MACzD,CAAC;AAED,WAAK,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK,IAAI;AAC/D,aAAO,iBAAoB,UAAU,QAAQ;AAAA,IAC/C,SAAS,KAAK;AACZ,YAAM,KAAK,eAAe,WAAY,IAAI,aAAa,OAAQ;AAC/D,WAAK,cAAc,EAAE;AACrB,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,6BACP,QACiC;AACjC,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,YAAY,OAAO;AAAA,IACnB,GAAI,OAAO,aAAa,UAAa,EAAE,UAAU,OAAO,SAAS;AAAA,IACjE,GAAI,OAAO,aAAa,UAAa,EAAE,UAAU,OAAO,SAAS;AAAA,IACjE,GAAI,OAAO,YAAY,UAAa,EAAE,SAAS,OAAO,QAAQ;AAAA,EAChE;AACF;AAEA,SAAS,4BACP,OACA,QACoC;AACpC,SAAO;AAAA,IACL;AAAA,IACA,GAAI,OAAO,WAAW,UAAa,EAAE,QAAQ,OAAO,OAAO;AAAA,EAC7D;AACF;AAEA,SAAS,mBAAmB,QAAmC;AAC7D,QAAM,YAAY,IAAI,gBAAgB;AACtC,MAAI,OAAO,UAAU,QAAW;AAC9B,cAAU,IAAI,SAAS,gBAAgB,OAAO,KAAK,CAAC;AAAA,EACtD;AACA,MAAI,OAAO,QAAQ,QAAW;AAC5B,cAAU,IAAI,OAAO,gBAAgB,OAAO,GAAG,CAAC;AAAA,EAClD;AACA,MAAI,OAAO,UAAU,OAAW,WAAU,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAC3E,MAAI,OAAO,SAAS,OAAW,WAAU,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC;AACxE,eAAa,WAAW,YAAY,OAAO,QAAQ;AACnD,eAAa,WAAW,gBAAgB,OAAO,YAAY;AAC3D,eAAa,WAAW,YAAY,OAAO,QAAQ;AACnD,eAAa,WAAW,gBAAgB,OAAO,YAAY;AAC3D,eAAa,WAAW,OAAO,OAAO,GAAG;AACzC,eAAa,WAAW,WAAW,OAAO,OAAO;AACjD,SAAO,qBAAqB,2BAA2B,YAAY,OAAO;AAAA,IACxE,OAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,mCACP,QACQ;AACR,QAAM,YAAY,IAAI,gBAAgB;AACtC,YAAU,IAAI,cAAc,OAAO,UAAU;AAC7C,QAAMC,oBAAmB,OAAO,QAAQ,KAAK;AAC7C,MAAIA,kBAAkB,WAAU,IAAI,UAAUA,iBAAgB;AAC9D,SAAO;AAAA,IACL,2BAA2B,YAAY;AAAA,IACvC,EAAE,OAAO,UAAU;AAAA,EACrB;AACF;AAEA,SAAS,gBAAgB,OAAgC;AACvD,SAAO,iBAAiB,OAAO,MAAM,YAAY,IAAI;AACvD;AAEA,SAAS,aACP,QACA,KACA,OACM;AACN,MAAI,UAAU,OAAW;AACzB,QAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AACpD,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAO,QAAO,OAAO,KAAK,KAAK;AAAA,EACrC;AACF;;;ACzZO,SAAS,YAAY,KAA8B;AACxD,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,QAAQ,IAAI;AAAA,IACZ,MAAM,IAAI;AAAA,IACV,aAAa,IAAI;AAAA,IACjB,kBAAkB,IAAI,mBAAmB,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW;AAAA,IACrE,UAAU,IAAI;AAAA,IACd,WAAW,IAAI,cAAc;AAAA,IAC7B,UAAU,IAAI,aAAa;AAAA,EAC7B;AACF;AAUO,IAAM,kBAAN,MAAuD;AAAA,EAC5D,YAA6B,MAAuB;AAAvB;AAAA,EAAwB;AAAA,EAErD,MAAM,OAA6B;AACjC,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,OAAO,EAAE,UAAU,EAAE,QAAQ,KAAK,EAAE;AAAA,MACpC,OAAO;AAAA,IACT,CAAC;AACD,QAAI,IAAI,aAAa;AACnB,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AACA,WAAO,IAAI,KAAK,IAAI,WAAW;AAAA,EACjC;AAAA,EAEA,MAAM,UAAqC;AACzC,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,OAAO,EAAE,WAAW,EAAE,QAAQ,KAAK,GAAG,UAAU,EAAE,QAAQ,KAAK,EAAE;AAAA,MACjE,OAAO;AAAA,IACT,CAAC;AACD,UAAM,MAAM,IAAI,KAAK,CAAC;AACtB,WAAO,MAAM,YAAY,GAAG,IAAI;AAAA,EAClC;AACF;;;AC3DA,IAAM,uBAAN,cAAmC,kBAAkB;AAAA,EACnD,KAA6C;AAC3C,WAAO,KAAK;AAAA,MACV,+BAA+B;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,OAAO,QAAmE;AACxE,UAAM,EAAE,IAAI,UAAU,IAAI;AAC1B,WAAO,KAAK;AAAA,MACV,+BAA+B;AAAA,MAC/B,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MAC3C,EAAE,YAAY,EAAE,GAAG,EAAE;AAAA,IACvB;AAAA,EACF;AACF;AAEA,IAAqB,SAArB,MAAqB,QAAO;AAAA,EAsB1B,YAAY,SAAuB;AALnC,yBAA+B;AAM7B,UAAM,iBAAiB,QAAQ;AAC/B,QAAI,CAAC,gBAAgB;AACnB,YAAM,kBAAkB,6BAA6B;AAAA,IACvD;AAEA,SAAK,SAAS,EAAE,GAAG,SAAS,eAAe;AAE3C,UAAM,WAA2B;AAAA,MAC/B,WAAW,KAAK,IAAI;AAAA,MACpB,WACE,OAAO,WAAW,cAAc,OAAO,WAAW,YAAY;AAAA,IAClE;AAEA,SAAK,QAAQ,EAAE,SAAS;AAExB,SAAK,WAAW,IAAI;AAAA,MAClB,KAAK,OAAO;AAAA,MACZ,QAAQ;AAAA,MACR,KAAK,OAAO;AAAA,IACd;AAEA,UAAM,iBAAiB,YAAoC;AACzD,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,SAAS,KAAK,aAAa;AACrD,eAAO,OAAO,SAAS;AAAA,MACzB,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,cAAc,CAAC,OAAsB;AACzC,WAAK,gBAAgB;AAAA,IACvB;AAEA,SAAK,WAAW,IAAI,eAAe;AAAA,MACjC,gBAAgB,KAAK,OAAO;AAAA,MAC5B,QAAQ,KAAK,OAAO;AAAA,MACpB,QAAQ,KAAK,OAAO;AAAA,MACpB,eAAe,MAAM,KAAK,SAAS,KAAK,SAAS;AAAA,MACjD;AAAA,MACA;AAAA,MACA,cAAc,KAAK,SAAS;AAAA,IAC9B,CAAC;AAED,SAAK,YAAY,IAAI,gBAAgB;AAAA,MACnC,gBAAgB,KAAK,OAAO;AAAA,MAC5B,QAAQ,KAAK,OAAO;AAAA,MACpB,eAAe,MAAM,KAAK,SAAS,KAAK,SAAS;AAAA,MACjD;AAAA,MACA;AAAA,IACF,CAAC;AAED,SAAK,UAAU,IAAI,cAAc;AAAA,MAC/B,gBAAgB,KAAK,OAAO;AAAA,MAC5B,QAAQ,KAAK,OAAO;AAAA,MACpB;AAAA,IACF,CAAC;AAED,SAAK,SAAS,IAAI,aAAa;AAAA,MAC7B,gBAAgB,KAAK,OAAO;AAAA,MAC5B,QAAQ,KAAK,OAAO;AAAA,MACpB,eAAe,MAAM,KAAK,SAAS,KAAK,SAAS;AAAA,MACjD;AAAA,MACA;AAAA,IACF,CAAC;AAED,SAAK,cAAc,IAAI;AAAA,MACrB,KAAK,OAAO;AAAA,MACZ;AAAA,MACA,MAAM,KAAK,SAAS,KAAK,SAAS;AAAA,MAClC;AAAA,MACA;AAAA,MACA,KAAK,OAAO;AAAA,IACd;AAEA,SAAK,UAAU,IAAI;AAAA,MAAgB,CAACC,aAClC,KAAK,YAAY,KAAK,SAAS,EAAE,KAAKA,QAAO;AAAA,IAC/C;AAEA,SAAK,UAAU,IAAI,mBAAmB,sBAAsB;AAAA,MAC1D,gBAAgB,KAAK,OAAO;AAAA,MAC5B,QAAQ,KAAK,OAAO;AAAA,MACpB,eAAe,MAAM,KAAK,SAAS,KAAK,SAAS;AAAA,MACjD;AAAA,MACA;AAAA,IACF,CAAC;AAED,SAAK,kBAAkB,IAAI;AAAA,MACzB;AAAA,MACA;AAAA,QACE,gBAAgB,KAAK,OAAO;AAAA,QAC5B,QAAQ,KAAK,OAAO;AAAA,QACpB,eAAe,MAAM,KAAK,SAAS,KAAK,SAAS;AAAA,QACjD;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgB,IAAI,qBAAqB,iBAAiB;AAAA,MAC9D,gBAAgB,KAAK,OAAO;AAAA,MAC5B,QAAQ,KAAK,OAAO;AAAA,MACpB,eAAe,MAAM,KAAK,SAAS,KAAK,SAAS;AAAA,MACjD;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,cAAc;AAAA,MACjB,IAAI,cAAc,GAAG,KAAK,aAAa;AAAA,MACvC,QAAQ,cAAc,OAAO,KAAK,aAAa;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,WAAwB;AACtB,WAAO,EAAE,GAAG,KAAK,MAAM;AAAA,EACzB;AAAA,EAEA,WAAW,QAAwB;AACjC,WAAO,IAAI,QAAO;AAAA,MAChB,GAAG,KAAK;AAAA,MACR,UACE,KAAK,OAAO,UAAU,YAAY,QAC9B;AAAA,QACE,GAAG,KAAK,OAAO;AAAA,QACf,OAAO,KAAK,SAAS,KAAK,SAAS,KAAK;AAAA,QACxC,cAAc,KAAK,SAAS,KAAK,gBAAgB,KAAK;AAAA,MACxD,IACA,KAAK,OAAO;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,YAA0B;AACxB,WAAO,EAAE,GAAG,KAAK,OAAO;AAAA,EAC1B;AACF;AAOO,SAAS,aAAa,SAA+B;AAC1D,SAAO,IAAI,OAAO,OAAO;AAC3B;;;AC/LO,SAAS,4BACd,SACA,UAC2B;AAC3B,QAAM,sBAAsB,IAAI;AAAA,IAC9B,SAAS,UAAU,IAAI,CAAC,SAAS,CAAC,KAAK,WAAW,IAAI,CAAC;AAAA,EACzD;AAEA,MAAI,uBAAuB;AAC3B,QAAM,WAAmC,QAAQ,SAAS,IAAI,CAAC,YAAY;AACzE,UAAM,OAAO,oBAAoB,IAAI,OAAO,QAAQ,EAAE,CAAC;AACvD,QAAI,CAAC,MAAM;AACT,8BAAwB;AACxB,aAAO,EAAE,GAAG,SAAS,OAAO,GAAG,eAAe,EAAE;AAAA,IAClD;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,KAAK,cAAc,IAAI,KAAK;AAAA,MACnC,eAAe;AAAA,IACjB;AAAA,EACF,CAAC;AAED,QAAM,kBAAkB,SAAS,OAAO,CAAC,YAAY,CAAC,QAAQ,WAAW;AACzE,QAAM,iBACJ,gBAAgB,WAAW,IACvB,OACA,gBAAgB;AAAA,IACd,CAAC,KAAK,YACJ,MAAM,KAAK,IAAI,IAAI,QAAQ,SAAS,MAAM,QAAQ,iBAAiB,EAAE;AAAA,IACvE;AAAA,EACF;AAEN,QAAM,mBAAmB,SAAS,UAAU;AAAA,IAC1C,CAAC,SAAS,KAAK,WAAW,eAAe,KAAK;AAAA,EAChD;AACA,QAAM,oBACJ,OAAO,QAAQ,oCAAoC,YACnD,QAAQ,oCAAoC,OACxC,OAAO,QAAQ,gCAAgC,EAAE,IACjD,QAAQ,mCAAmC,OACzC,OAAO,QAAQ,+BAA+B,IAC9C;AACR,QAAM,kCACJ,qBAAqB,OAChB,SAAS,KAAK,CAAC,YAAY,OAAO,QAAQ,EAAE,MAAM,iBAAiB,KACpE,oBACA;AAEN,SAAO;AAAA,IACL,kBAAkB,yBAAyB,IAAI,aAAa;AAAA,IAC5D,SAAS;AAAA,MACP,GAAG;AAAA,MACH,SAAS,EAAE,GAAG,QAAQ,SAAS,eAAe;AAAA,MAC9C;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;ACzEO,SAAS,wBAAwB,MAAwB;AAC9D,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,QAAM,QAAQ;AACd,SACE,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,cAAc,YAC3B,MAAM,UAAU,SAAS,KACzB,OAAO,MAAM,SAAS,YACtB,MAAM,SAAS;AAEnB;;;ACOA,eAAe,gBACb,SACA,QACA,WACAC,YACA,YACkB;AAClB,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,eAAe,QAAQ,OAAO,GAAGA,UAAS,IAAI,UAAU,GAAG;AACjE,QAAM,gBAAgB,IAAI,WAAW,aAAa,SAAS,QAAQ,MAAM;AACzE,gBAAc,IAAI,YAAY;AAC9B,gBAAc,IAAI,SAAS,aAAa,MAAM;AAC9C,QAAM,MAAM,MAAM,OAAO,OAAO;AAAA,IAC9B;AAAA,IACA,QAAQ,OAAO,MAAM;AAAA,IACrB,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,IAChC;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AACA,MAAI,UAAU,SAAS,MAAM,KAAK,CAAC,iBAAiB,KAAK,SAAS,GAAG;AACnE,WAAO;AAAA,EACT;AACA,QAAM,WAAW,IAAI;AAAA,KAClB,UAAU,MAAM,OAAO,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,SAAS,MAAM,EAAE,CAAC;AAAA,EACnE;AACA,SAAO,OAAO,OAAO,OAAO,QAAQ,KAAK,UAAU,aAAa;AAClE;AAEA,SAAS,iBACPA,YACA,kBACS;AACT,MAAI,CAAC,QAAQ,KAAKA,UAAS,EAAG,QAAO;AACrC,QAAM,cAAc,OAAOA,UAAS;AACpC,MAAI,CAAC,OAAO,SAAS,WAAW,EAAG,QAAO;AAC1C,QAAM,SAAS,KAAK,IAAI,KAAK,IAAI,IAAI,WAAW;AAChD,SAAO,UAAU,mBAAmB;AACtC;AASA,IAAM,wBAAwB;AAO9B,SAAS,iBACP,kBAC4B;AAC5B,SACE,OAAO,qBAAqB,YAC5B,OAAO,SAAS,gBAAgB,KAChC,oBAAoB,KACpB,oBAAoB;AAExB;AAEA,eAAe,sBAIb,SACA,SACA,QACmB;AACnB,MAAI;AACF,UAAM,UAAU,IAAI,WAAW,MAAM,QAAQ,YAAY,CAAC;AAC1D,UAAM,sBAAsB,MAAM,SAAS,OAAO;AAClD,QAAI,oBAAqB,QAAO;AAEhC,UAAM,OAAO,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,OAAO,CAAC;AACzD,QAAI,CAAC,wBAAwB,IAAI,GAAG;AAClC,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,OAAO,+BAA+B,CAAC;AAAA,QACxD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF;AAEA,UAAM,QAAQ,IAA8B;AAC5C,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,SAAS,MAAM,SAAS,oBAAoB,CAAC;AAAA,MAC9D,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,6BAA6B,KAAK;AAChD,WAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,wBAAwB,CAAC,GAAG;AAAA,MACtE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAChD,CAAC;AAAA,EACH;AACF;AAEA,eAAsB,oBAIpB,SACA,SACA,SACmB;AAInB,QAAM,SAAkB,SAAS;AACjC,QAAM,sBAA+B,SAAS;AAG9C,QAAM,mBAAmB,uBAAuB;AAEhD,MAAI,OAAO,WAAW,YAAY,OAAO,KAAK,EAAE,WAAW,GAAG;AAC5D,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,2CAA2C,CAAC;AAAA,MACpE,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAGA,MAAI,CAAC,iBAAiB,gBAAgB,GAAG;AACvC,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,2CAA2C,CAAC;AAAA,MACpE,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,SAAO,sBAAsB,SAAS,SAAS,OAAO,YAAY;AAChE,UAAM,YAAY,QAAQ,QAAQ,IAAI,qBAAqB,KAAK;AAChE,UAAMA,aAAY,QAAQ,QAAQ,IAAI,qBAAqB,KAAK;AAChE,UAAM,aAAa,QAAQ,QAAQ,IAAI,uBAAuB,KAAK;AACnE,UAAM,QACJ,QAAQA,cAAa,UAAU,KAC/B,iBAAiBA,YAAW,gBAAgB,KAC3C,MAAM,gBAAgB,SAAS,QAAQ,WAAWA,YAAW,UAAU;AAE1E,QAAI,CAAC,OAAO;AACV,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,OAAO,4BAA4B,CAAC;AAAA,QACrD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACrJO,IAAM,2BAA2B;AAGjC,IAAM,mCAAmC;AAkEzC,SAAS,oBAAoB,MAAqC;AACvE,SAAO,wBAAwB,IAAI;AACrC;AAYO,IAAM,kCAAkC;AAExC,IAAM,+BAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAyMA,SAAS,iBAAiB,OAA0C;AAClE,SAAO,OAAO,UAAU,YAAY,OAAO,UAAU;AACvD;AAEA,SAAS,oBAAoB,OAA4C;AACvE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,MAAI,MAAM,SAAS,cAAc;AAC/B,WAAO,OAAO,MAAM,eAAe;AAAA,EACrC;AAEA,MAAI,MAAM,SAAS,QAAQ;AACzB,WACE,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,UAAU,YACvB,iBAAiB,MAAM,EAAE;AAAA,EAE7B;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAA4C;AACvE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,SACE,OAAO,MAAM,eAAe,YAC5B,iBAAiB,MAAM,EAAE,MACxB,MAAM,sBAAsB,UAC3B,OAAO,MAAM,sBAAsB,cACpC,MAAM,cAAc,UAAa,iBAAiB,MAAM,SAAS;AAEtE;AAEA,SAAS,sBACP,OACA,KACS;AACT,SACE,MAAM,GAAG,MAAM,UACf,MAAM,GAAG,MAAM,QACf,OAAO,MAAM,GAAG,MAAM;AAE1B;AAEA,SAAS,qBAAqB,OAA6C;AACzE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,SACE,MAAM,SAAS,WACf,MAAM,WAAW,wBAChB,MAAM,uBAAuB,UAC5B,OAAO,MAAM,uBAAuB,aACtC,sBAAsB,OAAO,eAAe,KAC5C,sBAAsB,OAAO,WAAW,KACxC,oBAAoB,MAAM,KAAK,KAC/B,oBAAoB,MAAM,KAAK;AAEnC;AAEA,SAAS,gCACP,OACwC;AACxC,SACE,OAAO,UAAU,YAChB,6BAAmD,SAAS,KAAK;AAEtE;AAEA,SAAS,uCACP,OAC+C;AAC/C,SACE,UAAU,YACV,UAAU,kBACV,UAAU,aACV,UAAU,sBACV,UAAU,6BACV,UAAU;AAEd;AAEA,SAAS,2BACP,OACmC;AACnC,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,MACE,MAAM,WAAW,WAChB,CAAC,SAAS,MAAM,MAAM,KACrB,CAAC,uCAAuC,MAAM,OAAO,UAAU,KAC/D,CAAC,iBAAiB,MAAM,OAAO,EAAE,IACnC;AACA,WAAO;AAAA,EACT;AAEA,UACG,MAAM,YAAY,UAAa,iBAAiB,MAAM,OAAO,OAC7D,MAAM,gBAAgB,UACrB,OAAO,MAAM,gBAAgB,cAC9B,MAAM,WAAW,UAAa,OAAO,MAAM,WAAW,cACtD,MAAM,gBAAgB,UACrB,OAAO,MAAM,gBAAgB,cAC9B,MAAM,aAAa,UAAa,OAAO,MAAM,aAAa,cAC1D,MAAM,kBAAkB,UACvB,iBAAiB,MAAM,aAAa,OACrC,MAAM,sBAAsB,UAC3B,OAAO,MAAM,sBAAsB,cACpC,MAAM,cAAc,UAAa,OAAO,MAAM,cAAc,cAC5D,MAAM,aAAa,UAAa,iBAAiB,MAAM,QAAQ,OAC/D,MAAM,iBAAiB,UACtB,OAAO,MAAM,iBAAiB,cAC/B,MAAM,iBAAiB,UACtB,OAAO,MAAM,iBAAiB,cAC/B,MAAM,gBAAgB,UACrB,OAAO,MAAM,gBAAgB,cAC9B,MAAM,qBAAqB,UAC1B,OAAO,MAAM,qBAAqB,cACnC,MAAM,eAAe,UAAa,OAAO,MAAM,eAAe,cAC9D,MAAM,oBAAoB,UACzB,OAAO,MAAM,oBAAoB,cAClC,MAAM,WAAW,UAAa,OAAO,MAAM,WAAW,cACtD,MAAM,eAAe,UAAa,OAAO,MAAM,eAAe,cAC9D,MAAM,mBAAmB,UACvB,SAAS,MAAM,cAAc,KAC5B,OAAO,MAAM,eAAe,aAAa,aACxC,MAAM,eAAe,SAAS,aAC7B,MAAM,eAAe,SAAS,aAChC,OAAO,MAAM,eAAe,OAAO,cACtC,MAAM,UAAU,UACd,SAAS,MAAM,KAAK,KACnB,OAAO,cAAc,MAAM,MAAM,WAAW,KAC5C,OAAO,MAAM,MAAM,WAAW,IAAI,KAClC,OAAO,MAAM,MAAM,aAAa;AAExC;AAEA,SAAS,uBAAuB,OAA+C;AAC7E,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,SACE,gCAAgC,MAAM,KAAK,KAC3C,OAAO,MAAM,aAAa,YAC1B,MAAM,SAAS,SAAS,KACxB,OAAO,MAAM,cAAc,YAC3B,MAAM,UAAU,SAAS,MACxB,MAAM,YAAY,UAAa,OAAO,MAAM,YAAY,cACxD,MAAM,kBAAkB,UACvB,OAAO,MAAM,kBAAkB,cAChC,MAAM,aAAa,UAAa,OAAO,MAAM,aAAa,cAC1D,MAAM,qBAAqB,UAC1B,OAAO,MAAM,qBAAqB,cACnC,MAAM,oBAAoB,UACzB,OAAO,MAAM,oBAAoB;AAEvC;AAEA,SAAS,kCACP,OACA,OACS;AACT,QAAM,iBAAiB,UAAU;AACjC,QAAM,qBAAqB,iBACvB,qBACA;AACJ,QAAM,iBAAiB,iBACnB,4BACA;AACJ,QAAM,iBAAiB,iBACnB,sBACA;AAEJ,SACE,MAAM,QAAQ,eAAe,sBAC7B,OAAO,MAAM,OAAO,OAAO,YAC3B,MAAM,OAAO,GAAG,SAAS,KACzB,OAAO,MAAM,qBAAqB,YAClC,MAAM,iBAAiB,SAAS,KAChC,SAAS,MAAM,cAAc,KAC7B,OAAO,MAAM,eAAe,aAAa,YACzC,MAAM,eAAe,SAAS,SAAS,MACtC,MAAM,eAAe,SAAS,aAC7B,MAAM,eAAe,SAAS,aAChC,OAAO,MAAM,eAAe,OAAO,YACnC,MAAM,eAAe,GAAG,SAAS,KACjC,SAAS,MAAM,KAAK,KACpB,OAAO,cAAc,MAAM,MAAM,WAAW,KAC5C,OAAO,MAAM,MAAM,WAAW,IAAI,KAClC,OAAO,MAAM,MAAM,aAAa,YAChC,MAAM,MAAM,SAAS,SAAS,KAC9B,MAAM,WAAW,kBACjB,MAAM,WAAW,kBACjB,OAAO,MAAM,eAAe,YAC5B,MAAM,WAAW,SAAS,KAC1B,CAAC,OAAO,MAAM,KAAK,MAAM,MAAM,UAAU,CAAC,MACzC,MAAM,eAAe,UACnB,OAAO,MAAM,eAAe,YAAY,MAAM,WAAW,SAAS,OACpE,MAAM,YAAY,UAChB,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,SAAS,OAC9D,iBACG,MAAM,OAAO,OAAO,MAAM,oBAC1B,MAAM,eAAe,SAAS,aAC9B,MAAM,oBAAoB,SAC1B,OAAO,MAAM,oBAAoB,YACjC,MAAM,gBAAgB,SAAS,KAC/B,MAAM,OAAO,OAAO,MAAM;AAElC;AAEA,SAAS,6BACP,OACA,OACS;AACT,QAAM,iBACJ,UAAU,wBACN,WACA,UAAU,sBACR,aACA,UAAU,sBACR,YACA;AACV,SACE,OAAO,MAAM,iBAAiB,YAC9B,MAAM,aAAa,SAAS,KAC5B,OAAO,MAAM,WAAW,YACxB,MAAM,OAAO,SAAS,KACtB,OAAO,MAAM,eAAe,YAC5B,MAAM,WAAW,SAAS,KAC1B,OAAO,MAAM,eAAe,YAC5B,MAAM,WAAW,SAAS,KAC1B,MAAM,eAAe,MAAM,YAC3B,MAAM,aAAa,kBACnB,OAAO,MAAM,eAAe,YAC5B,CAAC,OAAO,MAAM,KAAK,MAAM,MAAM,UAAU,CAAC;AAE9C;AAEA,SAAS,oCACP,OAC4C;AAC5C,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,SACE,MAAM,SAAS,kBACf,MAAM,WAAW,4BACjB,gCAAgC,MAAM,KAAK,KAC3C,uCAAuC,MAAM,gBAAgB,KAC7D,iBAAiB,MAAM,QAAQ;AAEnC;AAEA,SAAS,kBACP,QACA,UACS;AACT,SAAO,WAAW,UAAa,aAAa,UAAa,WAAW;AACtE;AASO,SAAS,2BACd,OACoD;AACpD,MACE,CAAC,oBAAoB,KAAK,KAC1B,MAAM,cAAc,YACpB,MAAM,cAAc,4BACpB,CAAC,qBAAqB,MAAM,MAAM,GAClC;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,eAAe,MAAM,OAAO,MAAM,YAAY;AACtD,WAAO;AAAA,EACT;AAEA,MACE,MAAM,OAAO,MAAM,SAAS,gBAC5B,MAAM,OAAO,MAAM,eAAe,MAAM,OAAO,MAAM,YACrD;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AASO,SAAS,mCACd,OAC2C;AAC3C,MACE,CAAC,oBAAoB,KAAK,KAC1B,MAAM,cAAc,mCACpB,MAAM,cAAc,oCACpB,CAAC,2BAA2B,MAAM,IAAI,KACtC,CAAC,uBAAwB,MAAqC,YAAY,GAC1E;AACA,WAAO;AAAA,EACT;AAEA,QAAM,eAAgB,MACnB;AACH,QAAM,OAAO,MAAM;AACnB,QAAM,SAAS,MAAM;AACrB,QAAM,mBAAmB,KAAK,QAAQ,cAAc,MAAM;AAC1D,QAAM,WAAW,KAAK,QAAQ;AAE9B,MAAI,CAAC,uCAAuC,gBAAgB,EAAG,QAAO;AACtE,MACE,KAAK,WAAW,UAChB,MAAM,eAAe,KAAK,OAAO,YACjC;AACA,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,QAAW;AACxB,QAAI,CAAC,oCAAoC,MAAM,EAAG,QAAO;AACzD,QAAI,OAAO,qBAAqB,iBAAkB,QAAO;AACzD,QAAI,OAAO,UAAU,aAAa,MAAO,QAAO;AAChD,QAAI,CAAC,kBAAkB,OAAO,UAAU,QAAQ,EAAG,QAAO;AAAA,EAC5D;AACA,QAAM,iBAAiB,oCAAoC,MAAM,IAC7D,OAAO,WACP;AAEJ,MACE,aAAa,UAAU,mCACvB,aAAa,UAAU,kCACvB;AACA,QAAI,CAAC,kCAAkC,MAAM,aAAa,KAAK,GAAG;AAChE,aAAO;AAAA,IACT;AACA,UAAM,eAAe;AACrB,UAAM,qBACJ,aAAa,UAAU,kCACnB,qBACA;AACN,UAAM,uBACJ,aAAa,UAAU,kCACnB,aAAa,mBACb,aAAa;AACnB,WACE,qBAAqB,sBACrB,OAAO,aAAa,qBAAqB,YACzC,aAAa,qBAAqB,aAAa,oBAC/C,OAAO,yBAAyB,YAChC,yBAAyB,aAAa,OAAO,MAC7C,kBAAkB,gBAAgB,aAAa,OAAO,EAAE;AAAA,EAE5D;AAEA,MACE,aAAa,UAAU,yBACvB,aAAa,UAAU,uBACvB,aAAa,UAAU,uBACvB,aAAa,UAAU,uBACvB;AACA,WACE,qBAAqB,0BACrB,6BAA6B,MAAM,aAAa,KAAK,KACrD,OAAO,aAAa,iBAAiB,YACrC,aAAa,iBAAiB,KAAK,gBACnC,kBAAkB,gBAAgB,KAAK,YAAY;AAAA,EAEvD;AAEA,MACE,aAAa,UAAU,eACvB,aAAa,UAAU,mBACvB,aAAa,UAAU,kBACvB;AACA,WACE,qBAAqB,YACrB,OAAO,aAAa,YAAY,YAChC,aAAa,QAAQ,SAAS,KAC9B,kBAAkB,KAAK,SAAS,QAAQ,KACxC,kBAAkB,aAAa,SAAS,QAAQ,KAChD,kBAAkB,KAAK,SAAS,aAAa,OAAO,KACpD,kBAAkB,gBAAgB,KAAK,WAAW,aAAa,OAAO;AAAA,EAE1E;AAEA,MAAI,aAAa,UAAU,sBAAsB;AAC/C,WACE,qBAAqB,kBACrB,kBAAkB,KAAK,eAAe,QAAQ,KAC9C,OAAO,aAAa,kBAAkB,YACtC,aAAa,cAAc,SAAS,KACpC,kBAAkB,aAAa,eAAe,QAAQ,KACtD,kBAAkB,KAAK,eAAe,aAAa,aAAa,KAChE,kBAAkB,gBAAgB,aAAa,aAAa;AAAA,EAEhE;AAEA,MACE,aAAa,UAAU,qBACvB,aAAa,UAAU,oBACvB,aAAa,UAAU,oBACvB,aAAa,UAAU,oBACvB,aAAa,UAAU,mBACvB;AACA,WACE,qBAAqB,aACrB,kBAAkB,KAAK,UAAU,QAAQ,KACzC,OAAO,aAAa,aAAa,YACjC,aAAa,SAAS,SAAS,KAC/B,kBAAkB,aAAa,UAAU,QAAQ,KACjD,kBAAkB,KAAK,UAAU,aAAa,QAAQ,KACtD,kBAAkB,gBAAgB,aAAa,QAAQ;AAAA,EAE3D;AAEA,SAAO;AACT;AAEO,SAAS,sCACd,OACQ;AACR,SAAO,GAAG,MAAM,aAAa,QAAQ,IAAI,MAAM,aAAa,SAAS;AACvE;AAEO,SAAS,0BACd,QACS;AACT,SAAO;AACT;AAEO,SAAS,yCACd,UACiC;AACjC,SAAO,OAAO,UAAU;AACtB,QAAI,CAAC,mCAAmC,KAAK,GAAG;AAC9C,YAAM,SAAS,YAAY,KAAK;AAChC;AAAA,IACF;AAEA,UAAM,UAAU,SAAS,MAAM,aAAa,KAAK;AACjD,QAAI,CAAC,SAAS;AACZ,YAAM,SAAS,YAAY,KAAK;AAChC;AAAA,IACF;AAEA,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA,gBAAgB,sCAAsC,KAAK;AAAA,IAC7D,CAAC;AAAA,EACH;AACF;AAEO,SAAS,kCACd,UACiC;AACjC,SAAO,yCAAyC,QAAQ;AAC1D;AAGO,SAAS,oBACd,OACA,YAC6C;AAC7C,SAAO,oBAAoB,KAAK,KAAK,MAAM,eAAe;AAC5D;AAGO,SAAS,mBACd,OACAC,YACoE;AACpE,SAAO,oBAAoB,KAAK,KAAK,MAAM,cAAcA;AAC3D;AAEO,IAAM,oCAAoC;AAgCjD,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,UAAU,OAAgC,KAAsB;AACvE,SAAO,OAAO,MAAM,GAAG,MAAM;AAC/B;AAEA,SAAS,kBACP,OACA,KACS;AACT,SAAO,OAAO,MAAM,GAAG,MAAM,YAAY,OAAO,MAAM,GAAG,MAAM;AACjE;AAEO,SAAS,oCACd,OAC4C;AAC5C,MACE,MAAM,eAAe,eACrB,MAAM,cAAc,qCACpB,CAAC,SAAS,MAAM,IAAI,GACpB;AACA,WAAO;AAAA,EACT;AAEA,SACE,kBAAkB,MAAM,MAAM,YAAY,KAC1C,UAAU,MAAM,MAAM,OAAO,KAC7B,UAAU,MAAM,MAAM,MAAM,KAC5B,UAAU,MAAM,MAAM,oBAAoB,KAC1C,UAAU,MAAM,MAAM,wBAAwB;AAElD;AAEO,SAAS,iCACd,UACiC;AACjC,SAAO,OAAO,UAAU;AACtB,QAAI,oCAAoC,KAAK,KAAK,SAAS,eAAe;AACxE,YAAM,SAAS,cAAc,MAAM,MAAM,KAAK;AAC9C;AAAA,IACF;AAEA,UAAM,SAAS,YAAY,KAAK;AAAA,EAClC;AACF;AAOA,eAAsB,cAIpB,SACA,SACA,SACmB;AACnB,SAAO,oBAA4B,SAAS,SAAS,OAAO;AAC9D;AAEO,SAAS,0BACd,YACA,SACmB;AACnB,SAAO,OAAO,UAA2B;AACvC,QAAI,MAAM,eAAe,YAAY;AACnC,YAAM,IAAI;AAAA,QACR,wBAAwB,UAAU,WAAW,MAAM,UAAU;AAAA,MAC/D;AAAA,IACF;AACA,WAAO,QAAQ,KAAK;AAAA,EACtB;AACF;;;ACl4BO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,IAAM,cAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAOO,IAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAIrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAUO,IAAM,qBAAqB;AAAA,EAChC,GAAG;AAAA,EACH,GAAG;AACL;;;ACpLA,IAAM,0BAA0B;AAChC,IAAM,sBAAsB;AAC5B,IAAM,2BAA2B;AACjC,IAAM,uBAAuB;AAEtB,IAAM,qBAAN,MAAyB;AAAA,EAQ9B,YACU,SACA,gBACA,UACA,aACR;AAJQ;AACA;AACA;AACA;AAXV,SAAQ,kBAA0C;AAClD,SAAQ,mBAAmB;AAC3B,SAAQ,kBAAkB;AAC1B,SAAQ,iBAAuD;AAC/D,SAAQ,YAAY,oBAAI,IAAsB;AAC9C,SAAQ,aAAa;AAAA,EAOlB;AAAA,EAEH,IAAI,YAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,IAAkC;AAC5C,SAAK,UAAU,IAAI,EAAE;AACrB,WAAO,MAAM,KAAK,UAAU,OAAO,EAAE;AAAA,EACvC;AAAA,EAEA,UAAgB;AACd,QAAI,KAAK,gBAAiB;AAE1B,SAAK,kBAAkB,IAAI,gBAAgB;AAC3C,SAAK,YAAY,KAAK,gBAAgB,MAAM;AAAA,EAC9C;AAAA,EAEA,aAAmB;AACjB,SAAK,aAAa;AAClB,QAAI,KAAK,gBAAgB;AACvB,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AACA,QAAI,KAAK,iBAAiB;AACxB,WAAK,gBAAgB,MAAM;AAC3B,WAAK,kBAAkB;AAAA,IACzB;AACA,SAAK,mBAAmB;AACxB,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,MAAc,YAAY,QAAoC;AAC5D,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,CAAC,OAAO;AACV,WAAK;AACL,UAAI,KAAK,mBAAmB,sBAAsB;AAEhD,aAAK,aAAa;AAClB,aAAK,kBAAkB;AACvB;AAAA,MACF;AACA,WAAK,kBAAkB;AACvB;AAAA,IACF;AACA,SAAK,kBAAkB;AAEvB,UAAM,SAAS,KAAK,aAAa,SAC7B,gBAAgB,KAAK,YAAY,KAAK,GAAG,CAAC,KAC1C;AACJ,UAAM,MAAM,GAAG,KAAK,OAAO,qBAAqB,MAAM;AAEtD,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,SAAS;AAAA,UACP,qBAAqB,KAAK;AAAA,UAC1B,eAAe,UAAU,KAAK;AAAA,QAChC;AAAA,QACA;AAAA,MACF,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI,SAAS,WAAW,KAAK;AAE3B,eAAK,kBAAkB;AACvB;AAAA,QACF;AACA,cAAM,IAAI,MAAM,0BAA0B,SAAS,MAAM,EAAE;AAAA,MAC7D;AAEA,UAAI,CAAC,SAAS,MAAM;AAClB,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AAEA,WAAK,aAAa;AAClB,WAAK,mBAAmB;AAExB,YAAM,KAAK,WAAW,SAAS,MAAM,MAAM;AAAA,IAC7C,QAAQ;AACN,UAAI,OAAO,QAAS;AACpB,WAAK,aAAa;AAClB,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAc,WACZ,MACA,QACe;AACf,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AACb,QAAI,eAAe;AACnB,QAAI,cAAc;AAElB,QAAI;AACF,aAAO,MAAM;AACX,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,QAAQ,OAAO,QAAS;AAE5B,kBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,cAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,iBAAS,MAAM,IAAI,KAAK;AAExB,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,WAAW,SAAS,GAAG;AAC9B,2BAAe,KAAK,MAAM,CAAC;AAAA,UAC7B,WAAW,KAAK,WAAW,QAAQ,GAAG;AACpC,4BAAgB,cAAc,OAAO,MAAM,KAAK,MAAM,CAAC;AAAA,UACzD,WAAW,SAAS,IAAI;AAEtB,gBAAI,iBAAiB,uBAAuB,aAAa;AACvD,kBAAI;AACF,sBAAM,QAAuB,KAAK,MAAM,WAAW;AACnD,2BAAW,YAAY,KAAK,WAAW;AACrC,sBAAI;AACF,6BAAS,KAAK;AAAA,kBAChB,QAAQ;AAAA,kBAER;AAAA,gBACF;AAAA,cACF,QAAQ;AAAA,cAER;AAAA,YACF;AACA,2BAAe;AACf,0BAAc;AAAA,UAChB;AAAA,QAEF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER,UAAE;AACA,aAAO,YAAY;AACnB,WAAK,aAAa;AAClB,UAAI,CAAC,OAAO,SAAS;AACnB,aAAK,kBAAkB;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,eAAgB;AAEzB,UAAMC,SAAQ,KAAK;AAAA,MACjB,0BACE,KAAK,IAAI,0BAA0B,KAAK,gBAAgB;AAAA,MAC1D;AAAA,IACF;AACA,SAAK;AAEL,SAAK,iBAAiB,WAAW,MAAM;AACrC,WAAK,iBAAiB;AACtB,WAAK,kBAAkB,IAAI,gBAAgB;AAC3C,WAAK,YAAY,KAAK,gBAAgB,MAAM;AAAA,IAC9C,GAAGA,MAAK;AAAA,EACV;AACF;;;AC5JO,IAAM,cAAc,CAAC,KAAK,KAAK,KAAK,MAAM,IAAI;AAGrD,SAAS,oBAAoB,OAAiC;AAC5D,QAAM,OAAO,IAAI,IAAY,WAAW;AACxC,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,UAAM,QAAQ,OAAO,GAAG;AACxB,QAAI,OAAO,SAAS,KAAK,KAAK,QAAQ,EAAG,MAAK,IAAI,KAAK;AAAA,EACzD;AACA,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACvC;AAaO,SAAS,YACd,OACA,cACA,MAAc,GACN;AACR,QAAM,SAAS,eAAe;AAC9B,QAAM,QAAQ,MAAM;AAEpB,MAAI,OAAO;AACT,eAAW,QAAQ,oBAAoB,KAAK,GAAG;AAC7C,UAAI,QAAQ,QAAQ;AAClB,cAAM,QAAQ,MAAM,GAAG,IAAI,EAAE;AAC7B,YAAI,OAAO,IAAK,QAAO,MAAM;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,OAAO;AACtB;AAWO,SAAS,eAAe,OAA0B;AACvD,QAAM,QAAkB,CAAC;AACzB,QAAM,gBAAgB,oBAAI,IAAY;AACtC,QAAM,QAAQ,MAAM;AAEpB,MAAI,OAAO;AACT,eAAW,QAAQ,oBAAoB,KAAK,GAAG;AAC7C,YAAM,QAAQ,MAAM,GAAG,IAAI,EAAE;AAC7B,UAAI,OAAO,OAAO,MAAM,SAAS,CAAC,cAAc,IAAI,MAAM,KAAK,GAAG;AAChE,sBAAc,IAAI,MAAM,KAAK;AAC7B,cAAM,KAAK,GAAG,MAAM,GAAG,IAAI,MAAM,KAAK,GAAG;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,OAAO,MAAM,SAAS,CAAC,cAAc,IAAI,MAAM,KAAK,GAAG;AAC/D,UAAM,KAAK,GAAG,MAAM,GAAG,IAAI,MAAM,KAAK,GAAG;AAAA,EAC3C;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAQO,SAAS,aAAa,OAAsC;AACjE,SAAO,MAAM,QAAQ;AACvB;AAQO,SAAS,gBAAgB,OAA4C;AAC1E,SAAO,MAAM,WAAW;AAC1B;AAqBO,SAAS,yBACd,OACA,SACwB;AACxB,QAAM,OAAO,SAAS,QAAQ;AAC9B,QAAM,eAAe,SAAS,gBAAgB;AAE9C,MAAI,SAAS,OAAQ,QAAO,CAAC;AAE7B,QAAM,QAAQ,MAAM,UAAU,YAAY;AAE1C,MAAI,SAAS,QAAQ;AACnB,UAAM,OAAO,MAAM;AACnB,QAAI,MAAM;AACR,aAAO;AAAA,QACL,iBAAiB,OAAO,IAAI;AAAA,QAC5B,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,MACtB;AAAA,IACF;AAEA,QAAI,OAAO;AACT,aAAO,EAAE,iBAAiB,MAAM;AAAA,IAClC;AACA,WAAO,CAAC;AAAA,EACV;AAGA,MAAI,OAAO;AACT,WAAO,EAAE,iBAAiB,MAAM;AAAA,EAClC;AACA,SAAO,CAAC;AACV;;;ACnLO,IAAM,sBAAsB,MAAM;AAEvC,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,OAAO,IAAI,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE;AAClD,QAAM,SAAS,IAAI,SAAS,IAAI,GAAG,SAAS,EAAE,SAAS,GAAG,GAAG;AAC7D,QAAM,MAAM,IAAI,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AAEpD,QAAMC,SAAQ,IAAI,YAAY,CAAC;AAC/B,aAAW,OAAO,gBAAgBA,MAAK;AACvC,QAAM,WAAWA,OAAM,CAAC,KAAK,KAAK,KAAS,SAAS,EAAE,SAAS,GAAG,GAAG;AAErE,SAAO,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,GAAG,MAAM;AACvC;;;ACLO,IAAM,kBAAkB,CAAC,UAAuB;AACrD,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAM,aAAa,gBAAgB,MAAM,CAAC,GAAG,OAAO,GAAG,SAAS;AAEhE,SAAO,MAAM,WAAW,IACpB,aACA,GAAG,UAAU,WAAM,MAAM,SAAS,CAAC;AACzC;;;ACfA,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAiCjB,SAAS,kBACd,YACA,SACQ;AACR,QAAM,SAAS,IAAI,gBAAgB;AACnC,SAAO,IAAI,SAAS,OAAO,SAAS,SAAS,GAAG,CAAC;AACjD,MAAI,SAAS,OAAQ,QAAO,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AAChE,MAAI,SAAS,QAAQ,KAAM,QAAO,IAAI,QAAQ,OAAO,QAAQ,IAAI,CAAC;AAClE,MAAI,SAAS,QAAS,QAAO,IAAI,YAAY,QAAQ,OAAO;AAC5D,MAAI,SAAS,MAAO,QAAO,IAAI,UAAU,MAAM;AAC/C,MAAI,SAAS,MAAO,QAAO,IAAI,UAAU,MAAM;AAC/C,MAAI,SAAS,OAAQ,QAAO,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AAChE,SAAO,GAAG,cAAc,IAAI,UAAU,kBAAkB,MAAM;AAChE;AA2BO,SAAS,YACd,YACA,SACQ;AACR,QAAM,SAAS,IAAI,gBAAgB;AACnC,SAAO,IAAI,SAAS,OAAO,SAAS,SAAS,GAAG,CAAC;AACjD,MAAI,SAAS,SAAS,KAAM,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AACrE,MAAI,SAAS,OAAO,KAAM,QAAO,IAAI,OAAO,OAAO,QAAQ,GAAG,CAAC;AAC/D,MAAI,SAAS,IAAK,QAAO,IAAI,OAAO,OAAO,QAAQ,GAAG,CAAC;AACvD,SAAO,GAAG,cAAc,IAAI,UAAU,iBAAiB,MAAM;AAC/D;AAaO,SAAS,mBAAmB,YAA4B;AAC7D,SAAO,GAAG,cAAc,IAAI,UAAU;AACxC;AAaO,SAAS,kBAAkB,YAA4B;AAC5D,SAAO,GAAG,eAAe,IAAI,UAAU;AACzC;AAYO,SAAS,eACd,YACA,aAAwC,QAChC;AACR,SAAO,GAAG,eAAe,IAAI,UAAU,IAAI,UAAU;AACvD;;;A5CjHO,SAASC,cAAa,SAA6C;AACxE,SAAO,aAAqB,OAAO;AACrC;","names":["createClient","method","object","uuid","time","object","value","uuid","time","key","page","operation","operation","value","value","money","operation","DEFAULT_TIMEOUT","operation","DEFAULT_TIMEOUT","operation","mediaArray","item","operation","normalizedMarket","options","timestamp","operation","delay","array","createClient"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/core/internal/utils/credentials.ts","../src/core/internal/utils/api-url.ts","../src/core/internal/utils/http.ts","../src/core/internal/utils/query-string.ts","../src/core/api/parse-response.ts","../../../internal/http-contracts/src/index.ts","../src/core/api/endpoints.ts","../src/core/api/customer-scoped-api.ts","../src/core/api/benefit-voucher-types.ts","../src/core/api/customer-benefit-vouchers-api.ts","../src/core/api/customer-credit-types.ts","../src/core/api/customer-credits-api.ts","../src/core/collection/http-client.ts","../src/utils/types.ts","../src/core/collection/query-builder.ts","../src/core/collection/collection-client.ts","../src/core/community/community-client.ts","../src/core/content/content-client.ts","../src/core/api/canonical-response.ts","../src/core/customer/customer-auth.ts","../src/core/customer/customer-oauth.ts","../src/core/customer/customer-namespace.ts","../src/core/api/commerce-idempotency.ts","../src/core/api/cart-api.ts","../src/core/api/checkout-api.ts","../src/core/api/payment-session-api.ts","../src/utils/product-selection-media.ts","../src/utils/ecommerce.ts","../src/core/api/product-api.ts","../src/core/commerce/commerce-client.ts","../src/core/events/events-client.ts","../src/core/market/market-discovery.ts","../src/core/client/client.ts","../src/core/commerce/merge-catalog-stock.ts","../src/core/webhook/validation.ts","../src/core/webhook/receiver.ts","../src/core/webhook/index.ts","../src/core/collection/const.ts","../src/core/query/realtime.ts","../src/utils/image.ts","../src/utils/order/generateOrderNumber.ts","../src/utils/order/formatOrderName.ts","../src/utils/video.ts"],"sourcesContent":["import type { ClientConfig, RootClientWithEvents } from './core/client/types'\nimport { createClient as createClientInternal } from './core/client/client'\n\n// Public domain types\nexport type {\n Article,\n ArticleAuthor,\n ArticleCategory,\n ArticleTag,\n Image,\n Post,\n PostCategory,\n Video,\n Tenant,\n Document,\n} from './payload-types'\n\n// Core browser-safe SDK\nexport function createClient(options: ClientConfig): RootClientWithEvents {\n return createClientInternal(options) as RootClientWithEvents\n}\n\nexport type {\n ApiQueryOptions,\n ClientConfig,\n ClientMetadata,\n ClientState,\n Collection,\n DebugConfig,\n DeepPartial,\n ExtractArrayType,\n PayloadFindResponse,\n PayloadMutationResponse,\n PublicReadQueryOptions,\n PublicCollection,\n RootCollectionClient,\n RootClient as Client,\n RootClient as ClientType,\n RootClient,\n RootClientWithEvents,\n RootReadOnlyQueryBuilder,\n RetryConfig,\n Sort,\n Where,\n} from './core/client/types'\nexport type {\n CollectionType,\n PublicMarket as Market,\n PublicProduct as Product,\n PublicProductCollection as ProductCollection,\n PublicProductVariant as ProductVariant,\n} from './core/collection/types'\nexport type { MarketDTO } from './core/market/market-discovery'\nexport * from './core/api'\nexport { CommerceClient } from './core/commerce/commerce-client'\nexport type { CommerceClientOptions } from './core/commerce/commerce-client'\nexport {\n mergeProductDetailWithStock,\n type MergedProductDetailResult,\n type ProductDetailStockMergeStatus,\n} from './core/commerce/merge-catalog-stock'\nexport { CommunityClient } from './core/community/community-client'\nexport type {\n CommunityClientOptions,\n CommunityComment,\n CommunityCommentListSort,\n CommunityPost,\n CommunityPostCategory,\n CommunityPostListSort,\n CommunityPublicAuthorSnapshot,\n CommunityPublicMediaAsset,\n CommunityPublicReference,\n CommunityPostTag,\n Comment,\n} from './core/community/community-client'\nexport { ContentClient } from './core/content/content-client'\nexport type {\n ContentClientOptions,\n StorefrontContentListOptions,\n StorefrontContentReference,\n StorefrontGalleryItem,\n StorefrontGalleryItemsListOptions,\n StorefrontGalleryItemsSort,\n StorefrontLink,\n StorefrontLinksListOptions,\n StorefrontLinksSort,\n} from './core/content/content-client'\nexport { EventsClient } from './core/events/events-client'\nexport type { VideoPlaybackResponse } from './core/video/video-playback-client'\nexport type {\n EventAdmissionAvailabilityParams,\n EventAdmissionAvailabilityResponse,\n EventAdmissionAvailabilityType,\n EventAdmissionPricePresentment,\n EventMyRegistration,\n EventMyRegistrationsParams,\n EventMyRegistrationsResponse,\n EventGuestCancelParams,\n EventGuestRegistration,\n EventGuestRegistrationResponse,\n EventRegistrationAnswerInput,\n EventRegistrationAttendeeInput,\n EventRegistrationPublic,\n EventRegistrationRegisterParams,\n EventRegistrationRegisterResponse,\n EventsCalendarItem,\n EventsClientOptions,\n EventsDateParam,\n EventsExternalSource,\n EventsLocation,\n EventsOccurrenceLocation,\n EventsRangeEvent,\n EventsRangeOccurrence,\n EventsRangeParams,\n EventsRangeResponse,\n EventsTaxonomyItem,\n} from './core/events/events-client'\nexport * from './core/customer'\nexport * from './core/webhook'\nexport {\n COLLECTIONS,\n INTERNAL_COLLECTIONS,\n SERVER_COLLECTIONS,\n SERVER_ONLY_COLLECTIONS,\n} from './core/collection/const'\nexport {\n RealtimeConnection,\n type RealtimeEvent,\n type RealtimeListener,\n} from './core/query/realtime'\n\n// Utils\nexport * from './utils'\n\n// Errors\nexport {\n SDKError,\n NetworkError,\n ValidationError,\n ApiError,\n ConfigError,\n TimeoutError,\n GoneError,\n ServiceUnavailableError,\n UsageLimitError,\n AuthError,\n PermissionError,\n NotFoundError,\n ConflictError,\n RateLimitError,\n COMMERCE_ERROR_CODES,\n type CommerceErrorCode,\n type CommerceSDKError,\n isSDKError,\n isNetworkError,\n isValidationError,\n isApiError,\n isConfigError,\n isTimeoutError,\n isGoneError,\n isServiceUnavailableError,\n isUsageLimitError,\n isAuthError,\n isPermissionError,\n isNotFoundError,\n isConflictError,\n isRateLimitError,\n isCommerceSDKError,\n getSDKErrorReason,\n createAuthError,\n createPermissionError,\n createNotFoundError,\n createConflictError,\n createRateLimitError,\n} from './errors'\n\nexport type { BenefitVouchersApi } from './core/api/benefit-vouchers-api'\nexport type { CreditsApi } from './core/api/credits-api'\nexport type * from './core/api/customer-credit-types'\nexport type * from './core/api/benefit-voucher-types'\n","const SDK_ERROR_BRAND = Symbol.for('@01.software/sdk/SDKError')\nconst SDK_ERROR_TYPE_BRAND = Symbol.for('@01.software/sdk/SDKError.type')\n\ntype SDKErrorType =\n | 'NetworkError'\n | 'ValidationError'\n | 'ApiError'\n | 'ConfigError'\n | 'TimeoutError'\n | 'GoneError'\n | 'ServiceUnavailableError'\n | 'UsageLimitError'\n | 'AuthError'\n | 'PermissionError'\n | 'NotFoundError'\n | 'ConflictError'\n | 'RateLimitError'\n\nfunction defineSDKErrorBrand(error: SDKError): void {\n Object.defineProperty(error, SDK_ERROR_BRAND, {\n value: true,\n enumerable: false,\n configurable: false,\n writable: false,\n })\n}\n\nfunction defineSDKErrorType(error: SDKError, type: SDKErrorType): void {\n Object.defineProperty(error, SDK_ERROR_TYPE_BRAND, {\n value: type,\n enumerable: false,\n configurable: false,\n writable: false,\n })\n}\n\nexport class SDKError extends Error {\n readonly code: string\n readonly status?: number\n readonly details?: unknown\n readonly userMessage?: string\n readonly suggestion?: string\n readonly requestId?: string\n readonly kind?: 'commerce'\n readonly reason?: CommerceErrorCode | 'unknown_commerce_error'\n readonly rawReason?: string\n /** Machine-readable reason from a non-commerce API response. */\n readonly apiReason?: string\n readonly retryable?: boolean\n readonly retryAfter?: number\n\n constructor(\n code: string,\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(message)\n this.name = 'SDKError'\n this.code = code\n this.status = status\n this.details = details\n this.userMessage = userMessage\n this.suggestion = suggestion\n this.requestId = requestId\n defineSDKErrorBrand(this)\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, new.target)\n }\n }\n\n getUserMessage(): string {\n return this.userMessage || this.message\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n status: this.status,\n details: this.details,\n userMessage: this.userMessage,\n suggestion: this.suggestion,\n ...(this.requestId !== undefined && { requestId: this.requestId }),\n ...(this.kind !== undefined && { kind: this.kind }),\n ...(this.reason !== undefined && { reason: this.reason }),\n ...(this.rawReason !== undefined && { rawReason: this.rawReason }),\n ...(this.apiReason !== undefined && { apiReason: this.apiReason }),\n ...(this.retryable !== undefined && { retryable: this.retryable }),\n ...(this.retryAfter !== undefined && { retryAfter: this.retryAfter }),\n }\n }\n}\n\n/**\n * Canonical Cart/Checkout/PaymentSession error reasons. This public SDK mirror\n * intentionally does not import the private contracts package; parity is\n * enforced by a type test.\n */\nexport const COMMERCE_ERROR_CODES = [\n 'validation_failed',\n 'bad_request',\n 'unauthorized',\n 'forbidden',\n 'account_suspended',\n 'key_invalid',\n 'pat_tenant_header_forbidden',\n 'tenant_mismatch',\n 'test_tenant_expired',\n 'token_invalid',\n 'token_expired',\n 'origin_not_allowed',\n 'server_credentials_required',\n 'role_denied',\n 'scope_denied',\n 'feature_disabled',\n 'not_found',\n 'conflict',\n 'locked',\n 'cart_revision_conflict',\n 'rate_limit_exceeded',\n 'usage_limit_exceeded',\n 'service_unavailable',\n 'idempotency_conflict',\n 'idempotency_in_progress',\n 'idempotency_key_required',\n 'invalid_idempotency_key',\n 'cart_not_active',\n 'cart_locked',\n 'cart_empty',\n 'shipping_address_required',\n 'cart_market_unavailable',\n 'cart_market_mismatch',\n 'checkout_not_open',\n 'checkout_already_open',\n 'payment_slot_held',\n 'reservation_expired',\n 'payment_session_not_cancelable',\n 'payment_session_conflict',\n 'provider_identity_mismatch',\n 'managed_refund_attestation_forbidden',\n 'payment_method_unavailable',\n 'provider_unavailable',\n 'lock_timeout',\n 'price_changed',\n 'pricing_fact_in_use',\n 'insufficient_stock',\n 'credit_insufficient',\n 'reservation_conflict',\n 'stock_lock_unavailable',\n 'variant_not_found',\n 'variant_stock_write_failed',\n 'stock_invariant_violation',\n 'payment_confirmation_in_flight',\n 'checkout_reservation_release_requires_transaction',\n 'admission_metadata_invalid',\n 'admission_metadata_required',\n 'admission_not_eligible',\n 'admission_eligibility_unavailable',\n 'admission_authority_unavailable',\n 'admission_customer_binding_required',\n 'admission_eligibility_unproven',\n 'capacity_exceeded',\n 'admission_required',\n 'occurrence_lock_unavailable',\n 'occurrence_not_open',\n 'admission_type_capacity_exceeded',\n 'admission_type_occurrence_mismatch',\n 'admission_hold_expired',\n 'admission_hold_checkout_item_conflict',\n 'admission_hold_checkout_conflict',\n 'admission_hold_quantity_mismatch',\n 'admission_hold_unbound',\n 'admission_hold_missing',\n 'admission_hold_checkout_item_missing',\n 'admission_hold_expiry_failed',\n 'admission_hold_expiry_requires_transaction',\n 'admission_hold_line_item_mismatch',\n 'admission_materialization_failed',\n 'variant_inactive',\n 'variant_product_mismatch',\n 'product_not_public',\n 'product_not_eligible',\n 'purchase_limit_exceeded',\n 'market_not_found',\n 'market_shipping_currency_unsupported',\n 'missing_market_rate',\n 'missing_shipping_amount',\n 'no_enabled_payment_provider',\n 'product_market_unavailable',\n 'unsupported_currency',\n 'missing_price_row',\n 'payment_provider_currency_unsupported',\n 'discount_code_not_found',\n 'discount_not_started',\n 'discount_expired',\n 'discount_usage_limit',\n 'discount_per_customer_limit',\n 'discount_customer_required',\n 'discount_first_order_only',\n 'discount_customer_not_eligible',\n 'discount_customer_excluded',\n 'discount_items_required',\n 'discount_product_not_eligible',\n 'discount_product_excluded',\n 'discount_min_order_amount',\n 'discount_currency_scope_required',\n 'discount_allocation_method_unsupported',\n 'currency_mismatch',\n 'customer_token_required',\n 'market_required',\n 'server_derived',\n 'internal_error',\n] as const\n\nexport type CommerceErrorCode = (typeof COMMERCE_ERROR_CODES)[number]\n\ntype CommerceSDKErrorBase = SDKError & {\n readonly kind: 'commerce'\n readonly requestId: string\n readonly retryable: boolean\n readonly retryAfter?: number\n readonly details?: Record<string, unknown>\n}\n\nexport type CommerceSDKError = CommerceSDKErrorBase &\n (\n | { readonly reason: CommerceErrorCode; readonly rawReason?: never }\n | {\n readonly reason: 'unknown_commerce_error'\n readonly rawReason: string\n }\n )\n\nconst COMMERCE_ERROR_CODE_SET: ReadonlySet<string> = new Set(\n COMMERCE_ERROR_CODES,\n)\nconst COMMERCE_ERROR_ENVELOPE_KEYS = new Set([\n 'error',\n 'reason',\n 'requestId',\n 'retryable',\n 'details',\n])\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport type CommerceErrorEnvelope = {\n error: string\n reason: string\n requestId: string\n retryable: boolean\n details?: Record<string, unknown>\n}\n\nfunction commerceProtocolError(\n issue: string,\n trustedRequestId?: string,\n): SDKError {\n return createApiError(\n 'Invalid canonical commerce error response.',\n 502,\n { protocol: 'commerce-error-envelope', issue },\n 'The server returned an incompatible commerce error response.',\n 'Verify that the Console commerce contract is deployed before using this SDK version.',\n trustedRequestId,\n )\n}\n\n/** @internal Strictly parse a canonical commerce error without retaining its raw body. */\nexport function parseCommerceErrorEnvelope(\n body: unknown,\n headerRequestId?: string,\n): CommerceErrorEnvelope {\n if (headerRequestId === undefined) {\n throw commerceProtocolError('missing_request_id_header')\n }\n if (headerRequestId.length === 0) {\n throw commerceProtocolError('empty_request_id_header')\n }\n if (!isPlainRecord(body)) {\n throw commerceProtocolError('expected_object', headerRequestId)\n }\n if (Object.keys(body).some((key) => !COMMERCE_ERROR_ENVELOPE_KEYS.has(key))) {\n throw commerceProtocolError('unexpected_field', headerRequestId)\n }\n if (\n typeof body.error !== 'string' ||\n body.error.length === 0 ||\n typeof body.reason !== 'string' ||\n body.reason.length === 0 ||\n typeof body.requestId !== 'string' ||\n body.requestId.length === 0 ||\n (body.retryable !== undefined && typeof body.retryable !== 'boolean') ||\n (body.details !== undefined && !isPlainRecord(body.details))\n ) {\n throw commerceProtocolError('invalid_field', headerRequestId)\n }\n\n if (headerRequestId !== undefined && headerRequestId !== body.requestId) {\n throw commerceProtocolError('request_id_mismatch', headerRequestId)\n }\n\n return {\n error: body.error,\n reason: body.reason,\n requestId: body.requestId,\n retryable: body.retryable === true,\n ...(body.details === undefined ? {} : { details: body.details }),\n }\n}\n\n/** @internal Validate and apply the canonical commerce error envelope. */\nexport function enhanceCommerceError(\n error: SDKError,\n body: unknown,\n headerRequestId?: string,\n): SDKError {\n const envelope = parseCommerceErrorEnvelope(body, headerRequestId)\n\n const known = COMMERCE_ERROR_CODE_SET.has(envelope.reason)\n Object.assign(error, {\n code: envelope.reason,\n kind: 'commerce' as const,\n reason: known\n ? (envelope.reason as CommerceErrorCode)\n : 'unknown_commerce_error',\n ...(known ? {} : { rawReason: envelope.reason }),\n requestId: envelope.requestId,\n retryable: envelope.retryable,\n details: envelope.details,\n })\n return error\n}\n\n/** @internal Apply a non-commerce reason without canonical-commerce validation. */\nexport function enhanceNonCommerceError(\n error: SDKError,\n reason: unknown,\n): SDKError {\n if (typeof reason === 'string') Object.assign(error, { apiReason: reason })\n return error\n}\n\n/**\n * Read the server-provided machine reason across strict commerce and\n * non-commerce SDK errors. Unknown commerce reasons are returned verbatim.\n */\nexport function getSDKErrorReason(error: SDKError): string | undefined {\n if (error.kind !== 'commerce') return error.apiReason\n return error.reason === 'unknown_commerce_error'\n ? error.rawReason\n : error.reason\n}\n\nexport function isCommerceSDKError(error: unknown): error is CommerceSDKError {\n if (!isSDKError(error) || error.kind !== 'commerce') return false\n if (\n typeof error.requestId !== 'string' ||\n typeof error.retryable !== 'boolean' ||\n (error.retryAfter !== undefined &&\n (!Number.isSafeInteger(error.retryAfter) || error.retryAfter < 0)) ||\n typeof error.reason !== 'string'\n ) {\n return false\n }\n return error.reason === 'unknown_commerce_error'\n ? typeof error.rawReason === 'string'\n : COMMERCE_ERROR_CODE_SET.has(error.reason) && error.rawReason === undefined\n}\n\nexport class NetworkError extends SDKError {\n constructor(\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('NETWORK_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'NetworkError'\n defineSDKErrorType(this, 'NetworkError')\n }\n}\n\nexport class ValidationError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status = 400,\n ) {\n super('VALIDATION_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'ValidationError'\n defineSDKErrorType(this, 'ValidationError')\n }\n}\n\nexport class ApiError extends SDKError {\n constructor(\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'API_ERROR',\n message,\n status,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'ApiError'\n defineSDKErrorType(this, 'ApiError')\n }\n}\n\nexport class ConfigError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('CONFIG_ERROR', message, undefined, details, userMessage, suggestion)\n this.name = 'ConfigError'\n defineSDKErrorType(this, 'ConfigError')\n }\n}\n\nexport class TimeoutError extends SDKError {\n constructor(\n message = 'Request timed out.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('TIMEOUT_ERROR', message, 408, details, userMessage, suggestion)\n this.name = 'TimeoutError'\n defineSDKErrorType(this, 'TimeoutError')\n }\n}\n\nexport class GoneError extends SDKError {\n constructor(\n message = 'The requested resource is no longer available.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('GONE_ERROR', message, 410, details, userMessage, suggestion)\n this.name = 'GoneError'\n defineSDKErrorType(this, 'GoneError')\n }\n}\n\nexport class ServiceUnavailableError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message = 'Service temporarily unavailable.',\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super(\n 'SERVICE_UNAVAILABLE_ERROR',\n message,\n 503,\n details,\n userMessage,\n suggestion,\n )\n this.name = 'ServiceUnavailableError'\n this.retryAfter = retryAfter\n defineSDKErrorType(this, 'ServiceUnavailableError')\n }\n}\n\nexport class UsageLimitError extends SDKError {\n readonly usage: { limit: number; current: number; remaining: number }\n\n constructor(\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('USAGE_LIMIT_ERROR', message, 429, details, userMessage, suggestion)\n this.name = 'UsageLimitError'\n this.usage = usage\n defineSDKErrorType(this, 'UsageLimitError')\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n usage: this.usage,\n }\n }\n}\n\nexport class AuthError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'auth_error',\n message,\n 401,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'AuthError'\n defineSDKErrorType(this, 'AuthError')\n }\n}\n\nexport class PermissionError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'permission_error',\n message,\n 403,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'PermissionError'\n defineSDKErrorType(this, 'PermissionError')\n }\n}\n\nexport class NotFoundError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'not_found',\n message,\n 404,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'NotFoundError'\n defineSDKErrorType(this, 'NotFoundError')\n }\n}\n\nexport class ConflictError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super('conflict', message, 409, details, userMessage, suggestion, requestId)\n this.name = 'ConflictError'\n defineSDKErrorType(this, 'ConflictError')\n }\n}\n\nexport class RateLimitError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'rate_limit_exceeded',\n message,\n 429,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n defineSDKErrorType(this, 'RateLimitError')\n }\n}\n\nfunction hasBrandedSDKErrorShape(error: unknown): error is SDKError {\n if (error === null || typeof error !== 'object') return false\n\n const candidate = error as Record<PropertyKey, unknown>\n return (\n candidate[SDK_ERROR_BRAND] === true &&\n typeof candidate.name === 'string' &&\n typeof candidate.code === 'string' &&\n typeof candidate.message === 'string' &&\n (candidate.status === undefined || typeof candidate.status === 'number') &&\n (candidate.userMessage === undefined ||\n typeof candidate.userMessage === 'string') &&\n (candidate.suggestion === undefined ||\n typeof candidate.suggestion === 'string') &&\n (candidate.requestId === undefined ||\n typeof candidate.requestId === 'string') &&\n (candidate.kind === undefined || candidate.kind === 'commerce') &&\n (candidate.reason === undefined || typeof candidate.reason === 'string') &&\n (candidate.rawReason === undefined ||\n typeof candidate.rawReason === 'string') &&\n (candidate.apiReason === undefined ||\n typeof candidate.apiReason === 'string') &&\n (candidate.retryable === undefined ||\n typeof candidate.retryable === 'boolean') &&\n (candidate.retryAfter === undefined ||\n typeof candidate.retryAfter === 'number') &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nfunction hasSDKErrorType(error: unknown, type: SDKErrorType): boolean {\n return (\n hasBrandedSDKErrorShape(error) &&\n (error as unknown as Record<PropertyKey, unknown>)[SDK_ERROR_TYPE_BRAND] ===\n type\n )\n}\n\nexport function isSDKError(error: unknown): error is SDKError {\n return error instanceof SDKError || hasBrandedSDKErrorShape(error)\n}\n\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError || hasSDKErrorType(error, 'NetworkError')\n}\n\nexport function isValidationError(error: unknown): error is ValidationError {\n if (\n error instanceof ValidationError ||\n hasSDKErrorType(error, 'ValidationError')\n ) {\n return true\n }\n if (error == null || typeof error !== 'object') return false\n\n const candidate = error as {\n code?: unknown\n name?: unknown\n message?: unknown\n getUserMessage?: unknown\n toJSON?: unknown\n }\n return (\n candidate.name === 'ValidationError' &&\n candidate.code === 'VALIDATION_ERROR' &&\n typeof candidate.message === 'string' &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nexport function isApiError(error: unknown): error is ApiError {\n return error instanceof ApiError || hasSDKErrorType(error, 'ApiError')\n}\n\nexport function isConfigError(error: unknown): error is ConfigError {\n return error instanceof ConfigError || hasSDKErrorType(error, 'ConfigError')\n}\n\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return error instanceof TimeoutError || hasSDKErrorType(error, 'TimeoutError')\n}\n\nexport function isGoneError(error: unknown): error is GoneError {\n return error instanceof GoneError || hasSDKErrorType(error, 'GoneError')\n}\n\nexport function isServiceUnavailableError(\n error: unknown,\n): error is ServiceUnavailableError {\n return (\n error instanceof ServiceUnavailableError ||\n hasSDKErrorType(error, 'ServiceUnavailableError')\n )\n}\n\nexport function isUsageLimitError(error: unknown): error is UsageLimitError {\n return (\n error instanceof UsageLimitError ||\n hasSDKErrorType(error, 'UsageLimitError')\n )\n}\n\nexport function isAuthError(error: unknown): error is AuthError {\n return error instanceof AuthError || hasSDKErrorType(error, 'AuthError')\n}\n\nexport function isPermissionError(error: unknown): error is PermissionError {\n return (\n error instanceof PermissionError ||\n hasSDKErrorType(error, 'PermissionError')\n )\n}\n\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return (\n error instanceof NotFoundError || hasSDKErrorType(error, 'NotFoundError')\n )\n}\n\nexport function isConflictError(error: unknown): error is ConflictError {\n return (\n error instanceof ConflictError || hasSDKErrorType(error, 'ConflictError')\n )\n}\n\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return (\n error instanceof RateLimitError || hasSDKErrorType(error, 'RateLimitError')\n )\n}\n\nexport const createNetworkError = (\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new NetworkError(message, status, details, userMessage, suggestion)\n\nexport const createValidationError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status?: number,\n) => new ValidationError(message, details, userMessage, suggestion, status)\n\nexport const createApiError = (\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ApiError(message, status, details, userMessage, suggestion, requestId)\n\nexport const createConfigError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new ConfigError(message, details, userMessage, suggestion)\n\nexport const createTimeoutError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new TimeoutError(message, details, userMessage, suggestion)\n\nexport const createGoneError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new GoneError(message, details, userMessage, suggestion)\n\nexport const createServiceUnavailableError = (\n message?: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) =>\n new ServiceUnavailableError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n )\n\nexport const createUsageLimitError = (\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new UsageLimitError(message, usage, details, userMessage, suggestion)\n\nexport const createAuthError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new AuthError(message, details, userMessage, suggestion, requestId)\n\nexport const createPermissionError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new PermissionError(message, details, userMessage, suggestion, requestId)\n\nexport const createNotFoundError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new NotFoundError(message, details, userMessage, suggestion, requestId)\n\nexport const createConflictError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ConflictError(message, details, userMessage, suggestion, requestId)\n\nexport const createRateLimitError = (\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) =>\n new RateLimitError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n","import { createConfigError } from '../errors'\n\nexport function requirePublishableKeyForSecret(\n apiName: string,\n publishableKey: string | undefined,\n secretKey: string | undefined,\n): string {\n if (secretKey && !publishableKey) {\n throw createConfigError(\n `publishableKey is required for ${apiName} when secretKey is used. ` +\n 'It is sent as X-Publishable-Key for tenant routing, rate limiting, and quota enforcement.',\n )\n }\n\n return publishableKey ?? ''\n}\n","declare const __DEFAULT_API_URL__: string\n\nexport function resolveApiUrl(apiUrl?: string): string {\n if (apiUrl) {\n return apiUrl.replace(/\\/$/, '')\n }\n\n if (typeof process !== 'undefined' && process.env) {\n const envUrl =\n process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL\n if (envUrl) {\n return envUrl.replace(/\\/$/, '')\n }\n }\n return __DEFAULT_API_URL__\n}\n","import {\n createAuthError,\n createConflictError,\n createGoneError,\n createNetworkError,\n createNotFoundError,\n createPermissionError,\n createRateLimitError,\n createServiceUnavailableError,\n createValidationError,\n createUsageLimitError,\n createTimeoutError,\n enhanceCommerceError,\n enhanceNonCommerceError,\n isCommerceSDKError,\n parseCommerceErrorEnvelope,\n TimeoutError,\n NetworkError,\n RateLimitError,\n UsageLimitError,\n SDKError,\n} from '../errors'\nimport type { DebugConfig, RetryConfig } from '../../client/types'\nimport { resolveApiUrl } from './api-url'\nconst DEFAULT_TIMEOUT = 30000\nconst STOREFRONT_BROWSER_TIMEOUT = 15_000\n// 429 is intentionally NOT retryable: a real rate limit maps to RateLimitError\n// (terminal) so the SDK does not hammer a limited endpoint with plain backoff.\nconst DEFAULT_RETRYABLE_STATUSES = [408, 500, 502, 503, 504]\nconst NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422]\nconst SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']\nconst DEFAULT_MAX_RETRIES = 3\nconst STOREFRONT_BROWSER_MAX_RETRIES = 1\n// Do not keep a caller request open for an arbitrarily large server hint.\n// Longer windows are surfaced on the typed error for caller-controlled retry.\nconst MAX_AUTOMATIC_RETRY_AFTER_SECONDS = 5 * 60\n\nexport interface FetchOptions extends RequestInit {\n apiUrl?: string\n publishableKey?: string\n secretKey?: string\n customerToken?: string\n timeout?: number\n debug?: boolean | DebugConfig\n retry?: RetryConfig\n /** Called on 401 when customerToken is set and reason=token_expired. A new token permits retry only for GET/HEAD/OPTIONS; null fails. */\n onUnauthorized?: () => Promise<string | null>\n /** Selects a strict endpoint-owned error envelope. */\n errorFamily?: 'commerce'\n /** Strict commerce reasons on an otherwise legacy-compatible endpoint. */\n typedCommerceErrorReasons?: readonly string[]\n}\n\nfunction debugLog(\n debug: boolean | DebugConfig | undefined,\n type: 'request' | 'response' | 'error',\n message: string,\n data?: unknown,\n) {\n if (!debug) return\n\n const shouldLog =\n debug === true ||\n (type === 'request' && (debug as DebugConfig).logRequests) ||\n (type === 'response' && (debug as DebugConfig).logResponses) ||\n (type === 'error' && (debug as DebugConfig).logErrors)\n\n if (shouldLog) {\n console.group(`[SDK ${type.toUpperCase()}] ${message}`)\n if (data) console.log(data)\n console.groupEnd()\n }\n}\n\nfunction redactSensitiveHeader(value: string): string {\n const prefix = value.toLowerCase().startsWith('bearer ') ? 'Bearer ' : ''\n return value.length > 20 ? `${prefix}...****${value.slice(-8)}` : '****'\n}\n\nfunction redactSensitiveHeaders(headers: Headers): Record<string, string> {\n const redacted = Object.fromEntries(headers.entries())\n if (redacted.authorization) {\n redacted.authorization = redactSensitiveHeader(redacted.authorization)\n }\n if (redacted['x-preview-token']) {\n redacted['x-preview-token'] = redactSensitiveHeader(\n redacted['x-preview-token'],\n )\n }\n if (redacted['x-custom-payment-signature']) {\n redacted['x-custom-payment-signature'] = redactSensitiveHeader(\n redacted['x-custom-payment-signature'],\n )\n }\n return redacted\n}\n\nfunction getErrorSuggestion(status: number): string | undefined {\n if (status === 400)\n return 'The request data failed validation. Check field values and types.'\n if (status === 401) return 'Please check your authentication credentials.'\n if (status === 403)\n return 'Access denied. Check your credentials or permissions.'\n if (status === 404) return 'The requested resource was not found.'\n if (status === 422) return 'The request data failed validation.'\n if (status >= 500) return 'A server error occurred. Please try again later.'\n return undefined\n}\n\nfunction isUsageLimitExceededResponse(response: Response): boolean {\n if (response.status !== 429) return false\n\n const limit = parseInt(response.headers.get('X-Usage-Limit') || '', 10)\n const current = parseInt(response.headers.get('X-Usage-Current') || '', 10)\n if (!Number.isFinite(limit) || !Number.isFinite(current)) return false\n\n return response.headers.get('X-Usage-Exceeded') === 'true' || current > limit\n}\n\n/**\n * Parse error details from HTTP response body.\n * Supports Payload native format:\n * - ValidationError: { errors: [{ message, data: { errors: [{ path, message }] } }] }\n * - Simple: { errors: [{ message, field? }] }\n * Also supports custom endpoint format ({ error: string, reason?: string, message?: string }).\n */\nasync function parseErrorBody(response: Response): Promise<{\n errorMessage: string\n userMessage: string\n reason?: string\n /**\n * Machine reason a Payload `APIError` carries as `errors[0].data.code` (or\n * `.reason`). Surfaced only as the non-commerce `apiReason`; it never drives\n * commerce classification, token refresh, or retry decisions.\n */\n payloadErrorReason?: string\n body?: Record<string, unknown>\n errors?: Array<{ message?: string; field?: string }>\n}> {\n const fallback = {\n errorMessage: `HTTP ${response.status}: ${response.statusText}`,\n userMessage: `Request failed (status: ${response.status})`,\n }\n\n try {\n const body = await response.json()\n const reason: string | undefined =\n typeof body.reason === 'string'\n ? body.reason\n : typeof body.code === 'string'\n ? body.code\n : undefined\n const payloadErrorReason = Array.isArray(body.errors)\n ? readPayloadErrorReason(body.errors)\n : undefined\n const payloadReasonField =\n payloadErrorReason !== undefined ? { payloadErrorReason } : {}\n\n // Payload native: { errors: [{ message, field?, data? }] }\n if (body.errors && Array.isArray(body.errors)) {\n // Extract nested ValidationError field details\n // Payload ValidationError format: errors[].data.errors[].{path, message}\n const fieldErrors: Array<{ message?: string; field?: string }> = []\n for (const e of body.errors) {\n if (\n e.data?.errors &&\n Array.isArray(e.data.errors) &&\n e.data.errors.length > 0\n ) {\n for (const fe of e.data.errors) {\n fieldErrors.push({\n field: fe.path || fe.field,\n message: fe.message,\n })\n }\n } else if (e.field || e.message) {\n fieldErrors.push({ field: e.field, message: e.message })\n }\n }\n\n const details = (fieldErrors.length > 0 ? fieldErrors : body.errors)\n .map((e: { message?: string; field?: string }) =>\n e.field ? `${e.field}: ${e.message}` : e.message,\n )\n .filter(Boolean)\n .join('; ')\n if (details) {\n return {\n errorMessage: `HTTP ${response.status}: ${details}`,\n userMessage: details,\n reason,\n ...payloadReasonField,\n body,\n errors: fieldErrors.length > 0 ? fieldErrors : body.errors,\n }\n }\n }\n\n // Custom endpoint: { error: string, reason?: string, details?: { fieldErrors? } }\n if (typeof body.error === 'string') {\n return {\n errorMessage: `HTTP ${response.status}: ${body.error}`,\n userMessage: body.error,\n reason,\n ...payloadReasonField,\n body,\n }\n }\n\n // Fallback: { message: string }\n if (body.message) {\n return {\n errorMessage: `HTTP ${response.status}: ${body.message}`,\n userMessage: body.message,\n reason,\n ...payloadReasonField,\n body,\n }\n }\n\n return { ...fallback, reason, ...payloadReasonField, body }\n } catch {\n return fallback\n }\n}\n\n// Payload formats a thrown APIError as `{ errors: [{ name, message, data }] }`,\n// so its machine code is nested rather than top-level.\nfunction readPayloadErrorReason(errors: unknown[]): string | undefined {\n const data = (errors[0] as { data?: unknown } | null | undefined)?.data\n if (!data || typeof data !== 'object') return undefined\n const { reason, code } = data as { reason?: unknown; code?: unknown }\n if (typeof reason === 'string') return reason\n if (typeof code === 'string') return code\n return undefined\n}\n\nfunction getParsedErrorSuggestion(\n status: number,\n parsed: Awaited<ReturnType<typeof parseErrorBody>>,\n): string | undefined {\n if (status === 403 && parsed.reason === 'origin_not_allowed') {\n return 'Add the request origin to the tenant Browser API origins, then retry the browser request.'\n }\n\n return getErrorSuggestion(status)\n}\n\nasync function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n// Attach requestId to any SDKError instance (readonly bypass is intentional — internal transport layer only)\nexport function attachRequestId<T extends SDKError>(\n err: T,\n id: string | undefined,\n): T {\n if (id) (err as Record<string, unknown>).requestId = id\n return err\n}\n\nexport function parseRetryAfter(response: Response): {\n seconds?: number\n permitsAutomaticRetry: boolean\n} {\n const raw = response.headers.get('Retry-After')\n if (!raw) return { permitsAutomaticRetry: true }\n\n const trimmed = raw.trim()\n let seconds: number\n if (/^\\d+$/.test(trimmed)) {\n seconds = Number(trimmed)\n if (!Number.isSafeInteger(seconds)) {\n return { permitsAutomaticRetry: false }\n }\n } else {\n const retryAt = Date.parse(trimmed)\n if (!Number.isFinite(retryAt)) return { permitsAutomaticRetry: true }\n seconds = Math.max(0, Math.ceil((retryAt - Date.now()) / 1000))\n }\n\n return {\n seconds,\n permitsAutomaticRetry: seconds <= MAX_AUTOMATIC_RETRY_AFTER_SECONDS,\n }\n}\n\n/**\n * Single source of truth for HTTP-status → typed SDKError mapping. Both the\n * non-retryable and retryable paths go through here so the error taxonomy stays\n * consistent. Canonical commerce in-progress/lock errors may also expose it.\n */\nfunction mapResponseToError(\n status: number,\n parsed: Awaited<ReturnType<typeof parseErrorBody>>,\n details: Record<string, unknown>,\n requestId: string | undefined,\n retryAfter: number | undefined,\n canonicalCommerceError: boolean,\n): SDKError {\n const errorDetails = {\n ...details,\n ...(parsed.errors && { errors: parsed.errors }),\n ...(!canonicalCommerceError && parsed.body && { body: parsed.body }),\n }\n const suggestion = getParsedErrorSuggestion(status, parsed)\n const finalize = (error: SDKError): SDKError => {\n const withRequestId = attachRequestId(error, requestId)\n if (retryAfter !== undefined) {\n Object.assign(withRequestId, { retryAfter })\n }\n return canonicalCommerceError\n ? enhanceCommerceError(withRequestId, parsed.body, requestId)\n : enhanceNonCommerceError(\n withRequestId,\n parsed.reason ?? parsed.payloadErrorReason,\n )\n }\n\n if (status === 400 || status === 422) {\n return finalize(\n createValidationError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n status,\n ),\n )\n }\n\n if (status === 401) {\n return finalize(\n createAuthError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 403) {\n return finalize(\n createPermissionError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 404) {\n return finalize(\n createNotFoundError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 409) {\n return finalize(\n createConflictError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 410) {\n return finalize(\n createGoneError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 429) {\n // requestId is attached via attachRequestId below, matching the other\n // branches — do not also pass it to the factory.\n return finalize(\n createRateLimitError(\n parsed.errorMessage,\n retryAfter,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n if (status === 503) {\n return finalize(\n createServiceUnavailableError(\n parsed.errorMessage,\n retryAfter,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n }\n\n return finalize(\n createNetworkError(\n parsed.errorMessage,\n status,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n )\n}\n\nexport async function httpFetch(\n url: string,\n options?: FetchOptions,\n): Promise<Response> {\n const {\n apiUrl,\n publishableKey,\n secretKey,\n customerToken,\n timeout: timeoutOption = DEFAULT_TIMEOUT,\n debug,\n retry,\n onUnauthorized,\n errorFamily,\n typedCommerceErrorReasons,\n ...requestInit\n } = options || {}\n\n const baseUrl = resolveApiUrl(apiUrl)\n const method = (requestInit.method || 'GET').toUpperCase()\n const isPublishableKeyBrowserGet =\n typeof window !== 'undefined' &&\n !secretKey &&\n !customerToken &&\n Boolean(publishableKey) &&\n SAFE_METHODS.includes(method)\n\n const timeout =\n timeoutOption === DEFAULT_TIMEOUT && isPublishableKeyBrowserGet\n ? STOREFRONT_BROWSER_TIMEOUT\n : timeoutOption\n\n const retryConfig = {\n maxRetries:\n retry?.maxRetries ??\n (isPublishableKeyBrowserGet\n ? STOREFRONT_BROWSER_MAX_RETRIES\n : DEFAULT_MAX_RETRIES),\n retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,\n retryDelay:\n retry?.retryDelay ??\n ((attempt: number) => Math.min(1000 * 2 ** attempt, 10000)),\n }\n\n // Server auth: secretKey is now the raw opaque bearer token (sk01_...).\n // Customer auth: customerToken is a JWT.\n let authToken: string | undefined\n if (secretKey) {\n authToken = secretKey\n } else if (customerToken) {\n authToken = customerToken\n }\n\n let lastError: Error | undefined\n let hasRetried401 = false\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n let terminalResponseError: SDKError | undefined\n try {\n const headers = new Headers(requestInit.headers)\n\n if (publishableKey) {\n headers.set('X-Publishable-Key', publishableKey)\n }\n\n if (authToken) {\n headers.set('Authorization', `Bearer ${authToken}`)\n }\n\n if (\n !headers.has('Content-Type') &&\n requestInit.body &&\n !(requestInit.body instanceof FormData)\n ) {\n headers.set('Content-Type', 'application/json')\n }\n\n // Redact sensitive headers for debug logging\n const redactedHeaders = redactSensitiveHeaders(headers)\n\n debugLog(debug, 'request', url, {\n method: requestInit.method || 'GET',\n headers: redactedHeaders,\n attempt: attempt + 1,\n })\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const response = await fetch(`${baseUrl}${url}`, {\n ...requestInit,\n headers,\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n const requestId = response.headers.get('x-request-id') ?? undefined\n\n debugLog(debug, 'response', url, {\n status: response.status,\n statusText: response.statusText,\n headers: redactSensitiveHeaders(response.headers),\n })\n\n if (!response.ok) {\n // Parse once. Strict error families validate the envelope before any\n // retry, refresh, or quota branch acts on its fields.\n const parsed = await parseErrorBody(response)\n const canonicalCommerceError =\n errorFamily === 'commerce' ||\n (typeof parsed.reason === 'string' &&\n typedCommerceErrorReasons?.includes(parsed.reason) === true)\n const commerceEnvelope = canonicalCommerceError\n ? parseCommerceErrorEnvelope(parsed.body, requestId)\n : undefined\n\n // Usage limit 429 — never retry. Older servers identify this when\n // current usage is above the limit; newer servers also send\n // X-Usage-Exceeded to avoid confusing other 429s with quota exhaustion.\n if (isUsageLimitExceededResponse(response)) {\n const limit = parseInt(\n response.headers.get('X-Usage-Limit') || '0',\n 10,\n )\n const current = parseInt(\n response.headers.get('X-Usage-Current') || '0',\n 10,\n )\n const remaining = parseInt(\n response.headers.get('X-Usage-Remaining') || '0',\n 10,\n )\n\n const usageError = attachRequestId(\n createUsageLimitError(\n `Monthly API usage limit exceeded (${current.toLocaleString('en-US')}/${limit.toLocaleString('en-US')})`,\n { limit, current, remaining },\n {\n url,\n method: requestInit.method || 'GET',\n attempt: attempt + 1,\n },\n 'Monthly API call limit exceeded. Please upgrade your plan.',\n 'Upgrade your tenant plan to increase the monthly API call limit.',\n ),\n requestId,\n )\n throw canonicalCommerceError\n ? enhanceCommerceError(usageError, parsed.body, requestId)\n : enhanceNonCommerceError(usageError, parsed.reason)\n }\n\n // Auto-refresh customer token on 401 — only when reason=token_expired\n if (\n response.status === 401 &&\n onUnauthorized &&\n customerToken &&\n !hasRetried401 &&\n (commerceEnvelope?.reason ?? parsed.reason) === 'token_expired'\n ) {\n hasRetried401 = true\n try {\n const newToken = await onUnauthorized()\n if (\n newToken &&\n SAFE_METHODS.includes((requestInit.method || 'GET').toUpperCase())\n ) {\n authToken = newToken\n // This one safe resend has its own hasRetried401 bound. Keep\n // the current attempt so refresh never consumes a transient retry.\n attempt--\n continue\n }\n } catch {\n // Refresh failed, fall through to throw\n }\n }\n\n const details = {\n url,\n method: requestInit.method || 'GET',\n attempt: attempt + 1,\n }\n\n const retryAfter = parseRetryAfter(response)\n const error = mapResponseToError(\n response.status,\n parsed,\n details,\n requestId,\n retryAfter.seconds,\n canonicalCommerceError,\n )\n\n const method = (requestInit.method || 'GET').toUpperCase()\n // Rate/usage limits are terminal: never retry them even if the caller\n // lists 429 in retryableStatuses — retrying only adds load.\n const isTerminal =\n error instanceof RateLimitError || error instanceof UsageLimitError\n const responseAllowsRetry = isCommerceSDKError(error)\n ? error.retryable\n : true\n if (\n attempt < retryConfig.maxRetries &&\n SAFE_METHODS.includes(method) &&\n !isTerminal &&\n responseAllowsRetry &&\n retryAfter.permitsAutomaticRetry &&\n !NON_RETRYABLE_STATUSES.includes(response.status) &&\n retryConfig.retryableStatuses.includes(response.status)\n ) {\n lastError = error\n const retryDelay = Math.max(\n retryConfig.retryDelay(attempt),\n (retryAfter.seconds ?? 0) * 1000,\n )\n debugLog(debug, 'error', `Retrying in ${retryDelay}ms...`, error)\n await delay(retryDelay)\n continue\n }\n\n terminalResponseError = error\n throw error\n }\n\n return response\n } catch (error) {\n debugLog(debug, 'error', url, error)\n\n // The HTTP branch already applied the complete response retry policy.\n // Keep its terminal decision out of the transport-failure retry path.\n if (terminalResponseError && error === terminalResponseError) {\n throw error\n }\n\n const method = (requestInit.method || 'GET').toUpperCase()\n const isSafe = SAFE_METHODS.includes(method)\n\n if (error instanceof Error && error.name === 'AbortError') {\n const timeoutError = createTimeoutError(\n `Request timed out after ${timeout}ms.`,\n { url, timeout, attempt: attempt + 1 },\n 'The request timed out.',\n 'Please check your network connection or try again later.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = timeoutError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw timeoutError\n }\n\n if (error instanceof TypeError) {\n const networkError = createNetworkError(\n 'Network connection failed.',\n undefined,\n { url, originalError: error.message, attempt: attempt + 1 },\n 'Network connection failed.',\n 'Please check your internet connection and try again.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = networkError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw networkError\n }\n\n if (error instanceof NetworkError || error instanceof TimeoutError) {\n if (\n isSafe &&\n attempt < retryConfig.maxRetries &&\n error.status &&\n !NON_RETRYABLE_STATUSES.includes(error.status) &&\n retryConfig.retryableStatuses.includes(error.status)\n ) {\n lastError = error\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw error\n }\n\n // Re-throw any other SDKError subclass (e.g. UsageLimitError) without wrapping\n if (error instanceof SDKError) {\n throw error\n }\n\n const unknownError = createNetworkError(\n error instanceof Error\n ? error.message\n : 'An unknown network error occurred.',\n undefined,\n { url, originalError: error, attempt: attempt + 1 },\n 'An unknown error occurred.',\n 'Please try again later.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = unknownError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw unknownError\n }\n }\n\n throw lastError ?? new NetworkError('Request failed after retries')\n}\n","import type {\n ProductFallbackLocaleOption,\n ProductLocaleOption,\n} from '../../api/product-api'\n\nfunction normalizedMarket(value: string | undefined): string | undefined {\n const market = value?.trim()\n return market || undefined\n}\n\ntype ProductLocaleQueryOptions = {\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n}\n\nfunction appendProductLocaleSearchParams(\n search: URLSearchParams,\n options?: ProductLocaleQueryOptions,\n): void {\n if (options?.locale) search.set('locale', options.locale)\n if (options?.fallbackLocale !== undefined) {\n search.set(\n 'fallbackLocale',\n options.fallbackLocale === false ? 'none' : options.fallbackLocale,\n )\n }\n}\n\nexport function productDetailSearchParams(\n params: ({ slug: string } | { id: string }) & {\n market?: string\n } & ProductLocaleQueryOptions,\n): string {\n const search = new URLSearchParams()\n if ('slug' in params) {\n search.set('slug', params.slug)\n } else {\n search.set('id', params.id)\n }\n const market = normalizedMarket(params.market)\n if (market) search.set('market', market)\n appendProductLocaleSearchParams(search, params)\n return search.toString()\n}\n\nexport function listingGroupsSearchParams(\n params: {\n productIds: string[]\n market?: string\n } & ProductLocaleQueryOptions,\n): string {\n const ids = params.productIds.map(encodeURIComponent).join(',')\n const search = new URLSearchParams()\n const market = normalizedMarket(params.market)\n if (market) search.set('market', market)\n appendProductLocaleSearchParams(search, params)\n const query = search.toString()\n return `ids=${ids}${query ? `&${query}` : ''}`\n}\n\ntype ListingGroupsQueryUrlOptions = {\n market?: string\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n page?: number\n limit?: number\n sort?: string | string[]\n where?: Record<string, unknown>\n}\n\nfunction appendListingGroupsQuerySearchParams(\n search: URLSearchParams,\n options?: ListingGroupsQueryUrlOptions,\n): void {\n const market = normalizedMarket(options?.market)\n if (market) search.set('market', market)\n appendProductLocaleSearchParams(search, options)\n if (options?.page != null) search.set('page', String(options.page))\n if (options?.limit != null) search.set('limit', String(options.limit))\n if (options?.sort != null) {\n const sort = options.sort\n search.set('sort', Array.isArray(sort) ? sort.join(',') : sort)\n }\n if (options?.where != null) {\n search.set('whereJson', JSON.stringify(options.where))\n }\n}\n\n/** Server-auth GET PLP listing-groups query (full variant stock fields). */\nexport function listingPageSearchParams(\n options?: ListingGroupsQueryUrlOptions,\n): string {\n const search = new URLSearchParams()\n appendListingGroupsQuerySearchParams(search, options)\n return search.toString()\n}\n\nexport function stockSnapshotSearchParams(params: {\n variantIds: string[]\n}): string {\n return `variantIds=${params.variantIds.map(encodeURIComponent).join(',')}`\n}\n","import {\n createApiError,\n createValidationError,\n createAuthError,\n createPermissionError,\n createNotFoundError,\n createConflictError,\n createRateLimitError,\n enhanceCommerceError,\n enhanceNonCommerceError,\n SDKError,\n} from '../internal/errors'\nimport { attachRequestId, parseRetryAfter } from '../internal/utils/http'\n\n/**\n * Shared JSON response parser for BaseApi and CartApi.\n * Parses response JSON body and throws typed errors based on the `reason` field.\n * Only called for responses that passed httpFetch (i.e. response.ok = true);\n * handles application-level errors embedded in 2xx bodies.\n */\nexport async function parseApiResponse<T>(\n response: Response,\n endpoint: string,\n options: { errorFamily?: 'commerce' } = {},\n): Promise<T> {\n if (\n response.status === 204 ||\n response.headers.get('content-length') === '0'\n ) {\n return undefined as T\n }\n\n let parsed: unknown\n try {\n parsed = await response.json()\n } catch {\n throw createApiError(\n `Invalid JSON response from ${endpoint}`,\n response.status,\n undefined,\n 'Server returned an invalid response.',\n 'Check if the API endpoint is available.',\n )\n }\n\n // A 2xx body may legitimately be `null` (e.g. memberships.me when the\n // customer has no membership) or another non-object value. Only object\n // bodies can carry an application-level `{ error, reason }` envelope, so\n // short-circuit everything else as the success value instead of touching\n // `.error` on a null body (which would throw a raw TypeError).\n if (parsed === null || typeof parsed !== 'object') {\n return parsed as T\n }\n const data = parsed as Record<string, unknown>\n const hasCommerceEnvelopeSignal =\n options.errorFamily === 'commerce' &&\n ['error', 'reason', 'requestId', 'retryable', 'details'].some((key) =>\n Object.prototype.hasOwnProperty.call(data, key),\n )\n\n if (data.error || hasCommerceEnvelopeSignal) {\n const errorMessage =\n typeof data.error === 'string' ? data.error : 'Unknown API error'\n const reason = typeof data.reason === 'string' ? data.reason : undefined\n const requestId = response.headers.get('x-request-id') ?? undefined\n const retryAfter = parseRetryAfter(response).seconds\n\n let error: SDKError\n if (reason === 'validation_failed') {\n error = createValidationError(errorMessage, data, errorMessage)\n } else if (\n reason === 'token_expired' ||\n reason === 'token_invalid' ||\n reason === 'preview_token_invalid' ||\n reason === 'preview_token_required' ||\n reason === 'key_invalid' ||\n reason === 'key_revoked'\n ) {\n error = createAuthError(errorMessage, data, errorMessage)\n } else if (reason === 'forbidden') {\n error = createPermissionError(errorMessage, data, errorMessage)\n } else if (reason === 'rate_limit_exceeded') {\n error = createRateLimitError(errorMessage, retryAfter, data, errorMessage)\n } else if (reason === 'not_found') {\n error = createNotFoundError(errorMessage, data, errorMessage)\n } else if (reason === 'conflict') {\n error = createConflictError(errorMessage, data, errorMessage)\n } else {\n error = createApiError(\n errorMessage,\n response.status,\n data,\n errorMessage,\n 'An error occurred while processing the request.',\n )\n }\n const withRequestId = attachRequestId(error, requestId)\n if (retryAfter !== undefined) Object.assign(withRequestId, { retryAfter })\n throw options.errorFamily === 'commerce'\n ? enhanceCommerceError(withRequestId, data, requestId)\n : enhanceNonCommerceError(withRequestId, reason)\n }\n\n return data as T\n}\n","const operationBrand: unique symbol = Symbol('sdk-http-operation')\n\n/** Successful legacy privileged-bearer response: canonical UTC rotation deadline. */\nexport const CREDENTIAL_ROTATION_DEADLINE_HEADER =\n 'X-01-Credential-Rotation-Deadline' as const\n\n/**\n * Opt-in representation for Standard V2 PortOne action capabilities.\n *\n * The default application/json projection stays byte-shape compatible with\n * strict SDK parsers released before these capability literals existed.\n */\nexport const PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE =\n 'application/vnd.01software.portone-action-capabilities.v1+json' as const\n\nexport function requestsPortOneStandardActionCapabilities(\n accept: string | null | undefined,\n): boolean {\n return (\n accept?.trim().toLowerCase() ===\n PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE\n )\n}\n\n/** Exact opt-in only: case-insensitive after outer whitespace trimming.\n * Lists, wildcards and parameters (including q/charset) do not opt in.\n * Only applicable successful credit funding representations carry this type;\n * those responses are private, no-store. This is never payment authority.\n */\nexport const CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE =\n 'application/vnd.01software.credit-funding.v1+json' as const\n\nexport function requestsCustomerCreditFunding(\n accept: string | null | undefined,\n): boolean {\n return accept?.trim().toLowerCase() === CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE\n}\n\nexport type HttpOperation = {\n readonly [operationBrand]: true\n readonly collection: string | null\n readonly method: 'get' | 'post' | 'patch' | 'delete'\n readonly path: `/${string}`\n readonly errorFamily?: 'commerce'\n /**\n * Canonical commerce reasons emitted by an otherwise legacy-compatible\n * endpoint. Only these responses may be normalized and parsed as the strict\n * commerce envelope; every other response retains its established shape.\n */\n readonly typedCommerceErrorReasons?: readonly string[]\n}\n\nconst operation = <\n TCollection extends string | null,\n TMethod extends HttpOperation['method'],\n TPath extends `/${string}`,\n>(\n collection: TCollection,\n method: TMethod,\n path: TPath,\n errorFamily?: HttpOperation['errorFamily'],\n) =>\n Object.freeze({\n [operationBrand]: true,\n collection,\n method,\n path,\n ...(errorFamily && { errorFamily }),\n } as const)\n\nconst strictCommerceOperation = <\n TCollection extends string | null,\n TMethod extends HttpOperation['method'],\n TPath extends `/${string}`,\n>(\n collection: TCollection,\n method: TMethod,\n path: TPath,\n) => operation(collection, method, path, 'commerce')\n\nconst selectiveCommerceOperation = <\n TCollection extends string | null,\n TMethod extends HttpOperation['method'],\n TPath extends `/${string}`,\n TReasons extends readonly [string, ...string[]],\n>(\n collection: TCollection,\n method: TMethod,\n path: TPath,\n typedCommerceErrorReasons: TReasons,\n) =>\n Object.freeze({\n ...operation(collection, method, path),\n typedCommerceErrorReasons: Object.freeze([...typedCommerceErrorReasons]),\n } as const)\n\nexport const COMMERCE_ENDPOINT_OPERATIONS = {\n products: {\n detail: operation('products', 'get', '/detail'),\n detailCatalog: operation('products', 'get', '/detail/catalog'),\n listingGroups: operation('products', 'get', '/listing-groups'),\n listingGroupsCatalog: operation(\n 'products',\n 'get',\n '/listing-groups/catalog',\n ),\n listingGroupsQuery: operation('products', 'post', '/listing-groups/query'),\n listingGroupsQueryGet: operation(\n 'products',\n 'get',\n '/listing-groups/query',\n ),\n listingGroupsQueryCatalog: operation(\n 'products',\n 'get',\n '/listing-groups/query/catalog',\n ),\n stockCheck: operation('products', 'post', '/stock-check'),\n stockSnapshot: operation('products', 'get', '/stock'),\n upsert: operation('products', 'post', '/upsert'),\n graphRevision: operation('products', 'get', '/:id/graph-revision'),\n variantsPatch: operation('products', 'patch', '/:id/variants'),\n },\n orders: {\n create: operation('orders', 'post', '/create'),\n update: operation('orders', 'post', '/update'),\n confirmPayment: operation('orders', 'post', '/confirm-payment'),\n byPayment: operation('orders', 'get', '/by-payment'),\n cancel: operation('orders', 'post', '/cancel'),\n resolveCancelRefund: selectiveCommerceOperation(\n 'orders',\n 'post',\n '/resolve-cancel-refund',\n ['managed_refund_attestation_forbidden'],\n ),\n checkout: strictCommerceOperation('orders', 'post', '/checkout'),\n createFulfillment: operation('orders', 'post', '/create-fulfillment'),\n updateFulfillment: operation('orders', 'post', '/update-fulfillment'),\n },\n checkouts: {\n detail: strictCommerceOperation('checkouts', 'post', '/detail'),\n query: strictCommerceOperation('checkouts', 'post', '/query'),\n },\n draftOrders: {\n calculate: operation('draft-orders', 'post', '/:id/calculate'),\n complete: operation('draft-orders', 'post', '/:id/complete'),\n finalize: operation('draft-orders', 'post', '/:id/finalize'),\n },\n transactions: {\n update: operation('transactions', 'post', '/update'),\n },\n returns: {\n create: operation('returns', 'post', '/create'),\n update: operation('returns', 'post', '/update'),\n returnRefund: operation('returns', 'post', '/return-refund'),\n },\n fulfillmentOrders: {\n prepare: operation(\n 'fulfillment-orders',\n 'post',\n '/prepare-fulfillment-order',\n ),\n },\n fulfillments: {\n bulkImport: operation('fulfillments', 'post', '/bulk-import'),\n },\n carts: {\n create: strictCommerceOperation('carts', 'post', '/create'),\n retrieve: strictCommerceOperation('carts', 'post', '/retrieve'),\n mine: strictCommerceOperation('carts', 'post', '/mine'),\n merge: strictCommerceOperation('carts', 'post', '/merge'),\n addItem: strictCommerceOperation('carts', 'post', '/add-item'),\n updateItem: strictCommerceOperation('carts', 'post', '/update-item'),\n removeItem: strictCommerceOperation('carts', 'post', '/remove-item'),\n updateDiscountCodes: strictCommerceOperation(\n 'carts',\n 'post',\n '/update-discount-codes',\n ),\n updateAttributes: strictCommerceOperation(\n 'carts',\n 'post',\n '/update-attributes',\n ),\n clear: strictCommerceOperation('carts', 'post', '/clear'),\n },\n paymentSessions: {\n create: strictCommerceOperation('payment-sessions', 'post', '/create'),\n retrieve: strictCommerceOperation('payment-sessions', 'post', '/retrieve'),\n cancel: strictCommerceOperation('payment-sessions', 'post', '/cancel'),\n server: {\n create: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/create',\n ),\n retrieve: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/retrieve',\n ),\n cancel: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/cancel',\n ),\n confirm: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/confirm',\n ),\n findPortOne: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/portone/find',\n ),\n reconcilePortOne: strictCommerceOperation(\n 'payment-sessions',\n 'post',\n '/server/portone/reconcile',\n ),\n },\n custom: {\n create: operation('orders', 'post', '/custom-payment-sessions'),\n retrieve: operation(\n 'orders',\n 'post',\n '/custom-payment-sessions/retrieve',\n ),\n confirm: operation('orders', 'post', '/custom-payment-sessions/confirm'),\n },\n },\n shippingPolicies: {\n calculate: operation('shipping-policies', 'post', '/calculate'),\n },\n discounts: {\n validate: operation('discounts', 'post', '/validate'),\n },\n} as const\n\nconst portOneStandardActionCapabilityOperations = new Set<HttpOperation>([\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.create,\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.retrieve,\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.create,\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.retrieve,\n])\n\n/**\n * Whether this operation may negotiate the Standard V2 capability projection.\n *\n * Create still requires a Standard V2 request profile, while retrieve discovers\n * the provider/profile from the stored session. Cancel and confirm deliberately\n * remain on the released JSON representation.\n */\nexport function supportsPortOneStandardActionCapabilityNegotiation(\n descriptor: HttpOperation,\n): boolean {\n return portOneStandardActionCapabilityOperations.has(descriptor)\n}\n\nexport const MEMBERSHIP_ENDPOINT_OPERATIONS = {\n subscribe: operation(null, 'post', '/memberships/subscribe'),\n endSubscribeIntent: operation(\n null,\n 'post',\n '/memberships/subscribe-intent/end',\n ),\n billingCustody: operation(null, 'post', '/memberships/billing-custody'),\n cancel: operation(null, 'post', '/memberships/:id/cancel'),\n me: operation(null, 'get', '/memberships/me'),\n chargeResult: operation(null, 'post', '/memberships/:id/charge-result'),\n refundResult: operation(null, 'post', '/memberships/:id/refund-result'),\n revoke: operation(null, 'post', '/memberships/:id/revoke'),\n} as const\n\n/** Server-only tenant-owned operations; no raw claim collection is published. */\nexport const EXTERNAL_EFFECT_CLAIM_ENDPOINT_OPERATIONS = {\n claim: operation(null, 'post', '/external-effect-claims/claim'),\n get: operation(null, 'post', '/external-effect-claims/get'),\n arm: operation(null, 'post', '/external-effect-claims/arm'),\n release: operation(null, 'post', '/external-effect-claims/release'),\n report: operation(null, 'post', '/external-effect-claims/report'),\n recovery: operation(null, 'post', '/external-effect-claims/recovery'),\n} as const\n\n/** Bound-server, purpose-specific installation ciphertext operations. */\nexport const INSTALLATION_CREDENTIAL_ENDPOINT_OPERATIONS = {\n create: operation(null, 'post', '/installation-credentials/create'),\n get: operation(null, 'post', '/installation-credentials/get'),\n replace: operation(null, 'post', '/installation-credentials/replace'),\n dispose: operation(null, 'post', '/installation-credentials/dispose'),\n} as const\n\n/** Server-only shaped external Customer links owned by the Customers bucket. */\nexport const EXTERNAL_CUSTOMER_LINK_ENDPOINT_OPERATIONS = {\n connect: operation('customers', 'post', '/external-links/connect'),\n get: operation('customers', 'post', '/external-links/get'),\n list: operation('customers', 'post', '/external-links/list'),\n unlink: operation('customers', 'post', '/external-links/unlink'),\n capturePreviousState: operation(\n 'customers',\n 'post',\n '/external-links/capture-previous-state',\n ),\n clearPreviousState: operation(\n 'customers',\n 'post',\n '/external-links/clear-previous-state',\n ),\n} as const\n\n/** Customer-owned single-use benefit vouchers. */\nexport const BENEFIT_VOUCHER_ENDPOINT_OPERATIONS = {\n issue: operation('customers', 'post', '/benefit-vouchers/issue'),\n get: operation('customers', 'post', '/benefit-vouchers/get'),\n list: operation('customers', 'post', '/benefit-vouchers/list'),\n redeem: operation('customers', 'post', '/benefit-vouchers/redeem'),\n void: operation('customers', 'post', '/benefit-vouchers/void'),\n listMine: operation('customers', 'get', '/me/benefit-vouchers'),\n} as const\n\n/** Credit commands are server-only; self reads require a Customer session.\n * Configuration is Console-session-only and has no SDK method. */\nexport const CUSTOMER_CREDIT_ENDPOINT_OPERATIONS = {\n grant: strictCommerceOperation('customers', 'post', '/credits/grant'),\n getGrant: strictCommerceOperation('customers', 'post', '/credits/get-grant'),\n getAccount: strictCommerceOperation('customers', 'post', '/credits/account'),\n revoke: strictCommerceOperation('customers', 'post', '/credits/revoke'),\n mine: strictCommerceOperation('customers', 'get', '/me/credits'),\n history: strictCommerceOperation('customers', 'get', '/me/credits/history'),\n configure: strictCommerceOperation(\n 'customers',\n 'post',\n '/credits/configuration',\n ),\n} as const\n\n/** Server-authenticated source-aware Customer Group authority operations. */\nexport const CUSTOMER_GROUP_ENDPOINT_OPERATIONS = {\n members: operation('customer-groups', 'get', '/:id/members'),\n grant: operation('customer-groups', 'post', '/:id/members/grant'),\n revoke: operation('customer-groups', 'post', '/:id/members/revoke'),\n} as const\n\n/** Browser-public customer self actions; each operation owns its authentication. */\nexport const CUSTOMER_AUTH_ENDPOINT_OPERATIONS = {\n register: operation('customers', 'post', '/register'),\n login: operation('customers', 'post', '/login'),\n refresh: operation('customers', 'post', '/refresh'),\n me: operation('customers', 'get', '/me'),\n updateProfile: operation('customers', 'patch', '/me'),\n forgotPassword: operation('customers', 'post', '/forgot-password'),\n resetPassword: operation('customers', 'post', '/reset-password'),\n changePassword: operation('customers', 'post', '/change-password'),\n\n revokeRefresh: operation('customers', 'post', '/revoke-refresh'),\n withdraw: operation('customers', 'post', '/withdraw'),\n} as const\n\n/** PAT-only operator controls for the active tenant embedded admin binding. */\nexport const EMBEDDED_ADMIN_ENDPOINT_OPERATIONS = {\n show: operation('tenants', 'get', '/embedded-admin-app'),\n configure: operation('tenants', 'patch', '/embedded-admin-app'),\n disable: operation('tenants', 'delete', '/embedded-admin-app'),\n} as const\n\n/** CLI-only active-tenant Admin Panel field visibility; never API authorization. */\nexport const FIELD_CONFIG_ENDPOINT_OPERATIONS = {\n list: operation('field-configs', 'get', '/list'),\n save: operation('field-configs', 'post', '/save'),\n} as const\n\n/** Shaped event operations shared by their owning runtime and SDK surfaces. */\nexport const EVENTS_ENDPOINT_OPERATIONS = {\n registrations: {\n register: operation('event-registrations', 'post', '/register'),\n guestLookup: operation('event-registrations', 'post', '/guest/lookup'),\n guestLookupByUrl: operation('event-registrations', 'get', '/guest/:token'),\n guestCancel: operation('event-registrations', 'post', '/guest/cancel'),\n guestCancelByUrl: operation(\n 'event-registrations',\n 'post',\n '/guest/:token/cancel',\n ),\n listMine: operation('event-registrations', 'get', '/my'),\n },\n events: {\n convertSchedule: operation('events', 'post', '/:id/schedule'),\n },\n occurrences: {\n range: operation('event-occurrences', 'get', '/range'),\n admissionAvailability: operation(\n 'event-occurrences',\n 'get',\n '/admission-availability',\n ),\n },\n} as const\n\n/** Public, shaped browser reads served by community collections. */\nexport const COMMUNITY_ENDPOINT_OPERATIONS = {\n posts: {\n detail: operation('posts', 'get', '/detail'),\n },\n} as const\n\n/** Public, shaped gallery item reads. Linked raw videos remain server-only. */\nexport const GALLERY_ENDPOINT_OPERATIONS = {\n items: {\n storefront: operation('gallery-items', 'get', '/storefront'),\n },\n} as const\n\n/** Public, shaped VOD playback admission. Raw videos remain server-only. */\nexport const VIDEO_ENDPOINT_OPERATIONS = {\n playback: operation('videos', 'post', '/:id/playback'),\n} as const\n\nexport function resolveOperationTemplate(descriptor: HttpOperation): string {\n return descriptor.collection\n ? `/api/${descriptor.collection}${descriptor.path}`\n : `/api${descriptor.path}`\n}\n\nexport function resolveOperationPath(\n descriptor: HttpOperation,\n options?: {\n pathParams?: Readonly<Record<string, string>>\n query?: string | URLSearchParams\n },\n): string {\n const path = resolveOperationTemplate(descriptor).replace(\n /:([A-Za-z][A-Za-z0-9_]*)/g,\n (_, key) => {\n const value = options?.pathParams?.[key]\n if (value === undefined) {\n throw new TypeError(`Missing path parameter: ${key}`)\n }\n return encodeURIComponent(value)\n },\n )\n const unresolved = path.match(/:([A-Za-z][A-Za-z0-9_]*)/)\n if (unresolved) {\n throw new TypeError(`Missing path parameter: ${unresolved[1]}`)\n }\n\n const query = options?.query?.toString().replace(/^\\?/, '')\n return query ? `${path}?${query}` : path\n}\n\nexport function resolveOperationMethod(\n descriptor: HttpOperation,\n): Uppercase<HttpOperation['method']> {\n return descriptor.method.toUpperCase() as Uppercase<HttpOperation['method']>\n}\n","// SDK-facing semantic view over the shared commerce transport manifest.\n//\n// The private http-contracts workspace package is the sole authority for\n// commerce and membership transport identity (collection, method, path).\n// Console mounts the same operations, and\n// `apps/console/tests/unit/sdk/endpoint-contract-parity.test.ts` proves each\n// declared operation is registered exactly once with a handler — see\n// `docs/contracts/platform/public-api-boundary.md` (PLAT-API-016).\n//\n// This module only groups those operations under the names the SDK APIs call\n// them by, including the deliberate browser/server aliases that are an\n// authorization lane rather than a second transport. It must not declare a\n// method or path literal; `tests/unit/api/endpoint-transport-authority.test.ts`\n// fails closed if one reappears.\n//\n// Keep this internal — it is the transport contract, not public SDK surface.\nimport {\n CUSTOMER_GROUP_ENDPOINT_OPERATIONS,\n EXTERNAL_CUSTOMER_LINK_ENDPOINT_OPERATIONS,\n BENEFIT_VOUCHER_ENDPOINT_OPERATIONS,\n CUSTOMER_CREDIT_ENDPOINT_OPERATIONS,\n COMMERCE_ENDPOINT_OPERATIONS,\n EXTERNAL_EFFECT_CLAIM_ENDPOINT_OPERATIONS,\n INSTALLATION_CREDENTIAL_ENDPOINT_OPERATIONS,\n MEMBERSHIP_ENDPOINT_OPERATIONS,\n PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE,\n CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE,\n type HttpOperation,\n} from '@01.software/http-contracts'\n\nexport {\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\nexport {\n CUSTOMER_GROUP_ENDPOINT_OPERATIONS,\n CUSTOMER_CREDIT_ENDPOINT_OPERATIONS,\n EXTERNAL_CUSTOMER_LINK_ENDPOINT_OPERATIONS,\n BENEFIT_VOUCHER_ENDPOINT_OPERATIONS,\n COMMERCE_ENDPOINT_OPERATIONS,\n EXTERNAL_EFFECT_CLAIM_ENDPOINT_OPERATIONS,\n INSTALLATION_CREDENTIAL_ENDPOINT_OPERATIONS,\n MEMBERSHIP_ENDPOINT_OPERATIONS,\n PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE,\n CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE,\n}\n\nexport type CommerceEndpointDescriptor = HttpOperation\n\n/**\n * Widens a manifest operation to the nameable `HttpOperation` type. Without it\n * the inferred literal type leaks the manifest's private brand symbol into the\n * SDK declaration output (TS4023).\n */\nconst sharedEndpoint = (descriptor: HttpOperation): HttpOperation => descriptor\n\nexport function resolveOperationErrorFamily(\n descriptor: CommerceEndpointDescriptor,\n): 'commerce' | undefined {\n return descriptor.errorFamily\n}\n\nexport function resolveOperationTypedCommerceErrorReasons(\n descriptor: CommerceEndpointDescriptor,\n): readonly string[] | undefined {\n return descriptor.typedCommerceErrorReasons\n}\n\nexport const COMMERCE_ENDPOINTS = {\n products: {\n detail: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.products.detail),\n detailCatalog: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,\n ),\n listingGroups: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroups,\n ),\n listingGroupsCatalog: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,\n ),\n // The manifest keeps the GET read and the POST body-query apart; this\n // semantic name has always resolved to the GET one.\n listingGroupsQuery: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryGet,\n ),\n listingGroupsQueryCatalog: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryCatalog,\n ),\n stockCheck: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockCheck,\n ),\n stockSnapshot: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockSnapshot,\n ),\n upsert: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.products.upsert),\n },\n orders: {\n update: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.update),\n byPayment: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.byPayment),\n cancel: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.cancel),\n resolveCancelRefund: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.orders.resolveCancelRefund,\n ),\n createFulfillment: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.orders.createFulfillment,\n ),\n updateFulfillment: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.orders.updateFulfillment,\n ),\n },\n checkouts: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.checkout),\n retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.checkouts.detail),\n server: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.checkout),\n retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.checkouts.detail),\n query: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.checkouts.query),\n },\n },\n returns: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.returns.create),\n update: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.returns.update),\n returnRefund: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.returns.returnRefund,\n ),\n },\n fulfillmentOrders: {\n prepare: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.fulfillmentOrders.prepare,\n ),\n },\n fulfillments: {\n bulkImport: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.fulfillments.bulkImport,\n ),\n },\n carts: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.create),\n retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.retrieve),\n mine: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.mine),\n merge: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.merge),\n server: {\n // Server credentials are an authorization lane, not a second Cart\n // transport. These must stay bound to the registered shared operations.\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.create),\n retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.retrieve),\n mine: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.mine),\n merge: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.merge),\n addItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.addItem),\n updateItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.updateItem),\n removeItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.removeItem),\n updateDiscountCodes: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.carts.updateDiscountCodes,\n ),\n updateAttributes: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.carts.updateAttributes,\n ),\n clear: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.clear),\n },\n addItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.addItem),\n updateItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.updateItem),\n removeItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.removeItem),\n updateDiscountCodes: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.carts.updateDiscountCodes,\n ),\n updateAttributes: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.carts.updateAttributes,\n ),\n clear: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.clear),\n },\n paymentSessions: {\n create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.create),\n retrieve: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.retrieve,\n ),\n cancel: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.cancel),\n custom: {\n create: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.custom.create,\n ),\n retrieve: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.custom.retrieve,\n ),\n confirm: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.custom.confirm,\n ),\n },\n server: {\n create: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.create,\n ),\n retrieve: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.retrieve,\n ),\n cancel: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.cancel,\n ),\n confirm: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.confirm,\n ),\n findPortOne: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.findPortOne,\n ),\n reconcilePortOne: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.reconcilePortOne,\n ),\n },\n },\n shippingPolicies: {\n calculate: sharedEndpoint(\n COMMERCE_ENDPOINT_OPERATIONS.shippingPolicies.calculate,\n ),\n },\n} as const\n","import { createConfigError, SDKError } from '../internal/errors'\nimport { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\nimport { parseApiResponse } from './parse-response'\nimport {\n resolveOperationErrorFamily,\n resolveOperationMethod,\n resolveOperationPath,\n type CommerceEndpointDescriptor,\n} from './endpoints'\n\nexport interface CustomerScopedApiOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n requiresCredential?: boolean\n}\n\nexport interface CustomerScopedRequestOptions {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n body?: unknown\n headers?: Record<string, string>\n errorFamily?: 'commerce'\n}\n\ntype EndpointRequestOptions = {\n headers?: Record<string, string>\n pathParams?: Readonly<Record<string, string>>\n query?: string | URLSearchParams\n}\n\nclass CustomerScopedTransport {\n private readonly publishableKey: string\n private readonly secretKey?: string\n private readonly apiUrl?: string\n private readonly customerToken?: string | (() => string | null)\n private readonly onUnauthorized?: () => Promise<string | null>\n private readonly onRequestId?: (id: string | null) => void\n\n constructor(apiName: string, options: CustomerScopedApiOptions) {\n if (\n options.requiresCredential !== false &&\n !options.secretKey &&\n !options.customerToken\n ) {\n throw createConfigError(\n `Either secretKey or customerToken is required for ${apiName}.`,\n )\n }\n\n this.publishableKey = requirePublishableKeyForSecret(\n apiName,\n options.publishableKey,\n options.secretKey,\n )\n this.secretKey = options.secretKey\n this.apiUrl = options.apiUrl\n this.customerToken = options.customerToken\n this.onUnauthorized = options.onUnauthorized\n this.onRequestId = options.onRequestId\n }\n\n async request<T>(\n endpoint: string,\n options: CustomerScopedRequestOptions,\n ): Promise<T> {\n const token =\n typeof this.customerToken === 'function'\n ? this.customerToken()\n : this.customerToken\n\n try {\n const response = await httpFetch(endpoint, {\n method: options.method,\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n customerToken: token ?? undefined,\n ...(token &&\n this.onUnauthorized && { onUnauthorized: this.onUnauthorized }),\n ...(options.body !== undefined && {\n body: JSON.stringify(options.body),\n }),\n ...(options.headers && { headers: options.headers }),\n ...(options.errorFamily && { errorFamily: options.errorFamily }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint, {\n errorFamily: options.errorFamily,\n })\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n}\n\n/** Operation-only base for customer-scoped commerce APIs. */\nexport class CustomerScopedApi {\n private readonly transport: CustomerScopedTransport\n\n constructor(apiName: string, options: CustomerScopedApiOptions) {\n this.transport = new CustomerScopedTransport(apiName, options)\n }\n\n protected requestEndpoint<T>(\n endpoint: CommerceEndpointDescriptor,\n body?: unknown,\n options?: EndpointRequestOptions,\n ): Promise<T> {\n return this.transport.request<T>(resolveOperationPath(endpoint, options), {\n method: resolveOperationMethod(endpoint),\n body,\n headers: options?.headers,\n errorFamily: resolveOperationErrorFamily(endpoint),\n })\n }\n}\n\n/** Raw transport base reserved for non-commerce customer-scoped APIs. */\nexport class RawCustomerScopedApi {\n private readonly transport: CustomerScopedTransport\n\n constructor(apiName: string, options: CustomerScopedApiOptions) {\n this.transport = new CustomerScopedTransport(apiName, options)\n }\n\n protected request<T>(\n endpoint: string,\n options: CustomerScopedRequestOptions,\n ): Promise<T> {\n return this.transport.request<T>(endpoint, options)\n }\n}\n","import { createApiError } from '../internal/errors'\nexport const BENEFIT_VOUCHER_VOID_REASONS = [\n 'issued_in_error',\n 'benefit_revoked',\n 'customer_request',\n 'other',\n] as const\nexport const BENEFIT_VOUCHER_ERROR_REASONS = [\n 'invalid_request',\n 'forbidden',\n 'customer_not_found',\n 'customer_ineligible',\n 'definition_not_found',\n 'definition_archived',\n 'definition_in_use',\n 'voucher_not_found',\n 'source_conflict',\n 'request_conflict',\n 'voucher_already_redeemed',\n 'voucher_voided',\n 'voucher_expired',\n 'feature_disabled',\n 'authority_unavailable',\n 'internal_error',\n] as const\nexport type BenefitVoucherErrorReason =\n (typeof BENEFIT_VOUCHER_ERROR_REASONS)[number]\nexport type CustomerBenefitVoucher = {\n id: string\n name: string\n description: string | null\n state: 'issued' | 'redeemed' | 'expired' | 'voided'\n issuedAt: string\n expiresAt: string\n closedAt: string | null\n}\nexport type BenefitVoucher = {\n id: string\n name: string\n description: string | null\n state: CustomerBenefitVoucher['state']\n issuedAt: string\n expiresAt: string\n customerId: string\n definitionId: string\n source: { namespace: string; ref: string }\n closed: null | {\n at: string\n channel: 'server' | 'console'\n actor: { type: 'server_credential' | 'operator'; id: string }\n actorRef: string | null\n voidReason: (typeof BENEFIT_VOUCHER_VOID_REASONS)[number] | null\n }\n}\nexport type IssueBenefitVoucherRequest = {\n definitionId: string\n customerId: string\n sourceNamespace: string\n sourceRef: string\n expiresAt?: string\n}\nexport type GetBenefitVoucherRequest = { customerId: string; voucherId: string }\nexport type RedeemBenefitVoucherRequest = GetBenefitVoucherRequest & {\n requestId: string\n actorRef: string\n}\nexport type VoidBenefitVoucherRequest = RedeemBenefitVoucherRequest & {\n reason: (typeof BENEFIT_VOUCHER_VOID_REASONS)[number]\n}\nexport type ListBenefitVouchersRequest = {\n customerId: string\n state?: BenefitVoucher['state']\n definitionId?: string\n limit?: number\n cursor?: string\n}\nexport type ListMyBenefitVouchersRequest = {\n status?: 'available' | 'all'\n limit?: number\n cursor?: string\n}\nexport type IssueBenefitVoucherResponse = {\n voucher: BenefitVoucher\n created: boolean\n}\nexport type MutateBenefitVoucherResponse = {\n voucher: BenefitVoucher\n replayed: boolean\n}\nexport type ListBenefitVouchersResponse = {\n vouchers: BenefitVoucher[]\n nextCursor: string | null\n evaluatedAt: string\n}\nexport type ListMyBenefitVouchersResponse = {\n vouchers: CustomerBenefitVoucher[]\n nextCursor: string | null\n evaluatedAt: string\n}\n\nexport function invalidBenefitVoucherResponse(): never {\n throw createApiError('Invalid benefit voucher response', 200)\n}\nfunction object(value: unknown, keys: string[]): Record<string, unknown> {\n if (\n !value ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n Object.keys(value).length !== keys.length ||\n keys.some((key) => !(key in value))\n )\n invalidBenefitVoucherResponse()\n return value as Record<string, unknown>\n}\nconst uuid = (v: unknown): v is string =>\n typeof v === 'string' &&\n (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(\n v,\n ) ||\n v === '00000000-0000-0000-0000-000000000000' ||\n v.toLowerCase() === 'ffffffff-ffff-ffff-ffff-ffffffffffff')\nconst time = (v: unknown): v is string =>\n typeof v === 'string' &&\n /^\\d{4}-\\d{2}-\\d{2}T/.test(v) &&\n Number.isFinite(Date.parse(v)) &&\n new Date(Date.parse(v)).toISOString() === v\nconst actor = (v: unknown): v is string =>\n typeof v === 'string' && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(v)\nexport function parseBenefitVoucher(\n value: unknown,\n mine: true,\n): CustomerBenefitVoucher\nexport function parseBenefitVoucher(\n value: unknown,\n mine?: false,\n): BenefitVoucher\nexport function parseBenefitVoucher(\n value: unknown,\n mine = false,\n): CustomerBenefitVoucher | BenefitVoucher {\n const v = object(value, [\n 'id',\n 'name',\n 'description',\n 'state',\n 'issuedAt',\n 'expiresAt',\n ...(mine\n ? ['closedAt']\n : ['customerId', 'definitionId', 'source', 'closed']),\n ])\n if (\n !uuid(v.id) ||\n typeof v.name !== 'string' ||\n !v.name.length ||\n v.name.length > 120 ||\n (v.description !== null &&\n (typeof v.description !== 'string' || v.description.length > 1000)) ||\n !['issued', 'redeemed', 'expired', 'voided'].includes(v.state as string) ||\n !time(v.issuedAt) ||\n !time(v.expiresAt)\n )\n invalidBenefitVoucherResponse()\n if (mine) {\n if (v.closedAt !== null && !time(v.closedAt))\n invalidBenefitVoucherResponse()\n } else {\n if (!uuid(v.customerId) || !uuid(v.definitionId))\n invalidBenefitVoucherResponse()\n const source = object(v.source, ['namespace', 'ref'])\n if (\n typeof source.namespace !== 'string' ||\n !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(source.namespace) ||\n typeof source.ref !== 'string' ||\n !source.ref.length ||\n source.ref.length > 256\n )\n invalidBenefitVoucherResponse()\n if (v.closed !== null) {\n const closed = object(v.closed, [\n 'at',\n 'channel',\n 'actor',\n 'actorRef',\n 'voidReason',\n ])\n const principal = object(closed.actor, ['type', 'id'])\n if (\n !time(closed.at) ||\n !uuid(principal.id) ||\n !['server', 'console'].includes(closed.channel as string) ||\n !['server_credential', 'operator'].includes(principal.type as string) ||\n (closed.actorRef !== null && !actor(closed.actorRef)) ||\n (closed.voidReason !== null &&\n !BENEFIT_VOUCHER_VOID_REASONS.includes(closed.voidReason as never))\n )\n invalidBenefitVoucherResponse()\n }\n }\n return value as CustomerBenefitVoucher | BenefitVoucher\n}\nexport function parseBenefitVoucherList(\n value: unknown,\n mine: true,\n): ListMyBenefitVouchersResponse\nexport function parseBenefitVoucherList(\n value: unknown,\n mine?: false,\n): ListBenefitVouchersResponse\nexport function parseBenefitVoucherList(\n value: unknown,\n mine = false,\n): ListMyBenefitVouchersResponse | ListBenefitVouchersResponse {\n const v = object(value, ['vouchers', 'nextCursor', 'evaluatedAt'])\n if (\n !Array.isArray(v.vouchers) ||\n v.vouchers.length > 100 ||\n !time(v.evaluatedAt) ||\n (v.nextCursor !== null &&\n (typeof v.nextCursor !== 'string' ||\n !v.nextCursor.length ||\n v.nextCursor.length > 2048))\n )\n invalidBenefitVoucherResponse()\n for (const row of v.vouchers) {\n if (mine) parseBenefitVoucher(row, true)\n else parseBenefitVoucher(row)\n }\n return value as ListMyBenefitVouchersResponse | ListBenefitVouchersResponse\n}\n","import { CustomerScopedApi } from './customer-scoped-api'\nimport { BENEFIT_VOUCHER_ENDPOINT_OPERATIONS } from './endpoints'\nimport {\n parseBenefitVoucherList,\n type ListMyBenefitVouchersRequest,\n type ListMyBenefitVouchersResponse,\n} from './benefit-voucher-types'\nexport class CustomerBenefitVouchersApi extends CustomerScopedApi {\n async listMine(\n params: ListMyBenefitVouchersRequest = {},\n ): Promise<ListMyBenefitVouchersResponse> {\n const query = new URLSearchParams()\n for (const [key, value] of Object.entries(params))\n if (value !== undefined) query.set(key, String(value))\n return parseBenefitVoucherList(\n await this.requestEndpoint<unknown>(\n BENEFIT_VOUCHER_ENDPOINT_OPERATIONS.listMine,\n undefined,\n { query },\n ),\n true,\n )\n }\n}\n","import { createApiError } from '../internal/errors'\n\n/** Non-negative integer KRW, encoded without loss of aggregate precision. */\nexport type CustomerCreditBalances = {\n available: string\n held: string\n spent: string\n expired: string\n revoked: string\n}\nexport type GetCustomerCreditGrantRequest = {\n sourceNamespace: string\n sourceRef: string\n}\nexport type GrantCustomerCreditRequest = GetCustomerCreditGrantRequest & {\n customerId: string\n templateId: string\n amount?: number\n}\nexport type RevokeCustomerCreditRequest = GetCustomerCreditGrantRequest\nexport type CustomerCreditGrant = GetCustomerCreditGrantRequest & {\n id: string\n customerId: string\n templateId: string\n templateVersion: number\n mode: 'fixed' | 'bounded'\n maximum: string\n amount: string\n currency: 'KRW'\n validityDays: number\n grantedAt: string\n expiresAt: string\n}\nexport type RevokeCustomerCreditResponse = {\n revoked: string\n pending: string\n spent: string\n}\nexport type MyCustomerCreditsRequest = { page?: number }\nexport type MyCustomerCreditHistoryRequest = MyCustomerCreditsRequest\nexport type MyCustomerCreditsResponse = {\n currency: 'KRW'\n evaluatedAt: string\n granted: string\n balances: CustomerCreditBalances\n buckets: {\n id: string\n grantId: string\n kind: 'original' | 'grace'\n grantedAt: string\n expiresAt: string\n isRevoked: boolean\n balances: CustomerCreditBalances\n }[]\n page: number\n hasNextPage: boolean\n}\nexport type MyCustomerCreditHistoryResponse = {\n currency: 'KRW'\n evaluatedAt: string\n entries: {\n id: string\n grantId: string\n kind:\n | 'grant'\n | 'reserve'\n | 'consume'\n | 'release'\n | 'restore'\n | 'expire'\n | 'revoke'\n amount: string\n fromState: keyof CustomerCreditBalances | null\n toState: keyof CustomerCreditBalances | null\n createdAt: string\n }[]\n page: number\n hasNextPage: boolean\n}\nexport type GetCustomerCreditAccountRequest = {\n customerId: string\n page?: number\n}\nexport type CustomerCreditAccountResponse = {\n summary: MyCustomerCreditsResponse\n history: MyCustomerCreditHistoryResponse\n}\n\nexport function parseCustomerCreditAccount(\n value: unknown,\n): CustomerCreditAccountResponse {\n const data = object(value, ['summary', 'history'])\n return {\n summary: parseMyCustomerCredits(data.summary),\n history: parseMyCustomerCreditHistory(data.history),\n }\n}\n\nfunction invalid(): never {\n throw createApiError('Invalid customer credit response', 502)\n}\nfunction object(\n value: unknown,\n keys: readonly string[],\n): Record<string, unknown> {\n if (\n !value ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n Object.keys(value).length !== keys.length ||\n keys.some((key) => !Object.prototype.hasOwnProperty.call(value, key))\n )\n invalid()\n return value as Record<string, unknown>\n}\nfunction money(value: unknown): value is string {\n return typeof value === 'string' && /^(0|[1-9][0-9]*)$/.test(value)\n}\nfunction uuid(value: unknown): value is string {\n return (\n typeof value === 'string' &&\n /^([0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i.test(\n value,\n )\n )\n}\nfunction time(value: unknown): value is string {\n if (typeof value !== 'string') return false\n const match =\n /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.\\d+)?Z$/.exec(value)\n if (!match) return false\n const [, year, month, day, hour, minute, second = '0'] = match\n const y = Number(year),\n m = Number(month),\n d = Number(day)\n const days = [\n 31,\n y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0) ? 29 : 28,\n 31,\n 30,\n 31,\n 30,\n 31,\n 31,\n 30,\n 31,\n 30,\n 31,\n ]\n return (\n m >= 1 &&\n m <= 12 &&\n d >= 1 &&\n d <= days[m - 1]! &&\n Number(hour) < 24 &&\n Number(minute) < 60 &&\n Number(second) < 60\n )\n}\nconst states = ['available', 'held', 'spent', 'expired', 'revoked'] as const\nfunction balances(value: unknown): void {\n const data = object(value, states)\n if (states.some((key) => !money(data[key]))) invalid()\n}\nfunction page(value: Record<string, unknown>): void {\n if (\n value.currency !== 'KRW' ||\n !time(value.evaluatedAt) ||\n !Number.isSafeInteger(value.page) ||\n (value.page as number) < 1 ||\n typeof value.hasNextPage !== 'boolean'\n )\n invalid()\n}\n\nexport function parseCustomerCreditGrant(value: unknown): CustomerCreditGrant {\n const data = object(value, [\n 'id',\n 'customerId',\n 'templateId',\n 'templateVersion',\n 'mode',\n 'maximum',\n 'amount',\n 'currency',\n 'validityDays',\n 'grantedAt',\n 'expiresAt',\n 'sourceNamespace',\n 'sourceRef',\n ])\n if (\n !uuid(data.id) ||\n !uuid(data.customerId) ||\n !uuid(data.templateId) ||\n !Number.isSafeInteger(data.templateVersion) ||\n (data.templateVersion as number) < 1 ||\n !['fixed', 'bounded'].includes(data.mode as string) ||\n !money(data.maximum) ||\n !money(data.amount) ||\n data.currency !== 'KRW' ||\n !Number.isInteger(data.validityDays) ||\n (data.validityDays as number) < 1 ||\n (data.validityDays as number) > 1825 ||\n !time(data.grantedAt) ||\n !time(data.expiresAt) ||\n typeof data.sourceNamespace !== 'string' ||\n !/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/.test(data.sourceNamespace) ||\n typeof data.sourceRef !== 'string' ||\n !data.sourceRef.length ||\n data.sourceRef.length > 256 ||\n // eslint-disable-next-line no-control-regex -- The public source identity explicitly forbids ASCII control characters.\n /[\\u0000-\\u001f\\u007f]/.test(data.sourceRef)\n )\n invalid()\n return value as CustomerCreditGrant\n}\nexport function parseRevokeCustomerCredit(\n value: unknown,\n): RevokeCustomerCreditResponse {\n const data = object(value, ['revoked', 'pending', 'spent'])\n if (!money(data.revoked) || !money(data.pending) || !money(data.spent))\n invalid()\n return value as RevokeCustomerCreditResponse\n}\nexport function parseMyCustomerCredits(\n value: unknown,\n): MyCustomerCreditsResponse {\n const data = object(value, [\n 'currency',\n 'evaluatedAt',\n 'granted',\n 'balances',\n 'buckets',\n 'page',\n 'hasNextPage',\n ])\n page(data)\n balances(data.balances)\n if (\n !money(data.granted) ||\n !Array.isArray(data.buckets) ||\n data.buckets.length > 50\n )\n invalid()\n for (const value of data.buckets) {\n const bucket = object(value, [\n 'id',\n 'grantId',\n 'kind',\n 'grantedAt',\n 'expiresAt',\n 'isRevoked',\n 'balances',\n ])\n if (\n !uuid(bucket.id) ||\n !uuid(bucket.grantId) ||\n !['original', 'grace'].includes(bucket.kind as string) ||\n !time(bucket.grantedAt) ||\n !time(bucket.expiresAt) ||\n typeof bucket.isRevoked !== 'boolean'\n )\n invalid()\n balances(bucket.balances)\n }\n return value as MyCustomerCreditsResponse\n}\nexport function parseMyCustomerCreditHistory(\n value: unknown,\n): MyCustomerCreditHistoryResponse {\n const data = object(value, [\n 'currency',\n 'evaluatedAt',\n 'entries',\n 'page',\n 'hasNextPage',\n ])\n page(data)\n if (!Array.isArray(data.entries) || data.entries.length > 50) invalid()\n for (const value of data.entries) {\n const entry = object(value, [\n 'id',\n 'grantId',\n 'kind',\n 'amount',\n 'fromState',\n 'toState',\n 'createdAt',\n ])\n if (\n !uuid(entry.id) ||\n !uuid(entry.grantId) ||\n !money(entry.amount) ||\n !time(entry.createdAt) ||\n ![\n 'grant',\n 'reserve',\n 'consume',\n 'release',\n 'restore',\n 'expire',\n 'revoke',\n ].includes(entry.kind as string) ||\n (entry.fromState !== null &&\n !states.includes(entry.fromState as never)) ||\n (entry.toState !== null && !states.includes(entry.toState as never))\n )\n invalid()\n }\n return value as MyCustomerCreditHistoryResponse\n}\n","import { CustomerScopedApi } from './customer-scoped-api'\nimport { CUSTOMER_CREDIT_ENDPOINT_OPERATIONS as operations } from './endpoints'\nimport {\n parseMyCustomerCredits,\n parseMyCustomerCreditHistory,\n type MyCustomerCreditsRequest,\n type MyCustomerCreditsResponse,\n type MyCustomerCreditHistoryRequest,\n type MyCustomerCreditHistoryResponse,\n} from './customer-credit-types'\n\n/** Customer JWT + publishable key; no customer/tenant selector is accepted. */\nexport class CustomerCreditsApi extends CustomerScopedApi {\n async mine(\n params: MyCustomerCreditsRequest = {},\n ): Promise<MyCustomerCreditsResponse> {\n const query = new URLSearchParams()\n if (params.page !== undefined) query.set('page', String(params.page))\n return parseMyCustomerCredits(\n await this.requestEndpoint<unknown>(operations.mine, undefined, {\n query,\n }),\n )\n }\n async history(\n params: MyCustomerCreditHistoryRequest = {},\n ): Promise<MyCustomerCreditHistoryResponse> {\n const query = new URLSearchParams()\n if (params.page !== undefined) query.set('page', String(params.page))\n return parseMyCustomerCreditHistory(\n await this.requestEndpoint<unknown>(operations.history, undefined, {\n query,\n }),\n )\n }\n}\n","import { stringify } from 'qs-esm'\nimport {\n httpFetch,\n requirePublishableKeyForSecret,\n type FetchOptions,\n} from '../internal/utils'\nimport type {\n ApiQueryOptions,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport {\n SDKError,\n createApiError,\n createValidationError,\n} from '../internal/errors'\n\n// Payload parses bracketed queries with depth 10 and arrayLimit 1000. Reject\n// values that qs would discard or rewrite before any collection request.\n// Return whether Payload needs its native JSON where parameter to retain null.\nfunction validateWhere(where: ApiQueryOptions['where']): boolean {\n if (where === undefined) return false\n let hasNull = false\n function visit(value: unknown, depth: number, key?: string): void {\n if (depth > 10) {\n throw createValidationError(\n 'Collection where must not exceed nesting depth 10.',\n )\n }\n if (value === null && (key === 'equals' || key === 'not_equals')) {\n hasNull = true\n return\n }\n if (value == null) {\n throw createValidationError(\n 'Collection where must not contain null or undefined values.',\n )\n }\n if (Array.isArray(value)) {\n if (value.length === 0) {\n throw createValidationError(\n 'Collection where must not contain empty arrays, including and/or.',\n )\n }\n if (value.length > 1000) {\n throw createValidationError(\n 'Collection where arrays must not contain more than 1000 elements.',\n )\n }\n for (const item of value) visit(item, depth + 1)\n } else if (typeof value === 'object' && !(value instanceof Date)) {\n const values = Object.entries(value)\n if (values.length === 0) {\n throw createValidationError(\n 'Collection where must not contain empty condition objects.',\n )\n }\n for (const [key, item] of values) visit(item, depth + 1, key)\n }\n }\n visit(where, 0)\n return hasNull\n}\n\nexport class HttpClient {\n protected publishableKey: string\n protected secretKey?: string\n private getCustomerToken?: () => string | null\n private onUnauthorized?: () => Promise<string | null>\n private onRequestId?: (id: string | null) => void\n private apiUrl?: string\n\n constructor(\n publishableKey: string,\n secretKey?: string,\n getCustomerToken?: () => string | null,\n onUnauthorized?: () => Promise<string | null>,\n onRequestId?: (id: string | null) => void,\n apiUrl?: string,\n ) {\n this.publishableKey = requirePublishableKeyForSecret(\n 'CollectionClient',\n publishableKey,\n secretKey,\n )\n this.secretKey = secretKey\n this.getCustomerToken = getCustomerToken\n this.onUnauthorized = onUnauthorized\n this.onRequestId = onRequestId\n this.apiUrl = apiUrl\n }\n\n protected get defaultOptions(): FetchOptions {\n const opts: FetchOptions = {\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n }\n const token = this.getCustomerToken?.()\n if (token) {\n opts.customerToken = token\n if (this.onUnauthorized) {\n opts.onUnauthorized = this.onUnauthorized\n }\n }\n return opts\n }\n\n protected async fetchWithTracking(url: string, opts: FetchOptions): Promise<Response> {\n try {\n const response = await httpFetch(url, opts)\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return response\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n\n protected buildUrl(endpoint: string, options?: ApiQueryOptions): string {\n if (!options) return endpoint\n const { fallbackLocale, ...rest } = options\n const queryOptions =\n fallbackLocale === undefined\n ? rest\n : {\n ...rest,\n 'fallback-locale':\n fallbackLocale === false ? 'none' : fallbackLocale,\n }\n // Payload parseParams JSON-decodes a string where before field coercion.\n // The string 'null' alone is only coerced for some field types.\n const encodedOptions = validateWhere(queryOptions.where)\n ? { ...queryOptions, where: JSON.stringify(queryOptions.where) }\n : queryOptions\n const queryString = stringify(encodedOptions, { addQueryPrefix: true })\n return queryString ? `${endpoint}${queryString}` : endpoint\n }\n\n protected assertJsonResponse(response: Response): void {\n const contentType = response.headers.get('content-type')\n if (!contentType?.includes('application/json')) {\n throw createApiError('Response is not in JSON format.', response.status, {\n contentType,\n })\n }\n }\n\n /**\n * Parse Payload CMS find response (list query)\n * Returns native Payload response structure\n */\n protected async parseFindResponse<T>(\n response: Response,\n ): Promise<PayloadFindResponse<T>> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n\n // Validate it's a find response\n if (jsonData.docs === undefined) {\n throw createApiError('Invalid find response.', response.status, {\n jsonData,\n })\n }\n\n return {\n docs: jsonData.docs,\n totalDocs: jsonData.totalDocs ?? 0,\n limit: jsonData.limit || 20,\n totalPages: jsonData.totalPages ?? 0,\n page: jsonData.page || 1,\n pagingCounter: jsonData.pagingCounter || 1,\n hasPrevPage: jsonData.hasPrevPage ?? false,\n hasNextPage: jsonData.hasNextPage ?? false,\n prevPage: jsonData.prevPage ?? null,\n nextPage: jsonData.nextPage ?? null,\n }\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n\n /**\n * Parse Payload CMS mutation response (create/update)\n * Returns native Payload response structure\n */\n protected async parseMutationResponse<T>(\n response: Response,\n ): Promise<PayloadMutationResponse<T>> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n\n // Validate it's a mutation response\n if (jsonData.doc === undefined) {\n throw createApiError('Invalid mutation response.', response.status, {\n jsonData,\n })\n }\n\n return {\n message: jsonData.message || '',\n doc: jsonData.doc,\n errors: jsonData.errors,\n }\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n\n /**\n * Parse Payload CMS document response (findById/delete)\n * Returns document directly without wrapper\n */\n protected async parseDocumentResponse<T>(response: Response): Promise<T> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n return jsonData as T\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n}\n","/**\n * Resolves a Payload CMS relation field value.\n * When depth is 0, relation fields return just the ID (string or number).\n * When depth > 0, they return the full document object (T).\n * This utility normalizes both cases to T | null.\n *\n * @param ref - The relation field value (T, string, number, null, or undefined)\n * @returns The resolved document object, or null if not populated\n */\nexport function resolveRelation<T>(\n ref: T | string | number | null | undefined,\n): T | null\nexport function resolveRelation<T>(ref: unknown): T | null\nexport function resolveRelation<T>(ref: unknown): T | null {\n if (\n typeof ref === 'string' ||\n typeof ref === 'number' ||\n ref === null ||\n ref === undefined\n )\n return null\n return ref as T\n}\n","import type {\n ApiDeleteOptions,\n ApiDocumentWriteOptions,\n ApiQueryOptions,\n ApiWriteOptions,\n Collection,\n PublicCollection,\n PublicReadQueryOptions,\n ServerCollection,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport { generateMetadata, extractSeo } from '../metadata'\nimport type { GenerateMetadataOptions, Metadata } from '../metadata'\nimport type { CollectionClient } from './collection-client'\nimport type { CollectionType } from './types'\nimport { createValidationError } from '../errors'\n\ninterface ReadOnlyCollectionApi {\n requestFind<T = unknown>(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<PayloadFindResponse<T>>\n requestFindById<T = unknown>(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<T>\n requestCount(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<{ totalDocs: number }>\n}\n\nconst PUBLIC_READ_DEPTH_ERROR =\n 'Publishable collection reads require depth: 0. Use a shaped commerce endpoint or server client for populated data.'\nconst PUBLIC_READ_JOINS_ERROR =\n 'Publishable collection reads require joins: false. Use a shaped commerce endpoint or server client for joined data.'\nconst PUBLIC_READ_POPULATE_ERROR =\n 'Publishable collection reads do not support populate. Use a shaped commerce endpoint or server client for populated data.'\n\nfunction withDefaultPublicReadOptions(\n options?: PublicReadQueryOptions,\n): PublicReadQueryOptions {\n const rawOptions = options as ApiQueryOptions | undefined\n\n if (rawOptions?.depth !== undefined && rawOptions.depth !== 0) {\n throw createValidationError(PUBLIC_READ_DEPTH_ERROR)\n }\n if (rawOptions?.joins !== undefined && rawOptions.joins !== false) {\n throw createValidationError(PUBLIC_READ_JOINS_ERROR)\n }\n if (rawOptions?.populate !== undefined) {\n throw createValidationError(PUBLIC_READ_POPULATE_ERROR)\n }\n\n return {\n ...options,\n depth: options?.depth ?? 0,\n joins: options?.joins ?? false,\n }\n}\n\n// Forward only the write query fields so `file`/`filename` never reach the URL.\nfunction toWriteOptions(\n options?: ApiWriteOptions,\n): ApiWriteOptions | undefined {\n return options?.locale === undefined ? undefined : { locale: options.locale }\n}\n\n/**\n * Read-only subset of CollectionQueryBuilder.\n * Client.from() returns this type to prevent write operations at compile time.\n */\nexport type ReadOnlyQueryBuilder<T extends PublicCollection> =\n ReadOnlyCollectionQueryBuilder<T>\n\nexport class ReadOnlyCollectionQueryBuilder<T extends PublicCollection> {\n constructor(\n private api: ReadOnlyCollectionApi,\n private collection: T,\n ) {}\n\n async find(\n options?: PublicReadQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestFind<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n withDefaultPublicReadOptions(options),\n )\n }\n\n async findById(\n id: string | number,\n options?: PublicReadQueryOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestFindById<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n withDefaultPublicReadOptions(options),\n )\n }\n\n async count(\n options?: PublicReadQueryOptions,\n ): Promise<{ totalDocs: number }> {\n return this.api.requestCount(\n `/api/${String(this.collection)}/count`,\n withDefaultPublicReadOptions(options),\n )\n }\n}\n\nexport class CollectionQueryBuilder<T extends Collection> {\n constructor(\n private api: CollectionClient,\n private collection: T,\n ) {}\n\n /**\n * Find documents (list query)\n * GET /api/{collection}\n * @returns Payload CMS find response with docs array and pagination\n */\n async find(\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestFind<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n options,\n )\n }\n\n /**\n * Find document by ID\n * GET /api/{collection}/{id}\n * @returns Document object directly (no wrapper)\n */\n async findById(\n id: string | number,\n options?: ApiQueryOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestFindById<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n options,\n )\n }\n\n /**\n * Create a new document\n * POST /api/{collection}\n * Pass `locale` to write localized fields in a tenant-enabled locale.\n * @returns Payload CMS mutation response with doc and message\n */\n async create(\n data: Partial<CollectionType<T>>,\n options?: ApiDocumentWriteOptions,\n ): Promise<PayloadMutationResponse<CollectionType<T>>> {\n const endpoint = `/api/${String(this.collection)}`\n const writeOptions = toWriteOptions(options)\n if (options?.file) {\n return this.api.requestCreateWithFile<CollectionType<T>>(\n endpoint,\n data,\n options.file,\n options.filename,\n writeOptions,\n )\n }\n return this.api.requestCreate<CollectionType<T>>(\n endpoint,\n data,\n writeOptions,\n )\n }\n\n /**\n * Update a document by ID\n * PATCH /api/{collection}/{id}\n * Pass `locale` to write localized fields in a tenant-enabled locale.\n * @returns Payload CMS mutation response with doc and message\n */\n async update(\n id: string,\n data: Partial<CollectionType<T>>,\n options?: ApiDocumentWriteOptions,\n ): Promise<PayloadMutationResponse<CollectionType<T>>> {\n const endpoint = `/api/${String(this.collection)}/${String(id)}`\n const writeOptions = toWriteOptions(options)\n if (options?.file) {\n return this.api.requestUpdateWithFile<CollectionType<T>>(\n endpoint,\n data,\n options.file,\n options.filename,\n writeOptions,\n )\n }\n return this.api.requestUpdate<CollectionType<T>>(\n endpoint,\n data,\n writeOptions,\n )\n }\n\n /**\n * Count documents\n * GET /api/{collection}/count\n * @returns Count response with totalDocs\n */\n async count(options?: ApiQueryOptions): Promise<{ totalDocs: number }> {\n return this.api.requestCount(\n `/api/${String(this.collection)}/count`,\n options,\n )\n }\n\n /**\n * Find first matching document and return its Next.js Metadata.\n * Applies depth: 1 (SEO image populate) and limit: 1 automatically.\n * @returns Metadata or null if no document matches\n */\n async findMetadata(\n options?: ApiQueryOptions,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata | null> {\n const { docs } = await this.find({ ...options, limit: 1, depth: 1 })\n const doc = docs[0]\n if (!doc) return null\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n /**\n * Find document by ID and return its Next.js Metadata.\n * Applies depth: 1 (SEO image populate) automatically.\n * @returns Metadata (throws on 404)\n */\n async findMetadataById(\n id: string,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata> {\n const doc = await this.findById(id, { depth: 1 })\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n /**\n * Update multiple documents (bulk update)\n * PATCH /api/{collection}\n * @returns Payload CMS find response with updated docs\n */\n async updateMany(\n where: ApiQueryOptions['where'],\n data: Partial<CollectionType<T>>,\n options?: ApiWriteOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestUpdateMany<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n { where, data },\n toWriteOptions(options),\n )\n }\n\n /**\n * Delete a document by ID\n * DELETE /api/{collection}/{id}\n * @returns Deleted document object directly (no wrapper)\n */\n async remove(\n id: string,\n options?: ApiDeleteOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestDelete<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n options,\n )\n }\n\n /**\n * Delete multiple documents (bulk delete)\n * DELETE /api/{collection}\n * @returns Payload CMS find response with deleted docs\n */\n async removeMany(\n where: ApiQueryOptions['where'],\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestDeleteMany<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n { where },\n )\n }\n}\n\nexport class ServerCollectionQueryBuilder<\n T extends ServerCollection,\n> extends CollectionQueryBuilder<T> {}\n","import { HttpClient } from './http-client'\nimport type {\n ApiDeleteOptions,\n ApiQueryOptions,\n ApiWriteOptions,\n Collection,\n PublicCollection,\n PublicReadQueryOptions,\n ServerCollection,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport {\n CollectionQueryBuilder,\n ReadOnlyCollectionQueryBuilder,\n ServerCollectionQueryBuilder,\n type ReadOnlyQueryBuilder,\n} from './query-builder'\n\nfunction buildPayloadFormData(\n data: unknown,\n file: File | Blob,\n filename?: string,\n): FormData {\n const formData = new FormData()\n formData.append('file', file, filename)\n if (data != null) {\n formData.append('_payload', JSON.stringify(data))\n }\n return formData\n}\n\nexport class CollectionClient<\n TCollection extends Collection = PublicCollection,\n> extends HttpClient {\n from<T extends TCollection>(collection: T): CollectionQueryBuilder<T> {\n return new CollectionQueryBuilder(this, collection)\n }\n\n // ============================================================================\n // Payload-native methods\n // ============================================================================\n\n /**\n * Find documents (list query)\n * GET /api/{collection}\n */\n async requestFind<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find-like response from a custom endpoint\n * POST /api/...custom-endpoint\n */\n async requestFindEndpoint<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find-like response from a cacheable GET custom endpoint.\n */\n async requestFindEndpointGet<T = unknown>(\n endpoint: string,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find document by ID\n * GET /api/{collection}/{id}\n */\n async requestFindById<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n /**\n * Create document\n * POST /api/{collection}\n */\n async requestCreate<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: ApiWriteOptions,\n ): Promise<PayloadMutationResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Update document\n * PATCH /api/{collection}/{id}\n */\n async requestUpdate<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: ApiWriteOptions,\n ): Promise<PayloadMutationResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Count documents\n * GET /api/{collection}/count\n */\n async requestCount(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<{ totalDocs: number }> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<{ totalDocs: number }>(response)\n }\n\n /**\n * Update multiple documents (bulk update)\n * PATCH /api/{collection}\n */\n async requestUpdateMany<T = unknown>(\n endpoint: string,\n data: { where?: ApiQueryOptions['where']; data: unknown },\n options?: ApiWriteOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, { where: data.where, ...options })\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: JSON.stringify(data.data),\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Delete document\n * DELETE /api/{collection}/{id}\n */\n async requestDelete<T = unknown>(\n endpoint: string,\n options?: ApiDeleteOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'DELETE',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n /**\n * Delete multiple documents (bulk delete)\n * DELETE /api/{collection}\n */\n async requestDeleteMany<T = unknown>(\n endpoint: string,\n data: { where?: ApiQueryOptions['where'] },\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, { where: data.where })\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'DELETE',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Create document with file upload\n * POST /api/{collection} (multipart/form-data)\n */\n async requestCreateWithFile<T = unknown>(\n endpoint: string,\n data: unknown,\n file: File | Blob,\n filename?: string,\n options?: ApiWriteOptions,\n ): Promise<PayloadMutationResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'POST',\n body: buildPayloadFormData(data, file, filename),\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Update document with file upload\n * PATCH /api/{collection}/{id} (multipart/form-data)\n */\n async requestUpdateWithFile<T = unknown>(\n endpoint: string,\n data: unknown,\n file: File | Blob,\n filename?: string,\n options?: ApiWriteOptions,\n ): Promise<PayloadMutationResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: buildPayloadFormData(data, file, filename),\n })\n return this.parseMutationResponse<T>(response)\n }\n}\n\nexport class ServerCollectionClient extends CollectionClient<ServerCollection> {\n override from<T extends ServerCollection>(\n collection: T,\n ): ServerCollectionQueryBuilder<T> {\n return new ServerCollectionQueryBuilder(this, collection)\n }\n}\n\nexport class ReadOnlyCollectionClient extends HttpClient {\n from<T extends PublicCollection>(collection: T): ReadOnlyQueryBuilder<T> {\n return new ReadOnlyCollectionQueryBuilder(this, collection)\n }\n\n async requestFind<T = unknown>(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n async requestFindEndpoint<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseFindResponse<T>(response)\n }\n\n async requestFindEndpointGet<T = unknown>(\n endpoint: string,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n async requestFindById<T = unknown>(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n async requestCount(\n endpoint: string,\n options?: PublicReadQueryOptions,\n ): Promise<{ totalDocs: number }> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<{ totalDocs: number }>(response)\n }\n}\n","import { RawCustomerScopedApi } from '../api/customer-scoped-api'\nimport { getSDKErrorReason, NotFoundError, SDKError } from '../internal/errors'\nimport type { CollectionType } from '../collection/types'\nimport {\n COMMUNITY_ENDPOINT_OPERATIONS,\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\n\ntype RawCommunityPost = CollectionType<'posts'>\ntype RawCommunityComment = CollectionType<'comments'>\ntype RawCommunityReaction = CollectionType<'reactions'>\ntype RawCommunityBookmark = CollectionType<'bookmarks'>\n\nexport interface CommunityClientOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport type CommunityPublicMediaAsset =\n | string\n | {\n id?: string | number | null\n alt?: string | null\n width?: number | null\n height?: number | null\n mimeType?: string | null\n filename?: string | null\n url?: string | null\n sizes?: Record<\n string,\n {\n width?: number | null\n height?: number | null\n mimeType?: string | null\n filename?: string | null\n url?: string | null\n }\n > | null\n }\n\nexport type CommunityPublicReference =\n | string\n | {\n id?: string | number | null\n title?: string | null\n name?: string | null\n slug?: string | null\n displayName?: string | null\n handle?: string | null\n color?: string | null\n image?: CommunityPublicMediaAsset | null\n thumbnail?: CommunityPublicMediaAsset | null\n avatar?: CommunityPublicMediaAsset | null\n }\n\nexport interface CommunityPublicAuthorSnapshot {\n displayName?: string | null\n handle?: string | null\n avatarUrl?: string | null\n avatar?: CommunityPublicMediaAsset | null\n}\n\n/** Public read shape for projected community post endpoints. */\nexport interface CommunityPost {\n id: RawCommunityPost['id']\n title?: RawCommunityPost['title']\n slug?: RawCommunityPost['slug']\n content?: RawCommunityPost['content']\n status?: RawCommunityPost['status']\n thumbnail?: CommunityPublicMediaAsset | null\n categories?: CommunityPublicReference[] | null\n tags?: CommunityPublicReference[] | null\n authorProfile?: CommunityPublicReference | null\n authorSnapshot?: CommunityPublicAuthorSnapshot | null\n viewCount?: RawCommunityPost['viewCount']\n commentCount?: RawCommunityPost['commentCount']\n reactionCount?: RawCommunityPost['reactionCount']\n isPinned?: RawCommunityPost['isPinned']\n allowsComments?: RawCommunityPost['allowsComments']\n isEdited?: RawCommunityPost['isEdited']\n editedAt?: RawCommunityPost['editedAt']\n lastActivityAt?: RawCommunityPost['lastActivityAt']\n publishedAt?: RawCommunityPost['publishedAt']\n createdAt: RawCommunityPost['createdAt']\n updatedAt: RawCommunityPost['updatedAt']\n}\n\n/** Public read shape for projected community comment endpoints. */\nexport interface CommunityComment {\n id: RawCommunityComment['id']\n body?: RawCommunityComment['body']\n post?: CommunityPublicReference | null\n parent?: CommunityPublicReference | null\n rootComment?: CommunityPublicReference | null\n authorProfile?: CommunityPublicReference | null\n authorSnapshot?: CommunityPublicAuthorSnapshot | null\n depth?: RawCommunityComment['depth']\n status?: RawCommunityComment['status']\n reactionCount?: RawCommunityComment['reactionCount']\n replyCount?: RawCommunityComment['replyCount']\n isEdited?: RawCommunityComment['isEdited']\n editedAt?: RawCommunityComment['editedAt']\n createdAt: RawCommunityComment['createdAt']\n updatedAt: RawCommunityComment['updatedAt']\n}\n\n/** @deprecated Use {@link CommunityComment}. */\nexport type Comment = CommunityComment\n\n/** Public read shape for `post-categories`. */\nexport type CommunityPostCategory = CollectionType<'post-categories'>\n\n/** Public read shape for `post-tags`. */\nexport type CommunityPostTag = CollectionType<'post-tags'>\n\nexport type CommunityPostListSort =\n | 'createdAt'\n | '-createdAt'\n | 'lastActivityAt'\n | '-lastActivityAt'\n | 'viewCount'\n | '-viewCount'\n | 'commentCount'\n | '-commentCount'\n\nexport type CommunityCommentListSort = 'createdAt' | '-createdAt'\n\nexport interface Reaction {\n id: string\n post?: CommunityPublicReference | null\n comment?: CommunityPublicReference | null\n type?: CommunityPublicReference | null\n createdAt?: string\n updatedAt?: string\n [key: string]: unknown\n}\n\nexport interface ReactionSummary {\n counts: Record<string, number>\n total: number\n userReactions: string[]\n}\n\nexport interface Bookmark {\n id: string\n post?: string | CommunityPost | null\n createdAt?: string\n updatedAt?: string\n [key: string]: unknown\n}\n\nexport interface ReactionType {\n id: string\n title: string\n slug: string\n emoji?: string\n [key: string]: unknown\n}\n\nexport interface PaginatedResponse<T> {\n docs: T[]\n totalDocs: number\n limit: number\n totalPages: number\n page: number\n pagingCounter: number\n hasPrevPage: boolean\n hasNextPage: boolean\n prevPage: number | null\n nextPage: number | null\n}\n\nexport type CommunityPostMutationResponse = CommunityPost | RawCommunityPost\nexport type CommunityCommentMutationResponse =\n | CommunityComment\n | RawCommunityComment\nexport type CommunityReactionMutationResponse = Reaction | RawCommunityReaction\nexport type CommunityBookmarkMutationResponse = Bookmark | RawCommunityBookmark\n\nconst DEFAULT_POST_LIST_SORT: CommunityPostListSort = '-lastActivityAt'\nconst DEFAULT_COMMENT_LIST_SORT: CommunityCommentListSort = '-createdAt'\n\nfunction unwrapPayloadDoc<T>(value: T | { doc: T }): T {\n if (value && typeof value === 'object' && 'doc' in value) {\n return (value as { doc: T }).doc\n }\n return value as T\n}\n\nfunction hasCanonicalNotFoundReason(error: NotFoundError): boolean {\n return getSDKErrorReason(error) === 'not_found'\n}\n\nexport class CommunityClient extends RawCustomerScopedApi {\n private readonly requiresSafePublicRawReads: boolean\n\n constructor(options: CommunityClientOptions) {\n super('CommunityClient', { ...options, requiresCredential: false })\n this.requiresSafePublicRawReads = !options.secretKey\n }\n\n private buildQuery(\n params?: Record<string, string | number | undefined>,\n ): string {\n if (!params) return ''\n const entries = Object.entries(params)\n .filter((e): e is [string, string | number] => e[1] !== undefined)\n .map(([k, v]) => [k, String(v)])\n return entries.length ? `?${new URLSearchParams(entries).toString()}` : ''\n }\n\n private withSafePublicRawReadQuery(query: string): string {\n if (!this.requiresSafePublicRawReads) return query\n if (!query) return '?depth=0&joins=false'\n return `?depth=0&joins=false&${query.slice(1)}`\n }\n\n private buildSafePublicRawListQuery(params?: {\n page?: number\n limit?: number\n }): string {\n if (!this.requiresSafePublicRawReads) {\n return this.buildQuery(params)\n }\n\n const queryParams: Record<string, string | number> = {}\n if (params?.page !== undefined) queryParams.page = params.page\n if (params?.limit !== undefined) queryParams.limit = params.limit\n\n return this.withSafePublicRawReadQuery(this.buildQuery(queryParams))\n }\n\n private buildPostsListQuery(params?: {\n page?: number\n limit?: number\n categoryId?: string\n tagId?: string\n sort?: CommunityPostListSort\n }): string {\n const urlParams = new URLSearchParams()\n const sort = params?.sort ?? DEFAULT_POST_LIST_SORT\n urlParams.set('sort', sort)\n if (params?.limit !== undefined)\n urlParams.set('limit', String(params.limit))\n if (params?.page !== undefined) urlParams.set('page', String(params.page))\n if (params?.categoryId !== undefined) {\n urlParams.set('where[categories][in]', params.categoryId)\n }\n if (params?.tagId !== undefined) {\n urlParams.set('where[tags][in]', params.tagId)\n }\n return `/api/posts/public?${urlParams.toString()}`\n }\n\n private buildCommentsListQuery(params: {\n postId?: string\n parentId?: string\n rootComment?: string\n topLevelOnly?: boolean\n page?: number\n limit?: number\n sort?: CommunityCommentListSort\n }): string {\n const urlParams = new URLSearchParams()\n const sort = params.sort ?? DEFAULT_COMMENT_LIST_SORT\n urlParams.set('sort', sort)\n if (params.postId !== undefined) {\n urlParams.set('where[post][equals]', params.postId)\n }\n if (params.parentId !== undefined) {\n urlParams.set('where[parent][equals]', params.parentId)\n }\n if (params.rootComment !== undefined) {\n urlParams.set('where[rootComment][equals]', params.rootComment)\n }\n if (params.topLevelOnly) {\n urlParams.set('where[parent][exists]', 'false')\n }\n if (params.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params.page !== undefined) urlParams.set('page', String(params.page))\n return `/api/comments/public?${urlParams.toString()}`\n }\n\n private async execute<T>(\n endpoint: string,\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n body?: unknown,\n ): Promise<T> {\n return this.request<T>(endpoint, { method, body })\n }\n\n private async executeDoc<T>(\n endpoint: string,\n method: 'POST' | 'PATCH',\n body?: unknown,\n ): Promise<T> {\n const response = await this.execute<T | { doc: T }>(endpoint, method, body)\n return unwrapPayloadDoc(response)\n }\n\n createPost(params: {\n title?: string | null\n content?: unknown\n categories?: string[]\n thumbnail?: string\n }): Promise<CommunityPostMutationResponse> {\n return this.executeDoc<CommunityPostMutationResponse>(\n '/api/posts',\n 'POST',\n params,\n )\n }\n\n /**\n * Public post feed. Server applies the same visibility contract as\n * `communityPostRead` (published + visible + moderation-safe).\n */\n listPosts(params?: {\n page?: number\n limit?: number\n categoryId?: string\n tagId?: string\n sort?: CommunityPostListSort\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n this.buildPostsListQuery(params),\n 'GET',\n )\n }\n\n /**\n * Public post detail projected by the same allowlist as the public feed.\n * Missing, hidden, and cross-tenant posts all resolve to `null`.\n */\n async getPost(params: { postId: string }): Promise<CommunityPost | null> {\n const query = new URLSearchParams({ postId: params.postId })\n try {\n return await this.execute<CommunityPost>(\n resolveOperationPath(COMMUNITY_ENDPOINT_OPERATIONS.posts.detail, {\n query,\n }),\n resolveOperationMethod(COMMUNITY_ENDPOINT_OPERATIONS.posts.detail),\n )\n } catch (error) {\n if (error instanceof NotFoundError && hasCanonicalNotFoundReason(error)) {\n return null\n }\n throw error\n }\n }\n\n listPostCategories(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPostCategory>> {\n return this.execute<PaginatedResponse<CommunityPostCategory>>(\n `/api/post-categories${this.buildSafePublicRawListQuery(params)}`,\n 'GET',\n )\n }\n\n listPostTags(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPostTag>> {\n return this.execute<PaginatedResponse<CommunityPostTag>>(\n `/api/post-tags${this.buildSafePublicRawListQuery(params)}`,\n 'GET',\n )\n }\n\n getMyPosts(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n `/api/posts/my${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n getTrending(params?: {\n page?: number\n limit?: number\n period?: string\n metric?: 'reactions' | 'comments' | 'views' | 'activity'\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n `/api/posts/trending${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n incrementView(params: { postId: string }): Promise<{ viewCount: number }> {\n return this.execute<{ viewCount: number }>(\n `/api/posts/${params.postId}/view`,\n 'POST',\n )\n }\n\n reportPost(params: {\n postId: string\n reason?: string\n reasonDetail?: string\n }): Promise<{ success: boolean }> {\n const { postId, ...body } = params\n return this.execute<{ success: boolean }>(\n `/api/posts/${postId}/report`,\n 'POST',\n body,\n )\n }\n\n // Comments\n\n createComment(params: {\n postId: string\n body: string\n parentId?: string\n }): Promise<CommunityCommentMutationResponse> {\n const { postId, parentId, body: commentBody } = params\n const body: Record<string, unknown> = { post: postId, body: commentBody }\n if (parentId !== undefined) {\n body.parent = parentId\n }\n return this.executeDoc<CommunityCommentMutationResponse>(\n '/api/comments',\n 'POST',\n body,\n )\n }\n\n /**\n * List comments for a post.\n *\n * - Default: all visible comments on the post (any depth).\n * - `topLevelOnly: true`: only root comments (`parent` unset).\n * - `rootComment`: comments belonging to a thread rooted at that comment.\n */\n listComments(params: {\n postId: string\n page?: number\n limit?: number\n rootComment?: string\n topLevelOnly?: boolean\n sort?: CommunityCommentListSort\n }): Promise<PaginatedResponse<CommunityComment>> {\n const { postId, page, limit, rootComment, topLevelOnly, sort } = params\n return this.execute<PaginatedResponse<CommunityComment>>(\n this.buildCommentsListQuery({\n postId,\n page,\n limit,\n rootComment,\n topLevelOnly,\n sort,\n }),\n 'GET',\n )\n }\n\n /** Direct replies to a comment (`where[parent][equals]`). */\n listReplies(params: {\n commentId: string\n page?: number\n limit?: number\n sort?: CommunityCommentListSort\n }): Promise<PaginatedResponse<CommunityComment>> {\n const { commentId, page, limit, sort } = params\n return this.execute<PaginatedResponse<CommunityComment>>(\n this.buildCommentsListQuery({\n parentId: commentId,\n page,\n limit,\n sort,\n }),\n 'GET',\n )\n }\n\n updateComment(params: {\n commentId: string\n body: string\n }): Promise<CommunityCommentMutationResponse> {\n const { commentId, body } = params\n return this.executeDoc<CommunityCommentMutationResponse>(\n `/api/comments/${commentId}`,\n 'PATCH',\n { body },\n )\n }\n\n deleteComment(params: {\n commentId: string\n }): Promise<CommunityCommentMutationResponse> {\n return this.execute<CommunityCommentMutationResponse>(\n `/api/comments/${params.commentId}`,\n 'DELETE',\n )\n }\n\n reportComment(params: {\n commentId: string\n reason?: string\n reasonDetail?: string\n }): Promise<{ success: boolean }> {\n const { commentId, ...body } = params\n return this.execute<{ success: boolean }>(\n `/api/comments/${commentId}/report`,\n 'POST',\n body,\n )\n }\n\n // Reactions\n\n addReaction(params: {\n postId: string\n typeSlug?: string\n /** @deprecated Use `typeSlug`. */\n type?: string\n }): Promise<CommunityReactionMutationResponse> {\n const { postId, typeSlug, type } = params\n const reactionType = typeSlug ?? type\n if (!reactionType) {\n throw new SDKError(\n 'validation_failed',\n 'addReaction requires typeSlug (or deprecated type)',\n 400,\n )\n }\n return this.executeDoc<CommunityReactionMutationResponse>(\n '/api/reactions',\n 'POST',\n {\n post: postId,\n type: reactionType,\n },\n )\n }\n\n removeReaction(params: {\n postId: string\n type: string\n }): Promise<{ success: boolean }> {\n const { postId, type } = params\n return this.execute<{ success: boolean }>(\n `/api/posts/${postId}/react?type=${encodeURIComponent(type)}`,\n 'DELETE',\n )\n }\n\n addCommentReaction(params: {\n commentId: string\n typeSlug?: string\n /** @deprecated Use `typeSlug`. */\n type?: string\n }): Promise<CommunityReactionMutationResponse> {\n const { commentId, typeSlug, type } = params\n const reactionType = typeSlug ?? type\n if (!reactionType) {\n throw new SDKError(\n 'validation_failed',\n 'addCommentReaction requires typeSlug (or deprecated type)',\n 400,\n )\n }\n return this.executeDoc<CommunityReactionMutationResponse>(\n '/api/reactions',\n 'POST',\n {\n comment: commentId,\n type: reactionType,\n },\n )\n }\n\n removeCommentReaction(params: {\n commentId: string\n type: string\n }): Promise<{ success: boolean }> {\n const { commentId, type } = params\n return this.execute<{ success: boolean }>(\n `/api/comments/${commentId}/react?type=${encodeURIComponent(type)}`,\n 'DELETE',\n )\n }\n\n getReactionSummary(params: { postId: string }): Promise<ReactionSummary> {\n return this.execute<ReactionSummary>(\n `/api/posts/${params.postId}/reactions`,\n 'GET',\n )\n }\n\n getCommentReactionSummary(params: {\n commentId: string\n }): Promise<ReactionSummary> {\n return this.execute<ReactionSummary>(\n `/api/comments/${params.commentId}/reactions`,\n 'GET',\n )\n }\n\n getReactionTypes(): Promise<PaginatedResponse<ReactionType>> {\n return this.execute<PaginatedResponse<ReactionType>>(\n `/api/reaction-types${this.buildSafePublicRawListQuery({ limit: 100 })}`,\n 'GET',\n )\n }\n\n // Bookmarks\n\n addBookmark(params: {\n postId: string\n }): Promise<CommunityBookmarkMutationResponse> {\n return this.executeDoc<CommunityBookmarkMutationResponse>(\n '/api/bookmarks',\n 'POST',\n {\n post: params.postId,\n },\n )\n }\n\n removeBookmark(params: { postId: string }): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n `/api/posts/${params.postId}/bookmark`,\n 'DELETE',\n )\n }\n\n getMyBookmarks(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<Bookmark>> {\n return this.execute<PaginatedResponse<Bookmark>>(\n `/api/bookmarks/my${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n // Profiles\n\n listProfileLists(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CollectionType<'customer-profile-lists'>>> {\n return this.execute<\n PaginatedResponse<CollectionType<'customer-profile-lists'>>\n >(\n `/api/customer-profile-lists${this.buildSafePublicRawListQuery(params)}`,\n 'GET',\n )\n }\n\n async getProfileList(\n params: { slug: string } | { id: string },\n ): Promise<CollectionType<'customer-profile-lists'> | null> {\n const query =\n 'slug' in params\n ? `?where[slug][equals]=${encodeURIComponent(params.slug)}&limit=1`\n : `?where[id][equals]=${encodeURIComponent(params.id)}&limit=1`\n const res = await this.execute<\n PaginatedResponse<CollectionType<'customer-profile-lists'>>\n >(\n `/api/customer-profile-lists${this.withSafePublicRawReadQuery(query)}`,\n 'GET',\n )\n return res.docs[0] ?? null\n }\n\n updatePublicProfile(body: {\n displayName?: string | null\n handle?: string | null\n avatar?: string | null\n bio?: string | null\n bioRichText?: CollectionType<'customer-profiles'>['bioRichText']\n }): Promise<CollectionType<'customer-profiles'>> {\n return this.execute<CollectionType<'customer-profiles'>>(\n '/api/customers/me/profile',\n 'PATCH',\n body,\n )\n }\n}\n","import {\n GALLERY_ENDPOINT_OPERATIONS,\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\n\nimport { RawCustomerScopedApi } from '../api/customer-scoped-api'\nimport type { PublicMediaAsset } from '../api/public-media'\nimport type { PayloadFindResponse } from '../client/types'\n\nexport type StorefrontContentReference = {\n id?: string | number | null\n title?: string | null\n name?: string | null\n slug?: string | null\n displayName?: string | null\n handle?: string | null\n color?: string | null\n image?: PublicMediaAsset | null\n thumbnail?: PublicMediaAsset | null\n avatar?: PublicMediaAsset | null\n}\n\nexport type StorefrontLink = {\n id?: string | number | null\n title?: string | null\n subtitle?: string | null\n url?: string | null\n description?: string | null\n slug?: string | null\n type?: 'external' | 'social' | 'internal' | string | null\n platform?: string | null\n opensInNewTab?: boolean | null\n noFollow?: boolean | null\n expiresAt?: string | null\n isFeatured?: boolean | null\n publishedAt?: string | null\n createdAt?: string | null\n updatedAt?: string | null\n categories?: StorefrontContentReference[] | StorefrontContentReference | null\n tags?: StorefrontContentReference[] | StorefrontContentReference | null\n thumbnail?: PublicMediaAsset | null\n icon?: PublicMediaAsset | null\n}\n\nexport type StorefrontGalleryItem = {\n id?: string | number | null\n title?: string | null\n description?: string | null\n content?: unknown\n createdAt?: string | null\n updatedAt?: string | null\n gallery?: StorefrontContentReference | string | null\n /** Missing on older responses; treat it as image. */\n mediaType?: 'image' | 'video'\n image?: PublicMediaAsset | null\n video?: {\n id?: string | number | null\n thumbnail?: PublicMediaAsset | null\n availability: 'ready' | 'processing' | 'unavailable'\n }\n}\n\nexport type StorefrontLinksSort =\n | 'createdAt'\n | '-createdAt'\n | 'updatedAt'\n | '-updatedAt'\n | 'publishedAt'\n | '-publishedAt'\n | 'title'\n | '-title'\n | 'isFeatured'\n | '-isFeatured'\n\nexport type StorefrontGalleryItemsSort =\n | 'manual'\n | 'createdAt'\n | '-createdAt'\n | 'updatedAt'\n | '-updatedAt'\n | 'title'\n | '-title'\n\nexport type StorefrontContentListOptions<TSort extends string = string> = {\n page?: number\n limit?: number\n sort?: TSort\n}\n\nexport type StorefrontLinksListOptions =\n StorefrontContentListOptions<StorefrontLinksSort> & {\n categoryId?: string\n categorySlug?: string\n tagId?: string\n tagSlug?: string\n featured?: boolean\n }\n\nexport type StorefrontGalleryItemsListOptions =\n StorefrontContentListOptions<StorefrontGalleryItemsSort> &\n (\n | {\n galleryId: string\n gallerySlug?: string\n }\n | {\n galleryId?: string\n gallerySlug: string\n }\n )\n\nexport type ContentClientOptions = {\n publishableKey: string\n apiUrl?: string\n onRequestId?: (id: string | null) => void\n}\n\nclass PublicContentApi extends RawCustomerScopedApi {\n get<T>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET' })\n }\n\n galleryItems<T>(options: StorefrontGalleryItemsListOptions): Promise<T> {\n const operation = GALLERY_ENDPOINT_OPERATIONS.items.storefront\n return this.request<T>(\n resolveOperationPath(operation, {\n query: galleryItemsListQuery(options),\n }),\n { method: resolveOperationMethod(operation) },\n )\n }\n}\n\nfunction appendCommonParams<TSort extends string>(\n search: URLSearchParams,\n options: StorefrontContentListOptions<TSort> | undefined,\n defaultSort: string,\n): void {\n search.set('sort', options?.sort ?? defaultSort)\n if (options?.page != null) search.set('page', String(options.page))\n if (options?.limit != null) search.set('limit', String(options.limit))\n}\n\nfunction linksListPath(options?: StorefrontLinksListOptions): string {\n const search = new URLSearchParams()\n appendCommonParams(search, options, '-publishedAt,-createdAt')\n if (options?.categoryId) search.set('categoryId', options.categoryId)\n if (options?.categorySlug) {\n search.set('categorySlug', options.categorySlug)\n }\n if (options?.tagId) search.set('tagId', options.tagId)\n if (options?.tagSlug) search.set('tagSlug', options.tagSlug)\n if (options?.featured != null)\n search.set('featured', String(options.featured))\n return `/api/links/storefront?${search}`\n}\n\nfunction galleryItemsListQuery(\n options: StorefrontGalleryItemsListOptions,\n): URLSearchParams {\n const search = new URLSearchParams()\n appendCommonParams(search, options, 'manual')\n if (options?.galleryId) search.set('galleryId', options.galleryId)\n if (options?.gallerySlug) search.set('gallerySlug', options.gallerySlug)\n return search\n}\n\nexport class ContentClient {\n readonly links: {\n list: (\n options?: StorefrontLinksListOptions,\n ) => Promise<PayloadFindResponse<StorefrontLink>>\n }\n\n readonly galleryItems: {\n list: (\n options: StorefrontGalleryItemsListOptions,\n ) => Promise<PayloadFindResponse<StorefrontGalleryItem>>\n }\n\n constructor(options: ContentClientOptions) {\n const api = new PublicContentApi('ContentClient', {\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n onRequestId: options.onRequestId,\n requiresCredential: false,\n })\n\n this.links = {\n list: (params) =>\n api.get<PayloadFindResponse<StorefrontLink>>(linksListPath(params)),\n }\n\n this.galleryItems = {\n list: (params) =>\n api.galleryItems<PayloadFindResponse<StorefrontGalleryItem>>(params),\n }\n }\n}\n","import { createApiError } from '../internal/errors'\nimport type { CheckoutPaymentSessionRef } from './checkout-api'\n\ntype RecordValue = Record<string, unknown>\n\nconst CART_STATUSES = ['active', 'completed', 'abandoned'] as const\nconst MAX_CART_LINE_QUANTITY = 99\nconst MAX_COMMERCE_SHORT_TEXT_LENGTH = 200\nconst MAX_COMMERCE_ADDRESS_LENGTH = 500\nconst MAX_COMMERCE_EMAIL_LENGTH = 254\nconst MAX_COMMERCE_PHONE_LENGTH = 32\nconst MAX_COMMERCE_POSTAL_CODE_LENGTH = 32\nconst MAX_COMMERCE_EXTENSION_VALUE_LENGTH = 500\nconst MAX_COMMERCE_RESOURCE_ID_LENGTH = 255\nconst MAX_COMMERCE_CAPABILITY_LENGTH = 512\nconst MAX_CART_DISCOUNT_CODE_LENGTH = 128\nconst ORDER_FINANCIAL_STATUSES = [\n 'pending',\n 'authorized',\n 'expired',\n 'partially_paid',\n 'paid',\n 'canceled',\n 'partially_refunded',\n 'refunded',\n 'reconciliation_required',\n] as const\nconst ORDER_FULFILLMENT_STATUSES = [\n 'unfulfilled',\n 'in_progress',\n 'on_hold',\n 'partially_fulfilled',\n 'shipped',\n 'fulfilled',\n 'canceled',\n] as const\nconst ORDER_RETURN_STATUSES = [\n 'no_return',\n 'return_requested',\n 'in_progress',\n 'returned',\n] as const\nconst ORDER_CONFIRMATION_STATUSES = ['unconfirmed', 'confirmed'] as const\nconst ORDER_PRIMARY_DISPLAY_STATUSES = [\n 'pending',\n 'paid',\n 'canceled',\n 'refunded',\n 'preparing',\n 'shipped',\n 'delivered',\n 'confirmed',\n] as const\nconst CHECKOUT_STATUSES = ['open', 'placed', 'abandoned'] as const\nconst ABANDONED_REASONS = ['expired', 'customer', 'operator'] as const\ntype ManagedPaymentProvider = CheckoutPaymentSessionRef['provider']\n\nfunction managedPaymentProviders<\n const Providers extends readonly ManagedPaymentProvider[],\n>(\n providers: Providers &\n (ManagedPaymentProvider extends Providers[number] ? unknown : never),\n): Providers {\n return providers\n}\n\nconst PAYMENT_PROVIDERS = managedPaymentProviders([\n 'toss',\n 'portone',\n 'stripe',\n] as const)\n/**\n * Provider-specific cancel methods that can recover an applied cancellation.\n * `'stripe'` is accept-only until a Stripe method exists, so its mismatches\n * stay generic invalid-canonical errors.\n */\nconst CANCEL_RECOVERY_METHODS = {\n toss: 'cancel()',\n portone: 'cancelPortOne()',\n stripe: null,\n} as const satisfies Record<ManagedPaymentProvider, string | null>\n/** Same raw-value guards as the contracts Stripe action authority. */\n// eslint-disable-next-line no-control-regex -- rejecting C0 controls is the point.\nconst STRIPE_RETURN_URL_RAW_CHARACTERS = /^[^\\s\\u0000-\\u001F\\u007F\\\\]+$/\n// Exactly two slashes and a non-empty authority without `@`: WHATWG ignores\n// slash count for special schemes, so `https:@host` would hide an empty userinfo.\nconst STRIPE_RETURN_URL_AUTHORITY =\n /^[A-Za-z][A-Za-z0-9+.-]*:\\/\\/[^/?#@]+(?:[/?#]|$)/\nconst PAYMENT_PROVIDER_STATUSES = [\n 'requires_payment_method',\n 'requires_action',\n 'requires_confirmation',\n 'initializing',\n 'processing',\n 'authorized',\n 'canceling',\n 'unknown',\n 'captured',\n 'failed',\n 'canceled',\n] as const\nconst PAYMENT_FAILURE_REASONS = [\n 'payment_declined',\n 'authentication_failed',\n 'authorization_expired',\n 'payment_method_unavailable',\n 'provider_terminal_failure',\n 'unknown_provider_terminal_failure',\n] as const\nconst PAYMENT_RECONCILIATION_REASONS = [\n 'provider_outcome_unknown',\n 'local_commit_ambiguous',\n 'amount_mismatch',\n 'currency_mismatch',\n 'excess_capture_pending_order',\n 'inventory_unavailable',\n 'admission_unavailable',\n 'excess_capture',\n 'late_capture',\n 'cross_checkout_duplicate',\n] as const\nconst CART_WARNING_CODES = [\n 'DISCOUNT_CODE_NOT_HONOURED',\n 'DISCOUNT_CURRENTLY_INACTIVE',\n 'DISCOUNT_CUSTOMER_NOT_ELIGIBLE',\n 'DISCOUNT_CUSTOMER_USAGE_LIMIT_REACHED',\n 'DISCOUNT_ELIGIBLE_CUSTOMER_MISSING',\n 'DISCOUNT_NO_ENTITLED_LINE_ITEMS',\n 'DISCOUNT_NO_ENTITLED_SHIPPING_LINES',\n 'DISCOUNT_NOT_FOUND',\n 'DISCOUNT_PURCHASE_NOT_IN_RANGE',\n 'DISCOUNT_USAGE_LIMIT_REACHED',\n 'MERCHANDISE_NOT_ENOUGH_STOCK',\n 'MERCHANDISE_OUT_OF_STOCK',\n] as const\n\nexport function invalidCanonicalResponse(\n resource: string,\n details: Record<string, unknown>,\n): never {\n throw createApiError(\n `Invalid canonical ${resource} response.`,\n 502,\n { resource, ...details },\n `The server returned an incompatible ${resource} response.`,\n 'Verify that the Console commerce contract is deployed before using this SDK version.',\n )\n}\n\nfunction fail(resource: string, path: string, expected: string): never {\n invalidCanonicalResponse(resource, { path, expected })\n}\n\nfunction providerMismatch(\n resource: string,\n expected: ManagedPaymentProvider,\n actual: ManagedPaymentProvider,\n operation?: 'cancel',\n): never {\n const method = CANCEL_RECOVERY_METHODS[actual]\n if (operation === 'cancel' && method !== null) {\n throw createApiError(\n `Canonical ${resource} response provider mismatch: expected ${expected}, received ${actual}.`,\n 502,\n { resource, path: '$.provider', expected, actual },\n `The server applied the cancellation to a ${actual} PaymentSession, but this SDK method expects ${expected}.`,\n `Re-invoke ${method} with the same idempotencyKey; do not create a new key.`,\n )\n }\n invalidCanonicalResponse(resource, {\n path: '$.provider',\n expected,\n actual,\n })\n}\n\nfunction record(value: unknown, resource: string, path: string): RecordValue {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n fail(resource, path, 'object')\n }\n return value as RecordValue\n}\n\nfunction exact(\n value: RecordValue,\n required: readonly string[],\n optional: readonly string[],\n resource: string,\n path: string,\n): void {\n for (const key of required) {\n if (!(key in value)) fail(resource, `${path}.${key}`, 'required field')\n }\n const allowed = new Set([...required, ...optional])\n const unexpected = Object.keys(value).find((key) => !allowed.has(key))\n if (unexpected) fail(resource, `${path}.${unexpected}`, 'no unknown fields')\n}\n\n// A resource may come from either server generation, never a partial\n// expansion: any new key makes the whole set required by the caller's exact().\nfunction responseExtensionKeys(\n value: RecordValue,\n keys: readonly string[],\n resource: string,\n path: string,\n): string[] {\n if (!keys.some((key) => Object.prototype.hasOwnProperty.call(value, key)))\n return []\n enumValue(\n value.deliveryMethod,\n ['shipping', 'pickup'],\n resource,\n `${path}.deliveryMethod`,\n )\n return [...keys]\n}\n\nfunction string(value: unknown, resource: string, path: string): string {\n if (typeof value !== 'string' || value.length === 0) {\n fail(resource, path, 'non-empty string')\n }\n return value\n}\n\nfunction boundedString(\n value: unknown,\n maxLength: number,\n resource: string,\n path: string,\n allowEmpty = false,\n): string {\n if (\n typeof value !== 'string' ||\n (!allowEmpty && value.length === 0) ||\n value.length > maxLength\n ) {\n fail(\n resource,\n path,\n `${allowEmpty ? '' : 'non-empty '}string of at most ${maxLength} characters`,\n )\n }\n return value\n}\n\nfunction nullableString(value: unknown, resource: string, path: string): void {\n if (value !== null && typeof value !== 'string') {\n fail(resource, path, 'string or null')\n }\n}\n\nfunction nullableNonEmptyString(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== null) string(value, resource, path)\n}\n\nfunction nonBlankString(\n value: unknown,\n resource: string,\n path: string,\n): string {\n const parsed = string(value, resource, path)\n if (parsed.trim().length === 0) {\n fail(resource, path, 'non-blank string')\n }\n return parsed\n}\n\nfunction nullableNonBlankString(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== null) nonBlankString(value, resource, path)\n}\n\nfunction nullableResourceId(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== null) {\n boundedString(value, MAX_COMMERCE_RESOURCE_ID_LENGTH, resource, path)\n }\n}\n\nfunction cartLineQuantity(\n value: unknown,\n resource: string,\n path: string,\n): number {\n const quantity = positiveInteger(value, resource, path)\n if (quantity > MAX_CART_LINE_QUANTITY) {\n fail(resource, path, `integer between 1 and ${MAX_CART_LINE_QUANTITY}`)\n }\n return quantity\n}\n\nfunction boolean(value: unknown, resource: string, path: string): void {\n if (typeof value !== 'boolean') fail(resource, path, 'boolean')\n}\n\nfunction safeMinor(value: unknown, resource: string, path: string): number {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n fail(resource, path, 'non-negative safe integer')\n }\n return value as number\n}\n\nfunction positiveInteger(\n value: unknown,\n resource: string,\n path: string,\n): number {\n if (!Number.isSafeInteger(value) || (value as number) <= 0) {\n fail(resource, path, 'positive safe integer')\n }\n return value as number\n}\n\nfunction enumValue(\n value: unknown,\n values: readonly string[],\n resource: string,\n path: string,\n): string {\n if (typeof value !== 'string' || !values.includes(value)) {\n fail(resource, path, values.join(' | '))\n }\n return value\n}\n\nfunction timestamp(value: unknown, resource: string, path: string): void {\n if (\n typeof value !== 'string' ||\n !/^\\d{4}-\\d{2}-\\d{2}T.*(?:Z|[+-]\\d{2}:\\d{2})$/.test(value) ||\n !Number.isFinite(Date.parse(value))\n ) {\n fail(resource, path, 'ISO 8601 timestamp with offset')\n }\n}\n\nfunction currency(value: unknown, resource: string, path: string): void {\n if (typeof value !== 'string' || !/^[A-Z]{3}$/.test(value)) {\n fail(resource, path, 'three-letter uppercase currency code')\n }\n}\n\nfunction array(value: unknown, resource: string, path: string): unknown[] {\n if (!Array.isArray(value)) fail(resource, path, 'array')\n return value\n}\n\nfunction optionalNullableNumber(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== undefined && value !== null && typeof value !== 'number') {\n fail(resource, path, 'number or null')\n }\n}\n\nfunction validateMediaSize(value: unknown, resource: string, path: string) {\n const item = record(value, resource, path)\n exact(\n item,\n [],\n ['width', 'height', 'mimeType', 'filename', 'url'],\n resource,\n path,\n )\n optionalNullableNumber(item.width, resource, `${path}.width`)\n optionalNullableNumber(item.height, resource, `${path}.height`)\n for (const key of ['mimeType', 'filename', 'url'] as const) {\n if (item[key] !== undefined)\n nullableString(item[key], resource, `${path}.${key}`)\n }\n}\n\nfunction validateMedia(value: unknown, resource: string, path: string): void {\n if (typeof value === 'string') return\n const media = record(value, resource, path)\n exact(\n media,\n [],\n ['id', 'alt', 'width', 'height', 'mimeType', 'filename', 'url', 'sizes'],\n resource,\n path,\n )\n if (\n media.id !== undefined &&\n media.id !== null &&\n typeof media.id !== 'string' &&\n typeof media.id !== 'number'\n ) {\n fail(resource, `${path}.id`, 'string, number, or null')\n }\n for (const key of ['alt', 'mimeType', 'filename', 'url'] as const) {\n if (media[key] !== undefined)\n nullableString(media[key], resource, `${path}.${key}`)\n }\n optionalNullableNumber(media.width, resource, `${path}.width`)\n optionalNullableNumber(media.height, resource, `${path}.height`)\n if (media.sizes !== undefined) {\n const sizes = record(media.sizes, resource, `${path}.sizes`)\n Object.entries(sizes).forEach(([key, size]) =>\n validateMediaSize(size, resource, `${path}.sizes.${key}`),\n )\n }\n}\n\nfunction validateReference(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const ref = record(value, resource, path)\n exact(ref, ['id', 'title', 'handle', 'image'], [], resource, path)\n string(ref.id, resource, `${path}.id`)\n string(ref.title, resource, `${path}.title`)\n if (ref.handle !== null) string(ref.handle, resource, `${path}.handle`)\n if (ref.image !== null) validateMedia(ref.image, resource, `${path}.image`)\n}\n\nfunction validateAdmission(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const admission = record(value, resource, path)\n exact(\n admission,\n ['eventId', 'occurrenceId', 'admissionTypeId'],\n [],\n resource,\n path,\n )\n string(admission.eventId, resource, `${path}.eventId`)\n string(admission.occurrenceId, resource, `${path}.occurrenceId`)\n string(admission.admissionTypeId, resource, `${path}.admissionTypeId`)\n}\n\nfunction compareAdmissions(left: RecordValue, right: RecordValue): number {\n for (const field of ['eventId', 'occurrenceId', 'admissionTypeId'] as const) {\n if ((left[field] as string) < (right[field] as string)) return -1\n if ((left[field] as string) > (right[field] as string)) return 1\n }\n return 0\n}\n\nfunction validateAdmissions(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const admissions = array(value, resource, path)\n if (admissions.length > 32) fail(resource, path, 'at most 32 admissions')\n let prior: RecordValue | undefined\n admissions.forEach((admission, index) => {\n validateAdmission(admission, resource, `${path}[${index}]`)\n const item = admission as RecordValue\n const comparison = prior ? compareAdmissions(item, prior) : undefined\n if (comparison !== undefined && comparison <= 0) {\n fail(resource, `${path}[${index}]`, 'unique canonical-sorted admissions')\n }\n prior = item\n })\n}\n\nfunction validateAttributes(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const attributes = array(value, resource, path)\n if (attributes.length > 50) fail(resource, path, 'at most 50 attributes')\n const keys = new Set<string>()\n attributes.forEach((value, index) => {\n const itemPath = `${path}[${index}]`\n const attribute = record(value, resource, itemPath)\n exact(attribute, ['key', 'value'], [], resource, itemPath)\n const key = string(attribute.key, resource, `${itemPath}.key`)\n if (key.length > 40 || key.startsWith('__') || keys.has(key)) {\n fail(\n resource,\n `${itemPath}.key`,\n 'unique, non-reserved key of at most 40 characters',\n )\n }\n keys.add(key)\n if (typeof attribute.value !== 'string' || attribute.value.length > 500) {\n fail(resource, `${itemPath}.value`, 'string of at most 500 characters')\n }\n })\n}\n\nfunction validateCustomer(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const customer = record(value, resource, path)\n exact(customer, ['email'], ['name', 'phone'], resource, path)\n const email = boundedString(\n customer.email,\n MAX_COMMERCE_EMAIL_LENGTH,\n resource,\n `${path}.email`,\n )\n // Mirrors Zod's default email primitive used by the private contract.\n if (\n !/^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9-]*\\.)+[A-Za-z]{2,}$/.test(\n email,\n )\n ) {\n fail(resource, `${path}.email`, 'email address')\n }\n if (customer.name !== undefined)\n boundedString(\n customer.name,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.name`,\n )\n if (customer.phone !== undefined)\n boundedString(\n customer.phone,\n MAX_COMMERCE_PHONE_LENGTH,\n resource,\n `${path}.phone`,\n )\n}\n\nfunction validateShippingAddress(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const address = record(value, resource, path)\n exact(\n address,\n ['recipientName', 'phone', 'postalCode', 'address', 'detailAddress'],\n ['countryCode', 'regionCode', 'deliveryMessage'],\n resource,\n path,\n )\n boundedString(\n address.recipientName,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.recipientName`,\n )\n boundedString(\n address.phone,\n MAX_COMMERCE_PHONE_LENGTH,\n resource,\n `${path}.phone`,\n )\n boundedString(\n address.postalCode,\n MAX_COMMERCE_POSTAL_CODE_LENGTH,\n resource,\n `${path}.postalCode`,\n )\n for (const key of ['address', 'detailAddress'] as const) {\n boundedString(\n address[key],\n MAX_COMMERCE_ADDRESS_LENGTH,\n resource,\n `${path}.${key}`,\n )\n }\n if (address.countryCode !== undefined) {\n if (\n typeof address.countryCode !== 'string' ||\n address.countryCode.trim().length !== 2\n ) {\n fail(resource, `${path}.countryCode`, 'two-letter country code')\n }\n }\n if (address.regionCode !== undefined) {\n if (\n typeof address.regionCode !== 'string' ||\n address.regionCode.trim().length === 0 ||\n address.regionCode.trim().length > 64\n ) {\n fail(\n resource,\n `${path}.regionCode`,\n 'trimmed string of at most 64 characters',\n )\n }\n }\n if (address.deliveryMessage !== undefined) {\n boundedString(\n address.deliveryMessage,\n MAX_COMMERCE_EXTENSION_VALUE_LENGTH,\n resource,\n `${path}.deliveryMessage`,\n true,\n )\n }\n}\n\nfunction validateOrderReference(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const order = record(value, resource, path)\n exact(order, ['id', 'orderNumber'], [], resource, path)\n string(order.id, resource, `${path}.id`)\n string(order.orderNumber, resource, `${path}.orderNumber`)\n}\n\nfunction validateIntegrationMetadata(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const metadata = record(value, resource, path)\n if (Object.keys(metadata).length > 50)\n fail(resource, path, 'at most 50 entries')\n Object.entries(metadata).forEach(([key, entry]) => {\n if (!key || key.length > 40 || key.includes('[') || key.includes(']')) {\n fail(resource, `${path}.${key}`, 'valid metadata key')\n }\n if (typeof entry !== 'string' || entry.length > 500) {\n fail(resource, `${path}.${key}`, 'string of at most 500 characters')\n }\n })\n}\n\nfunction validateCartItem(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const item = record(value, resource, path)\n exact(\n item,\n [\n 'id',\n 'product',\n 'variant',\n 'admissions',\n 'quantity',\n 'unitPriceMinor',\n 'discountMinor',\n 'estimatedLineTotalMinor',\n 'requiresShipping',\n ],\n [],\n resource,\n path,\n )\n string(item.id, resource, `${path}.id`)\n validateReference(item.product, resource, `${path}.product`)\n validateReference(item.variant, resource, `${path}.variant`)\n validateAdmissions(item.admissions, resource, `${path}.admissions`)\n cartLineQuantity(item.quantity, resource, `${path}.quantity`)\n const unitPrice = safeMinor(\n item.unitPriceMinor,\n resource,\n `${path}.unitPriceMinor`,\n )\n const discount = safeMinor(\n item.discountMinor,\n resource,\n `${path}.discountMinor`,\n )\n const estimatedLineTotal = safeMinor(\n item.estimatedLineTotalMinor,\n resource,\n `${path}.estimatedLineTotalMinor`,\n )\n const quantity = item.quantity as number\n const expectedLineTotal =\n BigInt(unitPrice) * BigInt(quantity) - BigInt(discount)\n if (\n expectedLineTotal < 0n ||\n BigInt(estimatedLineTotal) !== expectedLineTotal\n ) {\n fail(\n resource,\n `${path}.estimatedLineTotalMinor`,\n 'unitPriceMinor * quantity - discountMinor',\n )\n }\n boolean(item.requiresShipping, resource, `${path}.requiresShipping`)\n}\n\nexport function validatePublicCart<T>(value: unknown, resource = 'Cart'): T {\n const cart = record(value, resource, '$')\n exact(\n cart,\n [\n ...responseExtensionKeys(\n cart,\n ['deliveryMethod', 'shippingMinor', 'totalMinor'],\n resource,\n '$',\n ),\n 'id',\n 'status',\n 'revision',\n 'currency',\n 'market',\n 'subtotalMinor',\n 'discountMinor',\n 'estimatedTotalMinor',\n 'discountCodes',\n 'attributes',\n 'items',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n ],\n [],\n resource,\n '$',\n )\n string(cart.id, resource, '$.id')\n enumValue(cart.status, CART_STATUSES, resource, '$.status')\n safeMinor(cart.revision, resource, '$.revision')\n currency(cart.currency, resource, '$.currency')\n const market = record(cart.market, resource, '$.market')\n exact(market, ['id', 'handle', 'name'], [], resource, '$.market')\n for (const key of ['id', 'handle', 'name'] as const)\n string(market[key], resource, `$.market.${key}`)\n const subtotal = safeMinor(cart.subtotalMinor, resource, '$.subtotalMinor')\n const discount = safeMinor(cart.discountMinor, resource, '$.discountMinor')\n const estimatedTotal = safeMinor(\n cart.estimatedTotalMinor,\n resource,\n '$.estimatedTotalMinor',\n )\n array(cart.discountCodes, resource, '$.discountCodes').forEach(\n (value, index) => {\n const itemPath = `$.discountCodes[${index}]`\n const code = record(value, resource, itemPath)\n exact(code, ['code', 'applicable'], [], resource, itemPath)\n boundedString(\n code.code,\n MAX_CART_DISCOUNT_CODE_LENGTH,\n resource,\n `${itemPath}.code`,\n )\n boolean(code.applicable, resource, `${itemPath}.applicable`)\n },\n )\n validateAttributes(cart.attributes, resource, '$.attributes')\n const items = array(cart.items, resource, '$.items')\n items.forEach((item, index) =>\n validateCartItem(item, resource, `$.items[${index}]`),\n )\n const expectedSubtotal = items.reduce<bigint>((total, value) => {\n const item = value as Record<string, unknown>\n return (\n total +\n BigInt(item.unitPriceMinor as number) * BigInt(item.quantity as number)\n )\n }, 0n)\n const expectedDiscount = items.reduce<bigint>((total, value) => {\n const item = value as Record<string, unknown>\n return total + BigInt(item.discountMinor as number)\n }, 0n)\n if (BigInt(subtotal) !== expectedSubtotal) {\n fail(resource, '$.subtotalMinor', 'sum of undiscounted cart line totals')\n }\n if (BigInt(discount) !== expectedDiscount) {\n fail(resource, '$.discountMinor', 'sum of cart line discounts')\n }\n if (\n expectedSubtotal - BigInt(discount) < 0n ||\n BigInt(estimatedTotal) !== expectedSubtotal - BigInt(discount)\n ) {\n fail(resource, '$.estimatedTotalMinor', 'subtotalMinor - discountMinor')\n }\n if ('deliveryMethod' in cart) {\n const shipping = safeMinor(cart.shippingMinor, resource, '$.shippingMinor')\n const total = safeMinor(cart.totalMinor, resource, '$.totalMinor')\n if (BigInt(total) !== BigInt(estimatedTotal) + BigInt(shipping)) {\n fail(resource, '$.totalMinor', 'estimatedTotalMinor + shippingMinor')\n }\n }\n timestamp(cart.expiresAt, resource, '$.expiresAt')\n timestamp(cart.createdAt, resource, '$.createdAt')\n timestamp(cart.updatedAt, resource, '$.updatedAt')\n return value as T\n}\n\nfunction validateWarnings(\n value: unknown,\n resource: string,\n path: string,\n): void {\n array(value, resource, path).forEach((value, index) => {\n const itemPath = `${path}[${index}]`\n const warning = record(value, resource, itemPath)\n exact(warning, ['code', 'message', 'target'], [], resource, itemPath)\n enumValue(warning.code, CART_WARNING_CODES, resource, `${itemPath}.code`)\n string(warning.message, resource, `${itemPath}.message`)\n string(warning.target, resource, `${itemPath}.target`)\n })\n}\n\nexport function validateCartMutationResult<T>(value: unknown): T {\n const result = record(value, 'Cart mutation result', '$')\n exact(result, ['cart', 'warnings'], [], 'Cart mutation result', '$')\n validatePublicCart(result.cart)\n validateWarnings(result.warnings, 'Cart mutation result', '$.warnings')\n return value as T\n}\n\nexport function validateCreateCartResult<T>(value: unknown): T {\n const result = record(value, 'Cart create result', '$')\n exact(\n result,\n ['cart', 'warnings', 'cartToken'],\n [],\n 'Cart create result',\n '$',\n )\n const cart = record(result.cart, 'Cart create result', '$.cart')\n validatePublicCart(cart)\n if (cart.revision !== 0) {\n fail('Cart create result', '$.cart.revision', '0 for a newly created Cart')\n }\n validateWarnings(result.warnings, 'Cart create result', '$.warnings')\n boundedString(\n result.cartToken,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n 'Cart create result',\n '$.cartToken',\n )\n return value as T\n}\n\nexport function validateCartMineResult<T>(value: unknown): T {\n const result = record(value, 'Cart mine result', '$')\n exact(result, ['cart', 'cartToken'], [], 'Cart mine result', '$')\n if (result.cart === null || result.cartToken === null) {\n if (result.cart !== null || result.cartToken !== null) {\n fail('Cart mine result', '$', 'cart and cartToken must both be null')\n }\n } else {\n validatePublicCart(result.cart)\n boundedString(\n result.cartToken,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n 'Cart mine result',\n '$.cartToken',\n )\n }\n return value as T\n}\n\nexport function validateCartMergeResult<T>(value: unknown): T {\n const result = record(value, 'Cart merge result', '$')\n exact(\n result,\n ['cart', 'warnings', 'cartToken', 'resolution', 'merged', 'claimed'],\n [],\n 'Cart merge result',\n '$',\n )\n validatePublicCart(result.cart)\n validateWarnings(result.warnings, 'Cart merge result', '$.warnings')\n boundedString(\n result.cartToken,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n 'Cart merge result',\n '$.cartToken',\n )\n const resolution = enumValue(\n result.resolution,\n ['unchanged', 'claimed', 'merged'],\n 'Cart merge result',\n '$.resolution',\n )\n boolean(result.merged, 'Cart merge result', '$.merged')\n boolean(result.claimed, 'Cart merge result', '$.claimed')\n const expected =\n resolution === 'merged'\n ? [true, false]\n : resolution === 'claimed'\n ? [false, true]\n : [false, false]\n if (result.merged !== expected[0] || result.claimed !== expected[1]) {\n fail('Cart merge result', '$', 'resolution-consistent merged/claimed flags')\n }\n return value as T\n}\n\nfunction validatePublicOrderItem(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const item = record(value, resource, path)\n exact(\n item,\n [\n 'id',\n 'product',\n 'variant',\n 'productTitle',\n 'variantTitle',\n 'sku',\n 'admissions',\n 'quantity',\n 'unitPriceMinor',\n 'discountMinor',\n 'lineTotalMinor',\n 'requiresShipping',\n ],\n [],\n resource,\n path,\n )\n string(item.id, resource, `${path}.id`)\n if (item.product !== null) {\n validateReference(item.product, resource, `${path}.product`)\n }\n if (item.variant !== null) {\n validateReference(item.variant, resource, `${path}.variant`)\n }\n string(item.productTitle, resource, `${path}.productTitle`)\n nullableNonEmptyString(item.variantTitle, resource, `${path}.variantTitle`)\n nullableNonEmptyString(item.sku, resource, `${path}.sku`)\n validateAdmissions(item.admissions, resource, `${path}.admissions`)\n // Order snapshots can contain quantities created before the current cart\n // mutation cap, so only enforce the durable positive-integer invariant here.\n const quantity = positiveInteger(item.quantity, resource, `${path}.quantity`)\n const unitPrice = safeMinor(\n item.unitPriceMinor,\n resource,\n `${path}.unitPriceMinor`,\n )\n const discount = safeMinor(\n item.discountMinor,\n resource,\n `${path}.discountMinor`,\n )\n const lineTotal = safeMinor(\n item.lineTotalMinor,\n resource,\n `${path}.lineTotalMinor`,\n )\n const expected = BigInt(unitPrice) * BigInt(quantity) - BigInt(discount)\n if (expected < 0n || BigInt(lineTotal) !== expected) {\n fail(\n resource,\n `${path}.lineTotalMinor`,\n 'unitPriceMinor * quantity - discountMinor',\n )\n }\n boolean(item.requiresShipping, resource, `${path}.requiresShipping`)\n}\n\nfunction validatePublicOrderAt(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const order = record(value, resource, path)\n exact(\n order,\n [\n ...responseExtensionKeys(\n order,\n ['deliveryMethod', 'pickup', 'source'],\n resource,\n path,\n ),\n 'id',\n 'orderNumber',\n 'amounts',\n 'market',\n 'customerSnapshot',\n 'shippingAddress',\n 'attributes',\n 'items',\n 'financialStatus',\n 'fulfillmentStatus',\n 'returnStatus',\n 'confirmationStatus',\n 'primaryDisplayStatus',\n 'placedAt',\n 'createdAt',\n 'updatedAt',\n ],\n [],\n resource,\n path,\n )\n if ('deliveryMethod' in order) {\n enumValue(\n order.source,\n ['web', 'app', 'manual', 'api', 'import', 'in_person'],\n resource,\n `${path}.source`,\n )\n if (order.deliveryMethod === 'shipping') {\n if (order.pickup !== null)\n fail(resource, `${path}.pickup`, 'null for shipping')\n } else {\n const pickup = record(order.pickup, resource, `${path}.pickup`)\n exact(\n pickup,\n ['status', 'readyAt', 'pickedUpAt'],\n [],\n resource,\n `${path}.pickup`,\n )\n enumValue(\n pickup.status,\n ['pending', 'ready_for_pickup', 'picked_up', 'canceled'],\n resource,\n `${path}.pickup.status`,\n )\n for (const key of ['readyAt', 'pickedUpAt'] as const) {\n if (pickup[key] !== null)\n timestamp(pickup[key], resource, `${path}.pickup.${key}`)\n }\n }\n }\n string(order.id, resource, `${path}.id`)\n string(order.orderNumber, resource, `${path}.orderNumber`)\n\n const amounts = record(order.amounts, resource, `${path}.amounts`)\n exact(\n amounts,\n [\n 'currency',\n 'subtotalMinor',\n 'shippingMinor',\n 'discountMinor',\n 'totalMinor',\n 'refundedMinor',\n 'currentTotalMinor',\n ],\n [],\n resource,\n `${path}.amounts`,\n )\n currency(amounts.currency, resource, `${path}.amounts.currency`)\n const subtotal = safeMinor(\n amounts.subtotalMinor,\n resource,\n `${path}.amounts.subtotalMinor`,\n )\n const shipping = safeMinor(\n amounts.shippingMinor,\n resource,\n `${path}.amounts.shippingMinor`,\n )\n const discount = safeMinor(\n amounts.discountMinor,\n resource,\n `${path}.amounts.discountMinor`,\n )\n const total = safeMinor(\n amounts.totalMinor,\n resource,\n `${path}.amounts.totalMinor`,\n )\n const refunded = safeMinor(\n amounts.refundedMinor,\n resource,\n `${path}.amounts.refundedMinor`,\n )\n const current = safeMinor(\n amounts.currentTotalMinor,\n resource,\n `${path}.amounts.currentTotalMinor`,\n )\n const expectedTotal = BigInt(subtotal) + BigInt(shipping) - BigInt(discount)\n if (expectedTotal < 0n || BigInt(total) !== expectedTotal) {\n fail(\n resource,\n `${path}.amounts.totalMinor`,\n 'subtotalMinor + shippingMinor - discountMinor',\n )\n }\n if (BigInt(total) - BigInt(refunded) < 0n || current !== total - refunded) {\n fail(\n resource,\n `${path}.amounts.currentTotalMinor`,\n 'totalMinor - refundedMinor',\n )\n }\n\n if (order.market !== null) {\n const market = record(order.market, resource, `${path}.market`)\n exact(market, ['id', 'handle', 'name'], [], resource, `${path}.market`)\n for (const key of ['id', 'handle', 'name'] as const) {\n string(market[key], resource, `${path}.market.${key}`)\n }\n }\n validateCustomer(order.customerSnapshot, resource, `${path}.customerSnapshot`)\n if (order.shippingAddress !== null) {\n validateShippingAddress(\n order.shippingAddress,\n resource,\n `${path}.shippingAddress`,\n )\n }\n validateAttributes(order.attributes, resource, `${path}.attributes`)\n\n const items = array(order.items, resource, `${path}.items`)\n if (items.length === 0) fail(resource, `${path}.items`, 'non-empty array')\n items.forEach((item, index) =>\n validatePublicOrderItem(item, resource, `${path}.items[${index}]`),\n )\n const expectedSubtotal = items.reduce<bigint>((sum, value) => {\n const item = value as RecordValue\n return (\n sum +\n BigInt(item.unitPriceMinor as number) * BigInt(item.quantity as number)\n )\n }, 0n)\n const expectedDiscount = items.reduce<bigint>((sum, value) => {\n const item = value as RecordValue\n return sum + BigInt(item.discountMinor as number)\n }, 0n)\n if (BigInt(subtotal) !== expectedSubtotal) {\n fail(resource, `${path}.amounts.subtotalMinor`, 'sum of line subtotals')\n }\n if (BigInt(discount) !== expectedDiscount) {\n fail(resource, `${path}.amounts.discountMinor`, 'sum of line discounts')\n }\n\n enumValue(\n order.financialStatus,\n ORDER_FINANCIAL_STATUSES,\n resource,\n `${path}.financialStatus`,\n )\n enumValue(\n order.fulfillmentStatus,\n ORDER_FULFILLMENT_STATUSES,\n resource,\n `${path}.fulfillmentStatus`,\n )\n enumValue(\n order.returnStatus,\n ORDER_RETURN_STATUSES,\n resource,\n `${path}.returnStatus`,\n )\n enumValue(\n order.confirmationStatus,\n ORDER_CONFIRMATION_STATUSES,\n resource,\n `${path}.confirmationStatus`,\n )\n enumValue(\n order.primaryDisplayStatus,\n ORDER_PRIMARY_DISPLAY_STATUSES,\n resource,\n `${path}.primaryDisplayStatus`,\n )\n timestamp(order.placedAt, resource, `${path}.placedAt`)\n timestamp(order.createdAt, resource, `${path}.createdAt`)\n timestamp(order.updatedAt, resource, `${path}.updatedAt`)\n}\n\nexport function validatePublicOrder<T>(value: unknown): T {\n validatePublicOrderAt(value, 'Order', '$')\n return value as T\n}\n\nfunction nullablePositiveInteger(\n value: unknown,\n resource: string,\n path: string,\n): void {\n if (value !== null) positiveInteger(value, resource, path)\n}\n\nexport function validatePublicOrderList<T>(value: unknown): T {\n const resource = 'Order list'\n const result = record(value, resource, '$')\n exact(\n result,\n [\n 'docs',\n 'totalDocs',\n 'limit',\n 'totalPages',\n 'page',\n 'pagingCounter',\n 'hasPrevPage',\n 'hasNextPage',\n 'prevPage',\n 'nextPage',\n ],\n [],\n resource,\n '$',\n )\n array(result.docs, resource, '$.docs').forEach((order, index) =>\n validatePublicOrderAt(order, resource, `$.docs[${index}]`),\n )\n safeMinor(result.totalDocs, resource, '$.totalDocs')\n positiveInteger(result.limit, resource, '$.limit')\n safeMinor(result.totalPages, resource, '$.totalPages')\n positiveInteger(result.page, resource, '$.page')\n positiveInteger(result.pagingCounter, resource, '$.pagingCounter')\n boolean(result.hasPrevPage, resource, '$.hasPrevPage')\n boolean(result.hasNextPage, resource, '$.hasNextPage')\n nullablePositiveInteger(result.prevPage, resource, '$.prevPage')\n nullablePositiveInteger(result.nextPage, resource, '$.nextPage')\n return value as T\n}\n\nfunction validateCheckoutItem(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const item = record(value, resource, path)\n exact(\n item,\n [\n 'id',\n 'product',\n 'variant',\n 'productTitle',\n 'variantTitle',\n 'sku',\n 'admissions',\n 'quantity',\n 'unitPriceMinor',\n 'discountMinor',\n 'lineTotalMinor',\n 'requiresShipping',\n ],\n [],\n resource,\n path,\n )\n string(item.id, resource, `${path}.id`)\n validateReference(item.product, resource, `${path}.product`)\n validateReference(item.variant, resource, `${path}.variant`)\n string(item.productTitle, resource, `${path}.productTitle`)\n nullableNonEmptyString(item.variantTitle, resource, `${path}.variantTitle`)\n nullableNonEmptyString(item.sku, resource, `${path}.sku`)\n validateAdmissions(item.admissions, resource, `${path}.admissions`)\n cartLineQuantity(item.quantity, resource, `${path}.quantity`)\n const unitPrice = safeMinor(\n item.unitPriceMinor,\n resource,\n `${path}.unitPriceMinor`,\n )\n const discount = safeMinor(\n item.discountMinor,\n resource,\n `${path}.discountMinor`,\n )\n const lineTotal = safeMinor(\n item.lineTotalMinor,\n resource,\n `${path}.lineTotalMinor`,\n )\n const expectedLineTotal =\n BigInt(unitPrice) * BigInt(item.quantity as number) - BigInt(discount)\n if (expectedLineTotal < 0n || BigInt(lineTotal) !== expectedLineTotal) {\n fail(\n resource,\n `${path}.lineTotalMinor`,\n 'unitPriceMinor * quantity - discountMinor',\n )\n }\n boolean(item.requiresShipping, resource, `${path}.requiresShipping`)\n}\n\nfunction validateCheckoutAmounts(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const amounts = record(value, resource, path)\n exact(\n amounts,\n [\n 'currency',\n 'subtotalMinor',\n 'shippingMinor',\n 'discountMinor',\n 'totalMinor',\n ],\n [],\n resource,\n path,\n )\n currency(amounts.currency, resource, `${path}.currency`)\n const subtotal = safeMinor(\n amounts.subtotalMinor,\n resource,\n `${path}.subtotalMinor`,\n )\n const shipping = safeMinor(\n amounts.shippingMinor,\n resource,\n `${path}.shippingMinor`,\n )\n const discount = safeMinor(\n amounts.discountMinor,\n resource,\n `${path}.discountMinor`,\n )\n const total = safeMinor(amounts.totalMinor, resource, `${path}.totalMinor`)\n if (\n BigInt(total) !==\n BigInt(subtotal) + BigInt(shipping) - BigInt(discount)\n ) {\n fail(\n resource,\n `${path}.totalMinor`,\n 'subtotalMinor + shippingMinor - discountMinor',\n )\n }\n}\n\nfunction validatePaymentSessionReference(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const session = record(value, resource, path)\n exact(session, ['id', 'provider', 'providerStatus'], [], resource, path)\n string(session.id, resource, `${path}.id`)\n enumValue(session.provider, PAYMENT_PROVIDERS, resource, `${path}.provider`)\n enumValue(\n session.providerStatus,\n PAYMENT_PROVIDER_STATUSES,\n resource,\n `${path}.providerStatus`,\n )\n}\n\nfunction checkoutVariantKeys(\n status: string,\n placedVia: unknown,\n): {\n required: string[]\n optional: string[]\n} {\n const base = [\n 'id',\n 'amounts',\n 'items',\n 'customerSnapshot',\n 'shippingAddress',\n 'attributes',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n 'status',\n 'paymentState',\n 'order',\n ]\n if (status === 'open') return { required: base, optional: [] }\n if (status === 'abandoned') {\n return {\n required: [...base, 'abandonedAt', 'abandonedReason'],\n optional: [],\n }\n }\n return placedVia === 'late_capture'\n ? {\n required: [\n ...base,\n 'placedAt',\n 'placedVia',\n 'abandonedAt',\n 'abandonedReason',\n ],\n optional: [],\n }\n : { required: [...base, 'placedAt'], optional: [] }\n}\n\nfunction validateCheckoutCore(\n value: unknown,\n resource: string,\n list: boolean,\n server: boolean,\n): void {\n const checkout = record(value, resource, '$')\n const status = enumValue(\n checkout.status,\n CHECKOUT_STATUSES,\n resource,\n '$.status',\n )\n const keys = checkoutVariantKeys(status, checkout.placedVia)\n keys.required.push(\n ...responseExtensionKeys(\n checkout,\n ['deliveryMethod', 'source'],\n resource,\n '$',\n ),\n )\n if ('deliveryMethod' in checkout)\n enumValue(checkout.source, ['web', 'in_person'], resource, '$.source')\n keys.optional.push('funding')\n if (list) {\n keys.required = keys.required.filter(\n (key) => !['items', 'shippingAddress', 'attributes'].includes(key),\n )\n keys.required.push('clientReferenceId')\n } else if (server) {\n keys.required.push('clientReferenceId', 'integrationMetadata')\n }\n exact(checkout, keys.required, keys.optional, resource, '$')\n string(checkout.id, resource, '$.id')\n validateCheckoutAmounts(checkout.amounts, resource, '$.amounts')\n if (Object.prototype.hasOwnProperty.call(checkout, 'funding')) {\n const funding = record(checkout.funding, resource, '$.funding')\n exact(\n funding,\n ['creditAmount', 'providerPayableAmount'],\n [],\n resource,\n '$.funding',\n )\n const credit = safeMinor(\n funding.creditAmount,\n resource,\n '$.funding.creditAmount',\n )\n const provider = safeMinor(\n funding.providerPayableAmount,\n resource,\n '$.funding.providerPayableAmount',\n )\n const amounts = checkout.amounts as Record<string, unknown>\n if (\n BigInt(credit) + BigInt(provider) !==\n BigInt(amounts.totalMinor as number) ||\n (credit > 0 && amounts.currency !== 'KRW')\n )\n fail(\n resource,\n '$.funding',\n 'exact purchase total split; positive credits require KRW',\n )\n }\n if (!list) {\n const items = array(checkout.items, resource, '$.items')\n if (items.length === 0) fail(resource, '$.items', 'non-empty array')\n items.forEach((item, index) =>\n validateCheckoutItem(item, resource, `$.items[${index}]`),\n )\n const expectedSubtotal = items.reduce<bigint>((total, value) => {\n const item = value as Record<string, unknown>\n return (\n total +\n BigInt(item.unitPriceMinor as number) * BigInt(item.quantity as number)\n )\n }, 0n)\n const expectedDiscount = items.reduce<bigint>((total, value) => {\n const item = value as Record<string, unknown>\n return total + BigInt(item.discountMinor as number)\n }, 0n)\n const amounts = checkout.amounts as Record<string, unknown>\n if (BigInt(amounts.subtotalMinor as number) !== expectedSubtotal) {\n fail(\n resource,\n '$.amounts.subtotalMinor',\n 'sum of undiscounted checkout line totals',\n )\n }\n if (BigInt(amounts.discountMinor as number) !== expectedDiscount) {\n fail(\n resource,\n '$.amounts.discountMinor',\n 'sum of checkout line discounts',\n )\n }\n if (checkout.shippingAddress !== null) {\n validateShippingAddress(\n checkout.shippingAddress,\n resource,\n '$.shippingAddress',\n )\n }\n validateAttributes(checkout.attributes, resource, '$.attributes')\n }\n validateCustomer(checkout.customerSnapshot, resource, '$.customerSnapshot')\n timestamp(checkout.expiresAt, resource, '$.expiresAt')\n timestamp(checkout.createdAt, resource, '$.createdAt')\n timestamp(checkout.updatedAt, resource, '$.updatedAt')\n\n const paymentState = record(checkout.paymentState, resource, '$.paymentState')\n exact(paymentState, ['activePaymentSession'], [], resource, '$.paymentState')\n if (status === 'open') {\n if (paymentState.activePaymentSession !== null) {\n validatePaymentSessionReference(\n paymentState.activePaymentSession,\n resource,\n '$.paymentState.activePaymentSession',\n )\n }\n if (checkout.order !== null)\n fail(resource, '$.order', 'null for open Checkout')\n } else {\n if (paymentState.activePaymentSession !== null) {\n fail(\n resource,\n '$.paymentState.activePaymentSession',\n 'null for spent Checkout',\n )\n }\n if (status === 'placed') {\n timestamp(checkout.placedAt, resource, '$.placedAt')\n validateOrderReference(checkout.order, resource, '$.order')\n if (\n checkout.placedVia !== undefined &&\n checkout.placedVia !== 'late_capture'\n ) {\n fail(resource, '$.placedVia', 'late_capture')\n }\n if (checkout.placedVia === 'late_capture') {\n timestamp(checkout.abandonedAt, resource, '$.abandonedAt')\n enumValue(\n checkout.abandonedReason,\n ABANDONED_REASONS,\n resource,\n '$.abandonedReason',\n )\n }\n } else {\n timestamp(checkout.abandonedAt, resource, '$.abandonedAt')\n enumValue(\n checkout.abandonedReason,\n ABANDONED_REASONS,\n resource,\n '$.abandonedReason',\n )\n if (checkout.order !== null)\n fail(resource, '$.order', 'null for abandoned Checkout')\n }\n }\n if (list || server) {\n if (checkout.clientReferenceId !== null) {\n boundedString(\n checkout.clientReferenceId,\n MAX_COMMERCE_RESOURCE_ID_LENGTH,\n resource,\n '$.clientReferenceId',\n )\n }\n }\n if (server)\n validateIntegrationMetadata(\n checkout.integrationMetadata,\n resource,\n '$.integrationMetadata',\n )\n}\n\nexport function validatePublicCheckout<T>(value: unknown): T {\n validateCheckoutCore(value, 'Checkout', false, false)\n return value as T\n}\n\nexport function validateServerCheckout<T>(value: unknown): T {\n validateCheckoutCore(value, 'Server Checkout', false, true)\n return value as T\n}\n\nexport function validateCreateCheckoutResult<T>(\n value: unknown,\n server: boolean,\n): T {\n const resource = server\n ? 'Server Checkout create result'\n : 'Checkout create result'\n const result = record(value, resource, '$')\n exact(result, ['checkout', 'checkoutToken'], [], resource, '$')\n if (server) validateServerCheckout(result.checkout)\n else validatePublicCheckout(result.checkout)\n boundedString(\n result.checkoutToken,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n resource,\n '$.checkoutToken',\n )\n return value as T\n}\n\nexport function validateCheckoutQueryResult<T>(value: unknown): T {\n const result = record(value, 'Checkout query result', '$')\n exact(\n result,\n ['data', 'hasMore', 'nextCursor'],\n [],\n 'Checkout query result',\n '$',\n )\n array(result.data, 'Checkout query result', '$.data').forEach((item) =>\n validateCheckoutCore(item, 'Checkout list item', true, false),\n )\n boolean(result.hasMore, 'Checkout query result', '$.hasMore')\n if (result.nextCursor !== null)\n boundedString(\n result.nextCursor,\n MAX_COMMERCE_CAPABILITY_LENGTH,\n 'Checkout query result',\n '$.nextCursor',\n )\n if (result.hasMore === true && result.nextCursor === null) {\n fail(\n 'Checkout query result',\n '$.nextCursor',\n 'non-null when hasMore is true',\n )\n }\n return value as T\n}\n\nfunction validateMoney(value: unknown, resource: string, path: string): void {\n const money = record(value, resource, path)\n exact(money, ['amountMinor', 'currency'], [], resource, path)\n safeMinor(money.amountMinor, resource, `${path}.amountMinor`)\n currency(money.currency, resource, `${path}.currency`)\n}\n\nexport function validateCustomPaymentSession<T>(value: unknown): T {\n const resource = 'custom PaymentSession'\n const session = record(value, resource, '$')\n exact(\n session,\n ['id', 'provider', 'providerSessionId', 'money'],\n [],\n resource,\n '$',\n )\n string(session.id, resource, '$.id')\n const provider = string(session.provider, resource, '$.provider')\n if (!/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(provider)) {\n fail(resource, '$.provider', 'provider slug')\n }\n string(session.providerSessionId, resource, '$.providerSessionId')\n validateMoney(session.money, resource, '$.money')\n return value as T\n}\n\nexport function validateRetrievedCustomPaymentSession<T>(value: unknown): T {\n const resource = 'retrieved custom PaymentSession'\n const session = record(value, resource, '$')\n exact(\n session,\n [\n 'id',\n 'provider',\n 'providerSessionId',\n 'providerPaymentId',\n 'status',\n 'providerStatus',\n 'finalizationStatus',\n 'money',\n 'orderId',\n ],\n [],\n resource,\n '$',\n )\n boundedString(session.id, MAX_COMMERCE_RESOURCE_ID_LENGTH, resource, '$.id')\n const provider = string(session.provider, resource, '$.provider')\n if (!/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(provider)) {\n fail(resource, '$.provider', 'provider slug')\n }\n nonBlankString(session.providerSessionId, resource, '$.providerSessionId')\n nullableNonBlankString(\n session.providerPaymentId,\n resource,\n '$.providerPaymentId',\n )\n enumValue(\n session.status,\n ['pending', 'captured', 'failed', 'canceled'] as const,\n resource,\n '$.status',\n )\n enumValue(\n session.providerStatus,\n PAYMENT_PROVIDER_STATUSES,\n resource,\n '$.providerStatus',\n )\n enumValue(\n session.finalizationStatus,\n ['not_ready', 'pending', 'committed'] as const,\n resource,\n '$.finalizationStatus',\n )\n validateMoney(session.money, resource, '$.money')\n nullableResourceId(session.orderId, resource, '$.orderId')\n return value as T\n}\n\nfunction validatePortOnePaymentCurrentState(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const current = record(value, resource, path)\n exact(\n current,\n ['paymentSession', 'checkout', 'order', 'money'],\n [],\n resource,\n path,\n )\n const session = record(\n current.paymentSession,\n resource,\n `${path}.paymentSession`,\n )\n exact(\n session,\n [\n 'id',\n 'provider',\n 'providerStatus',\n 'finalizationStatus',\n 'sessionRole',\n 'reconciliation',\n ],\n [],\n resource,\n `${path}.paymentSession`,\n )\n boundedString(\n session.id,\n MAX_COMMERCE_RESOURCE_ID_LENGTH,\n resource,\n `${path}.paymentSession.id`,\n )\n if (session.provider !== 'portone') {\n fail(resource, `${path}.paymentSession.provider`, 'portone')\n }\n enumValue(\n session.providerStatus,\n PAYMENT_PROVIDER_STATUSES,\n resource,\n `${path}.paymentSession.providerStatus`,\n )\n enumValue(\n session.finalizationStatus,\n ['not_ready', 'pending', 'committed'] as const,\n resource,\n `${path}.paymentSession.finalizationStatus`,\n )\n enumValue(\n session.sessionRole,\n ['active', 'canonical_candidate', 'canonical', 'residual', 'historical'],\n resource,\n `${path}.paymentSession.sessionRole`,\n )\n const reconciliation = record(\n session.reconciliation,\n resource,\n `${path}.paymentSession.reconciliation`,\n )\n if (reconciliation.status === 'none') {\n validateNoReconciliation(\n reconciliation,\n resource,\n `${path}.paymentSession.reconciliation`,\n )\n } else {\n validateRequiredReconciliation(\n reconciliation,\n PAYMENT_RECONCILIATION_REASONS,\n resource,\n `${path}.paymentSession.reconciliation`,\n )\n }\n\n const checkout = record(current.checkout, resource, `${path}.checkout`)\n exact(checkout, ['id'], [], resource, `${path}.checkout`)\n boundedString(\n checkout.id,\n MAX_COMMERCE_RESOURCE_ID_LENGTH,\n resource,\n `${path}.checkout.id`,\n )\n if (current.order !== null) {\n const order = record(current.order, resource, `${path}.order`)\n exact(order, ['id', 'orderNumber'], [], resource, `${path}.order`)\n boundedString(\n order.id,\n MAX_COMMERCE_RESOURCE_ID_LENGTH,\n resource,\n `${path}.order.id`,\n )\n nonBlankString(order.orderNumber, resource, `${path}.order.orderNumber`)\n }\n validateMoney(current.money, resource, `${path}.money`)\n}\n\nexport function validatePortOnePaymentFacadeResult<T>(\n value: unknown,\n mutating: boolean,\n): T {\n const resource = mutating\n ? 'PortOne payment reconciliation result'\n : 'PortOne payment find result'\n const result = record(value, resource, '$')\n boolean(result.found, resource, '$.found')\n if (result.found === false) {\n exact(\n result,\n mutating ? ['found', 'disposition'] : ['found'],\n [],\n resource,\n '$',\n )\n if (mutating && result.disposition !== 'requires_attention') {\n fail(resource, '$.disposition', 'requires_attention')\n }\n return value as T\n }\n\n exact(\n result,\n mutating ? ['found', 'disposition', 'current'] : ['found', 'current'],\n [],\n resource,\n '$',\n )\n if (mutating) {\n enumValue(\n result.disposition,\n [\n 'applied',\n 'observed',\n 'recovered_after_ambiguous_result',\n 'requires_attention',\n ],\n resource,\n '$.disposition',\n )\n }\n validatePortOnePaymentCurrentState(result.current, resource, '$.current')\n return value as T\n}\n\nexport function validateConfirmCustomPaymentSessionResponse<T>(\n value: unknown,\n): T {\n const resource = 'custom PaymentSession confirmation'\n const result = record(value, resource, '$')\n exact(\n result,\n ['orderId', 'transactionId', 'status'],\n ['alreadyConfirmed'],\n resource,\n '$',\n )\n string(result.orderId, resource, '$.orderId')\n string(result.transactionId, resource, '$.transactionId')\n if (result.status !== 'paid') fail(resource, '$.status', 'paid')\n if (result.alreadyConfirmed !== undefined) {\n boolean(result.alreadyConfirmed, resource, '$.alreadyConfirmed')\n }\n return value as T\n}\n\nfunction validateCaptureEvidence(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const evidence = record(value, resource, path)\n exact(evidence, ['amountMinor', 'currency', 'observedAt'], [], resource, path)\n safeMinor(evidence.amountMinor, resource, `${path}.amountMinor`)\n currency(evidence.currency, resource, `${path}.currency`)\n timestamp(evidence.observedAt, resource, `${path}.observedAt`)\n}\n\nfunction validateNoReconciliation(\n value: unknown,\n resource: string,\n path: string,\n): void {\n const reconciliation = record(value, resource, path)\n exact(reconciliation, ['status'], [], resource, path)\n if (reconciliation.status !== 'none') fail(resource, `${path}.status`, 'none')\n}\n\nfunction validateRequiredReconciliation(\n value: unknown,\n allowed: readonly string[],\n resource: string,\n path: string,\n): void {\n const reconciliation = record(value, resource, path)\n exact(reconciliation, ['status', 'reasons'], [], resource, path)\n if (reconciliation.status !== 'required')\n fail(resource, `${path}.status`, 'required')\n const reasons = array(reconciliation.reasons, resource, `${path}.reasons`)\n if (reasons.length === 0) fail(resource, `${path}.reasons`, 'non-empty array')\n let previous = -1\n reasons.forEach((reason, index) => {\n const current = allowed.indexOf(reason as string)\n if (current < 0 || current <= previous) {\n fail(\n resource,\n `${path}.reasons[${index}]`,\n 'unique canonical-sorted reconciliation reason',\n )\n }\n previous = current\n })\n}\n\nfunction validateNextAction(\n value: unknown,\n provider: ManagedPaymentProvider,\n resource: string,\n path: string,\n): void {\n const action = record(value, resource, path)\n if (provider === 'stripe') {\n exact(\n action,\n ['type', 'clientSecret', 'publishableKey', 'returnUrl'],\n [],\n resource,\n path,\n )\n if (action.type !== 'stripe_payment_element')\n fail(resource, `${path}.type`, 'stripe_payment_element')\n const clientSecret = boundedString(\n action.clientSecret,\n 255,\n resource,\n `${path}.clientSecret`,\n )\n if (!/^pi_[A-Za-z0-9]+_secret_[A-Za-z0-9]+$/.test(clientSecret)) {\n fail(\n resource,\n `${path}.clientSecret`,\n 'Stripe PaymentIntent client secret',\n )\n }\n const publishableKey = boundedString(\n action.publishableKey,\n 255,\n resource,\n `${path}.publishableKey`,\n )\n if (!/^pk_(?:test|live)_[A-Za-z0-9]+$/.test(publishableKey)) {\n fail(resource, `${path}.publishableKey`, 'Stripe publishable key')\n }\n const returnUrl = boundedString(\n action.returnUrl,\n 2048,\n resource,\n `${path}.returnUrl`,\n )\n if (\n !STRIPE_RETURN_URL_RAW_CHARACTERS.test(returnUrl) ||\n !STRIPE_RETURN_URL_AUTHORITY.test(returnUrl)\n ) {\n fail(\n resource,\n `${path}.returnUrl`,\n 'HTTPS or loopback URL without embedded credentials',\n )\n }\n try {\n const parsed = new URL(returnUrl)\n const loopback =\n parsed.protocol === 'http:' &&\n (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1')\n if (\n (!loopback && parsed.protocol !== 'https:') ||\n parsed.username ||\n parsed.password\n )\n throw new Error('unsafe return URL')\n } catch {\n fail(\n resource,\n `${path}.returnUrl`,\n 'HTTPS or loopback URL without embedded credentials',\n )\n }\n return\n }\n if (provider === 'portone') {\n if (action.type === 'portone_sdk') {\n const hasCancelable = 'cancelable' in action\n const hasRetryPolicy = 'retryPolicy' in action\n if (hasCancelable !== hasRetryPolicy) {\n fail(\n resource,\n path,\n 'exact released action or exact negotiated capability action',\n )\n }\n exact(\n action,\n [\n 'type',\n 'version',\n ...(hasCancelable ? ['cancelable', 'retryPolicy'] : []),\n 'storeId',\n 'channelKey',\n 'paymentId',\n 'orderName',\n 'totalAmount',\n 'currency',\n 'payMethod',\n 'redirectUrl',\n ],\n [],\n resource,\n path,\n )\n if (action.version !== 'v2') fail(resource, `${path}.version`, 'v2')\n if (hasCancelable && action.cancelable !== false)\n fail(resource, `${path}.cancelable`, 'false')\n if (hasRetryPolicy && action.retryPolicy !== 'same_action_only') {\n fail(resource, `${path}.retryPolicy`, 'same_action_only')\n }\n for (const key of ['storeId', 'channelKey'] as const) {\n boundedString(action[key], 255, resource, `${path}.${key}`)\n }\n const paymentId = boundedString(\n action.paymentId,\n 40,\n resource,\n `${path}.paymentId`,\n )\n if (!/^[A-Za-z0-9]{6,40}$/.test(paymentId)) {\n fail(\n resource,\n `${path}.paymentId`,\n '6-40 ASCII alphanumeric characters',\n )\n }\n boundedString(\n action.orderName,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.orderName`,\n )\n positiveInteger(action.totalAmount, resource, `${path}.totalAmount`)\n if (action.currency !== 'CURRENCY_KRW') {\n fail(resource, `${path}.currency`, 'CURRENCY_KRW')\n }\n if (action.payMethod !== 'CARD')\n fail(resource, `${path}.payMethod`, 'CARD')\n const redirectUrl = boundedString(\n action.redirectUrl,\n 2048,\n resource,\n `${path}.redirectUrl`,\n )\n try {\n const parsed = new URL(redirectUrl)\n const loopback =\n parsed.protocol === 'http:' &&\n (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1')\n if (\n (!loopback && parsed.protocol !== 'https:') ||\n parsed.username ||\n parsed.password\n )\n throw new Error('unsafe redirect URL')\n } catch {\n fail(\n resource,\n `${path}.redirectUrl`,\n 'HTTPS or loopback URL without embedded credentials',\n )\n }\n if (!hasCancelable) {\n action.cancelable = false\n action.retryPolicy = 'same_action_only'\n }\n return\n }\n exact(action, ['type', 'checkoutUrl'], [], resource, path)\n if (action.type !== 'portone_checkout') {\n fail(resource, `${path}.type`, 'portone_checkout | portone_sdk')\n }\n const checkoutUrl = boundedString(\n action.checkoutUrl,\n 2048,\n resource,\n `${path}.checkoutUrl`,\n )\n try {\n const parsed = new URL(checkoutUrl)\n if (\n parsed.protocol !== 'https:' ||\n parsed.username !== '' ||\n parsed.password !== ''\n ) {\n throw new Error('unsafe checkout URL')\n }\n } catch {\n fail(\n resource,\n `${path}.checkoutUrl`,\n 'absolute HTTPS URL without embedded credentials',\n )\n }\n return\n }\n exact(\n action,\n [\n 'type',\n 'clientKey',\n 'paymentMethodVariantKey',\n 'agreementVariantKey',\n 'providerOrderId',\n 'providerCustomerKey',\n 'orderName',\n ],\n ['customerName', 'customerEmail'],\n resource,\n path,\n )\n if (action.type !== 'toss_widget')\n fail(resource, `${path}.type`, 'toss_widget')\n for (const key of [\n 'clientKey',\n 'paymentMethodVariantKey',\n 'agreementVariantKey',\n ] as const) {\n boundedString(action[key], 255, resource, `${path}.${key}`)\n }\n string(action.providerOrderId, resource, `${path}.providerOrderId`)\n string(action.providerCustomerKey, resource, `${path}.providerCustomerKey`)\n boundedString(\n action.orderName,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.orderName`,\n )\n if (!/^[A-Za-z0-9_-]{6,64}$/.test(action.providerOrderId as string)) {\n fail(resource, `${path}.providerOrderId`, 'valid Toss provider order ID')\n }\n if (\n action.providerCustomerKey !== 'ANONYMOUS' &&\n !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(\n action.providerCustomerKey as string,\n )\n ) {\n fail(resource, `${path}.providerCustomerKey`, 'ANONYMOUS or UUIDv4')\n }\n if (action.customerName !== undefined)\n boundedString(\n action.customerName,\n MAX_COMMERCE_SHORT_TEXT_LENGTH,\n resource,\n `${path}.customerName`,\n )\n if (action.customerEmail !== undefined)\n validateCustomer({ email: action.customerEmail }, resource, path)\n}\n\nexport function validatePublicPaymentSession<T>(\n value: unknown,\n expectedProvider?: ManagedPaymentProvider,\n operation?: 'cancel',\n): T {\n const resource = 'PaymentSession'\n const session = record(value, resource, '$')\n const provider = enumValue(\n session.provider,\n PAYMENT_PROVIDERS,\n resource,\n '$.provider',\n ) as (typeof PAYMENT_PROVIDERS)[number]\n const status = enumValue(\n session.providerStatus,\n PAYMENT_PROVIDER_STATUSES,\n resource,\n '$.providerStatus',\n )\n const common = [\n 'id',\n 'money',\n 'expiresAt',\n 'sessionRole',\n 'provider',\n 'providerStatus',\n 'presentationStatus',\n 'finalizationStatus',\n 'reconciliation',\n 'order',\n ]\n const optional: string[] = []\n if (status === 'requires_payment_method' || status === 'requires_action')\n optional.push('nextAction')\n else if (status === 'captured') common.push('providerEvidence')\n else if (status === 'failed') common.push('failure')\n else if (status === 'canceled') common.push('cancellationReason')\n exact(session, common, optional, resource, '$')\n string(session.id, resource, '$.id')\n validateMoney(session.money, resource, '$.money')\n if (session.expiresAt !== null)\n timestamp(session.expiresAt, resource, '$.expiresAt')\n\n if (status === 'requires_payment_method' || status === 'requires_action') {\n if (session.sessionRole === 'active') {\n if (\n session.presentationStatus !== 'actionable' ||\n session.finalizationStatus !== 'not_ready'\n ) {\n fail(resource, '$', 'actionable active not-ready state')\n }\n if (!('nextAction' in session))\n fail(resource, '$.nextAction', 'required field')\n validateNextAction(\n session.nextAction,\n provider as ManagedPaymentProvider,\n resource,\n '$.nextAction',\n )\n } else if (session.sessionRole === 'residual') {\n if (\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready'\n ) {\n fail(resource, '$', 'suppressed residual not-ready state')\n }\n if ('nextAction' in session)\n fail(resource, '$.nextAction', 'absent for suppressed state')\n } else fail(resource, '$.sessionRole', 'active | residual')\n validateNoReconciliation(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n if (session.order !== null) fail(resource, '$.order', 'null')\n } else if (\n [\n 'requires_confirmation',\n 'initializing',\n 'processing',\n 'authorized',\n 'canceling',\n ].includes(status)\n ) {\n enumValue(\n session.sessionRole,\n ['active', 'residual'],\n resource,\n '$.sessionRole',\n )\n if (\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready'\n ) {\n fail(resource, '$', 'suppressed not-ready state')\n }\n validateNoReconciliation(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n if (session.order !== null) fail(resource, '$.order', 'null')\n } else if (status === 'unknown') {\n enumValue(\n session.sessionRole,\n ['active', 'residual'],\n resource,\n '$.sessionRole',\n )\n if (\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready'\n ) {\n fail(resource, '$', 'suppressed not-ready state')\n }\n validateRequiredReconciliation(\n session.reconciliation,\n ['provider_outcome_unknown'],\n resource,\n '$.reconciliation',\n )\n if (session.order !== null) fail(resource, '$.order', 'null')\n } else if (status === 'captured') {\n validateCaptureEvidence(\n session.providerEvidence,\n resource,\n '$.providerEvidence',\n )\n if (session.presentationStatus !== 'suppressed')\n fail(resource, '$.presentationStatus', 'suppressed')\n if (session.finalizationStatus === 'pending') {\n enumValue(\n session.sessionRole,\n ['canonical_candidate', 'residual'],\n resource,\n '$.sessionRole',\n )\n if (session.order !== null)\n fail(resource, '$.order', 'null for pending finalization')\n const reconciliation = record(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n if (reconciliation.status === 'none')\n validateNoReconciliation(reconciliation, resource, '$.reconciliation')\n else\n validateRequiredReconciliation(\n reconciliation,\n [\n 'local_commit_ambiguous',\n 'amount_mismatch',\n 'currency_mismatch',\n 'excess_capture_pending_order',\n ],\n resource,\n '$.reconciliation',\n )\n } else if (session.finalizationStatus === 'committed') {\n validateOrderReference(session.order, resource, '$.order')\n const reconciliation = record(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n if (reconciliation.status === 'none') {\n enumValue(\n session.sessionRole,\n ['canonical', 'historical'],\n resource,\n '$.sessionRole',\n )\n validateNoReconciliation(reconciliation, resource, '$.reconciliation')\n } else {\n enumValue(\n session.sessionRole,\n ['canonical', 'residual'],\n resource,\n '$.sessionRole',\n )\n validateRequiredReconciliation(\n reconciliation,\n [\n 'inventory_unavailable',\n 'admission_unavailable',\n 'amount_mismatch',\n 'currency_mismatch',\n 'excess_capture',\n 'late_capture',\n 'cross_checkout_duplicate',\n ],\n resource,\n '$.reconciliation',\n )\n }\n } else fail(resource, '$.finalizationStatus', 'pending | committed')\n } else if (status === 'failed') {\n if (\n session.sessionRole !== 'historical' ||\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready' ||\n session.order !== null\n ) {\n fail(resource, '$', 'historical suppressed failed state')\n }\n validateNoReconciliation(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n const failure = record(session.failure, resource, '$.failure')\n exact(failure, ['reason'], ['message'], resource, '$.failure')\n enumValue(\n failure.reason,\n PAYMENT_FAILURE_REASONS,\n resource,\n '$.failure.reason',\n )\n if (failure.message !== undefined)\n string(failure.message, resource, '$.failure.message')\n } else {\n if (\n session.sessionRole !== 'historical' ||\n session.presentationStatus !== 'suppressed' ||\n session.finalizationStatus !== 'not_ready' ||\n session.order !== null\n ) {\n fail(resource, '$', 'historical suppressed canceled state')\n }\n validateNoReconciliation(\n session.reconciliation,\n resource,\n '$.reconciliation',\n )\n enumValue(\n session.cancellationReason,\n ['expired', 'customer', 'operator', 'provider'],\n resource,\n '$.cancellationReason',\n )\n }\n if (expectedProvider !== undefined && provider !== expectedProvider) {\n if (\n operation === 'cancel' &&\n CANCEL_RECOVERY_METHODS[provider] !== null &&\n status !== 'canceling' &&\n status !== 'canceled'\n ) {\n fail(\n resource,\n '$.providerStatus',\n 'canceling or canceled after a successful cancellation',\n )\n }\n providerMismatch(resource, expectedProvider, provider, operation)\n }\n return value as T\n}\n","import { ApiError, SDKError } from '../internal/errors'\nimport {\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS,\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\nimport { parseApiResponse } from '../api/parse-response'\nimport { httpFetch } from '../internal/utils'\nimport type { PayloadFindResponse } from '../client/types'\nimport type { PublicOrder } from '../api/order-api'\nimport { validatePublicOrderList } from '../api/canonical-response'\nimport { resolveApiUrl } from '../internal/utils/api-url'\nimport type {\n CustomerAuthResponse,\n CustomerWithdrawalResult,\n CustomerRefreshResponse,\n CustomerRegisterData,\n CustomerRegisterResponse,\n CustomerLoginData,\n CustomerProfile,\n CustomerAuthOptions,\n UpdateProfileData,\n} from './types'\n\nconst DEFAULT_TIMEOUT = 15000\n\n/**\n * Upper bound for waiting on the cross-context refresh lock.\n *\n * A lease holder occupies the lease for at most one refresh request, which\n * `DEFAULT_TIMEOUT` already bounds, so the budget is derived from that hold\n * time rather than from a flat margin: it covers a serialized queue of three\n * contexts whose predecessors each burn their entire request timeout. A deeper\n * queue still degrades to an uncoordinated rotation by design — the server\n * adjudicates it through single-use rotation and refresh-family reuse\n * detection — but an ordinary slow API no longer pushes a waiter there.\n */\nconst REFRESH_LOCK_TIMEOUT = DEFAULT_TIMEOUT * 3\n\n/**\n * Canonical persisted session.\n *\n * The access and refresh tokens live in ONE JSON value written with one store\n * operation, so a partial failure can never publish a new access token beside\n * an already-consumed refresh token. `rev` increases on every commit, which\n * lets an in-flight rotation detect a logout, a fresh login, or a manual setter\n * that landed while it was waiting for the server.\n */\ntype SessionRecord = {\n v: number\n rev: number\n token: string | null\n refreshToken: string | null\n}\n\nconst SESSION_RECORD_VERSION = 1\n\n/**\n * The credentials a refresh call set out to present. The refresh token — or the\n * access token on the compatibility bearer path — is the credential the server\n * adjudicates, so it is what every fence compares.\n */\ntype SpentCredentials = {\n token: string | null\n refreshToken: string | null\n}\n\n/**\n * How canonical storage relates to the credential a call captured.\n *\n * - `current`: the spent credential is still canonical, so this call owns the\n * rotation and its successor must land.\n * - `superseded`: another context replaced the spent credential.\n * - `cleared`: the session was ended.\n */\ntype CanonicalState = 'cleared' | 'superseded' | 'current'\n\n/**\n * Canonical storage cannot be used: the read was denied, or the record is one\n * this version must not interpret. Either way the instance keeps its in-memory\n * session and stops participating in coordination.\n */\nconst STORAGE_UNUSABLE = Symbol('storage-unusable')\n\n/**\n * A canonical read plus its provenance. `stored: false` means the record key\n * was absent and the pair was synthesized from the earlier layout (or from\n * nothing), which a commit must not mistake for an existing persisted state.\n */\ntype CanonicalRead = {\n record: SessionRecord\n stored: boolean\n}\n\n/** A single-field or whole-pair change to publish. */\ntype SessionChange = {\n token?: string | null\n refreshToken?: string | null\n}\n\ntype RefreshLockRequester = (\n name: string,\n options: { signal: AbortSignal },\n callback: () => Promise<CustomerRefreshResponse>,\n) => Promise<CustomerRefreshResponse>\n\n/**\n * Two spellings of the same API endpoint must resolve to the same coordination\n * namespace, otherwise `https://api.example.com` and\n * `https://API.EXAMPLE.COM:443/` would rotate the same stored session under two\n * leases. Scheme and host are compared case-insensitively, a default port is\n * dropped, and a trailing slash is not significant.\n */\nfunction canonicalApiIdentity(apiUrl: string): string {\n try {\n const url = new URL(apiUrl)\n return `${url.protocol.toLowerCase()}//${url.host.toLowerCase()}${url.pathname.replace(/\\/+$/, '')}`\n } catch {\n return apiUrl.trim().toLowerCase().replace(/\\/+$/, '')\n }\n}\n\n/**\n * Coordination name for one persisted session. It is derived only from the\n * storage key and the canonical API/tenant identity the instance already sends\n * on every request; token material never appears in a lease name.\n */\nfunction buildRefreshLockName(\n apiUrl: string,\n publishableKey: string,\n storageKey: string,\n): string {\n return `01software:customer-auth-refresh:${canonicalApiIdentity(apiUrl)}:${publishableKey}:${storageKey}`\n}\n\n/**\n * Web Locks is the cross-context serialization primitive. Browsers without it,\n * environments whose `navigator.locks` accessor itself throws, and every\n * non-browser runtime get `null` and fall back to the instance-local single\n * flight. A platform exception never escapes to the caller.\n */\nfunction getRefreshLockRequester(): RefreshLockRequester | null {\n try {\n if (typeof navigator === 'undefined') return null\n const locks = (navigator as Navigator & { locks?: LockManager }).locks\n if (!locks || typeof locks.request !== 'function') return null\n return (name, options, callback) =>\n locks.request(name, options, () =>\n callback(),\n ) as Promise<CustomerRefreshResponse>\n } catch {\n return null\n }\n}\n\nfunction parseSessionRecord(raw: string): SessionRecord | null {\n try {\n const parsed: unknown = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object') return null\n const candidate = parsed as Partial<SessionRecord>\n // A record written by a newer SDK is not ours to interpret.\n if (candidate.v !== SESSION_RECORD_VERSION) return null\n if (typeof candidate.rev !== 'number' || !Number.isFinite(candidate.rev)) {\n return null\n }\n const token = candidate.token\n const refreshToken = candidate.refreshToken\n if (token !== null && typeof token !== 'string') return null\n if (refreshToken !== null && typeof refreshToken !== 'string') return null\n return {\n v: SESSION_RECORD_VERSION,\n rev: candidate.rev,\n token,\n refreshToken,\n }\n } catch {\n return null\n }\n}\n\nexport type CustomerOrderListOptions = {\n page?: number\n limit?: number\n financialStatus?: PublicOrder['financialStatus']\n fulfillmentStatus?: PublicOrder['fulfillmentStatus']\n returnStatus?: PublicOrder['returnStatus']\n confirmationStatus?: PublicOrder['confirmationStatus']\n primaryDisplayStatus?: PublicOrder['primaryDisplayStatus']\n}\n\n/**\n * Read the canonical session.\n *\n * The record is the only canonical source. When it is present but this version\n * cannot interpret it — corrupt, or written by a newer layout — the pre-record\n * mirror is NOT consulted: reinterpreting it would resurrect state the record's\n * writer already replaced. The mirror is a migration source only while the\n * record key is absent.\n */\nfunction readSessionRecord(\n recordKey: string,\n mirrorKey: string,\n mirrorRefreshKey: string,\n): CanonicalRead | typeof STORAGE_UNUSABLE {\n let raw: string | null\n try {\n raw = localStorage.getItem(recordKey)\n } catch {\n return STORAGE_UNUSABLE\n }\n if (raw !== null) {\n const parsed = parseSessionRecord(raw)\n return parsed ? { record: parsed, stored: true } : STORAGE_UNUSABLE\n }\n try {\n return {\n record: {\n v: SESSION_RECORD_VERSION,\n rev: 0,\n token: localStorage.getItem(mirrorKey),\n refreshToken: localStorage.getItem(mirrorRefreshKey),\n },\n stored: false,\n }\n } catch {\n return STORAGE_UNUSABLE\n }\n}\n\n/**\n * Customer authentication client.\n *\n * Manages customer registration, login, logout, and token lifecycle.\n * All requests include X-Publishable-Key for tenant resolution.\n */\nexport class CustomerAuth {\n private publishableKey: string\n private baseUrl: string\n private token: string | null\n private refreshTokenValue: string | null\n private onTokenChange?: (token: string | null) => void\n private onRefreshTokenChange?: (refreshToken: string | null) => void\n private refreshPromise: Promise<CustomerRefreshResponse> | null = null\n /** Canonical record key; null unless persistence is active in a browser. */\n private persistRecordKey: string | null = null\n /** Advisory single-value access mirror, plus the retired refresh mirror. */\n private persistMirrorKey: string | null = null\n private persistMirrorRefreshKey: string | null = null\n /** Cross-context refresh lock name; null when there is no shared storage. */\n private refreshLockName: string | null = null\n /** Revision of the canonical record this instance last observed. */\n private sessionRev = 0\n\n constructor(\n publishableKey: string,\n options?: CustomerAuthOptions,\n apiUrl?: string,\n ) {\n this.publishableKey = publishableKey\n this.baseUrl = resolveApiUrl(apiUrl)\n\n const persist = options?.persist ?? true\n if (persist) {\n const key = typeof persist === 'string' ? persist : 'customer-token'\n const isBrowser = typeof window !== 'undefined'\n this.token = null\n this.refreshTokenValue = null\n if (isBrowser) {\n this.persistRecordKey = `${key}:session`\n this.persistMirrorKey = key\n this.persistMirrorRefreshKey = `${key}:refresh`\n this.refreshLockName = buildRefreshLockName(\n this.baseUrl,\n publishableKey,\n key,\n )\n this.syncFromPersistedStorage()\n }\n } else {\n this.token = options?.token ?? null\n this.refreshTokenValue = options?.refreshToken ?? null\n this.onTokenChange = options?.onTokenChange\n this.onRefreshTokenChange = options?.onRefreshTokenChange\n }\n }\n\n /**\n * Register a new customer account\n */\n async register(\n data: CustomerRegisterData,\n ): Promise<CustomerRegisterResponse> {\n return this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.register),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.register,\n ),\n body: JSON.stringify(data),\n },\n )\n }\n\n /**\n * Login with email and password. Stores the token internally.\n */\n async login(data: CustomerLoginData): Promise<CustomerAuthResponse> {\n const result: CustomerAuthResponse = await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.login),\n {\n method: resolveOperationMethod(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.login),\n body: JSON.stringify(data),\n },\n )\n\n if (result.refreshToken) this.setSession(result.token, result.refreshToken)\n else this.setToken(result.token)\n return result\n }\n\n /**\n * Refresh the current token. Uses a refresh token when available, otherwise\n * falls back to the legacy bearer-token compatibility path.\n *\n * Refresh tokens are single-use, so a persisted session shared by several\n * tabs or SDK instances must rotate at most once: concurrent rotations of the\n * same token are replay from the server's point of view and revoke the whole\n * family. Persisted browser sessions therefore serialize rotation across\n * contexts and re-read the canonical persisted credentials inside the lock.\n */\n async refreshToken(): Promise<CustomerRefreshResponse> {\n this.syncFromPersistedStorage()\n if (!this.refreshTokenValue && !this.token) {\n throw new ApiError('Not authenticated', 401)\n }\n\n if (this.refreshPromise) return this.refreshPromise\n\n const intended = this.currentFence()\n this.refreshPromise = this.rotateAcrossContexts(intended)\n try {\n return await this.refreshPromise\n } finally {\n this.refreshPromise = null\n }\n }\n\n /**\n * Re-read the canonical persisted session. In persisted mode the shared\n * record — not this instance's memory — is the source of truth, so another\n * context's rotation, login, or logout is observed before the next credential\n * use. Change callbacks are deliberately not invoked: this is a read.\n */\n private syncFromPersistedStorage(): void {\n const canonical = this.readCanonicalSession()\n if (canonical === STORAGE_UNUSABLE) {\n this.disablePersistence()\n return\n }\n if (!canonical) return\n this.sessionRev = canonical.record.rev\n this.token = canonical.record.token\n this.refreshTokenValue = canonical.record.refreshToken\n }\n\n /** `null` when this instance does not persist. */\n private readCanonicalSession():\n | CanonicalRead\n | null\n | typeof STORAGE_UNUSABLE {\n if (\n !this.persistRecordKey ||\n !this.persistMirrorKey ||\n !this.persistMirrorRefreshKey\n ) {\n return null\n }\n return readSessionRecord(\n this.persistRecordKey,\n this.persistMirrorKey,\n this.persistMirrorRefreshKey,\n )\n }\n\n /**\n * Publish a change to canonical storage.\n *\n * The canonical pair is re-read immediately before the single record write so\n * that a field this call does not change is taken from that read rather than\n * from this instance's possibly stale copy. That merge is BEST-EFFORT: it\n * removes the stale counterpart an instance would otherwise carry, but it is\n * not a compare-and-swap. Web Storage offers none, and the synchronous public\n * mutators cannot await the refresh lease, so a commit that lands between\n * this read and the store operation is lost by ordering — including the\n * counterpart just read, which is then republished stale. The window is one\n * store operation wide and the server remains authoritative; see\n * `CUST-AUTH-033` for the stated limit.\n *\n * Returns `false` only when `requireLiveSession` refused a write because the\n * canonical session had already been cleared.\n */\n private commitPersistedSession(\n change: SessionChange,\n options?: { requireLiveSession?: boolean },\n ): boolean {\n const recordKey = this.persistRecordKey\n const mirrorKey = this.persistMirrorKey\n const mirrorRefreshKey = this.persistMirrorRefreshKey\n const canonical = this.readCanonicalSession()\n if (canonical === null || !recordKey || !mirrorKey || !mirrorRefreshKey) {\n return true\n }\n if (canonical === STORAGE_UNUSABLE) {\n this.disablePersistence()\n return true\n }\n // Decided on the same read that produces the revision below, so nothing\n // observable happens between the check and the write.\n const current = canonical.record\n if (\n options?.requireLiveSession &&\n !current.token &&\n !current.refreshToken\n ) {\n return false\n }\n\n const next: SessionRecord = {\n v: SESSION_RECORD_VERSION,\n rev: current.rev + 1,\n token: 'token' in change ? (change.token ?? null) : current.token,\n refreshToken:\n 'refreshToken' in change\n ? (change.refreshToken ?? null)\n : current.refreshToken,\n }\n if (\n // Only a state that is genuinely persisted can already say what this\n // write would say. An absent record reads as an empty pair, and treating\n // that as a no-op would drop the very tombstone that stops a later\n // migration from resurrecting the session out of the earlier layout.\n canonical.stored &&\n next.token === current.token &&\n next.refreshToken === current.refreshToken\n ) {\n this.sessionRev = current.rev\n this.token = current.token\n this.refreshTokenValue = current.refreshToken\n return true\n }\n try {\n localStorage.setItem(recordKey, JSON.stringify(next))\n } catch {\n // Safari private mode, quota, iframe sandbox: nothing was published.\n this.disablePersistence()\n return true\n }\n this.sessionRev = next.rev\n this.token = next.token\n this.refreshTokenValue = next.refreshToken\n\n // Single-value compatibility publication. Only the access token is\n // mirrored, because two mirror keys cannot be written together.\n try {\n // Retire the pre-record refresh entry FIRST. Publishing a fresh access\n // token beside a refresh token this rotation consumed is the exact pair\n // a downlevel reader would replay, and doing it in this order means that\n // pair is never published — not transiently, and not permanently if the\n // removal below throws.\n localStorage.removeItem(mirrorRefreshKey)\n } catch {\n // The stale refresh entry survives, so do not put a newer access token\n // next to it. The record stays authoritative for this SDK version.\n return true\n }\n try {\n if (next.token) localStorage.setItem(mirrorKey, next.token)\n else localStorage.removeItem(mirrorKey)\n } catch {\n // The mirror is advisory; the record above already holds canonical state.\n }\n return true\n }\n\n /**\n * Storage rejected a write or a read, so it is not a canonical store for this\n * instance. Fall back to the memory-only session and take no lease: there is\n * no shared state left to coordinate. Nothing is purged — the record commit\n * is atomic, so no inconsistent state was published, and another context's\n * valid session must not be destroyed by this instance's local failure.\n */\n private disablePersistence(): void {\n this.persistRecordKey = null\n this.persistMirrorKey = null\n this.persistMirrorRefreshKey = null\n this.refreshLockName = null\n }\n\n /**\n * Compare the canonical record with the fence this call captured before it\n * left. Every persisted decision — rotate, converge, or fail closed — goes\n * through this one comparison. The revision catches a logout, a fresh login,\n * or a manual setter even when token values coincide; the value comparison\n * additionally catches a mirror-only writer that cannot bump a revision.\n */\n private classifyCanonicalState(intended: SpentCredentials): CanonicalState {\n if (!this.persistRecordKey) return 'current'\n this.syncFromPersistedStorage()\n // A denied read during the re-check drops persistence; nothing to fence.\n if (!this.persistRecordKey) return 'current'\n\n if (!this.token && !this.refreshTokenValue) return 'cleared'\n if (intended.refreshToken !== null) {\n // Only the refresh credential decides ownership. An access token can be\n // replaced or invalidated by another context while this family stays\n // ours, and its absence is not evidence that the rotation was lost.\n return this.refreshTokenValue === intended.refreshToken\n ? 'current'\n : 'superseded'\n }\n // Compatibility bearer path: a refresh credential appearing anywhere is\n // strictly better than rotating a bearer token, so it supersedes this call.\n return this.token === intended.token && !this.refreshTokenValue\n ? 'current'\n : 'superseded'\n }\n\n /** The canonical persisted pair, as a refresh result. */\n private canonicalPair(token: string): CustomerRefreshResponse {\n return {\n token,\n ...(this.refreshTokenValue\n ? { refreshToken: this.refreshTokenValue }\n : {}),\n }\n }\n\n /** Current credentials plus the revision they were observed at. */\n private currentFence(): SpentCredentials {\n return { token: this.token, refreshToken: this.refreshTokenValue }\n }\n\n /**\n * Clear an access credential a 401 just proved unusable — but only while it\n * is still the canonical one. A rotation committed by another context while\n * the request was in flight is newer than this 401, so it must survive; the\n * instance adopts it instead. The refresh entry is never touched here: a\n * rejected access token says nothing about the refresh family.\n */\n private invalidateAccessToken(spentToken: string): void {\n this.syncFromPersistedStorage()\n if (this.token !== spentToken) return\n this.setToken(null)\n }\n\n /** Commit both credentials in one canonical write. */\n private setSession(\n token: string | null,\n refreshToken: string | null,\n options?: { requireLiveSession?: boolean },\n ): boolean {\n this.token = token\n this.refreshTokenValue = refreshToken\n const committed = this.commitPersistedSession(\n { token, refreshToken },\n options,\n )\n if (!committed) return false\n this.onTokenChange?.(this.token)\n this.onRefreshTokenChange?.(this.refreshTokenValue)\n return true\n }\n\n /**\n * Serialize rotation against every other context sharing the same storage\n * key and API/tenant identity. Coordination is best-effort: when it is\n * unavailable or times out the rotation still happens, so server-side reuse\n * detection is never bypassed by a client that failed to coordinate.\n */\n private async rotateAcrossContexts(\n intended: SpentCredentials,\n ): Promise<CustomerRefreshResponse> {\n const lockName = this.refreshLockName\n const requestLock = lockName ? getRefreshLockRequester() : null\n if (!lockName || !requestLock) {\n return this.rotateWithCanonicalState(intended)\n }\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), REFRESH_LOCK_TIMEOUT)\n let entered = false\n try {\n return await requestLock(\n lockName,\n { signal: controller.signal },\n async () => {\n entered = true\n return this.rotateWithCanonicalState(intended)\n },\n )\n } catch (error) {\n // A failure raised inside the lock is the caller's refresh failure.\n if (entered) throw error\n // The lock was never held: bounded wait aborted, or the API rejected the\n // request. Degrade to an uncoordinated rotation.\n return this.rotateWithCanonicalState(intended)\n } finally {\n // Always drop the abort timer; the lease itself is released when the\n // Web Locks callback settles.\n clearTimeout(timer)\n }\n }\n\n /**\n * Decide, against freshly re-read canonical state, whether this context still\n * owns the rotation.\n */\n private async rotateWithCanonicalState(\n intended: SpentCredentials,\n ): Promise<CustomerRefreshResponse> {\n let fence = intended\n // One re-fence is enough: it turns \"canonical moved and left no usable\n // access token\" into a rotation of the canonical refresh credential.\n for (let attempt = 0; attempt < 2; attempt += 1) {\n const state = this.classifyCanonicalState(fence)\n // Another context logged out while this call waited.\n if (state === 'cleared') throw new ApiError('Not authenticated', 401)\n if (state === 'current') return this._doRefreshToken(fence)\n // Another context already rotated the credential this call captured.\n // Converge on its successor instead of replaying a consumed token.\n if (this.token) return this.canonicalPair(this.token)\n // No usable access token, but a live canonical refresh credential:\n // rotate that one rather than the stale credential captured earlier.\n fence = this.currentFence()\n }\n throw new ApiError('Not authenticated', 401)\n }\n\n private async _doRefreshToken(\n intended: SpentCredentials,\n ): Promise<CustomerRefreshResponse> {\n const init: RequestInit = intended.refreshToken\n ? {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.refresh,\n ),\n body: JSON.stringify({ refreshToken: intended.refreshToken }),\n }\n : {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.refresh,\n ),\n headers: { Authorization: `Bearer ${intended.token as string}` },\n }\n const result: CustomerRefreshResponse = await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.refresh),\n init,\n )\n\n // The rotation was in flight for a whole round trip. Re-check the canonical\n // state before writing: a successor must never resurrect a session another\n // context ended, nor overwrite one it established in the meantime.\n const state = this.classifyCanonicalState(intended)\n // Logout wins: never resurrect a session another context ended.\n if (state === 'cleared') throw new ApiError('Not authenticated', 401)\n if (state === 'superseded') {\n // Another context owns the family now. Converge on what it published, or\n // fail closed rather than hand back an unusable pair.\n if (this.token) return this.canonicalPair(this.token)\n throw new ApiError('Not authenticated', 401)\n }\n\n // Still ours. The presented credential is consumed server-side, so the\n // successor is the only live one and MUST land — stranding it would leave\n // every context replaying a consumed token. Only an access token another\n // context deliberately replaced is preserved; an absent one is not a\n // replacement, so the freshly issued token fills it.\n const replacedAccessToken =\n this.token !== null && this.token !== intended.token ? this.token : null\n const nextToken = replacedAccessToken ?? result.token\n const nextRefresh = result.refreshToken ?? null\n // Decided on the write's own canonical read, so a logout committed before\n // it is not resurrected.\n if (\n !this.setSession(nextToken, nextRefresh, { requireLiveSession: true })\n ) {\n throw new ApiError('Not authenticated', 401)\n }\n return {\n token: nextToken,\n ...(nextRefresh ? { refreshToken: nextRefresh } : {}),\n }\n }\n\n /**\n * Clear local credentials synchronously. This compatibility API cannot\n * revoke the server-side refresh family; use logoutAsync() for that.\n * @deprecated Use logoutAsync() to end the direct server session.\n */\n logout(): void {\n // One canonical write, so no context can observe a half-cleared session.\n this.setSession(null, null)\n }\n\n /**\n * End the current direct refresh family and clear local credentials even if\n * revocation fails. A legacy access-only session has no refresh family here.\n */\n async logoutAsync(): Promise<void> {\n this.syncFromPersistedStorage()\n const refreshToken = this.refreshTokenValue\n this.logout()\n if (!refreshToken) return\n\n const operation = CUSTOMER_AUTH_ENDPOINT_OPERATIONS.revokeRefresh\n await this.requestJson(resolveOperationPath(operation), {\n method: resolveOperationMethod(operation),\n body: JSON.stringify({ refreshToken }),\n })\n }\n\n /** Archive the current password account and clear this client's credentials on success. */\n async withdraw(currentPassword: string): Promise<CustomerWithdrawalResult> {\n const token = this.getToken()\n if (!token) throw new ApiError('Not authenticated', 401)\n const operation = CUSTOMER_AUTH_ENDPOINT_OPERATIONS.withdraw\n const result = await this.requestJson<CustomerWithdrawalResult>(\n resolveOperationPath(operation),\n {\n method: resolveOperationMethod(operation),\n headers: { Authorization: `Bearer ${token}` },\n body: JSON.stringify({ currentPassword }),\n },\n )\n if (\n !result ||\n typeof result.withdrawnAt !== 'string' ||\n !Number.isFinite(Date.parse(result.withdrawnAt))\n )\n throw new ApiError('Invalid customer withdrawal response', 502)\n this.logout()\n return { withdrawnAt: result.withdrawnAt }\n }\n\n /**\n * Get the current authenticated customer's profile\n */\n async me(): Promise<CustomerProfile | null> {\n const token = this.getToken()\n if (!token) return null\n\n try {\n const data = await this.requestJson<{ customer: CustomerProfile }>(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.me),\n {\n method: resolveOperationMethod(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.me),\n headers: { Authorization: `Bearer ${token}` },\n },\n )\n return data.customer ?? null\n } catch (error) {\n if (error instanceof SDKError && error.status === 401) {\n this.invalidateAccessToken(token)\n return null\n }\n throw error\n }\n }\n\n /**\n * Request a password reset email\n */\n async forgotPassword(email: string): Promise<void> {\n await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.forgotPassword),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.forgotPassword,\n ),\n body: JSON.stringify({ email }),\n },\n )\n }\n\n /**\n * Reset password using a token from the reset email\n */\n async resetPassword(token: string, password: string): Promise<void> {\n await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.resetPassword),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.resetPassword,\n ),\n body: JSON.stringify({ token, password }),\n },\n )\n }\n\n /**\n * Update the authenticated customer's profile (name, phone, marketingConsent)\n */\n async updateProfile(data: UpdateProfileData): Promise<CustomerProfile> {\n const token = this.getToken()\n if (!token) throw new ApiError('Not authenticated', 401)\n\n const result = await this.requestJson<{ customer: CustomerProfile }>(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.updateProfile),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.updateProfile,\n ),\n headers: { Authorization: `Bearer ${token}` },\n body: JSON.stringify(data),\n },\n )\n return result.customer\n }\n\n /**\n * Change the password of the currently authenticated customer\n */\n async changePassword(\n currentPassword: string,\n newPassword: string,\n ): Promise<void> {\n const token = this.getToken()\n if (!token) throw new ApiError('Not authenticated', 401)\n\n await this.requestJson(\n resolveOperationPath(CUSTOMER_AUTH_ENDPOINT_OPERATIONS.changePassword),\n {\n method: resolveOperationMethod(\n CUSTOMER_AUTH_ENDPOINT_OPERATIONS.changePassword,\n ),\n headers: { Authorization: `Bearer ${token}` },\n body: JSON.stringify({ currentPassword, newPassword }),\n },\n )\n }\n\n /**\n * Get the authenticated customer's orders with pagination and optional status filter\n */\n async getMyOrders(\n options?: CustomerOrderListOptions,\n ): Promise<PayloadFindResponse<PublicOrder>> {\n const token = this.getToken()\n if (!token) throw new ApiError('Not authenticated', 401)\n\n const params = new URLSearchParams()\n if (options?.page) params.set('page', String(options.page))\n if (options?.limit) params.set('limit', String(options.limit))\n if (options?.financialStatus) {\n params.set('financialStatus', options.financialStatus)\n }\n if (options?.fulfillmentStatus) {\n params.set('fulfillmentStatus', options.fulfillmentStatus)\n }\n if (options?.returnStatus) params.set('returnStatus', options.returnStatus)\n if (options?.confirmationStatus) {\n params.set('confirmationStatus', options.confirmationStatus)\n }\n if (options?.primaryDisplayStatus) {\n params.set('primaryDisplayStatus', options.primaryDisplayStatus)\n }\n const qs = params.toString()\n const result = await this.requestJson<unknown>(\n `/api/customers/me/orders${qs ? `?${qs}` : ''}`,\n {\n method: 'GET',\n headers: { Authorization: `Bearer ${token}` },\n },\n )\n return validatePublicOrderList<PayloadFindResponse<PublicOrder>>(result)\n }\n\n /**\n * Get the current token (or null if not authenticated).\n *\n * In persisted mode this re-reads shared storage first, so a rotation or\n * logout performed by another tab is observed before the token is used.\n */\n getToken(): string | null {\n this.syncFromPersistedStorage()\n return this.token\n }\n\n /**\n * Get the current refresh token (or null if unavailable). Persisted mode\n * re-reads shared storage first, like {@link CustomerAuth.getToken}.\n */\n getRefreshToken(): string | null {\n this.syncFromPersistedStorage()\n return this.refreshTokenValue\n }\n\n /**\n * Set the token manually (e.g. from SSR)\n */\n setToken(token: string | null): void {\n this.token = token\n // Access only: the latest canonical refresh token is preserved.\n this.commitPersistedSession({ token })\n this.onTokenChange?.(token)\n }\n\n /**\n * Set the refresh token manually (e.g. from SSR cookie)\n */\n setRefreshToken(refreshToken: string | null): void {\n this.refreshTokenValue = refreshToken\n // Refresh only: the latest canonical access token is preserved.\n this.commitPersistedSession({ refreshToken })\n this.onRefreshTokenChange?.(refreshToken)\n }\n\n /**\n * Check if the customer is currently authenticated\n */\n isAuthenticated(): boolean {\n return this.getToken() !== null\n }\n\n /**\n * Internal: make a request with timeout and error handling.\n * Auth endpoints don't retry — failures are final.\n */\n private async requestJson<T = unknown>(\n path: string,\n init: RequestInit,\n ): Promise<T> {\n const headers = new Headers(init.headers)\n headers.set('X-Publishable-Key', this.publishableKey)\n if (!headers.has('Content-Type') && init.body) {\n headers.set('Content-Type', 'application/json')\n }\n\n const response = await httpFetch(path, {\n ...init,\n apiUrl: this.baseUrl,\n publishableKey: this.publishableKey,\n headers,\n timeout: DEFAULT_TIMEOUT,\n retry: { maxRetries: 0 },\n })\n\n return parseApiResponse<T>(response, path)\n }\n}\n","import { parseApiResponse } from '../api/parse-response'\nimport { httpFetch } from '../internal/utils'\nimport { resolveApiUrl } from '../internal/utils/api-url'\n\nconst DEFAULT_SCOPES = ['openid', 'profile', 'email'] as const\nconst DEFAULT_TIMEOUT = 15000\n\nexport interface CustomerOAuthConfig {\n clientId: string\n issuer: string\n timeout?: number\n}\n\nexport interface CustomerAuthorizationUrlInput {\n redirectUri: string\n returnTo?: string\n scopes?: readonly string[]\n}\n\nexport interface CustomerAuthorizationUrlResult {\n authorizationUrl: string\n codeChallenge: string\n codeVerifier: string\n nonce: string\n returnTo: string | null\n state: string\n}\n\nexport interface CustomerOAuthCallbackResult {\n code: string\n state: string\n}\n\nexport interface CustomerOAuthTokenSet {\n accessToken: string\n expiresAt: number\n expiresIn: number\n idToken?: string\n refreshToken: string\n scope?: string\n tokenType: 'Bearer'\n}\n\ninterface TokenEndpointResponse {\n access_token: string\n expires_in: number\n id_token?: string\n refresh_token: string\n scope?: string\n token_type: string\n}\n\nfunction issuerUrl(issuer: string, path: string): string {\n const base = resolveApiUrl(issuer)\n return new URL(path, base.endsWith('/') ? base : `${base}/`).toString()\n}\n\nfunction randomBase64Url(bytes: number): string {\n const buffer = new Uint8Array(bytes)\n crypto.getRandomValues(buffer)\n\n let binary = ''\n for (const value of buffer) {\n binary += String.fromCharCode(value)\n }\n\n return btoa(binary)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/g, '')\n}\n\nasync function sha256Base64Url(value: string): Promise<string> {\n const data = new TextEncoder().encode(value)\n const digest = await crypto.subtle.digest('SHA-256', data)\n\n let binary = ''\n for (const byte of new Uint8Array(digest)) {\n binary += String.fromCharCode(byte)\n }\n\n return btoa(binary)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/g, '')\n}\n\nfunction normalizeToken(body: TokenEndpointResponse): CustomerOAuthTokenSet {\n if (body.token_type !== 'Bearer') {\n throw new Error('Unsupported customer OAuth token type')\n }\n\n return {\n accessToken: body.access_token,\n expiresAt: Date.now() + body.expires_in * 1000,\n expiresIn: body.expires_in,\n ...(body.id_token ? { idToken: body.id_token } : {}),\n refreshToken: body.refresh_token,\n ...(body.scope ? { scope: body.scope } : {}),\n tokenType: 'Bearer',\n }\n}\n\nexport class CustomerOAuth {\n private readonly clientId: string\n private readonly issuer: string\n private readonly timeout: number\n\n constructor(config: CustomerOAuthConfig) {\n if (!config.clientId) throw new Error('customer OAuth clientId is required')\n if (!config.issuer) throw new Error('customer OAuth issuer is required')\n\n this.clientId = config.clientId\n this.issuer = config.issuer\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT\n }\n\n async createAuthorizationUrl(\n input: CustomerAuthorizationUrlInput,\n ): Promise<CustomerAuthorizationUrlResult> {\n const codeVerifier = randomBase64Url(48)\n const codeChallenge = await sha256Base64Url(codeVerifier)\n const state = randomBase64Url(32)\n const nonce = randomBase64Url(32)\n const scopes = input.scopes ?? DEFAULT_SCOPES\n const url = new URL(issuerUrl(this.issuer, 'customer-oauth/authorize'))\n\n url.searchParams.set('response_type', 'code')\n url.searchParams.set('client_id', this.clientId)\n url.searchParams.set('redirect_uri', input.redirectUri)\n url.searchParams.set('scope', scopes.join(' '))\n url.searchParams.set('state', state)\n url.searchParams.set('nonce', nonce)\n url.searchParams.set('code_challenge', codeChallenge)\n url.searchParams.set('code_challenge_method', 'S256')\n\n return {\n authorizationUrl: url.toString(),\n codeChallenge,\n codeVerifier,\n nonce,\n returnTo: input.returnTo ?? null,\n state,\n }\n }\n\n parseCallback(\n callbackUrl: string,\n options: { expectedState: string },\n ): CustomerOAuthCallbackResult {\n const url = new URL(callbackUrl)\n const error = url.searchParams.get('error')\n\n if (error) {\n throw new Error(\n url.searchParams.get('error_description') ?? `OAuth error: ${error}`,\n )\n }\n\n const code = url.searchParams.get('code')\n const state = url.searchParams.get('state')\n\n if (!code || !state) throw new Error('OAuth callback is missing code/state')\n if (state !== options.expectedState) throw new Error('OAuth state mismatch')\n\n return { code, state }\n }\n\n async exchangeCode(input: {\n code: string\n codeVerifier: string\n redirectUri: string\n }): Promise<CustomerOAuthTokenSet> {\n const body = new URLSearchParams({\n client_id: this.clientId,\n code: input.code,\n code_verifier: input.codeVerifier,\n grant_type: 'authorization_code',\n redirect_uri: input.redirectUri,\n })\n\n return this.tokenRequest(body)\n }\n\n async refresh(input: {\n refreshToken: string\n }): Promise<CustomerOAuthTokenSet> {\n const body = new URLSearchParams({\n client_id: this.clientId,\n grant_type: 'refresh_token',\n refresh_token: input.refreshToken,\n })\n\n return this.tokenRequest(body)\n }\n\n async logout(input: {\n postLogoutRedirectUri?: string\n refreshToken?: string\n }): Promise<{ redirectUrl?: string; success: boolean }> {\n const body: Record<string, string> = { client_id: this.clientId }\n\n if (input.refreshToken) body.refresh_token = input.refreshToken\n if (input.postLogoutRedirectUri) {\n body.post_logout_redirect_uri = input.postLogoutRedirectUri\n }\n\n const response = await httpFetch('/customer-oauth/logout', {\n apiUrl: this.issuer,\n method: 'POST',\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n timeout: this.timeout,\n retry: { maxRetries: 0 },\n })\n\n return parseApiResponse<{ redirectUrl?: string; success: boolean }>(\n response,\n '/customer-oauth/logout',\n )\n }\n\n verifyIdToken(): never {\n throw new Error(\n 'Customer OAuth ID token verification is not implemented; treat idToken as opaque.',\n )\n }\n\n private async tokenRequest(\n body: URLSearchParams,\n ): Promise<CustomerOAuthTokenSet> {\n const response = await httpFetch('/api/customer-oauth/token', {\n apiUrl: this.issuer,\n method: 'POST',\n body,\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n timeout: this.timeout,\n retry: { maxRetries: 0 },\n })\n\n return normalizeToken(\n await parseApiResponse<TokenEndpointResponse>(\n response,\n '/api/customer-oauth/token',\n ),\n )\n }\n}\n","import { CustomerAuth } from './customer-auth'\nimport { CustomerOAuth } from './customer-oauth'\nimport type { CustomerAuthOptions } from './types'\n\n/**\n * Customer namespace. Currently exposes .auth; reserved for future customer-\n * scoped capabilities (addresses, preferences, etc.).\n */\nexport class CustomerNamespace {\n readonly auth: CustomerAuth\n readonly oauth?: CustomerOAuth\n\n constructor(\n publishableKey: string,\n options?: CustomerAuthOptions,\n apiUrl?: string,\n ) {\n this.auth = new CustomerAuth(publishableKey, options, apiUrl)\n if (options?.oauth) {\n this.oauth = new CustomerOAuth(options.oauth)\n }\n }\n}\n","import { createValidationError } from '../internal/errors'\n\nconst UUID_V4_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\nconst PREFIXED_BASE64URL_PATTERN = /^ik_[A-Za-z0-9_-]{22}$/\n\nexport function isCommerceIdempotencyKey(value: unknown): value is string {\n return (\n typeof value === 'string' &&\n value.length <= 255 &&\n (UUID_V4_PATTERN.test(value) || PREFIXED_BASE64URL_PATTERN.test(value))\n )\n}\n\nexport function assertCommerceIdempotencyKey(\n value: unknown,\n): asserts value is string {\n if (isCommerceIdempotencyKey(value)) return\n throw createValidationError(\n 'idempotencyKey must be a UUIDv4 or ik_-prefixed 128-bit base64url value.',\n { field: 'idempotencyKey' },\n )\n}\n\n/** Create a cryptographically strong key for one logical commerce operation. */\nexport function createCommerceIdempotencyKey(): string {\n return globalThis.crypto.randomUUID()\n}\n","import { CustomerScopedApi } from './customer-scoped-api'\nimport {\n COMMERCE_ENDPOINTS,\n type CommerceEndpointDescriptor,\n} from './endpoints'\nimport type { PublicMediaAsset } from './public-media'\nimport {\n validateCartMergeResult,\n validateCartMineResult,\n validateCartMutationResult,\n validateCreateCartResult,\n validatePublicCart,\n} from './canonical-response'\nimport { assertCommerceIdempotencyKey } from './commerce-idempotency'\n\nexport interface CartApiOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport const MAX_CART_LINE_ADMISSIONS = 32\n\nexport type PublicAttribute = { key: string; value: string }\n\nexport type CreateCartParams = {\n market?: string\n attributes?: PublicAttribute[]\n}\n\nexport type PublicCartItemAdmission = {\n eventId: string\n occurrenceId: string\n admissionTypeId: string\n}\n\nexport type AddItemParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n productId: string\n variantId: string\n quantity: number\n admissions?: readonly [PublicCartItemAdmission, ...PublicCartItemAdmission[]]\n}\n\nexport type UpdateItemParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n cartItemId: string\n quantity: number\n}\n\nexport type ServerAddItemParams = AddItemParams & { customerToken?: string }\nexport type ServerUpdateItemParams = UpdateItemParams & {\n customerToken?: string\n}\n\nexport type RemoveItemParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n cartItemId: string\n}\n\nexport type UpdateDiscountCodesParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n discountCodes: string[]\n}\n\nexport type UpdateCartAttributesParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n attributes: PublicAttribute[]\n}\n\nexport type ClearCartParams = {\n cartToken: string\n expectedRevision: number\n idempotencyKey: string\n}\nexport type RetrieveCartParams = { cartToken: string }\nexport type CartMineParams = Record<string, never>\nexport type ServerCartMineParams = { customerToken: string }\nexport type CartMergeParams = { guestCartToken: string; idempotencyKey: string }\nexport type ServerCartMergeParams = CartMergeParams & { customerToken: string }\n\nexport type CartDiscountCode = {\n code: string\n applicable: boolean\n}\n\nexport type CartWarningCode =\n | 'DISCOUNT_CODE_NOT_HONOURED'\n | 'DISCOUNT_CURRENTLY_INACTIVE'\n | 'DISCOUNT_CUSTOMER_NOT_ELIGIBLE'\n | 'DISCOUNT_CUSTOMER_USAGE_LIMIT_REACHED'\n | 'DISCOUNT_ELIGIBLE_CUSTOMER_MISSING'\n | 'DISCOUNT_NO_ENTITLED_LINE_ITEMS'\n | 'DISCOUNT_NO_ENTITLED_SHIPPING_LINES'\n | 'DISCOUNT_NOT_FOUND'\n | 'DISCOUNT_PURCHASE_NOT_IN_RANGE'\n | 'DISCOUNT_USAGE_LIMIT_REACHED'\n | 'MERCHANDISE_NOT_ENOUGH_STOCK'\n | 'MERCHANDISE_OUT_OF_STOCK'\n\nexport type CartWarning = {\n code: CartWarningCode\n message: string\n target: string\n}\n\nexport type PublicCartReference = {\n id: string\n title: string\n handle: string | null\n image: PublicMediaAsset | null\n}\n\nexport type PublicCartMarket = {\n id: string\n handle: string\n name: string\n}\n\nexport type PublicCartItem = {\n id: string\n product: PublicCartReference\n variant: PublicCartReference\n admissions: PublicCartItemAdmission[]\n quantity: number\n unitPriceMinor: number\n discountMinor: number\n estimatedLineTotalMinor: number\n requiresShipping: boolean\n}\n\ntype PublicCartBase = {\n id: string\n status: 'active' | 'completed' | 'abandoned'\n revision: number\n currency: Uppercase<string>\n market: PublicCartMarket\n subtotalMinor: number\n discountMinor: number\n estimatedTotalMinor: number\n discountCodes: CartDiscountCode[]\n attributes: PublicAttribute[]\n items: PublicCartItem[]\n expiresAt: string\n createdAt: string\n updatedAt: string\n}\n\ntype PublicCartPickupResponse = PublicCartBase & {\n deliveryMethod: 'shipping' | 'pickup'\n shippingMinor: number\n totalMinor: number\n}\n\n/**\n * Released response or the complete ADR 0125 cutover response; no fields are\n * synthesized. Narrow with `'deliveryMethod' in value` to read the new fields.\n */\nexport type PublicCart =\n | PublicCartBase\n | {\n [K in keyof PublicCartPickupResponse]: PublicCartPickupResponse[K]\n }\n\nexport type CartMutationResult = {\n cart: PublicCart\n warnings: CartWarning[]\n}\n\nexport type CreateCartResult = {\n cart: PublicCart\n warnings: CartWarning[]\n cartToken: string\n}\n\nexport type CartMergeResultBase = CreateCartResult\n\nexport type CartMergeResult = CartMergeResultBase &\n (\n | { resolution: 'unchanged'; merged: false; claimed: false }\n | { resolution: 'claimed'; merged: false; claimed: true }\n | { resolution: 'merged'; merged: true; claimed: false }\n )\n\nexport type CartMineResult =\n | { cart: PublicCart; cartToken: string }\n | { cart: null; cartToken: null }\n\nexport class CartApi extends CustomerScopedApi {\n private readonly serverTransport: boolean\n\n constructor(options: CartApiOptions) {\n super('CartApi', { ...options, requiresCredential: false })\n this.serverTransport = Boolean(options.secretKey)\n }\n\n private endpoint<Key extends keyof typeof COMMERCE_ENDPOINTS.carts.server>(\n key: Key,\n ): CommerceEndpointDescriptor {\n return this.serverTransport\n ? COMMERCE_ENDPOINTS.carts.server[key]\n : COMMERCE_ENDPOINTS.carts[key]\n }\n\n private execute(\n endpoint: CommerceEndpointDescriptor,\n body: unknown,\n idempotencyKey?: string,\n ): Promise<unknown> {\n return this.requestEndpoint<unknown>(endpoint, body, {\n ...(idempotencyKey && {\n headers: { 'X-Idempotency-Key': idempotencyKey },\n }),\n })\n }\n\n create(params: CreateCartParams = {}): Promise<CreateCartResult> {\n return this.execute(this.endpoint('create'), params).then((value) =>\n validateCreateCartResult<CreateCartResult>(value),\n )\n }\n\n retrieve(params: RetrieveCartParams): Promise<PublicCart> {\n return this.execute(this.endpoint('retrieve'), params).then((value) =>\n validatePublicCart<PublicCart>(value),\n )\n }\n\n mine(\n params: CartMineParams | ServerCartMineParams = {},\n ): Promise<CartMineResult> {\n const endpoint = this.endpoint('mine')\n return this.execute(endpoint, params).then((value) =>\n validateCartMineResult<CartMineResult>(value),\n )\n }\n\n merge(\n params: CartMergeParams | ServerCartMergeParams,\n ): Promise<CartMergeResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n const endpoint = this.endpoint('merge')\n return this.execute(endpoint, body, idempotencyKey).then((value) =>\n validateCartMergeResult<CartMergeResult>(value),\n )\n }\n\n addItem(\n params: AddItemParams | ServerAddItemParams,\n ): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('addItem'), params)\n }\n\n private mutate(\n endpoint: CommerceEndpointDescriptor,\n params: { idempotencyKey: string },\n ): Promise<CartMutationResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n return this.execute(endpoint, body, idempotencyKey).then((value) =>\n validateCartMutationResult<CartMutationResult>(value),\n )\n }\n\n updateItem(\n params: UpdateItemParams | ServerUpdateItemParams,\n ): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('updateItem'), params)\n }\n\n removeItem(params: RemoveItemParams): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('removeItem'), params)\n }\n\n clear(params: ClearCartParams): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('clear'), params)\n }\n\n updateDiscountCodes(\n params: UpdateDiscountCodesParams,\n ): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('updateDiscountCodes'), params)\n }\n\n updateAttributes(\n params: UpdateCartAttributesParams,\n ): Promise<CartMutationResult> {\n return this.mutate(this.endpoint('updateAttributes'), params)\n }\n}\n","import { createApiError, createValidationError } from '../internal/errors'\nimport {\n CustomerScopedApi,\n type CustomerScopedApiOptions,\n} from './customer-scoped-api'\nimport {\n COMMERCE_ENDPOINTS,\n CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE,\n type CommerceEndpointDescriptor,\n} from './endpoints'\nimport type {\n PublicAttribute,\n PublicCartItemAdmission,\n PublicCartReference,\n} from './cart-api'\nimport { assertCommerceIdempotencyKey } from './commerce-idempotency'\nimport {\n validateCheckoutQueryResult,\n validateCreateCheckoutResult,\n validatePublicCheckout,\n validateServerCheckout,\n} from './canonical-response'\n\nexport type CheckoutApiOptions = CustomerScopedApiOptions\nexport type CheckoutStatus = 'open' | 'placed' | 'abandoned'\n\nexport type CustomerSnapshot = {\n email: string\n name?: string\n phone?: string\n}\n\nexport type CheckoutShippingAddress = {\n recipientName: string\n phone: string\n countryCode?: string\n regionCode?: string\n postalCode: string\n address: string\n detailAddress: string\n deliveryMessage?: string\n}\n\nexport type PublicCheckoutItem = {\n id: string\n product: PublicCartReference\n variant: PublicCartReference\n productTitle: string\n variantTitle: string | null\n sku: string | null\n admissions: PublicCartItemAdmission[]\n quantity: number\n unitPriceMinor: number\n discountMinor: number\n lineTotalMinor: number\n requiresShipping: boolean\n}\n\nexport type CheckoutAmounts = {\n currency: Uppercase<string>\n subtotalMinor: number\n shippingMinor: number\n discountMinor: number\n totalMinor: number\n}\n\nexport type CheckoutPaymentSessionRef = {\n id: string\n /**\n * Closed managed-provider vocabulary. `'stripe'` is accepted ahead of the\n * server and is not emitted until Stripe becomes available.\n */\n provider: 'toss' | 'portone' | 'stripe'\n providerStatus:\n | 'requires_payment_method'\n | 'requires_action'\n | 'requires_confirmation'\n | 'initializing'\n | 'processing'\n | 'authorized'\n | 'canceling'\n | 'unknown'\n | 'captured'\n | 'failed'\n | 'canceled'\n}\n\nexport type OpenCheckoutPaymentState = {\n activePaymentSession: CheckoutPaymentSessionRef | null\n}\n\nexport type SpentCheckoutPaymentState = {\n activePaymentSession: null\n}\n\nexport type CheckoutFunding = {\n creditAmount: number\n providerPayableAmount: number\n}\n\nexport type PublicCheckoutBase = {\n /** Frozen purchase split. Absence means legacy/unknown server support,\n * never creditAmount=0. Refunds do not rewrite these original amounts. */\n funding?: CheckoutFunding\n id: string\n amounts: CheckoutAmounts\n items: PublicCheckoutItem[]\n customerSnapshot: CustomerSnapshot\n shippingAddress: CheckoutShippingAddress | null\n attributes: PublicAttribute[]\n expiresAt: string\n createdAt: string\n updatedAt: string\n}\n\nexport type CheckoutOrderReference = { id: string; orderNumber: string }\nexport type CheckoutAbandonedReason = 'expired' | 'customer' | 'operator'\n\n/**\n * Released response or the complete ADR 0125 cutover response; no fields are\n * synthesized. Narrow with `'deliveryMethod' in value` to read the new fields.\n */\nexport type PublicCheckout = (\n | PublicCheckoutBase\n | (PublicCheckoutBase & {\n deliveryMethod: 'shipping' | 'pickup'\n source: 'web' | 'in_person'\n })\n) &\n (\n | {\n status: 'open'\n paymentState: OpenCheckoutPaymentState\n order: null\n placedAt?: never\n placedVia?: never\n abandonedAt?: never\n abandonedReason?: never\n }\n | {\n status: 'placed'\n placedAt: string\n paymentState: SpentCheckoutPaymentState\n order: CheckoutOrderReference\n placedVia?: never\n abandonedAt?: never\n abandonedReason?: never\n }\n | {\n status: 'placed'\n placedAt: string\n placedVia: 'late_capture'\n abandonedAt: string\n abandonedReason: CheckoutAbandonedReason\n paymentState: SpentCheckoutPaymentState\n order: CheckoutOrderReference\n }\n | {\n status: 'abandoned'\n abandonedAt: string\n abandonedReason: CheckoutAbandonedReason\n paymentState: {\n activePaymentSession: null\n }\n order: null\n placedAt?: never\n placedVia?: never\n }\n )\n\nexport type ServerCheckout = PublicCheckout & {\n clientReferenceId: string | null\n integrationMetadata: Record<string, string>\n}\n\nexport type RetrieveCheckoutParams = { checkoutToken: string }\nexport type RetrieveServerCheckoutParams = { checkoutId: string }\n\nexport type CreateCheckoutParams = {\n /** Exact positive integer KRW request. Never clamped or silently retried without credit. */\n creditAmount?: number\n cartToken: string\n customer: CustomerSnapshot\n shippingAddress?: CheckoutShippingAddress\n idempotencyKey: string\n}\n\nexport type CreateServerCheckoutParams = CreateCheckoutParams & {\n customerToken?: string\n clientReferenceId?: string\n integrationMetadata?: Record<string, string>\n}\n\nexport type CreateCheckoutResult = {\n checkout: PublicCheckout\n checkoutToken: string\n}\n\nexport type CreateServerCheckoutResult = {\n checkout: ServerCheckout\n checkoutToken: string\n}\n\nexport type CheckoutQueryParams = {\n limit?: number\n cursor?: string\n status?: CheckoutStatus[]\n createdAtFrom?: string\n createdAtTo?: string\n clientReferenceId?: string\n}\n\nexport type CheckoutListItem = PublicCheckout extends infer Checkout\n ? Checkout extends unknown\n ? Omit<Checkout, 'items' | 'shippingAddress' | 'attributes'> & {\n clientReferenceId: string | null\n }\n : never\n : never\n\nexport type CheckoutQueryResult = {\n data: CheckoutListItem[]\n hasMore: boolean\n nextCursor: string | null\n}\n\nexport class CheckoutApi extends CustomerScopedApi {\n constructor(options: CheckoutApiOptions) {\n super('CheckoutApi', { ...options, requiresCredential: false })\n }\n\n private post(\n endpoint: CommerceEndpointDescriptor,\n body: unknown,\n idempotencyKey?: string,\n ): Promise<unknown> {\n return this.requestEndpoint<unknown>(endpoint, body, {\n headers: {\n Accept: CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE,\n ...(idempotencyKey && { 'X-Idempotency-Key': idempotencyKey }),\n },\n })\n }\n\n private async publicCheckout(\n result: Promise<unknown>,\n ): Promise<PublicCheckout> {\n return validatePublicCheckout<PublicCheckout>(await result)\n }\n\n private async serverCheckout(\n result: Promise<unknown>,\n ): Promise<ServerCheckout> {\n return validateServerCheckout<ServerCheckout>(await result)\n }\n\n private async createResult(\n result: Promise<unknown>,\n creditAmount?: number,\n ): Promise<CreateCheckoutResult> {\n const parsed = validateCreateCheckoutResult<CreateCheckoutResult>(\n await result,\n false,\n )\n this.assertRequestedCredit(parsed.checkout, creditAmount)\n return parsed\n }\n\n private async createServerResult(\n result: Promise<unknown>,\n creditAmount?: number,\n ): Promise<CreateServerCheckoutResult> {\n const parsed = validateCreateCheckoutResult<CreateServerCheckoutResult>(\n await result,\n true,\n )\n this.assertRequestedCredit(parsed.checkout, creditAmount)\n return parsed\n }\n\n private assertCreditInput(amount: number | undefined): void {\n if (amount !== undefined && (!Number.isSafeInteger(amount) || amount <= 0))\n throw createValidationError(\n 'creditAmount must be a positive safe integer.',\n )\n }\n\n private assertRequestedCredit(\n checkout: PublicCheckout,\n requested: number | undefined,\n ): void {\n if (requested !== undefined && checkout.funding?.creditAmount !== requested)\n throw createApiError(\n 'Credit funding was not confirmed by the server.',\n 502,\n { resource: 'Checkout', path: '$.funding' },\n 'The response does not confirm the requested credit funding.',\n 'Retry the same create with the original idempotency key and credit amount, or retrieve the Checkout; never retry without credit.',\n )\n }\n\n create(params: CreateCheckoutParams): Promise<CreateCheckoutResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n this.assertCreditInput(body.creditAmount)\n return this.createResult(\n this.post(COMMERCE_ENDPOINTS.checkouts.create, body, idempotencyKey),\n body.creditAmount,\n )\n }\n\n createServer(\n params: CreateServerCheckoutParams,\n ): Promise<CreateServerCheckoutResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n this.assertCreditInput(body.creditAmount)\n return this.createServerResult(\n this.post(\n COMMERCE_ENDPOINTS.checkouts.server.create,\n body,\n idempotencyKey,\n ),\n body.creditAmount,\n )\n }\n\n retrieve(params: RetrieveCheckoutParams): Promise<PublicCheckout> {\n return this.publicCheckout(\n this.post(COMMERCE_ENDPOINTS.checkouts.retrieve, params),\n )\n }\n\n retrieveServer(\n params: RetrieveServerCheckoutParams,\n ): Promise<ServerCheckout> {\n return this.serverCheckout(\n this.post(COMMERCE_ENDPOINTS.checkouts.server.retrieve, params),\n )\n }\n\n async query(params: CheckoutQueryParams = {}): Promise<CheckoutQueryResult> {\n const result = await this.post(\n COMMERCE_ENDPOINTS.checkouts.server.query,\n params,\n )\n return validateCheckoutQueryResult<CheckoutQueryResult>(result)\n }\n}\n","import {\n CustomerScopedApi,\n type CustomerScopedApiOptions,\n} from './customer-scoped-api'\nimport { BaseApi, type ServerApiOptions } from './base-api'\nimport {\n COMMERCE_ENDPOINTS,\n PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE,\n type CommerceEndpointDescriptor,\n} from './endpoints'\nimport { assertCommerceIdempotencyKey } from './commerce-idempotency'\nimport {\n validateConfirmCustomPaymentSessionResponse,\n validateCustomPaymentSession,\n validatePortOnePaymentFacadeResult,\n validatePublicPaymentSession,\n validateRetrievedCustomPaymentSession,\n} from './canonical-response'\n\nexport type PaymentSessionApiOptions = CustomerScopedApiOptions\n\nexport type Money = { amountMinor: number; currency: Uppercase<string> }\n\nexport type PortOneHostedPaymentMethod =\n | 'CARD_KR'\n | 'N_PAY'\n | 'KAKAO_PAY'\n | 'TOSS_PAY'\n | 'CARD_INTERNATIONAL'\n | 'PAY_PAL'\n | 'UNION_PAY'\n | 'ALIPAY_CN'\n | 'ALIPAY_HK'\n | 'TRUE_MONEY'\n | 'DANA'\n | 'TOUCH_N_GO'\n | 'G_CASH'\n | 'WE_CHAT_PAY'\n | 'KLARNA'\n | 'E_CONTEXT'\n | 'GRAB_PAY_MY'\n | 'GRAB_PAY_SG'\n | 'SHOPEE_PAY_TH'\n | 'PAY_PAY'\n | 'BPI'\n | 'RABBIT_LINE_PAY'\n | 'CONVENIENCE_STORE_JP'\n | 'AMAZON_PAY'\n | 'RAKUTEN_PAY'\n | 'D_BARAI'\n | 'AU_PAY'\n | 'MERPAY'\n\n/** Standard Browser SDK methods intentionally do not reuse Hosted methods. */\nexport type PortOneStandardPaymentMethod = 'CARD'\n\nexport type CreatePaymentSessionParams = {\n checkoutToken: string\n idempotencyKey: string\n provider: 'toss'\n providerOptions: { profile: 'widget_v2' }\n}\n\nexport type CreateServerPaymentSessionParams = CreatePaymentSessionParams & {\n customerToken?: string\n}\n\nexport type CreatePortOnePaymentSessionParams = {\n checkoutToken: string\n idempotencyKey: string\n provider: 'portone'\n providerOptions:\n | {\n profile: 'hosted_v2'\n paymentMethod: PortOneHostedPaymentMethod\n }\n | {\n profile: 'standard_v2'\n paymentMethod: PortOneStandardPaymentMethod\n }\n}\n\nexport type CreateServerPortOnePaymentSessionParams =\n CreatePortOnePaymentSessionParams & { customerToken?: string }\n\nexport type RetrieveBrowserPaymentSessionParams = {\n paymentSessionId: string\n checkoutToken: string\n}\n\nexport type RetrieveServerPaymentSessionParams = { paymentSessionId: string }\n\nexport type PortOnePaymentSelector = {\n provider: 'portone'\n providerAccountKey: string\n environment: 'test' | 'live'\n providerPaymentId: string\n}\n\nexport type FindPortOnePaymentParams = PortOnePaymentSelector\n\nexport type ReconcilePortOnePaymentParams = PortOnePaymentSelector & {\n idempotencyKey: string\n}\n\nexport type CancelBrowserPaymentSessionParams =\n RetrieveBrowserPaymentSessionParams & { idempotencyKey: string }\n\nexport type CancelServerPaymentSessionParams =\n RetrieveServerPaymentSessionParams & { idempotencyKey: string }\n\nexport type ConfirmTossPaymentSessionParams = {\n paymentSessionId: string\n idempotencyKey: string\n action: {\n type: 'toss_authorization'\n paymentKey: string\n providerOrderId: string\n }\n}\n\nexport type CreateCustomPaymentSessionParams = {\n provider: string\n checkoutToken: string\n idempotencyKey: string\n customerToken?: string\n}\n\nexport type CustomPaymentSession = {\n id: string\n provider: string\n providerSessionId: string\n money: Money\n}\n\nexport type RetrieveCustomPaymentSessionParams = {\n provider: string\n by: { providerSessionId: string } | { providerPaymentId: string }\n}\n\nexport type RetrievedCustomPaymentSession = {\n id: string\n provider: string\n providerSessionId: string\n providerPaymentId: string | null\n status: 'pending' | 'captured' | 'failed' | 'canceled'\n providerStatus: PaymentProviderStatus\n finalizationStatus: 'not_ready' | 'pending' | 'committed'\n money: Money\n orderId: string | null\n}\n\nexport type PortOnePaymentCurrentState = {\n paymentSession: {\n id: string\n provider: 'portone'\n providerStatus: PaymentProviderStatus\n finalizationStatus: 'not_ready' | 'pending' | 'committed'\n sessionRole: PaymentSessionRole\n reconciliation:\n | { status: 'none' }\n | {\n status: 'required'\n reasons: readonly PaymentReconciliationReason[]\n }\n }\n checkout: { id: string }\n order: { id: string; orderNumber: string } | null\n money: Money\n}\n\nexport type FindPortOnePaymentResult =\n | { found: false }\n | { found: true; current: PortOnePaymentCurrentState }\n\nexport type PortOneReconciliationDisposition =\n | 'applied'\n | 'observed'\n | 'recovered_after_ambiguous_result'\n | 'requires_attention'\n\nexport type ReconcilePortOnePaymentResult =\n | { found: false; disposition: 'requires_attention' }\n | {\n found: true\n disposition: PortOneReconciliationDisposition\n current: PortOnePaymentCurrentState\n }\n\nexport type ConfirmCustomPaymentSessionParams = {\n provider: string\n providerSessionId: string\n providerPaymentId: string\n providerEventId: string\n /** Captured amount in the currency's minor unit. */\n amount: number\n currency: string\n occurredAt: string\n}\n\nexport type ConfirmCustomPaymentSessionResponse = {\n orderId: string\n transactionId: string\n status: 'paid'\n /**\n * `true` when the session was already confirmed at observation time.\n *\n * This field is absent from the initial successful confirmation. It does not\n * prove that this call caused the transition and is not an exactly-once gate;\n * a lost initial response followed by a retry also returns `true`.\n */\n alreadyConfirmed?: boolean\n}\n\nexport type CustomPaymentSessionProof = {\n timestamp: string\n signature: string\n}\n\nexport type ConfirmCustomPaymentSessionOptions = {\n /** Receives the exact JSON bytes the SDK will send. Required only where the Console custom-provider policy requires HMAC. */\n createProof?: (\n rawBody: string,\n ) => CustomPaymentSessionProof | Promise<CustomPaymentSessionProof>\n}\n\nexport type TossPaymentNextAction = {\n type: 'toss_widget'\n clientKey: string\n paymentMethodVariantKey: string\n agreementVariantKey: string\n providerOrderId: string\n providerCustomerKey: 'ANONYMOUS' | string\n orderName: string\n customerName?: string\n customerEmail?: string\n}\n\nexport type PortOnePaymentNextAction = {\n type: 'portone_checkout'\n checkoutUrl: string\n}\n\nexport type PortOneSdkPaymentNextAction = {\n type: 'portone_sdk'\n version: 'v2'\n /** Standard V2 actions cannot release their Checkout payment slot. */\n cancelable: false\n /** Retry only this exact action and payment ID; never start a sibling session. */\n retryPolicy: 'same_action_only'\n storeId: string\n channelKey: string\n paymentId: string\n orderName: string\n totalAmount: number\n /** PortOne Browser SDK V2 currency constant, not an ISO 4217 code. */\n currency: 'CURRENCY_KRW'\n payMethod: PortOneStandardPaymentMethod\n redirectUrl: string\n}\n\n/**\n * Accept-only Stripe Payment Element action. Not exported from a package entry\n * until a Stripe PaymentSession method exists; the parser validates it so a\n * provider mismatch can report the actual provider.\n */\nexport type StripePaymentNextAction = {\n type: 'stripe_payment_element'\n /** PaymentIntent client secret for Stripe.js; never capture evidence. */\n clientSecret: string\n publishableKey: string\n returnUrl: string\n}\n\n/** Existing Toss action surface retained for source compatibility. */\nexport type PaymentNextAction = TossPaymentNextAction\n\nexport type ManagedPaymentNextAction =\n | TossPaymentNextAction\n | PortOnePaymentNextAction\n | PortOneSdkPaymentNextAction\n\nexport type PaymentSessionRole =\n | 'active'\n | 'canonical_candidate'\n | 'canonical'\n | 'residual'\n | 'historical'\n\nexport type PaymentProviderStatus =\n | 'requires_payment_method'\n | 'requires_action'\n | 'requires_confirmation'\n | 'initializing'\n | 'processing'\n | 'authorized'\n | 'canceling'\n | 'unknown'\n | 'captured'\n | 'failed'\n | 'canceled'\n\nexport type PaymentReconciliationReason =\n | 'provider_outcome_unknown'\n | 'local_commit_ambiguous'\n | 'amount_mismatch'\n | 'currency_mismatch'\n | 'excess_capture_pending_order'\n | 'inventory_unavailable'\n | 'admission_unavailable'\n | 'excess_capture'\n | 'late_capture'\n | 'cross_checkout_duplicate'\n\nexport type PaymentFailureReason =\n | 'payment_declined'\n | 'authentication_failed'\n | 'authorization_expired'\n | 'payment_method_unavailable'\n | 'provider_terminal_failure'\n | 'unknown_provider_terminal_failure'\n\nexport type PublicCaptureEvidence = {\n amountMinor: number\n currency: Uppercase<string>\n observedAt: string\n}\n\nexport type ReconciliationRequired<Reason extends string> = {\n status: 'required'\n reasons: readonly [Reason, ...Reason[]]\n}\n\ntype PublicPaymentSessionBase = {\n id: string\n money: Money\n expiresAt: string | null\n sessionRole: PaymentSessionRole\n}\n\ntype PublicPaymentSessionState<\n Action extends ManagedPaymentNextAction | StripePaymentNextAction,\n> =\n | ({\n providerStatus: 'requires_payment_method' | 'requires_action'\n finalizationStatus: 'not_ready'\n reconciliation: { status: 'none' }\n order: null\n } & (\n | {\n sessionRole: 'active'\n presentationStatus: 'actionable'\n nextAction: Action\n }\n | {\n sessionRole: 'residual'\n presentationStatus: 'suppressed'\n nextAction?: never\n }\n ))\n | {\n providerStatus: 'requires_confirmation'\n sessionRole: 'active' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n reconciliation: { status: 'none' }\n order: null\n }\n | {\n providerStatus: 'initializing' | 'processing' | 'authorized'\n sessionRole: 'active' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n reconciliation: { status: 'none' }\n order: null\n }\n | {\n providerStatus: 'canceling'\n sessionRole: 'active' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n reconciliation: { status: 'none' }\n order: null\n }\n | {\n providerStatus: 'unknown'\n sessionRole: 'active' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n reconciliation: ReconciliationRequired<'provider_outcome_unknown'>\n order: null\n }\n | {\n providerStatus: 'captured'\n sessionRole: 'canonical_candidate' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'pending'\n nextAction?: never\n reconciliation: { status: 'none' }\n providerEvidence: PublicCaptureEvidence\n order: null\n }\n | {\n providerStatus: 'captured'\n sessionRole: 'canonical' | 'historical'\n presentationStatus: 'suppressed'\n finalizationStatus: 'committed'\n nextAction?: never\n reconciliation: { status: 'none' }\n providerEvidence: PublicCaptureEvidence\n order: { id: string; orderNumber: string }\n }\n | {\n providerStatus: 'captured'\n sessionRole: 'canonical_candidate' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'pending'\n nextAction?: never\n reconciliation: ReconciliationRequired<\n | 'local_commit_ambiguous'\n | 'amount_mismatch'\n | 'currency_mismatch'\n | 'excess_capture_pending_order'\n >\n providerEvidence: PublicCaptureEvidence\n order: null\n }\n | {\n providerStatus: 'captured'\n sessionRole: 'canonical' | 'residual'\n presentationStatus: 'suppressed'\n finalizationStatus: 'committed'\n nextAction?: never\n reconciliation: ReconciliationRequired<\n | 'inventory_unavailable'\n | 'admission_unavailable'\n | 'amount_mismatch'\n | 'currency_mismatch'\n | 'excess_capture'\n | 'late_capture'\n | 'cross_checkout_duplicate'\n >\n providerEvidence: PublicCaptureEvidence\n order: { id: string; orderNumber: string }\n }\n | {\n providerStatus: 'failed'\n sessionRole: 'historical'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n providerEvidence?: never\n cancellationReason?: never\n reconciliation: { status: 'none' }\n failure: { reason: PaymentFailureReason; message?: string }\n order: null\n }\n | {\n providerStatus: 'canceled'\n sessionRole: 'historical'\n presentationStatus: 'suppressed'\n finalizationStatus: 'not_ready'\n nextAction?: never\n providerEvidence?: never\n failure?: never\n cancellationReason: 'expired' | 'customer' | 'operator' | 'provider'\n reconciliation: { status: 'none' }\n order: null\n }\n\nexport type PublicPaymentSession = PublicPaymentSessionBase & {\n provider: 'toss'\n} & PublicPaymentSessionState<TossPaymentNextAction>\n\nexport type PortOnePublicPaymentSession = PublicPaymentSessionBase & {\n provider: 'portone'\n} & PublicPaymentSessionState<\n PortOnePaymentNextAction | PortOneSdkPaymentNextAction\n >\n\n/** Accept-only Stripe session shape; see `StripePaymentNextAction`. */\nexport type StripePublicPaymentSession = PublicPaymentSessionBase & {\n provider: 'stripe'\n} & PublicPaymentSessionState<StripePaymentNextAction>\n\nexport type ManagedPublicPaymentSession =\n | PublicPaymentSession\n | PortOnePublicPaymentSession\n\nexport class PaymentSessionApi extends CustomerScopedApi {\n private readonly serverTransport: boolean\n\n constructor(options: PaymentSessionApiOptions) {\n super('PaymentSessionApi', { ...options, requiresCredential: false })\n this.serverTransport = Boolean(options.secretKey)\n }\n\n private post(\n endpoint: CommerceEndpointDescriptor,\n body: unknown,\n idempotencyKey?: string,\n negotiateStandardActionCapabilities = false,\n ): Promise<unknown> {\n const headers = {\n ...(idempotencyKey && { 'X-Idempotency-Key': idempotencyKey }),\n ...(negotiateStandardActionCapabilities && {\n Accept: PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE,\n }),\n }\n return this.requestEndpoint<unknown>(endpoint, body, {\n ...(Object.keys(headers).length > 0 && { headers }),\n })\n }\n\n private async paymentSession<T extends ManagedPublicPaymentSession>(\n result: Promise<unknown>,\n expectedProvider: T['provider'],\n operation?: 'cancel',\n ): Promise<T> {\n return validatePublicPaymentSession<T>(\n await result,\n expectedProvider,\n operation,\n )\n }\n\n create(\n params: CreatePaymentSessionParams | CreateServerPaymentSessionParams,\n ): Promise<PublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n return this.paymentSession<PublicPaymentSession>(\n this.post(\n this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.create\n : COMMERCE_ENDPOINTS.paymentSessions.create,\n body,\n idempotencyKey,\n ),\n 'toss',\n )\n }\n\n createPortOne(\n params:\n | CreatePortOnePaymentSessionParams\n | CreateServerPortOnePaymentSessionParams,\n ): Promise<PortOnePublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n return this.paymentSession<PortOnePublicPaymentSession>(\n this.post(\n this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.create\n : COMMERCE_ENDPOINTS.paymentSessions.create,\n body,\n idempotencyKey,\n body.providerOptions.profile === 'standard_v2',\n ),\n 'portone',\n )\n }\n\n retrieve(\n params:\n | RetrieveBrowserPaymentSessionParams\n | RetrieveServerPaymentSessionParams,\n ): Promise<PublicPaymentSession> {\n const endpoint = this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.retrieve\n : COMMERCE_ENDPOINTS.paymentSessions.retrieve\n return this.paymentSession<PublicPaymentSession>(\n this.post(endpoint, params),\n 'toss',\n )\n }\n\n retrievePortOne(\n params:\n | RetrieveBrowserPaymentSessionParams\n | RetrieveServerPaymentSessionParams,\n ): Promise<PortOnePublicPaymentSession> {\n const endpoint = this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.retrieve\n : COMMERCE_ENDPOINTS.paymentSessions.retrieve\n return this.paymentSession<PortOnePublicPaymentSession>(\n this.post(endpoint, params, undefined, true),\n 'portone',\n )\n }\n\n cancel(\n params:\n | CancelBrowserPaymentSessionParams\n | CancelServerPaymentSessionParams,\n ): Promise<PublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n const endpoint = this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.cancel\n : COMMERCE_ENDPOINTS.paymentSessions.cancel\n return this.paymentSession<PublicPaymentSession>(\n this.post(endpoint, body, idempotencyKey),\n 'toss',\n 'cancel',\n )\n }\n\n cancelPortOne(\n params:\n | CancelBrowserPaymentSessionParams\n | CancelServerPaymentSessionParams,\n ): Promise<PortOnePublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n const endpoint = this.serverTransport\n ? COMMERCE_ENDPOINTS.paymentSessions.server.cancel\n : COMMERCE_ENDPOINTS.paymentSessions.cancel\n return this.paymentSession<PortOnePublicPaymentSession>(\n this.post(endpoint, body, idempotencyKey),\n 'portone',\n 'cancel',\n )\n }\n\n confirm(\n params: ConfirmTossPaymentSessionParams,\n ): Promise<PublicPaymentSession> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n return this.paymentSession<PublicPaymentSession>(\n this.post(\n COMMERCE_ENDPOINTS.paymentSessions.server.confirm,\n body,\n idempotencyKey,\n ),\n 'toss',\n )\n }\n}\n\n/** Server-only facade over the managed PortOne local/convergence engine. */\nexport class PortOnePaymentReconciliationApi extends BaseApi {\n constructor(options: ServerApiOptions) {\n super('PortOnePaymentReconciliationApi', options)\n }\n\n async find(\n params: FindPortOnePaymentParams,\n ): Promise<FindPortOnePaymentResult> {\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.server.findPortOne,\n params,\n )\n return validatePortOnePaymentFacadeResult<FindPortOnePaymentResult>(\n result,\n false,\n )\n }\n\n async reconcile(\n params: ReconcilePortOnePaymentParams,\n ): Promise<ReconcilePortOnePaymentResult> {\n const { idempotencyKey, ...body } = params\n assertCommerceIdempotencyKey(idempotencyKey)\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.server.reconcilePortOne,\n body,\n { headers: { 'X-Idempotency-Key': idempotencyKey } },\n )\n return validatePortOnePaymentFacadeResult<ReconcilePortOnePaymentResult>(\n result,\n true,\n )\n }\n}\n\nexport class CustomPaymentSessionApi extends BaseApi {\n constructor(options: ServerApiOptions) {\n super('CustomPaymentSessionApi', options)\n }\n\n async create(\n params: CreateCustomPaymentSessionParams,\n ): Promise<CustomPaymentSession> {\n assertCommerceIdempotencyKey(params.idempotencyKey)\n const body = {\n provider: params.provider,\n checkoutToken: params.checkoutToken,\n }\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.custom.create,\n body,\n { headers: { 'X-Idempotency-Key': params.idempotencyKey } },\n )\n return validateCustomPaymentSession<CustomPaymentSession>(result)\n }\n\n async retrieve(\n params: RetrieveCustomPaymentSessionParams,\n ): Promise<RetrievedCustomPaymentSession> {\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.custom.retrieve,\n params,\n )\n return validateRetrievedCustomPaymentSession<RetrievedCustomPaymentSession>(\n result,\n )\n }\n\n async confirm(\n params: ConfirmCustomPaymentSessionParams,\n options: ConfirmCustomPaymentSessionOptions = {},\n ): Promise<ConfirmCustomPaymentSessionResponse> {\n const body = {\n provider: params.provider,\n providerSessionId: params.providerSessionId,\n providerPaymentId: params.providerPaymentId,\n providerEventId: params.providerEventId,\n amount: params.amount,\n currency: params.currency,\n occurredAt: params.occurredAt,\n }\n const proof = await options.createProof?.(JSON.stringify(body))\n const result = await this.requestEndpoint<unknown>(\n COMMERCE_ENDPOINTS.paymentSessions.custom.confirm,\n body,\n proof\n ? {\n headers: {\n 'X-Custom-Payment-Timestamp': proof.timestamp,\n 'X-Custom-Payment-Signature': proof.signature,\n },\n }\n : undefined,\n )\n return validateConfirmCustomPaymentSessionResponse<ConfirmCustomPaymentSessionResponse>(\n result,\n )\n }\n}\n","export type NormalizedOptionSwatch<TMedia = unknown> = {\n type: 'color' | 'media' | null\n color?: string | null\n mediaItemId?: string | number | null\n /** Inlined swatch media when the API populated mediaItemId before pool indexing. */\n inlineMedia?: TMedia | null\n}\n\nexport function selectedSwatchMediaItemId(\n swatch: NormalizedOptionSwatch | null | undefined,\n): string | null {\n if (!swatch || swatch.type !== 'media') return null\n const id = swatch.mediaItemId\n if (id == null || id === '') return null\n return String(id)\n}\n\nexport type ProductSelectionMediaSource =\n | 'variant_media_selected'\n | 'variant_media_matching'\n | 'option_swatch'\n | 'none'\n\nexport type ProductDisplayMediaSource =\n | 'featured_image'\n | 'product_pool'\n | 'none'\n\n/** @deprecated Use {@link ProductSelectionMediaSource} or {@link ProductDisplayMediaSource}. */\nexport type ProductMediaResolutionSource =\n | ProductSelectionMediaSource\n | ProductDisplayMediaSource\n\nexport type ProductSelectionVariant<TMedia> = {\n id?: string | number | null\n images?: Array<TMedia | string | number | null | undefined> | null\n}\n\nexport type ProductSelectionOptionValue = {\n id?: string | number | null\n swatch?: NormalizedOptionSwatch<unknown> | null\n}\n\nexport type ProductSelectionMediaPointer =\n | string\n | number\n | { id?: string | number | null }\n | null\n\nexport type ResolveProductSelectionMediaInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n selectedVariant?: ProductSelectionVariant<TMedia> | null\n matchingVariants?: Array<\n ProductSelectionVariant<TMedia> | null | undefined\n > | null\n selectedOptionValues?: Array<\n ProductSelectionOptionValue | null | undefined\n > | null\n}\n\nexport type ResolveProductSelectionMediaResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductSelectionMediaSource\n}\n\nexport type ResolveProductDisplayMediaInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n featuredImage?: ProductSelectionMediaPointer\n}\n\nexport type ResolveProductDisplayMediaResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductDisplayMediaSource\n}\n\ntype MediaWithOptionalId = {\n id?: string | number | null\n}\n\nfunction getMediaId(value: unknown): string | null {\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value)\n }\n\n if (typeof value === 'object' && value !== null && 'id' in value) {\n const id = (value as MediaWithOptionalId).id\n if (typeof id === 'string' || typeof id === 'number') return String(id)\n }\n\n return null\n}\n\nfunction toPointerId(\n value: ProductSelectionMediaPointer | undefined,\n): string | null {\n return getMediaId(value)\n}\n\nfunction mediaArray<TMedia>(value: TMedia[] | null | undefined): TMedia[] {\n if (!Array.isArray(value)) return []\n return value.filter((entry): entry is TMedia => entry != null)\n}\n\nfunction uniqueWithPrimaryFirst<TMedia>(\n primary: TMedia | null,\n items: TMedia[],\n): TMedia[] {\n const unique = new Map<string, TMedia>()\n\n for (const item of items) {\n const id = getMediaId(item)\n const key = id ?? `inline:${unique.size}`\n if (!unique.has(key)) unique.set(key, item)\n }\n\n if (primary) {\n const primaryId = getMediaId(primary)\n const prefixed = new Map<string, TMedia>()\n const primaryKey = primaryId ?? 'inline:primary'\n prefixed.set(primaryKey, primary)\n\n for (const [key, value] of unique.entries()) {\n if (!prefixed.has(key)) prefixed.set(key, value)\n }\n\n return Array.from(prefixed.values())\n }\n\n return Array.from(unique.values())\n}\n\nfunction buildPoolById<TMedia>(pool: TMedia[]): Map<string, TMedia> {\n const poolById = new Map<string, TMedia>()\n\n for (const item of pool) {\n const id = getMediaId(item)\n if (id) poolById.set(id, item)\n }\n\n return poolById\n}\n\nfunction resolveVariantImageItems<TMedia>(\n variant: ProductSelectionVariant<TMedia> | null | undefined,\n poolById: Map<string, TMedia>,\n): TMedia[] {\n if (!variant || !Array.isArray(variant.images)) return []\n\n const resolved: TMedia[] = []\n\n for (const entry of variant.images) {\n if (entry == null) continue\n\n if (typeof entry === 'string' || typeof entry === 'number') {\n const pooled = poolById.get(String(entry))\n if (pooled) resolved.push(pooled)\n continue\n }\n\n const mediaId = getMediaId(entry)\n if (mediaId) {\n const pooled = poolById.get(mediaId)\n if (pooled) {\n resolved.push(pooled)\n }\n continue\n }\n }\n\n return resolved\n}\n\nfunction resolveOptionSwatchPrimary<TMedia>(\n selectedOptionValues:\n | Array<ProductSelectionOptionValue | null | undefined>\n | null\n | undefined,\n poolById: Map<string, TMedia>,\n): TMedia | null {\n if (!selectedOptionValues?.length) return null\n\n for (const optionValue of selectedOptionValues) {\n const swatch = optionValue?.swatch\n const swatchPointer = selectedSwatchMediaItemId(swatch)\n if (swatchPointer) {\n const pooled = poolById.get(swatchPointer)\n if (pooled) return pooled\n }\n\n const inline = swatch?.inlineMedia\n if (inline != null && typeof inline === 'object') {\n return inline as TMedia\n }\n }\n\n return null\n}\n\nexport function resolveProductSelectionMedia<TMedia>(\n input: ResolveProductSelectionMediaInput<TMedia>,\n): ResolveProductSelectionMediaResult<TMedia> {\n const pool = mediaArray(input.productMediaPool)\n const poolById = buildPoolById(pool)\n\n const selectedVariantImages = resolveVariantImageItems(\n input.selectedVariant,\n poolById,\n )\n\n if (selectedVariantImages.length > 0) {\n const primaryImage = selectedVariantImages[0] ?? null\n\n return {\n primaryImage,\n images: uniqueWithPrimaryFirst(primaryImage, selectedVariantImages),\n source: 'variant_media_selected',\n }\n }\n\n if (\n input.selectedVariant == null &&\n (input.matchingVariants?.length ?? 0) > 0\n ) {\n const mergedMatchingImages: TMedia[] = []\n\n for (const matchingVariant of input.matchingVariants ?? []) {\n mergedMatchingImages.push(\n ...resolveVariantImageItems(matchingVariant, poolById),\n )\n }\n\n if (mergedMatchingImages.length > 0) {\n const primaryImage = mergedMatchingImages[0] ?? null\n\n return {\n primaryImage,\n images: uniqueWithPrimaryFirst(primaryImage, mergedMatchingImages),\n source: 'variant_media_matching',\n }\n }\n }\n\n const optionSwatchPrimary = resolveOptionSwatchPrimary(\n input.selectedOptionValues,\n poolById,\n )\n\n if (optionSwatchPrimary) {\n return {\n primaryImage: optionSwatchPrimary,\n images: [optionSwatchPrimary],\n source: 'option_swatch',\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\nexport function resolveProductDisplayMedia<TMedia>(\n input: ResolveProductDisplayMediaInput<TMedia>,\n): ResolveProductDisplayMediaResult<TMedia> {\n const pool = mediaArray(input.productMediaPool)\n const poolById = buildPoolById(pool)\n\n const featuredImagePointer = toPointerId(input.featuredImage)\n if (featuredImagePointer) {\n const featuredImage = poolById.get(featuredImagePointer)\n if (featuredImage) {\n return {\n primaryImage: featuredImage,\n images: uniqueWithPrimaryFirst(featuredImage, pool),\n source: 'featured_image',\n }\n }\n }\n\n if (pool.length > 0) {\n const productPoolPrimary = pool[0] ?? null\n\n if (productPoolPrimary) {\n return {\n primaryImage: productPoolPrimary,\n images: uniqueWithPrimaryFirst(productPoolPrimary, pool),\n source: 'product_pool',\n }\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\nexport type FeaturedImagePointerInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n featuredImage?: TMedia | string | number | null\n resolvedPrimary?: TMedia | null\n resolvedSource?: ProductMediaResolutionSource\n}\n\nexport function resolveFeaturedImagePointer<TMedia>(\n input: FeaturedImagePointerInput<TMedia>,\n): string | null {\n const pool = mediaArray(input.productMediaPool)\n const resolvedPointer = getMediaId(input.resolvedPrimary)\n if (\n resolvedPointer &&\n input.resolvedSource !== 'product_pool' &&\n input.resolvedSource !== 'none'\n ) {\n return resolvedPointer\n }\n\n const poolById = buildPoolById(pool)\n const featuredImagePointer = getMediaId(input.featuredImage)\n if (featuredImagePointer && poolById.has(featuredImagePointer)) {\n return featuredImagePointer\n }\n\n if (pool.length > 0) {\n const firstPoolId = getMediaId(pool[0])\n if (firstPoolId) return firstPoolId\n }\n\n return null\n}\n","import type {\n ProductDetail,\n ProductDetailCatalog,\n ProductDetailMedia,\n ProductDetailOptionValue,\n ProductDetailVariant,\n ProductListingGroupsCatalogItem,\n ProductListingGroupsItem,\n ProductOptionValueSwatch,\n ProductLocalizedText,\n} from '../core/api/product-api'\nimport type { ApiQueryOptions } from '../core/client/types'\nimport {\n resolveProductDisplayMedia,\n resolveProductSelectionMedia,\n resolveFeaturedImagePointer,\n type NormalizedOptionSwatch,\n type ProductMediaResolutionSource,\n type ProductSelectionMediaSource,\n} from './product-selection-media'\n\ntype ProductSelectionDetail = ProductDetail | ProductDetailCatalog\ntype ProductSelectionVariant =\n | ProductDetailVariant\n | ProductDetailCatalog['variants'][number]\ntype ProductSelectionVariantForDetail<TDetail extends ProductSelectionDetail> =\n TDetail extends ProductDetail\n ? ProductDetailVariant\n : ProductDetailCatalog['variants'][number]\n\nfunction normalizeMatrixSwatch(\n swatch: ProductDetailOptionValue['swatch'],\n): NormalizedOptionSwatch<ProductDetailMedia> | null {\n if (!swatch) return null\n const rawMedia = swatch.mediaItemId as MediaValue\n const inlineMedia =\n rawMedia != null &&\n typeof rawMedia === 'object' &&\n 'url' in rawMedia &&\n typeof (rawMedia as { url?: unknown }).url === 'string'\n ? (rawMedia as ProductDetailMedia)\n : null\n return {\n type: swatch.type ?? null,\n color: swatch.color ?? null,\n mediaItemId: extractEntityId(rawMedia),\n inlineMedia,\n }\n}\n\ntype EntityID = string\n\ntype RelationshipValue =\n | string\n | number\n | null\n | undefined\n | { id?: string | number | null }\n\nexport type MediaValue = ProductDetailMedia | null | undefined\n\nexport type { ProductOptionValueSwatch }\n\n/** Raw Payload / REST swatch before strict public normalization. */\nexport type ProductOptionValueSwatchInput = {\n type?: 'color' | 'media' | null\n color?: string | null\n mediaItemId?: RelationshipValue\n}\n\nexport interface ProductOptionValueShape {\n id?: string | number | null\n option?: RelationshipValue\n value?: string | null\n slug?: string | null\n swatch?: ProductOptionValueSwatch | ProductOptionValueSwatchInput | null\n _order?: string | null\n '_product-option-values_values_order'?: string | null\n}\n\nexport interface ProductOptionShape {\n id?: string | number | null\n title?: string | null\n slug?: string | null\n _order?: string | null\n '_product-options_options_order'?: string | null\n values?: {\n docs?: unknown[]\n } | null\n}\n\nexport interface ProductVariantShape {\n id?: string | number | null\n optionValues?: unknown[] | null\n price?: number | null\n compareAtPrice?: number | null\n resolvedPrice?: {\n amount: number\n compareAtPrice?: number | null\n currency?: string | null\n marketId?: string | null\n source?: 'fixed' | 'computed'\n }\n stock?: number | null\n reservedStock?: number | null\n isUnlimited?: boolean | null\n inventoryPolicy?: ('deny' | 'continue') | null\n isActive?: boolean | null\n availableForSale?: boolean | null\n thumbnail?: MediaValue\n images?: MediaValue[] | null\n _order?: string | null\n}\n\nexport interface ProductListingProductShape {\n id?: EntityID\n title?: ProductLocalizedText\n images?: MediaValue[] | null\n featuredImage?: MediaValue\n priceRange?: {\n minVariantPrice?: { amount?: number | null } | null\n maxVariantPrice?: { amount?: number | null } | null\n isPriceRange?: boolean | null\n } | null\n compareAtPriceRange?: {\n minVariantPrice?: { amount?: number | null } | null\n maxVariantPrice?: { amount?: number | null } | null\n } | null\n availableForSale?: boolean | null\n selectedOrFirstAvailableVariant?: RelationshipValue | ProductVariantShape\n}\n\nexport type ProductOptionMatrixValue = {\n id: string\n optionId: string\n optionSlug: string\n label: string\n slug: string | null\n swatch: ProductOptionValueSwatch\n order: string\n}\n\nexport type ProductOptionMatrixOption = {\n id: string\n title: string\n slug: string\n order: string\n values: ProductOptionMatrixValue[]\n}\n\nexport type ProductOptionMatrixVariant<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n id: string\n optionValueIds: string[]\n optionValueByOptionId: Map<string, string>\n optionValueByOptionSlug: Map<string, string>\n source: TVariant\n}\n\nexport type ProductOptionMatrix<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n options: ProductOptionMatrixOption[]\n optionIds: string[]\n optionSlugs: string[]\n optionById: Map<string, ProductOptionMatrixOption>\n optionBySlug: Map<string, ProductOptionMatrixOption>\n valueById: Map<string, ProductOptionMatrixValue>\n valueToOptionId: Map<string, string>\n valueToOptionSlug: Map<string, string>\n variants: ProductOptionMatrixVariant<TVariant>[]\n}\n\nexport type ProductListingGroupProjection = {\n selectionHintVariant: EntityID | null\n primaryImage: EntityID | null\n minPrice: number | null\n maxPrice: number | null\n minCompareAtPrice: number | null\n maxCompareAtPrice: number | null\n isPriceRange: boolean\n availableForSale: boolean\n}\n\nexport type ProductListingGroup<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n optionId: EntityID\n optionTitle: string\n optionSlug: string\n optionValueId: EntityID\n optionValueLabel: string\n optionValueSlug: string | null\n optionValueSwatch: ProductOptionValueSwatch\n variantIds: EntityID[]\n variantCount: number\n variants: TVariant[]\n listing: ProductListingGroupProjection\n}\n\nexport type ProductListingCardPriceRange = {\n minPrice: number | null\n maxPrice: number | null\n minCompareAtPrice: number | null\n maxCompareAtPrice: number | null\n isPriceRange: boolean\n}\n\nexport type ProductListingSwatch = {\n optionId: EntityID\n optionValueId: EntityID\n label: string\n swatch: ProductOptionValueSwatch<ProductDetailMedia>\n href: string\n availableForSale: boolean\n}\n\ntype ProductListingCardSourceItem =\n | ProductListingGroupsCatalogItem\n | ProductListingGroupsItem\n\nexport type ProductListingCardRepresentativeVariant =\n ProductListingCardSourceItem['groups'][number]['variants'][number]\n\nexport type ProductListingCard = {\n id: EntityID\n href: string\n title: ProductLocalizedText\n representativeVariant?: ProductListingCardRepresentativeVariant | null\n primaryImage: ProductDetailMedia | null\n priceRange: ProductListingCardPriceRange\n availableForSale: boolean\n swatches: ProductListingSwatch[]\n}\n\nexport type ProductSelectionByOptionValue =\n | string\n | number\n | null\n | undefined\n | {\n valueId?: string | number | null\n valueSlug?: string | null\n }\n\nexport type ProductSelectionInput = {\n variantId?: string | number | null\n byOptionSlug?: Record<string, ProductSelectionByOptionValue>\n byOptionId?: Record<string, ProductSelectionByOptionValue>\n valueIds?: Iterable<unknown>\n search?: string | URLSearchParams | URL | null\n}\n\nexport type NormalizedProductSelection = {\n byOptionSlug: Record<string, string>\n byOptionId: Record<string, string>\n valueIds: string[]\n variantId: string | null\n}\n\nexport type CompatibilityProductSelectionParamEvent = {\n optionId: string\n optionSlug: string\n valueSlug: string\n searchParam: string\n}\n\nexport type LegacyProductSelectionParamEvent =\n CompatibilityProductSelectionParamEvent\n\nexport type ProductSelectionUrlEmit = 'slug-compat' | 'canonical-id'\n\nconst DEFAULT_PRODUCT_SELECTION_URL_EMIT: ProductSelectionUrlEmit =\n 'slug-compat'\n\nfunction resolveProductSelectionUrlEmit(\n emit?: ProductSelectionUrlEmit,\n): ProductSelectionUrlEmit {\n return emit ?? DEFAULT_PRODUCT_SELECTION_URL_EMIT\n}\n\nfunction appendSlugCompatSelectionParam(\n params: URLSearchParams,\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n optionId: string,\n valueId: string,\n): boolean {\n const option = matrix.optionById.get(optionId)\n const value = matrix.valueById.get(valueId)\n if (!option?.slug || !value?.slug) return false\n\n const slugMatches = option.values.filter(\n (candidate) => candidate.slug === value.slug,\n )\n if (slugMatches.length !== 1) return false\n\n params.append(`opt.${option.slug}`, value.slug)\n return true\n}\n\nfunction appendCanonicalSelectionParam(\n params: URLSearchParams,\n optionId: string,\n valueId: string,\n): void {\n params.append(`opt.${optionId}`, valueId)\n}\n\nexport type ProductSelectionCodecOptions = {\n emit?: ProductSelectionUrlEmit\n /**\n * When true, `resolveProductSelection()` fills unselected options to reach a\n * concrete variant. Does not change codec parse/stringify behavior.\n */\n fillDefaults?: boolean\n onCompatibilityOptionIdParam?: (\n event: CompatibilityProductSelectionParamEvent,\n ) => void\n onLegacyOptionIdParam?: (event: LegacyProductSelectionParamEvent) => void\n}\n\nexport type ProductSelectionResolutionContext = {\n detail?: Pick<\n ProductSelectionDetail,\n 'featuredImage' | 'images' | 'selectedOrFirstAvailableVariant'\n >\n featuredImage?: ProductSelectionDetail['featuredImage']\n images?: ProductSelectionDetail['images']\n selectedOrFirstAvailableVariant?: ProductSelectionDetail['selectedOrFirstAvailableVariant']\n}\n\nexport type ProductSelectionAvailableSwatch = {\n color?: string | null\n image?: MediaValue | null\n}\n\nexport type ProductSelectionAvailableValue = {\n valueId: string\n value: string\n label: string\n slug: string\n selected: boolean\n available: boolean\n exists: boolean\n availableForSale: boolean\n isUnlimited: boolean\n availableStock: number | null\n swatch: ProductOptionValueSwatch\n}\n\nexport type ProductSelectionResolution<\n TVariant extends ProductVariantShape = ProductSelectionVariant,\n> = {\n normalizedSelection: NormalizedProductSelection\n selectedVariant: TVariant | null\n matchingVariants: TVariant[]\n partialVariants: TVariant[]\n availableValuesByOptionSlug: Record<string, ProductSelectionAvailableValue[]>\n availableValuesByOptionId: Record<string, ProductSelectionAvailableValue[]>\n allOptionsSelected: boolean\n price: {\n min: number | null\n max: number | null\n compareAtMin: number | null\n compareAtMax: number | null\n isRange: boolean\n }\n media: {\n primaryImage: ProductDetailMedia | null\n images: ProductDetailMedia[]\n source?: ProductMediaResolutionSource\n }\n stock: {\n availableForSale: boolean\n isUnlimited: boolean\n stock: number | null\n reservedStock: number | null\n availableStock: number | null\n }\n}\n\nexport class ProductSelectionCodecError extends Error {\n code = 'ambiguous_product_selection_query'\n\n constructor(message: string) {\n super(message)\n this.name = 'ProductSelectionCodecError'\n }\n}\n\nfunction getRelationID(value: RelationshipValue): string | undefined {\n if (typeof value === 'string') return value\n if (typeof value === 'number') return String(value)\n if (value && typeof value === 'object' && 'id' in value) {\n const id = value.id\n if (typeof id === 'string') return id\n if (typeof id === 'number') return String(id)\n }\n return undefined\n}\n\n// Payload orderable `_order` values are fractional-indexing keys whose order is\n// defined by code-unit comparison (`0-9` < `A-Z` < `a-z`). A locale-aware\n// comparison would reorder them by the runtime locale (Danish sorts `aa` as\n// `å`, and every locale folds `Zz` after `a0`), so compare ordinally instead.\nfunction compareOrdinal(left: string, right: string): number {\n if (left < right) return -1\n if (left > right) return 1\n return 0\n}\n\nfunction compareOrder(\n left: string | null | undefined,\n right: string | null | undefined,\n): number {\n return compareOrdinal(left ?? '', right ?? '')\n}\n\nfunction isProductOptionValueDoc(\n value: unknown,\n): value is ProductOptionValueShape {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n ('value' in value || 'slug' in value)\n )\n}\n\nfunction extractEntityId(value: MediaValue): EntityID | null {\n if (typeof value === 'string') return value\n if (typeof value === 'number') return String(value)\n if (value && typeof value === 'object' && 'id' in value) {\n if (typeof value.id === 'string') return value.id\n if (typeof value.id === 'number') return String(value.id)\n }\n return null\n}\n\nfunction getFirstMediaId(\n values: MediaValue[] | null | undefined,\n): EntityID | null {\n if (!Array.isArray(values)) return null\n\n for (const value of values) {\n const id = extractEntityId(value)\n if (id != null) return id\n }\n\n return null\n}\n\nfunction inProductMediaPool(\n product: ProductListingProductShape | null | undefined,\n mediaId: EntityID | null,\n): EntityID | null {\n if (mediaId == null) return null\n const images = Array.isArray(product?.images) ? product.images : []\n for (const image of images) {\n if (extractEntityId(image) === mediaId) return mediaId\n }\n return null\n}\n\nfunction getVariantPrimaryImage(\n variant: ProductVariantShape | null | undefined,\n): EntityID | null {\n if (!variant) return null\n return extractEntityId(variant.thumbnail) ?? getFirstMediaId(variant.images)\n}\n\nfunction resolveGenericListingPrimaryImage(\n product: ProductListingProductShape | null | undefined,\n resolvedPrimary: MediaValue | null,\n resolvedSource?: ProductSelectionMediaSource,\n): EntityID | null {\n return resolveFeaturedImagePointer({\n productMediaPool: product?.images ?? [],\n featuredImage: product?.featuredImage ?? null,\n resolvedPrimary,\n resolvedSource,\n })\n}\n\nfunction getFirstAvailableVariantPrimaryImage(\n variants: ProductVariantShape[],\n): EntityID | null {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n\n for (const variant of orderedVariants) {\n if (!isVariantAvailableForSale(variant)) continue\n const image = getVariantPrimaryImage(variant)\n if (image != null) return image\n }\n\n return null\n}\n\nfunction normalizeProductOptionValueSwatch(\n swatch:\n | ProductOptionValueSwatch\n | ProductOptionValueSwatchInput\n | null\n | undefined,\n): ProductOptionValueSwatch {\n if (swatch == null) return null\n if (typeof swatch !== 'object') return null\n\n const raw = swatch as ProductOptionValueSwatchInput\n const mediaItemId = extractEntityId(raw.mediaItemId as MediaValue)\n const color = typeof raw.color === 'string' ? raw.color.trim() : ''\n const hasColor = color.length > 0\n\n if (raw.type === 'media' || (mediaItemId && raw.type !== 'color')) {\n if (!mediaItemId || hasColor) return null\n return {\n type: 'media',\n mediaItemId: mediaItemId as ProductDetailMedia,\n color: null,\n }\n }\n\n if (raw.type === 'color' || hasColor) {\n if (mediaItemId || !hasColor) return null\n return { type: 'color', color, mediaItemId: null }\n }\n\n return null\n}\n\nfunction normalizeOptionValue(\n value: ProductOptionValueShape,\n fallbackOptionId: string,\n fallbackOptionSlug: string,\n): ProductOptionMatrixValue {\n return {\n id: String(value.id),\n optionId: getRelationID(value.option) ?? fallbackOptionId,\n optionSlug: fallbackOptionSlug,\n label: value.value || value.slug || String(value.id),\n slug: value.slug ?? null,\n swatch: normalizeProductOptionValueSwatch(value.swatch),\n order: value._order ?? value['_product-option-values_values_order'] ?? '',\n }\n}\n\nfunction normalizeVariantOptionValues<TVariant extends ProductVariantShape>(\n variant: TVariant,\n optionById: Map<string, ProductOptionMatrixOption>,\n valueToOptionId: Map<string, string>,\n optionIds: string[],\n): ProductOptionMatrixVariant<TVariant> {\n const optionValueByOptionId = new Map<string, string>()\n const optionValueByOptionSlug = new Map<string, string>()\n\n for (const rawValue of Array.isArray(variant.optionValues)\n ? variant.optionValues\n : []) {\n const valueId = getRelationID(rawValue as RelationshipValue)\n if (!valueId) continue\n\n const optionId =\n valueToOptionId.get(valueId) ??\n (isProductOptionValueDoc(rawValue)\n ? getRelationID(rawValue.option)\n : undefined)\n if (!optionId || optionValueByOptionId.has(optionId)) continue\n\n optionValueByOptionId.set(optionId, valueId)\n const optionSlug = optionById.get(optionId)?.slug\n if (optionSlug && !optionValueByOptionSlug.has(optionSlug)) {\n optionValueByOptionSlug.set(optionSlug, valueId)\n }\n }\n\n const optionValueIds = optionIds\n .map((optionId) => optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n\n return {\n id: String(variant.id),\n optionValueIds,\n optionValueByOptionId,\n optionValueByOptionSlug,\n source: variant,\n }\n}\n\nexport function buildProductOptionMatrix<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>({\n options,\n variants = [],\n}: {\n options: ProductOptionShape[]\n variants?: TVariant[]\n}): ProductOptionMatrix<TVariant> {\n const normalizedOptions = options\n .map((option) => {\n const valuesById = new Map<string, ProductOptionMatrixValue>()\n const optionSlug = option.slug ?? String(option.id)\n\n for (const rawValue of option.values?.docs ?? []) {\n if (!isProductOptionValueDoc(rawValue)) continue\n\n const normalizedValue = normalizeOptionValue(\n rawValue,\n String(option.id),\n optionSlug,\n )\n valuesById.set(normalizedValue.id, normalizedValue)\n }\n\n return {\n id: String(option.id),\n title: option.title ?? String(option.id),\n slug: optionSlug,\n order: option._order ?? option['_product-options_options_order'] ?? '',\n values: Array.from(valuesById.values()).sort((left, right) =>\n compareOrder(left.order, right.order),\n ),\n }\n })\n .sort((left, right) => compareOrder(left.order, right.order))\n\n const optionById = new Map(\n normalizedOptions.map((option) => [option.id, option]),\n )\n const optionBySlug = new Map(\n normalizedOptions.map((option) => [option.slug, option]),\n )\n const valueById = new Map<string, ProductOptionMatrixValue>()\n const valueToOptionId = new Map<string, string>()\n const valueToOptionSlug = new Map<string, string>()\n\n for (const option of normalizedOptions) {\n for (const value of option.values) {\n valueById.set(value.id, value)\n valueToOptionId.set(value.id, option.id)\n valueToOptionSlug.set(value.id, option.slug)\n }\n }\n\n const optionIds = normalizedOptions.map((option) => option.id)\n const optionSlugs = normalizedOptions.map((option) => option.slug)\n const normalizedVariants = variants.map((variant) =>\n normalizeVariantOptionValues(\n variant,\n optionById,\n valueToOptionId,\n optionIds,\n ),\n )\n\n return {\n options: normalizedOptions,\n optionIds,\n optionSlugs,\n optionById,\n optionBySlug,\n valueById,\n valueToOptionId,\n valueToOptionSlug,\n variants: normalizedVariants,\n }\n}\n\nfunction matrixOrder(index: number): string {\n return String(index).padStart(6, '0')\n}\n\nexport function buildProductOptionMatrixFromDetail<\n TDetail extends ProductSelectionDetail,\n>(\n detail: TDetail,\n): ProductOptionMatrix<ProductSelectionVariantForDetail<TDetail>> {\n const normalizedOptions = detail.options.map((option, optionIndex) => ({\n id: String(option.id),\n title: option.title || String(option.id),\n slug: option.slug,\n order: matrixOrder(optionIndex),\n values: option.values.map((value, valueIndex) => ({\n id: String(value.id),\n optionId: String(option.id),\n optionSlug: option.slug,\n label: value.value || value.slug || String(value.id),\n slug: value.slug,\n swatch: normalizeProductOptionValueSwatch(value.swatch),\n order: matrixOrder(valueIndex),\n })),\n }))\n\n const optionById = new Map(\n normalizedOptions.map((option) => [option.id, option]),\n )\n const optionBySlug = new Map(\n normalizedOptions.map((option) => [option.slug, option]),\n )\n const valueById = new Map<string, ProductOptionMatrixValue>()\n const valueToOptionId = new Map<string, string>()\n const valueToOptionSlug = new Map<string, string>()\n\n for (const option of normalizedOptions) {\n for (const value of option.values) {\n valueById.set(value.id, value)\n valueToOptionId.set(value.id, option.id)\n valueToOptionSlug.set(value.id, option.slug)\n }\n }\n\n const optionIds = normalizedOptions.map((option) => option.id)\n const optionSlugs = normalizedOptions.map((option) => option.slug)\n const normalizedVariants = detail.variants.map((variant) => {\n const optionValueByOptionId = new Map<string, string>()\n const optionValueByOptionSlug = new Map<string, string>()\n\n for (const rawValue of variant.optionValues) {\n const optionId = String(rawValue.optionId)\n const valueId = String(rawValue.valueId)\n const optionSlug = rawValue.optionSlug\n if (!optionById.has(optionId)) continue\n if (valueToOptionId.get(valueId) !== optionId) continue\n if (optionValueByOptionId.has(optionId)) continue\n optionValueByOptionId.set(optionId, valueId)\n if (optionSlug && !optionValueByOptionSlug.has(optionSlug)) {\n optionValueByOptionSlug.set(optionSlug, valueId)\n }\n }\n\n const optionValueIds = optionIds\n .map((optionId) => optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n\n return {\n id: String(variant.id),\n optionValueIds,\n optionValueByOptionId,\n optionValueByOptionSlug,\n source: variant,\n }\n }) as ProductOptionMatrixVariant<ProductSelectionVariantForDetail<TDetail>>[]\n\n return {\n options: normalizedOptions,\n optionIds,\n optionSlugs,\n optionById,\n optionBySlug,\n valueById,\n valueToOptionId,\n valueToOptionSlug,\n variants: normalizedVariants,\n }\n}\n\nexport function getSelectedValueByOptionId<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): Map<string, string> {\n const selectedByOption = new Map<string, string>()\n\n for (const rawValue of selectedValueIds) {\n const valueId = getRelationID(rawValue as RelationshipValue)\n if (!valueId) continue\n\n const optionId = matrix.valueToOptionId.get(valueId)\n if (!optionId || selectedByOption.has(optionId)) continue\n\n selectedByOption.set(optionId, valueId)\n }\n\n return selectedByOption\n}\n\nexport function normalizeSelectedValueIds<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): string[] {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n\n return matrix.optionIds\n .map((optionId) => selectedByOption.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n}\n\nexport function getAvailableOptionValues<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n optionId: string,\n selectedValueIds: Iterable<unknown>,\n): ProductOptionMatrixValue[] {\n const option = matrix.optionById.get(optionId)\n if (!option) return []\n\n if (matrix.variants.length === 0) {\n return option.values\n }\n\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n selectedByOption.delete(optionId)\n\n const matchingVariants = matrix.variants.filter((variant) =>\n Array.from(selectedByOption.entries()).every(\n ([selectedOptionId, selectedValueId]) =>\n variant.optionValueByOptionId.get(selectedOptionId) === selectedValueId,\n ),\n )\n\n const availableValueIds = new Set(\n matchingVariants\n .filter((variant) => variant.source.isActive !== false)\n .map((variant) => variant.optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId)),\n )\n\n return option.values.filter((value) => availableValueIds.has(value.id))\n}\n\nexport function resolveVariantForSelection<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): ProductOptionMatrixVariant<TVariant> | undefined {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n if (selectedByOption.size !== matrix.optionIds.length) {\n return undefined\n }\n\n return matrix.variants.find((variant) =>\n matrix.optionIds.every(\n (optionId) =>\n variant.optionValueByOptionId.get(optionId) ===\n selectedByOption.get(optionId),\n ),\n )\n}\n\nfunction getVariantSelection(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n variantId: string | number | null | undefined,\n): ProductOptionMatrixVariant<ProductSelectionVariant> | undefined {\n if (variantId == null) return undefined\n const id = String(variantId)\n return matrix.variants.find((variant) => variant.id === id)\n}\n\nfunction hasExplicitSelection(selection: ProductSelectionInput): boolean {\n return Boolean(\n selection.variantId != null ||\n selection.search ||\n selection.valueIds ||\n Object.keys(selection.byOptionId ?? {}).length > 0 ||\n Object.keys(selection.byOptionSlug ?? {}).length > 0,\n )\n}\n\nfunction assignSelectedValue(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n optionId: string,\n valueId: string | number | null | undefined,\n): boolean {\n if (valueId == null) return false\n const normalizedValueId = String(valueId)\n if (matrix.valueToOptionId.get(normalizedValueId) !== optionId) return false\n selectedByOptionId.set(optionId, normalizedValueId)\n return true\n}\n\nfunction assignSelectedValueSlugByOptionId(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n optionId: string,\n valueSlug: string | null | undefined,\n): boolean {\n if (!valueSlug) return false\n const option = matrix.optionById.get(optionId)\n if (!option) return false\n const values = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (values.length > 1) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection value slug \"${valueSlug}\" for option \"${optionId}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n const value = values[0]\n if (!value) return false\n selectedByOptionId.set(optionId, value.id)\n return true\n}\n\nfunction assignSelectedValueSlugByOptionSlug(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n optionSlug: string,\n valueSlug: string | null | undefined,\n): boolean {\n if (!valueSlug) return false\n const option = matrix.optionBySlug.get(optionSlug)\n if (!option) return false\n const values = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (values.length > 1) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection value slug \"${valueSlug}\" for option \"${optionSlug}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n const value = values[0]\n if (!value) return false\n selectedByOptionId.set(option.id, value.id)\n return true\n}\n\nfunction toSearchParams(\n search: string | URLSearchParams | URL | null | undefined,\n): URLSearchParams {\n if (!search) return new URLSearchParams()\n if (search instanceof URLSearchParams) return new URLSearchParams(search)\n if (search instanceof URL) return new URLSearchParams(search.searchParams)\n\n const trimmed = search.trim()\n if (!trimmed) return new URLSearchParams()\n\n try {\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(trimmed)) {\n return new URL(trimmed).searchParams\n }\n } catch {\n return new URLSearchParams()\n }\n\n return new URLSearchParams(\n trimmed.startsWith('?') ? trimmed.slice(1) : trimmed,\n )\n}\n\nfunction slugLike(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\nfunction assertNoAmbiguousSelectionParams(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n params: URLSearchParams,\n) {\n const knownSelectionKeys = new Set<string>()\n const hasVariantParam = params.has('variant')\n const hasOptionParams = Array.from(params.keys()).some((key) =>\n key.startsWith('opt.'),\n )\n\n if (hasVariantParam && hasOptionParams) {\n throw new ProductSelectionCodecError(\n 'Product selection URL cannot mix variant=<variantId> with opt.<optionId>=<valueId> params.',\n )\n }\n\n for (const option of matrix.options) {\n knownSelectionKeys.add(slugLike(option.slug))\n knownSelectionKeys.add(slugLike(option.title))\n for (const value of option.values) {\n if (value.slug) knownSelectionKeys.add(slugLike(value.slug))\n }\n }\n\n for (const [key, value] of params.entries()) {\n if (key.startsWith('opt.')) {\n const optionToken = key.slice(4)\n if (\n !optionToken ||\n (!matrix.optionBySlug.has(optionToken) &&\n !matrix.optionById.has(optionToken))\n ) {\n throw new ProductSelectionCodecError(\n `Unknown product selection query parameter \"${key}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n if (!value) {\n throw new ProductSelectionCodecError(\n `Product selection query parameter \"${key}\" requires a value ID or compatibility value slug.`,\n )\n }\n continue\n }\n\n if (key === 'variant') {\n if (!value) {\n throw new ProductSelectionCodecError(\n 'Product selection query parameter \"variant\" requires a variant ID.',\n )\n }\n if (!getVariantSelection(matrix, value)) {\n throw new ProductSelectionCodecError(\n `Unknown product selection variant \"${value}\".`,\n )\n }\n continue\n }\n\n const keyToken = slugLike(key)\n if (\n knownSelectionKeys.has(keyToken) ||\n (value === '' && knownSelectionKeys.has(keyToken))\n ) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection query parameter \"${key}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n }\n}\n\nfunction emitCompatibilityOptionIdParam(\n options: ProductSelectionCodecOptions | undefined,\n event: CompatibilityProductSelectionParamEvent,\n) {\n try {\n if (options?.onCompatibilityOptionIdParam) {\n options.onCompatibilityOptionIdParam(event)\n return\n }\n options?.onLegacyOptionIdParam?.(event)\n } catch {\n // Compatibility telemetry must not change parser semantics.\n }\n}\n\nfunction assignSearchSelection(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n search: string | URLSearchParams | URL | null | undefined,\n options?: ProductSelectionCodecOptions,\n): string | null {\n if (!search) return null\n const params = toSearchParams(search)\n assertNoAmbiguousSelectionParams(matrix, params)\n\n const variantParam = params.get('variant')\n if (variantParam != null) {\n const variantSelection = getVariantSelection(matrix, variantParam)\n if (!variantSelection) {\n throw new ProductSelectionCodecError(\n `Unknown product selection variant \"${variantParam}\".`,\n )\n }\n for (const [optionId, valueId] of variantSelection.optionValueByOptionId) {\n selectedByOptionId.set(optionId, valueId)\n }\n return variantSelection.id\n }\n\n for (const [key, valueToken] of params.entries()) {\n if (!key.startsWith('opt.')) continue\n const optionToken = key.slice(4)\n\n const optionById = matrix.optionById.get(optionToken)\n if (optionById) {\n if (\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n optionById.id,\n valueToken,\n )\n ) {\n continue\n }\n\n const before = selectedByOptionId.get(optionById.id)\n if (\n assignSelectedValueSlugByOptionId(\n matrix,\n selectedByOptionId,\n optionById.id,\n valueToken,\n ) &&\n selectedByOptionId.get(optionById.id) !== before\n ) {\n emitCompatibilityOptionIdParam(options, {\n optionId: optionById.id,\n optionSlug: optionById.slug,\n valueSlug: valueToken,\n searchParam: key,\n })\n continue\n }\n\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n\n const optionBySlug = matrix.optionBySlug.get(optionToken)\n if (optionBySlug) {\n if (\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionBySlug.slug,\n valueToken,\n )\n ) {\n continue\n }\n\n if (matrix.valueById.has(valueToken)) {\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionSlug>=<valueSlug> for compatibility URLs.`,\n )\n }\n }\n\n return null\n}\n\nexport function normalizeProductSelection(\n detail: ProductSelectionDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n return normalizeProductSelectionFromMatrix(matrix, selection, options)\n}\n\nexport function normalizeProductSelectionFromMatrix(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const selectedByOptionId = new Map<string, string>()\n const variantSelection = getVariantSelection(matrix, selection.variantId)\n const variantId = variantSelection?.id ?? null\n\n if (variantSelection) {\n for (const [optionId, valueId] of variantSelection.optionValueByOptionId) {\n selectedByOptionId.set(optionId, valueId)\n }\n }\n\n for (const rawValueId of selection.valueIds ?? []) {\n const valueId = getRelationID(rawValueId as RelationshipValue)\n if (!valueId) continue\n const optionId = matrix.valueToOptionId.get(valueId)\n if (!optionId) continue\n selectedByOptionId.set(optionId, valueId)\n }\n\n const searchVariantId = assignSearchSelection(\n matrix,\n selectedByOptionId,\n selection.search,\n options,\n )\n\n for (const [rawOptionId, rawSelection] of Object.entries(\n selection.byOptionId ?? {},\n )) {\n const optionId = String(rawOptionId)\n if (!matrix.optionById.has(optionId)) continue\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueId' in rawSelection &&\n rawSelection.valueId != null\n ) {\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n optionId,\n rawSelection.valueId,\n )\n continue\n }\n\n if (typeof rawSelection === 'string' || typeof rawSelection === 'number') {\n assignSelectedValue(matrix, selectedByOptionId, optionId, rawSelection)\n continue\n }\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueSlug' in rawSelection\n ) {\n assignSelectedValueSlugByOptionId(\n matrix,\n selectedByOptionId,\n optionId,\n rawSelection.valueSlug,\n )\n }\n }\n\n for (const [rawOptionSlug, rawSelection] of Object.entries(\n selection.byOptionSlug ?? {},\n )) {\n const optionSlug = String(rawOptionSlug)\n if (!matrix.optionBySlug.has(optionSlug)) continue\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueId' in rawSelection &&\n rawSelection.valueId != null\n ) {\n const option = matrix.optionBySlug.get(optionSlug)\n if (option) {\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n option.id,\n rawSelection.valueId,\n )\n }\n continue\n }\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueSlug' in rawSelection\n ) {\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionSlug,\n rawSelection.valueSlug,\n )\n continue\n }\n\n if (typeof rawSelection === 'string' || typeof rawSelection === 'number') {\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionSlug,\n String(rawSelection),\n )\n }\n }\n\n const byOptionId = Object.fromEntries(\n matrix.optionIds\n .map((optionId) => [optionId, selectedByOptionId.get(optionId)])\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n const byOptionSlug = Object.fromEntries(\n matrix.options\n .map((option) => {\n const valueId = selectedByOptionId.get(option.id)\n const value = valueId ? matrix.valueById.get(valueId) : undefined\n return [option.slug, value?.slug ?? undefined]\n })\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n\n return {\n byOptionSlug,\n byOptionId,\n valueIds: matrix.optionIds\n .map((optionId) => byOptionId[optionId])\n .filter((valueId): valueId is string => Boolean(valueId)),\n variantId: searchVariantId ?? variantId,\n }\n}\n\nexport function parseProductSelection(\n detail: ProductSelectionDetail,\n search: string | URLSearchParams | URL | null | undefined,\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n return normalizeProductSelection(detail, { search }, options)\n}\n\nexport function stringifyProductSelection(\n detail: ProductSelectionDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): string {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n const normalized = normalizeProductSelectionFromMatrix(\n matrix,\n selection,\n options,\n )\n const params = new URLSearchParams()\n\n if (hasExplicitSelection(selection)) {\n const matchingVariants = getMatchingVariantEntries(matrix, normalized)\n const exactVariant = getExactSelectedVariantEntry(\n matrix,\n normalized,\n matchingVariants,\n )\n if (exactVariant) {\n params.set('variant', exactVariant.id)\n return params.toString()\n }\n }\n\n const emit = resolveProductSelectionUrlEmit(options?.emit)\n\n for (const optionId of matrix.optionIds) {\n const valueId = normalized.byOptionId[optionId]\n if (!valueId) continue\n if (!matrix.optionById.has(optionId) || !matrix.valueById.has(valueId)) {\n continue\n }\n\n if (emit === 'slug-compat') {\n if (appendSlugCompatSelectionParam(params, matrix, optionId, valueId)) {\n continue\n }\n }\n\n appendCanonicalSelectionParam(params, optionId, valueId)\n }\n\n return params.toString()\n}\n\nexport function createProductSelectionCodec(\n detail: ProductSelectionDetail,\n options?: ProductSelectionCodecOptions,\n): {\n parse: (\n search: string | URLSearchParams | URL | null | undefined,\n ) => NormalizedProductSelection\n stringify: (selection?: ProductSelectionInput) => string\n} {\n return {\n parse: (search) => parseProductSelection(detail, search, options),\n stringify: (selection = {}) =>\n stringifyProductSelection(detail, selection, options),\n }\n}\n\nfunction selectedEntries(\n selection: NormalizedProductSelection,\n): Array<[string, string]> {\n return Object.entries(selection.byOptionId)\n}\n\nfunction getMatchingVariantEntries(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selection: NormalizedProductSelection,\n): ProductOptionMatrixVariant<ProductSelectionVariant>[] {\n const entries = selectedEntries(selection)\n if (entries.length === 0) return matrix.variants\n\n return matrix.variants.filter((variant) =>\n entries.every(\n ([optionId, valueId]) =>\n variant.optionValueByOptionId.get(optionId) === valueId,\n ),\n )\n}\n\nfunction activeVariantEntries(\n variants: ProductOptionMatrixVariant<ProductSelectionVariant>[],\n): ProductOptionMatrixVariant<ProductSelectionVariant>[] {\n return variants.filter((variant) => variant.source.isActive !== false)\n}\n\nfunction getExactSelectedVariantEntry(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selection: NormalizedProductSelection,\n matchingVariants: ProductOptionMatrixVariant<ProductSelectionVariant>[],\n): ProductOptionMatrixVariant<ProductSelectionVariant> | null {\n if (matrix.optionIds.length === 0) {\n return (\n getVariantSelection(matrix, selection.variantId) ??\n (matchingVariants.length === 1 ? (matchingVariants[0] ?? null) : null)\n )\n }\n\n const allOptionsSelected = matrix.optionIds.every((optionId) =>\n Boolean(selection.byOptionId[optionId]),\n )\n if (!allOptionsSelected) return null\n\n return (\n matchingVariants.find((variant) =>\n matrix.optionIds.every(\n (optionId) =>\n variant.optionValueByOptionId.get(optionId) ===\n selection.byOptionId[optionId],\n ),\n ) ?? null\n )\n}\n\nfunction normalizedSelectionFromByOptionId(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n variantId: string | null,\n): NormalizedProductSelection {\n const byOptionId = Object.fromEntries(\n matrix.optionIds\n .map((optionId) => [optionId, selectedByOptionId.get(optionId)])\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n const byOptionSlug = Object.fromEntries(\n matrix.options\n .map((option) => {\n const valueId = selectedByOptionId.get(option.id)\n const value = valueId ? matrix.valueById.get(valueId) : undefined\n return [option.slug, value?.slug ?? undefined]\n })\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n\n return {\n byOptionSlug,\n byOptionId,\n valueIds: matrix.optionIds\n .map((optionId) => byOptionId[optionId])\n .filter((valueId): valueId is string => Boolean(valueId)),\n variantId,\n }\n}\n\nfunction buildFilledNormalizedSelection(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n normalizedSelection: NormalizedProductSelection,\n selectionHintVariant: string | number | null | undefined,\n): NormalizedProductSelection {\n const selectedByOptionId = new Map<string, string>(\n Object.entries(normalizedSelection.byOptionId),\n )\n\n if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n const variantId =\n normalizedSelection.variantId ??\n resolveVariantIdForCompleteSelection(matrix, selectedByOptionId)\n if (variantId === normalizedSelection.variantId) {\n return normalizedSelection\n }\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n variantId,\n )\n }\n\n for (const option of matrix.options) {\n if (selectedByOptionId.has(option.id)) continue\n if (option.values.length === 1) {\n selectedByOptionId.set(option.id, option.values[0]!.id)\n }\n }\n\n if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n const variantId =\n normalizedSelection.variantId ??\n resolveVariantIdForCompleteSelection(matrix, selectedByOptionId)\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n variantId,\n )\n }\n\n const partialNormalized = normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n normalizedSelection.variantId,\n )\n const matchingVariantEntries = getMatchingVariantEntries(\n matrix,\n partialNormalized,\n )\n const orderedMatches = [...matchingVariantEntries].sort((left, right) =>\n compareVariantOrder(left.source, right.source),\n )\n\n const hintVariantId =\n selectionHintVariant != null ? String(selectionHintVariant) : null\n const hintedEntry =\n hintVariantId != null\n ? orderedMatches.find((entry) => entry.id === hintVariantId)\n : undefined\n const availableEntry = orderedMatches.find((entry) =>\n isVariantAvailableForSale(entry.source),\n )\n const chosenEntry = hintedEntry ?? availableEntry ?? orderedMatches[0]\n\n if (!chosenEntry) {\n return normalizedSelection\n }\n\n for (const optionId of matrix.optionIds) {\n if (selectedByOptionId.has(optionId)) continue\n const valueId = chosenEntry.optionValueByOptionId.get(optionId)\n if (valueId) selectedByOptionId.set(optionId, valueId)\n }\n\n const filledVariantId = matrix.optionIds.every((optionId) =>\n selectedByOptionId.has(optionId),\n )\n ? (resolveVariantIdForCompleteSelection(matrix, selectedByOptionId) ??\n chosenEntry.id)\n : normalizedSelection.variantId\n\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n filledVariantId,\n )\n}\n\nfunction resolveVariantIdForCompleteSelection(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selectedByOptionId: Map<string, string>,\n): string | null {\n if (!matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n return null\n }\n\n const normalized = normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n null,\n )\n const matchingVariantEntries = getMatchingVariantEntries(matrix, normalized)\n return (\n getExactSelectedVariantEntry(matrix, normalized, matchingVariantEntries)\n ?.id ?? null\n )\n}\n\nfunction buildSelectionPrice(\n variants: ProductSelectionVariant[],\n): ProductSelectionResolution['price'] {\n const { min, max } = getMinMax(\n variants.map((variant) => variant.resolvedPrice?.amount ?? variant.price),\n )\n const { min: compareAtMin, max: compareAtMax } = getMinMax(\n variants.map(\n (variant) =>\n variant.resolvedPrice?.compareAtPrice ?? variant.compareAtPrice,\n ),\n )\n\n return {\n min,\n max,\n compareAtMin,\n compareAtMax,\n isRange: min !== null && max !== null ? min !== max : false,\n }\n}\n\nfunction isPresentMedia(value: MediaValue): value is ProductDetailMedia {\n return value != null\n}\n\nfunction mediaArray(\n values: MediaValue[] | null | undefined,\n): ProductDetailMedia[] {\n if (!Array.isArray(values)) return []\n return values.filter(isPresentMedia)\n}\n\nfunction buildSelectionMedia(\n detail: {\n featuredImage?: ProductDetail['featuredImage']\n images: ProductDetail['images']\n },\n selectedVariant: ProductSelectionVariant | null,\n matchingVariants: ProductSelectionVariant[],\n selectedValues: ProductOptionMatrixValue[],\n): ProductSelectionResolution['media'] {\n const productPool = mediaArray(detail.images)\n const resolvedMedia = resolveProductSelectionMedia<ProductDetailMedia>({\n productMediaPool: productPool,\n selectedVariant: selectedVariant\n ? {\n id: selectedVariant.id,\n images: selectedVariant.images,\n }\n : null,\n matchingVariants: matchingVariants.map((variant) => ({\n id: variant.id,\n images: variant.images,\n })),\n selectedOptionValues: selectedValues.map((value) => ({\n id: value.id,\n swatch: normalizeMatrixSwatch(value.swatch),\n })),\n })\n if (resolvedMedia.source !== 'none') {\n return {\n primaryImage: resolvedMedia.primaryImage,\n images: resolvedMedia.images,\n source: resolvedMedia.source,\n }\n }\n\n const displayMedia = resolveProductDisplayMedia<ProductDetailMedia>({\n productMediaPool: productPool,\n featuredImage: detail.featuredImage ?? null,\n })\n if (displayMedia.source !== 'none') {\n return {\n primaryImage: displayMedia.primaryImage,\n images: displayMedia.images,\n source: displayMedia.source,\n }\n }\n\n return { primaryImage: null, images: [], source: 'none' }\n}\n\nfunction buildSelectionStock(\n selectedVariant: ProductSelectionVariant | null,\n matchingVariants: ProductSelectionVariant[],\n): ProductSelectionResolution['stock'] {\n if (selectedVariant) {\n const availableStock = getVariantAvailableStock(selectedVariant)\n return {\n availableForSale: getVariantAvailableForSale(selectedVariant),\n isUnlimited: selectedVariant.isUnlimited,\n stock: 'stock' in selectedVariant ? selectedVariant.stock : null,\n reservedStock:\n 'reservedStock' in selectedVariant\n ? selectedVariant.reservedStock\n : null,\n availableStock,\n }\n }\n\n return {\n availableForSale: matchingVariants.some(isVariantAvailableForSale),\n isUnlimited: matchingVariants.some((variant) => variant.isUnlimited),\n stock: null,\n reservedStock: null,\n availableStock: null,\n }\n}\n\nfunction buildAvailableValueStock(\n variants: ProductSelectionVariant[],\n): Pick<\n ProductSelectionAvailableValue,\n 'availableForSale' | 'availableStock' | 'isUnlimited'\n> {\n const activeVariants = variants.filter(\n (variant) => variant.isActive !== false,\n )\n const isUnlimited = activeVariants.some((variant) => variant.isUnlimited)\n const availableStock = isUnlimited\n ? null\n : activeVariants.reduce(\n (sum, variant) => sum + (getVariantAvailableStock(variant) ?? 0),\n 0,\n )\n\n return {\n availableForSale: activeVariants.some(isVariantAvailableForSale),\n isUnlimited,\n availableStock,\n }\n}\n\nfunction buildProductSelectionAvailableValue(\n matrixValue: ProductOptionMatrixValue,\n _productImages: ProductDetailMedia[],\n selected: boolean,\n available: boolean,\n stock: Pick<\n ProductSelectionAvailableValue,\n 'availableForSale' | 'availableStock' | 'isUnlimited'\n >,\n): ProductSelectionAvailableValue {\n return {\n valueId: matrixValue.id,\n value: matrixValue.label,\n label: matrixValue.label,\n slug: matrixValue.slug ?? '',\n selected,\n available,\n exists: available,\n ...stock,\n swatch: matrixValue.swatch ?? null,\n }\n}\n\nfunction getCandidateVariantsForValue(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n optionId: string,\n valueId: string,\n selectedValueIds: Iterable<unknown>,\n): ProductSelectionVariant[] {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n selectedByOption.set(optionId, valueId)\n\n return matrix.variants\n .filter((variant) =>\n Array.from(selectedByOption.entries()).every(\n ([selectedOptionId, selectedValueId]) =>\n variant.optionValueByOptionId.get(selectedOptionId) ===\n selectedValueId,\n ),\n )\n .map((variant) => variant.source)\n}\n\nfunction getResolutionContext(context?: ProductSelectionResolutionContext): {\n featuredImage: ProductSelectionDetail['featuredImage']\n images: ProductSelectionDetail['images']\n selectedOrFirstAvailableVariant:\n | ProductSelectionDetail['selectedOrFirstAvailableVariant']\n | undefined\n} {\n return {\n featuredImage: context?.featuredImage ?? context?.detail?.featuredImage,\n images: context?.images ?? context?.detail?.images ?? [],\n selectedOrFirstAvailableVariant:\n context?.selectedOrFirstAvailableVariant ??\n context?.detail?.selectedOrFirstAvailableVariant,\n }\n}\n\nexport function resolveProductSelectionFromMatrix(\n matrix: ProductOptionMatrix<ProductSelectionVariant>,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n context?: ProductSelectionResolutionContext,\n): ProductSelectionResolution {\n const { featuredImage, images, selectedOrFirstAvailableVariant } =\n getResolutionContext(context)\n const selectionHintVariant = getRelationID(selectedOrFirstAvailableVariant)\n const effectiveSelection =\n hasExplicitSelection(selection) || selectionHintVariant == null\n ? selection\n : { ...selection, variantId: selectionHintVariant }\n let normalizedSelection = normalizeProductSelectionFromMatrix(\n matrix,\n effectiveSelection,\n options,\n )\n\n if (options?.fillDefaults) {\n normalizedSelection = buildFilledNormalizedSelection(\n matrix,\n normalizedSelection,\n selectionHintVariant,\n )\n }\n const matchingVariantEntries = getMatchingVariantEntries(\n matrix,\n normalizedSelection,\n )\n const activeMatchingVariantEntries = activeVariantEntries(\n matchingVariantEntries,\n )\n const selectedVariantEntry = getExactSelectedVariantEntry(\n matrix,\n normalizedSelection,\n matchingVariantEntries,\n )\n const selectedVariant = selectedVariantEntry?.source ?? null\n const matchingVariants = activeMatchingVariantEntries.map(\n (variant) => variant.source,\n )\n const selectedValues = matrix.optionIds\n .map((optionId) => normalizedSelection.byOptionId[optionId])\n .map((valueId) => (valueId ? matrix.valueById.get(valueId) : undefined))\n .filter((value): value is ProductOptionMatrixValue => value !== undefined)\n const availableValuesByOptionId = Object.fromEntries(\n matrix.options.map((option) => {\n const availableValueIds = new Set(\n getAvailableOptionValues(\n matrix,\n option.id,\n normalizedSelection.valueIds,\n ).map((value) => value.id),\n )\n return [\n option.id,\n option.values.map((value) =>\n buildProductSelectionAvailableValue(\n value,\n images,\n normalizedSelection.byOptionId[option.id] === value.id,\n availableValueIds.has(value.id),\n buildAvailableValueStock(\n getCandidateVariantsForValue(\n matrix,\n option.id,\n value.id,\n normalizedSelection.valueIds,\n ),\n ),\n ),\n ),\n ]\n }),\n )\n const availableValuesByOptionSlug = Object.fromEntries(\n matrix.options.map((option) => [\n option.slug,\n availableValuesByOptionId[option.id] ?? [],\n ]),\n )\n const allOptionsSelected = matrix.optionIds.every((optionId) =>\n Boolean(normalizedSelection.byOptionId[optionId]),\n )\n const priceVariants = selectedVariant ? [selectedVariant] : matchingVariants\n\n return {\n normalizedSelection,\n selectedVariant,\n matchingVariants,\n partialVariants: selectedVariant ? [] : matchingVariants,\n availableValuesByOptionSlug,\n availableValuesByOptionId,\n allOptionsSelected,\n price: buildSelectionPrice(priceVariants),\n media: buildSelectionMedia(\n {\n featuredImage,\n images,\n },\n selectedVariant,\n matchingVariants,\n selectedValues,\n ),\n stock: buildSelectionStock(selectedVariant, matchingVariants),\n }\n}\n\nexport function resolveProductSelection<TDetail extends ProductSelectionDetail>(\n detail: TDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): ProductSelectionResolution<ProductSelectionVariantForDetail<TDetail>> {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n return resolveProductSelectionFromMatrix(matrix, selection, options, {\n detail,\n }) as ProductSelectionResolution<ProductSelectionVariantForDetail<TDetail>>\n}\n\nexport function selectNext(\n detail: ProductDetail,\n current: ProductSelectionInput = {},\n optionSlug: string,\n valueSlug: string,\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n const selectionHintVariant = getRelationID(\n detail.selectedOrFirstAvailableVariant,\n )\n const normalizedCurrent = normalizeProductSelectionFromMatrix(\n matrix,\n current,\n options,\n )\n\n const option = matrix.optionBySlug.get(optionSlug)\n if (!option) return normalizedCurrent\n\n const valueMatches = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (valueMatches.length !== 1) return normalizedCurrent\n const clickedValueId = valueMatches[0]!.id\n\n const keepClickedSelection = (): NormalizedProductSelection => {\n const selectedByOptionId = new Map<string, string>()\n selectedByOptionId.set(option.id, clickedValueId)\n\n for (const otherOptionId of matrix.optionIds) {\n if (otherOptionId === option.id) continue\n const otherValueId = normalizedCurrent.byOptionId[otherOptionId]\n if (!otherValueId) continue\n\n const constraintIds = normalizeSelectedValueIds(\n matrix,\n Array.from(selectedByOptionId.values()),\n )\n const available = getAvailableOptionValues(\n matrix,\n otherOptionId,\n constraintIds,\n )\n if (available.some((candidate) => candidate.id === otherValueId)) {\n selectedByOptionId.set(otherOptionId, otherValueId)\n }\n }\n\n return buildFilledNormalizedSelection(\n matrix,\n normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),\n selectionHintVariant,\n )\n }\n\n const keepPriorSelection = (): NormalizedProductSelection => {\n const selectedByOptionId = new Map<string, string>(\n Object.entries(normalizedCurrent.byOptionId),\n )\n selectedByOptionId.delete(option.id)\n\n return buildFilledNormalizedSelection(\n matrix,\n normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),\n selectionHintVariant,\n )\n }\n\n const clickedResult = keepClickedSelection()\n const clickedVariantId = resolveVariantIdForCompleteSelection(\n matrix,\n new Map(Object.entries(clickedResult.byOptionId)),\n )\n\n const priorValueIds = Object.entries(normalizedCurrent.byOptionId)\n .filter(([otherOptionId]) => otherOptionId !== option.id)\n .map(([, valueId]) => valueId)\n\n const clickedAvailableWithPrior =\n priorValueIds.length === 0 ||\n getAvailableOptionValues(matrix, option.id, priorValueIds).some(\n (candidate) => candidate.id === clickedValueId,\n )\n\n if (clickedVariantId != null) {\n const priorClickedValue = normalizedCurrent.byOptionId[option.id]\n if (priorClickedValue != null && priorClickedValue !== clickedValueId) {\n return clickedResult\n }\n if (clickedAvailableWithPrior) {\n return clickedResult\n }\n }\n\n return keepPriorSelection()\n}\n\nexport type ProductDetailImageMedia = Extract<\n ProductDetailMedia,\n { id?: string | number | null; url?: string | null }\n>\n\nfunction isProductDetailImageMedia(\n value: ProductDetailMedia | null | undefined,\n): value is ProductDetailImageMedia {\n return typeof value === 'object' && value !== null\n}\n\nfunction mediaDedupeKey(value: ProductDetailImageMedia): string | null {\n if (value.id != null) return `id:${String(value.id)}`\n if (value.url) return `url:${value.url}`\n return null\n}\n\nexport function getProductSelectionImages(\n resolution: Pick<ProductSelectionResolution, 'media'>,\n): ProductDetailImageMedia[] {\n const seen = new Set<string>()\n const images: ProductDetailImageMedia[] = []\n const candidates = [\n resolution.media.primaryImage,\n ...resolution.media.images,\n ].filter(isProductDetailImageMedia)\n\n for (const candidate of candidates) {\n const key = mediaDedupeKey(candidate)\n if (key && seen.has(key)) continue\n if (key) seen.add(key)\n images.push(candidate)\n }\n\n return images\n}\n\nexport type ProductHrefProduct =\n | ProductDetail\n | {\n slug?: string | null\n product?: { slug?: string | null } | null\n }\n\nexport type ProductHrefGroup = {\n optionId?: string | number | null\n optionSlug?: string | null\n optionValueId?: string | number | null\n optionValueSlug?: string | null\n variantId?: string | number | null\n listing?: {\n selectionHintVariant?: string | number | null\n } | null\n}\n\nexport type ProductHrefOptions = {\n basePath?: string\n detail?: ProductSelectionDetail\n matrix?: ProductOptionMatrix<ProductSelectionVariant>\n selection?: ProductSelectionInput\n trailingSlash?: boolean\n emit?: ProductSelectionUrlEmit\n preferCompleteVariantFromHint?: boolean\n}\n\nexport type ProductListingCardOptions = {\n basePath?: string\n trailingSlash?: boolean\n emit?: ProductSelectionUrlEmit\n preferCompleteVariantFromHint?: boolean\n}\n\nfunction getProductHrefSlug(product: ProductHrefProduct): string {\n if ('product' in product && product.product?.slug) {\n return product.product.slug\n }\n if ('slug' in product && product.slug) return product.slug\n throw new ProductSelectionCodecError(\n 'Product slug is required to build a product href.',\n )\n}\n\nfunction joinProductPath(\n basePath: string,\n slug: string,\n trailingSlash: boolean,\n) {\n const base = basePath.replace(/\\/+$/, '')\n const encodedSlug = encodeURIComponent(slug)\n return `${base}/${encodedSlug}${trailingSlash ? '/' : ''}`\n}\n\nfunction getProductHrefGroupSelection(\n group: ProductHrefGroup | null | undefined,\n matrix?: ProductOptionMatrix<ProductSelectionVariant>,\n): ProductSelectionInput | null {\n if (!group) return null\n\n if (group.variantId != null) return { variantId: group.variantId }\n\n const optionId =\n group.optionId != null\n ? String(group.optionId)\n : group.optionSlug\n ? matrix?.optionBySlug.get(group.optionSlug)?.id\n : undefined\n if (!optionId) return null\n\n const option = matrix?.optionById.get(optionId)\n const optionValueId =\n group.optionValueId != null\n ? String(group.optionValueId)\n : group.optionValueSlug && option\n ? option.values.find((value) => value.slug === group.optionValueSlug)\n ?.id\n : undefined\n\n if (!optionValueId) return null\n return { byOptionId: { [optionId]: optionValueId } }\n}\n\nfunction getProductHrefCodecOptions(\n options: ProductHrefOptions,\n): ProductSelectionCodecOptions | undefined {\n return options.emit != null ? { emit: options.emit } : undefined\n}\n\nfunction appendGroupByOptionIdHrefParams(\n params: URLSearchParams,\n group: ProductHrefGroup | null | undefined,\n groupSelection: ProductSelectionInput,\n options: ProductHrefOptions,\n): boolean {\n const emit = resolveProductSelectionUrlEmit(options.emit)\n const byOptionId = groupSelection.byOptionId ?? {}\n const entries = Object.entries(byOptionId)\n if (entries.length === 0) return false\n\n for (const [optionId, valueId] of entries) {\n const optionSlug =\n group?.optionSlug ??\n options.matrix?.optionById.get(optionId)?.slug ??\n null\n const valueSlug =\n group?.optionValueSlug ??\n options.matrix?.valueById.get(String(valueId))?.slug ??\n null\n\n if (\n emit === 'slug-compat' &&\n optionSlug &&\n valueSlug &&\n entries.length === 1\n ) {\n params.set(`opt.${optionSlug}`, valueSlug)\n return true\n }\n\n if (\n emit === 'slug-compat' &&\n options.matrix &&\n appendSlugCompatSelectionParam(\n params,\n options.matrix,\n optionId,\n String(valueId),\n )\n ) {\n continue\n }\n appendCanonicalSelectionParam(params, optionId, String(valueId))\n }\n\n return params.size > 0\n}\n\nfunction getPreferCompleteVariantFromHintSelection(\n group: ProductHrefGroup | null | undefined,\n options: ProductHrefOptions,\n): ProductSelectionInput | null {\n if (!options.preferCompleteVariantFromHint) return null\n if (group?.optionValueId != null || group?.optionValueSlug) return null\n\n const hintVariantId = group?.listing?.selectionHintVariant\n if (hintVariantId == null) return null\n\n return { variantId: hintVariantId }\n}\n\nexport function buildProductHref(\n product: ProductHrefProduct,\n group?: ProductHrefGroup | null,\n options: ProductHrefOptions = {},\n): string {\n const path = joinProductPath(\n options.basePath ?? '/products',\n getProductHrefSlug(product),\n options.trailingSlash ?? false,\n )\n const params = new URLSearchParams()\n\n if (options.detail && options.selection) {\n const selection = stringifyProductSelection(\n options.detail,\n options.selection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n\n const preferVariantSelection = getPreferCompleteVariantFromHintSelection(\n group,\n options,\n )\n if (preferVariantSelection) {\n if (options.detail) {\n const selection = stringifyProductSelection(\n options.detail,\n preferVariantSelection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n if (preferVariantSelection.variantId != null) {\n params.set('variant', String(preferVariantSelection.variantId))\n return `${path}?${params.toString()}`\n }\n }\n\n const groupSelection = getProductHrefGroupSelection(group, options.matrix)\n if (groupSelection) {\n if (options.detail) {\n const selection = stringifyProductSelection(\n options.detail,\n groupSelection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n if (groupSelection.variantId != null) {\n params.set('variant', String(groupSelection.variantId))\n return `${path}?${params.toString()}`\n }\n if (\n appendGroupByOptionIdHrefParams(params, group, groupSelection, options)\n ) {\n return `${path}?${params.toString()}`\n }\n }\n\n if (group?.optionValueSlug) {\n const optionSlug =\n group.optionSlug ??\n (group.optionId != null\n ? options.matrix?.optionById.get(String(group.optionId))?.slug\n : undefined)\n if (optionSlug) {\n params.set(`opt.${optionSlug}`, group.optionValueSlug)\n }\n }\n\n return params.size > 0 ? `${path}?${params.toString()}` : path\n}\n\n/**\n * Variant order: Payload orderable `_order` values are fractional-indexing\n * keys (`a0`, `a1`, …) ordered by code unit, which matches the Admin Panel\n * order for current-format `[0-9a-z]` keys (legacy upper-case keys may differ\n * from the database collation). Variants without a key (null, or the empty\n * string that Payload never writes) intentionally sort after keyed ones, and\n * ties fall back to the id. Must stay identical to the\n * Console projection's `compareVariantOrder` (`productProjection.ts`) so\n * listing hints and the stored `selectedOrFirstAvailableVariant` agree.\n */\nfunction compareVariantOrder(a: ProductVariantShape, b: ProductVariantShape) {\n const aOrder = a._order || null\n const bOrder = b._order || null\n\n if (aOrder !== bOrder) {\n if (aOrder === null) return 1\n if (bOrder === null) return -1\n const byOrder = compareOrdinal(aOrder, bOrder)\n if (byOrder !== 0) return byOrder\n }\n\n const aId = String(getRelationID(a.id) ?? '')\n const bId = String(getRelationID(b.id) ?? '')\n return compareOrdinal(aId, bId)\n}\n\n/**\n * Server-equivalent sellability for a single variant: active, and either\n * unlimited or with positive sellable stock (`stock - reservedStock`). This is\n * the same rule the SDK applies when rolling availability up to the product, so\n * storefronts can compute a Shopify-style `availableForSale` without\n * re-implementing the check or shipping raw `stock`/`reservedStock` to the\n * browser.\n */\nexport function getVariantAvailableForSale(\n variant: ProductVariantShape,\n): boolean {\n if (variant.isActive === false) return false\n if (typeof variant.availableForSale === 'boolean') {\n return variant.availableForSale\n }\n if (variant.isUnlimited) return true\n // `continue` (Shopify backorder) stays purchasable past available stock.\n if (variant.inventoryPolicy === 'continue') return true\n return (variant.stock ?? 0) - (variant.reservedStock ?? 0) > 0\n}\n\n/**\n * Sellable quantity for a single variant (`stock - reservedStock`, clamped at\n * zero), or `null` when the variant is unlimited and has no finite quantity.\n * Mirrors Shopify's `ProductVariant.quantityAvailable` (a single computed\n * number, never the raw stock/reserved breakdown).\n */\nexport function getVariantAvailableStock(\n variant: ProductVariantShape,\n): number | null {\n if (variant.isUnlimited) return null\n return Math.max(0, (variant.stock ?? 0) - (variant.reservedStock ?? 0))\n}\n\nfunction isVariantAvailableForSale(variant: ProductVariantShape) {\n return getVariantAvailableForSale(variant)\n}\n\nfunction sortVariantsForMediaSelection(\n variants: ProductVariantShape[],\n): ProductVariantShape[] {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n const activeVariants = orderedVariants.filter(\n (variant) => variant.isActive !== false,\n )\n const availableVariants = activeVariants.filter(isVariantAvailableForSale)\n const unavailableActiveVariants = activeVariants.filter(\n (variant) => !isVariantAvailableForSale(variant),\n )\n\n return [...availableVariants, ...unavailableActiveVariants]\n}\n\nfunction variantHasPoolMedia(\n variant: ProductVariantShape | null,\n productMediaPool: MediaValue[],\n): boolean {\n if (!variant?.images?.length) return false\n return variant.images.some((image) => {\n const imageId = getRelationID(image)\n return Boolean(\n imageId &&\n productMediaPool.some((poolItem) => getRelationID(poolItem) === imageId),\n )\n })\n}\n\nfunction getMinMax(values: Array<number | null | undefined>) {\n const numbers = values.filter(\n (value): value is number => typeof value === 'number',\n )\n if (numbers.length === 0) {\n return { min: null, max: null }\n }\n\n return {\n min: Math.min(...numbers),\n max: Math.max(...numbers),\n }\n}\n\nexport function buildProductListingGroupProjection(\n product: ProductListingProductShape | null | undefined,\n variants: ProductVariantShape[],\n): ProductListingGroupProjection {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n const activeVariants = orderedVariants.filter(\n (variant) => variant.isActive !== false,\n )\n const availableVariants = activeVariants.filter(isVariantAvailableForSale)\n const selectionHintVariant = availableVariants[0] ?? activeVariants[0] ?? null\n\n const { min: minPrice, max: maxPrice } = getMinMax(\n activeVariants.map((variant) => variant.price),\n )\n const { min: minCompareAtPrice, max: maxCompareAtPrice } = getMinMax(\n activeVariants.map((variant) => variant.compareAtPrice),\n )\n\n const productMediaPool = product?.images ?? []\n const selectionHintHasPoolMedia = variantHasPoolMedia(\n selectionHintVariant,\n productMediaPool,\n )\n const mediaSelectionVariants = sortVariantsForMediaSelection(variants)\n const resolvedProductMedia = resolveProductSelectionMedia<MediaValue>({\n productMediaPool,\n selectedVariant:\n selectionHintVariant && selectionHintHasPoolMedia\n ? {\n id: selectionHintVariant.id,\n images: selectionHintVariant.images,\n }\n : null,\n matchingVariants: selectionHintHasPoolMedia ? [] : mediaSelectionVariants,\n })\n\n return {\n selectionHintVariant: getRelationID(selectionHintVariant?.id) ?? null,\n primaryImage: resolveGenericListingPrimaryImage(\n product,\n resolvedProductMedia.primaryImage,\n resolvedProductMedia.source,\n ),\n minPrice,\n maxPrice,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange:\n minPrice !== null && maxPrice !== null ? minPrice !== maxPrice : false,\n availableForSale: availableVariants.length > 0,\n }\n}\n\nexport function buildProductListingCard(\n item: ProductListingCardSourceItem,\n options: ProductListingCardOptions = {},\n): ProductListingCard {\n const product = item.product\n const groups = item.groups\n const variants = getProductListingCardVariants(item)\n const projectedListing = buildProductListingGroupProjection(product, variants)\n const selectionHintVariant =\n getRelationID(product.selectedOrFirstAvailableVariant) ??\n projectedListing.selectionHintVariant\n const representativeVariant = findListingCardRepresentativeVariant(\n variants,\n selectionHintVariant,\n )\n\n const productMediaPool = mediaArray(product.images)\n // Resolve featuredImage against the product media pool first so a bare-id\n // pointer becomes the populated media object (a card's primaryImage must be\n // consumable as media, not a dangling pointer). Falls back to the raw\n // featuredImage when it is not a pool member (e.g. a populated variant image).\n const featuredImageId = getRelationID(product.featuredImage)\n const featuredImageFromPool = featuredImageId\n ? productMediaPool.find((item) => getRelationID(item) === featuredImageId)\n : undefined\n const listingPrimaryMedia =\n featuredImageFromPool ??\n product.featuredImage ??\n productMediaPool[0] ??\n null\n\n const priceRange = resolveListingCardPriceRange(\n product,\n projectedListing,\n groups,\n )\n\n const availableForSale =\n product.availableForSale != null\n ? product.availableForSale\n : groups.length > 0\n ? groups.some((group) => group.listing.availableForSale)\n : projectedListing.availableForSale\n\n const swatches: ProductListingSwatch[] =\n groups.length > 1\n ? groups.map((group) => buildListingSwatch(product, group, options))\n : []\n\n return {\n id: String(product.id),\n href: buildProductHref(\n { slug: product.slug },\n { listing: { selectionHintVariant } },\n options,\n ),\n title: product.title ?? '',\n representativeVariant,\n primaryImage: listingPrimaryMedia,\n priceRange,\n availableForSale,\n swatches,\n }\n}\n\nfunction getProductListingCardVariants(\n item: ProductListingCardSourceItem,\n): ProductListingCardRepresentativeVariant[] {\n const productVariants = item.product.variants?.docs\n if (Array.isArray(productVariants) && productVariants.length > 0) {\n return productVariants\n }\n\n const variants: ProductListingCardRepresentativeVariant[] = []\n const seen = new Set<string>()\n\n for (const group of item.groups) {\n for (const variant of group.variants) {\n const id = getRelationID(variant.id)\n if (id && seen.has(id)) continue\n if (id) seen.add(id)\n variants.push(variant)\n }\n }\n\n return variants\n}\n\nfunction findListingCardRepresentativeVariant(\n variants: ProductListingCardRepresentativeVariant[],\n representativeVariantId: EntityID | null,\n): ProductListingCardRepresentativeVariant | null {\n if (representativeVariantId == null) return null\n return (\n variants.find(\n (variant) => getRelationID(variant.id) === representativeVariantId,\n ) ?? null\n )\n}\n\n/** Shopify `priceRangeV2` naming for persisted listing projection fields. */\nexport function toShopifyPriceRangeV2(listing: {\n minPrice?: number | null\n maxPrice?: number | null\n}): {\n minVariantPrice: { amount: number | null }\n maxVariantPrice: { amount: number | null }\n} {\n return {\n minVariantPrice: { amount: listing.minPrice ?? null },\n maxVariantPrice: { amount: listing.maxPrice ?? null },\n }\n}\n\nfunction hasCompleteProductPriceRange(\n priceRange: ProductListingCardSourceItem['product']['priceRange'],\n): priceRange is NonNullable<\n ProductListingCardSourceItem['product']['priceRange']\n> & {\n minVariantPrice: { amount: number }\n maxVariantPrice: { amount: number }\n} {\n return (\n priceRange?.minVariantPrice?.amount != null &&\n priceRange?.maxVariantPrice?.amount != null\n )\n}\n\nfunction resolveListingCardPriceRange(\n product: ProductListingCardSourceItem['product'],\n projectedListing: ReturnType<typeof buildProductListingGroupProjection>,\n groups: ProductListingCardSourceItem['groups'],\n): ProductListingCardPriceRange {\n if (hasCompleteProductPriceRange(product.priceRange)) {\n const groupRange =\n groups.length > 0 ? aggregateListingPriceRange(groups) : null\n const minCompareAtPrice =\n product.compareAtPriceRange?.minVariantPrice?.amount ??\n groupRange?.minCompareAtPrice ??\n null\n const maxCompareAtPrice =\n product.compareAtPriceRange?.maxVariantPrice?.amount ??\n groupRange?.maxCompareAtPrice ??\n null\n\n return {\n minPrice: product.priceRange.minVariantPrice.amount,\n maxPrice: product.priceRange.maxVariantPrice.amount,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange:\n product.priceRange.isPriceRange ??\n product.priceRange.minVariantPrice.amount !==\n product.priceRange.maxVariantPrice.amount,\n }\n }\n\n if (groups.length > 0) {\n return aggregateListingPriceRange(groups)\n }\n\n return {\n minPrice: projectedListing.minPrice,\n maxPrice: projectedListing.maxPrice,\n minCompareAtPrice: projectedListing.minCompareAtPrice,\n maxCompareAtPrice: projectedListing.maxCompareAtPrice,\n isPriceRange: projectedListing.isPriceRange,\n }\n}\n\nfunction aggregateListingPriceRange(\n groups: ProductListingCardSourceItem['groups'],\n): ProductListingCardPriceRange {\n const minPrice = minOfNullable(groups.map((g) => g.listing.minPrice))\n const maxPrice = maxOfNullable(groups.map((g) => g.listing.maxPrice))\n const minCompareAtPrice = minOfNullable(\n groups.map((g) => g.listing.minCompareAtPrice),\n )\n const maxCompareAtPrice = maxOfNullable(\n groups.map((g) => g.listing.maxCompareAtPrice),\n )\n const isPriceRange =\n minPrice !== null && maxPrice !== null && minPrice !== maxPrice\n return {\n minPrice,\n maxPrice,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange,\n }\n}\n\nfunction buildListingSwatch(\n product: ProductListingCardSourceItem['product'],\n group: ProductListingCardSourceItem['groups'][number],\n options: ProductListingCardOptions,\n): ProductListingSwatch {\n return {\n optionId: group.optionId,\n optionValueId: group.optionValueId,\n label: group.optionValueLabel,\n swatch: group.optionValueSwatch ?? null,\n href: buildProductHref(\n { slug: product.slug },\n {\n optionId: group.optionId,\n optionSlug: group.optionSlug,\n optionValueId: group.optionValueId,\n optionValueSlug: group.optionValueSlug,\n listing: group.listing,\n },\n options,\n ),\n availableForSale: group.listing.availableForSale,\n }\n}\n\nfunction minOfNullable(values: Array<number | null>): number | null {\n const numbers = values.filter((v): v is number => v !== null)\n return numbers.length === 0 ? null : Math.min(...numbers)\n}\n\nfunction maxOfNullable(values: Array<number | null>): number | null {\n const numbers = values.filter((v): v is number => v !== null)\n return numbers.length === 0 ? null : Math.max(...numbers)\n}\n\n/**\n * Server-side PLP query preset for raw `products` collection reads.\n *\n * Greenfield storefronts should prefer\n * `client.commerce.product.listingPage()` because it calls the shaped catalog\n * endpoint, preserves pagination metadata, returns card-ready `cards`, and\n * avoids exposing inventory quantities.\n *\n * This preset remains only for server-auth raw product query code\n * that deliberately understands Payload join behavior. It raises top-level\n * `products.options` and `products.variants` join limits, but it cannot fix\n * nested `options[].values.docs` joins because the Payload REST `joins` param\n * is flat.\n *\n * It is not accepted by publishable\n * `createClient().collections.from('products').find()` because browser-public\n * raw reads are constrained to `depth: 0`, `joins: false`, and no `populate`.\n */\nexport const PRODUCT_PLP_FIND_OPTIONS: ApiQueryOptions = {\n joins: {\n variants: { limit: 200, sort: '_order' },\n options: { limit: 50, sort: '_order' },\n },\n}\n\n/**\n * Adapts a raw Payload product document (from\n * `collections.from('products').find()`) into the listing shape the SDK\n * listing builders consume. A raw product already carries `priceRange`,\n * `compareAtPriceRange`, `availableForSale`, and `selectedOrFirstAvailableVariant`,\n * but it has no `featuredImage` field — only the `images` gallery. This pure,\n * non-lossy adapter fills `featuredImage` from the first non-null gallery image\n * (when not already set) so SSG/sitemap consumers on the raw `find()` escape\n * hatch can feed `buildProductListingGroupsByOption` / `buildProductListingCard`\n * without hand-rolling the projection. An explicit `featuredImage` is preserved.\n */\nexport function projectProductToListingShape<\n T extends ProductListingProductShape,\n>(product: T): T & { featuredImage: MediaValue } {\n const featuredImage =\n product.featuredImage != null\n ? product.featuredImage\n : product.images?.find((image) => image != null)\n // Always return a fresh shallow copy so reference semantics are uniform\n // regardless of whether featuredImage was synthesized.\n return { ...product, featuredImage }\n}\n\n/**\n * Builds product-first listing groups for one primary option.\n *\n * The returned groups are intended for product cards with nested swatches or\n * option-value sections. They do not make a product-paginated API response into\n * an expanded-card paginator; one product can still emit several groups.\n */\nexport function buildProductListingGroupsByOption<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(args: {\n product: ProductListingProductShape | null | undefined\n options: ProductOptionShape[]\n variants: TVariant[]\n primaryOptionId?: string | null\n}): ProductListingGroup<TVariant>[] {\n const primaryOptionId = args.primaryOptionId ?? undefined\n if (!primaryOptionId) return []\n\n const matrix = buildProductOptionMatrix({\n options: args.options,\n variants: args.variants,\n })\n const primaryOption = matrix.optionById.get(primaryOptionId)\n if (!primaryOption) return []\n\n return primaryOption.values.flatMap((value) => {\n const variants = matrix.variants\n .filter(\n (variant) =>\n variant.optionValueByOptionId.get(primaryOption.id) === value.id,\n )\n .map((variant) => variant.source)\n\n if (variants.length === 0) {\n return []\n }\n\n const listingBase = buildProductListingGroupProjection(undefined, variants)\n const normalizedSwatch = normalizeMatrixSwatch(value.swatch)\n const swatchMediaId =\n normalizedSwatch?.mediaItemId == null\n ? null\n : String(normalizedSwatch.mediaItemId)\n const groupPrimaryImage =\n inProductMediaPool(args.product, swatchMediaId) ??\n inProductMediaPool(\n args.product,\n getFirstAvailableVariantPrimaryImage(variants),\n ) ??\n getFirstMediaId(args.product?.images)\n\n return [\n {\n optionId: primaryOption.id,\n optionTitle: primaryOption.title,\n optionSlug: primaryOption.slug,\n optionValueId: value.id,\n optionValueLabel: value.label,\n optionValueSlug: value.slug,\n optionValueSwatch: value.swatch ?? null,\n variantIds: variants.map((variant) => String(variant.id)),\n variantCount: variants.length,\n variants,\n listing: {\n ...listingBase,\n primaryImage: groupPrimaryImage,\n },\n },\n ]\n })\n}\n","import { BaseApi, type ServerApiOptions } from './base-api'\nimport { COMMERCE_ENDPOINT_OPERATIONS } from './endpoints'\nimport {\n createValidationError,\n getSDKErrorReason,\n SDKError,\n} from '../internal/errors'\nimport {\n listingGroupsSearchParams,\n listingPageSearchParams,\n productDetailSearchParams,\n stockSnapshotSearchParams,\n} from '../internal/utils/query-string'\nimport type {\n ProductListingCard,\n ProductListingCardOptions,\n ProductListingGroup,\n ProductVariantShape,\n} from '../../utils/ecommerce'\nimport { buildProductListingCard } from '../../utils/ecommerce'\nimport type { PublicProduct } from '../collection/types'\nimport type { PayloadFindResponse } from '../client/types'\nimport type { ProductUpsertInput } from './product-upsert-contract'\n\nexport type ProductApiOptions = ServerApiOptions\n\nexport type StockCheckParams = {\n items: Array<{\n variantId: string\n quantity: number\n }>\n}\n\nexport type StockCheckResult = {\n variantId: string\n status: 'available' | 'not_published' | 'archived' | 'not_found'\n available: boolean\n availableStock: number\n isUnlimited: boolean\n requestedQuantity: number\n error?: string\n}\n\nexport type StockCheckResponse = {\n results: StockCheckResult[]\n allAvailable: boolean\n}\n\nexport type ListingGroupsParams = {\n productIds: string[]\n market?: string\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n}\n\nexport type ProductListingGroupVariant = Pick<\n ProductVariantShape,\n | 'id'\n | 'optionValues'\n | 'price'\n | 'compareAtPrice'\n | 'resolvedPrice'\n | 'stock'\n | 'isUnlimited'\n | 'inventoryPolicy'\n | 'isActive'\n | 'thumbnail'\n | 'images'\n | '_order'\n>\n\nexport type ProductListingGroupSummary =\n ProductListingGroup<ProductListingGroupVariant>\nexport type ProductListingGroupCatalogVariant = Omit<\n ProductListingGroupVariant,\n 'stock'\n>\nexport type ProductListingGroupCatalogSummary =\n ProductListingGroup<ProductListingGroupCatalogVariant>\n\ntype ProductListingGroupsProductVariants = NonNullable<\n PublicProduct['variants']\n>\ntype ProductListingGroupsProductSeo = Omit<\n NonNullable<PublicProduct['seo']>,\n 'title' | 'description' | 'openGraph'\n> & {\n title?: ProductLocalizedText | null\n description?: ProductLocalizedText | null\n openGraph?: Omit<\n NonNullable<NonNullable<PublicProduct['seo']>['openGraph']>,\n 'title' | 'description'\n > & {\n title?: ProductLocalizedText | null\n description?: ProductLocalizedText | null\n }\n}\nexport type ProductListingGroupsProduct = Omit<\n PublicProduct,\n | 'content'\n | 'createdAt'\n | 'description'\n | 'seo'\n | 'subtitle'\n | 'title'\n | 'updatedAt'\n | 'variants'\n> & {\n id: string\n slug: string\n title: ProductLocalizedText\n subtitle?: ProductLocalizedText | null\n description?: ProductLocalizedText | null\n content?: ProductLocalizedValue<NonNullable<PublicProduct['content']>> | null\n seo?: ProductListingGroupsProductSeo\n createdAt?: PublicProduct['createdAt']\n updatedAt?: PublicProduct['updatedAt']\n featuredImage?: ProductDetailMedia | null\n priceRange?: ProductPriceRange\n compareAtPriceRange?: ProductMoneyRange\n availableForSale?: boolean | null\n selectedOrFirstAvailableVariant?:\n | ProductListingGroupVariant\n | string\n | number\n | null\n variants?:\n | (Omit<ProductListingGroupsProductVariants, 'docs'> & {\n docs: ProductListingGroupVariant[]\n })\n | null\n}\n\nexport type ProductListingGroupsCatalogProduct = {\n id: string\n slug: string\n handle?: string | null\n title: ProductLocalizedText\n subtitle?: ProductListingGroupsProduct['subtitle']\n images?: ProductListingGroupsProduct['images']\n featuredImage?: ProductDetailMedia | null\n priceRange?: ProductPriceRange\n compareAtPriceRange?: ProductMoneyRange\n availableForSale?: boolean | null\n selectedOrFirstAvailableVariant?:\n | ProductListingGroupCatalogVariant\n | string\n | number\n | null\n variants?:\n | (Omit<NonNullable<ProductListingGroupsProduct['variants']>, 'docs'> & {\n docs: ProductListingGroupCatalogVariant[]\n })\n | null\n}\n\nexport type ProductListingGroupsItem = {\n product: ProductListingGroupsProduct\n groups: ProductListingGroupSummary[]\n}\nexport type ProductListingGroupsCatalogItem = {\n product: ProductListingGroupsCatalogProduct\n groups: ProductListingGroupCatalogSummary[]\n}\n\nexport type ProductListingGroupsResponse = {\n /**\n * Matching products in the same order as the requested productIds, excluding\n * ids that were not found, not published, or not accessible for the current\n * tenant/key.\n */\n docs: ProductListingGroupsItem[]\n /** Requested productIds that could not be returned. */\n missing: string[]\n}\nexport type ProductListingGroupsCatalogResponse = Omit<\n ProductListingGroupsResponse,\n 'docs'\n> & {\n docs: ProductListingGroupsCatalogItem[]\n}\n\nexport type ProductListingPageSort =\n | 'id'\n | '-id'\n | 'slug'\n | '-slug'\n | 'handle'\n | '-handle'\n | 'createdAt'\n | '-createdAt'\n | 'updatedAt'\n | '-updatedAt'\n | 'title'\n | '-title'\n | 'priceRange.minVariantPrice.amount'\n | '-priceRange.minVariantPrice.amount'\n | 'priceRange.maxVariantPrice.amount'\n | '-priceRange.maxVariantPrice.amount'\n | 'availableForSale'\n | '-availableForSale'\n\nexport type ProductListingPageFilters = {\n ids?: string[]\n slugs?: string[]\n handles?: string[]\n categoryIds?: string[]\n tagIds?: string[]\n price?: {\n min?: number\n max?: number\n }\n availableForSale?: boolean\n}\n\nexport type ProductListingPageBaseParams = {\n market?: string\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n page?: number\n limit?: number\n search?: string\n sort?: ProductListingPageSort | ProductListingPageSort[]\n filters?: ProductListingPageFilters\n} & ProductListingCardOptions\n\nexport type ProductListingPageCatalogParams = ProductListingPageBaseParams & {\n mode?: 'catalog'\n}\n\nexport type ProductListingPageFullParams = ProductListingPageBaseParams & {\n mode: 'full'\n}\n\nexport type ProductListingPageParams =\n | ProductListingPageCatalogParams\n | ProductListingPageFullParams\n\nexport type ProductListingPageResult<TItem> = PayloadFindResponse<TItem> & {\n cards: ProductListingCard[]\n}\n\nexport type ProductLocaleOption = 'ko' | 'en' | 'all'\nexport type ProductFallbackLocaleOption = 'ko' | 'en' | false\n\nexport type ProductLocaleReadParams = {\n locale?: ProductLocaleOption\n fallbackLocale?: ProductFallbackLocaleOption\n}\n\nexport type ProductLocalizedValue<T> =\n | T\n | {\n en?: T | null\n ko?: T | null\n }\n\nexport type ProductLocalizedText = ProductLocalizedValue<string>\n\nexport type ProductDetailParams = ({ slug: string } | { id: string }) & {\n market?: string\n} & ProductLocaleReadParams\nexport type ProductDetailPreviewParams = { id: string }\nexport type ProductDetailPreviewOptions = {\n previewToken: string\n}\n\nexport interface ProductDetailVariantOptionValue {\n optionId: string | number\n optionSlug: string\n valueId: string | number\n valueSlug: string\n value?: string | null\n}\n\nexport type ProductDetailMedia =\n | string\n | number\n | {\n id?: string | number | null\n url?: string | null\n alt?: string | null\n width?: number | null\n height?: number | null\n }\n\nexport type ProductOptionValueColorSwatch = {\n type: 'color'\n color: string\n mediaItemId?: null\n}\n\nexport type ProductOptionValueMediaSwatch<TMedia = ProductDetailMedia> = {\n type: 'media'\n mediaItemId: TMedia\n color?: null\n}\n\nexport type ProductOptionValueSwatch<TMedia = ProductDetailMedia> =\n | ProductOptionValueColorSwatch\n | ProductOptionValueMediaSwatch<TMedia>\n | null\n\nexport type ProductUpsertColorSwatchInput = {\n type: 'color'\n color: string\n mediaItemId?: null\n}\n\nexport type ProductUpsertMediaSwatchInput = {\n type: 'media'\n mediaItemId: string\n color?: null\n}\n\nexport type ProductUpsertSwatchInput =\n | ProductUpsertColorSwatchInput\n | ProductUpsertMediaSwatchInput\n\nexport type ProductDetailSelectionMediaSource =\n | 'variant_media_selected'\n | 'variant_media_matching'\n | 'option_swatch'\n | 'none'\n\nexport type ProductDetailDisplayMediaSource =\n | 'featured_image'\n | 'product_pool'\n | 'none'\n\n/** Selection + display sources returned by `resolveProductSelection()` media. */\nexport type ProductDetailMediaPointerSource =\n | ProductDetailSelectionMediaSource\n | ProductDetailDisplayMediaSource\n\nexport interface ResolvedCatalogPrice {\n amount: number\n compareAtPrice?: number | null\n currency?: string | null\n marketId?: string | null\n source?: 'fixed' | 'computed'\n}\n\nexport interface ProductDetailVariant {\n id: string | number\n optionKey: string\n title?: string | null\n displayName: string\n sku?: string | null\n price: number\n compareAtPrice?: number | null\n resolvedPrice?: ResolvedCatalogPrice\n stock: number\n reservedStock: number\n isUnlimited: boolean\n inventoryPolicy?: ('deny' | 'continue') | null\n isActive: boolean\n thumbnail?: ProductDetailMedia | null\n images?: ProductDetailMedia[]\n media?: {\n primaryImage: ProductDetailMedia | null\n images: ProductDetailMedia[]\n source: ProductDetailSelectionMediaSource\n }\n optionValues: ProductDetailVariantOptionValue[]\n}\n\nexport interface ProductDetailOptionValue {\n id: string | number\n value: string\n slug: string\n swatch?: ProductOptionValueSwatch<ProductDetailMedia>\n}\n\nexport interface ProductDetailOption {\n id: string | number\n title: string\n slug: string\n values: ProductDetailOptionValue[]\n}\n\nexport interface ProductDetailBrand {\n id: string | number\n name: string\n slug?: string | null\n logo?: unknown | null\n}\n\nexport interface ProductDetailCategory {\n id: string | number\n title: string\n slug?: string | null\n}\n\nexport interface ProductDetailTag {\n id: string | number\n title: string\n slug?: string | null\n}\n\nexport interface ProductDetailImage {\n id: string | number\n url?: string | null\n alt?: string | null\n width?: number | null\n height?: number | null\n}\n\nexport interface ProductDetailVideo {\n id: string | number\n url?: string | null\n}\n\nexport interface ProductMoneyRange {\n minVariantPrice: { amount: number | null }\n maxVariantPrice: { amount: number | null }\n}\n\nexport interface ProductPriceRange extends ProductMoneyRange {\n isPriceRange?: boolean | null\n}\n\nexport type ProductDetailCatalogVariant = Omit<\n ProductDetailVariant,\n 'stock' | 'reservedStock'\n> & {\n availableForSale?: boolean | null\n}\n\nexport interface ProductDetailCatalog {\n product: Omit<ProductDetail['product'], 'totalInventory'>\n variants: ProductDetailCatalogVariant[]\n options: ProductDetail['options']\n brand: ProductDetail['brand']\n categories: ProductDetail['categories']\n tags: ProductDetail['tags']\n images: ProductDetail['images']\n videos: ProductDetail['videos']\n featuredImage?: ProductDetail['featuredImage']\n priceRange?: ProductPriceRange\n compareAtPriceRange?: ProductMoneyRange\n availableForSale?: boolean | null\n selectedOrFirstAvailableVariant?:\n | ProductDetailCatalogVariant\n | string\n | number\n | null\n}\n\nexport type StockSnapshotItemStatus =\n | 'available'\n | 'not_published'\n | 'archived'\n | 'not_found'\n\nexport interface StockSnapshotItem {\n variantId: string\n status: StockSnapshotItemStatus\n availableStock: number\n availableForSale: boolean\n isUnlimited: boolean\n /**\n * Backorder policy for tracked variants (Shopify `inventoryPolicy`).\n * `continue` means the variant stays purchasable past available stock.\n */\n inventoryPolicy?: ('deny' | 'continue') | null\n}\n\nexport interface StockSnapshotResponse {\n snapshots: StockSnapshotItem[]\n}\n\nexport type StockSnapshotParams = {\n variantIds: string[]\n}\n\nexport interface ProductDetail {\n product: {\n id: string | number\n slug: string\n title: ProductLocalizedText\n subtitle?: ProductLocalizedText | null\n description?: ProductLocalizedText | null\n content?: unknown\n publishedAt?: string | null\n status: string\n totalInventory: number | null\n totalVariants: number\n hasUnlimitedVariant: boolean\n hasOnlyDefaultVariant: boolean\n }\n variants: ProductDetailVariant[]\n options: ProductDetailOption[]\n brand: ProductDetailBrand | null\n categories: ProductDetailCategory[]\n tags: ProductDetailTag[]\n images: ProductDetailImage[]\n videos: ProductDetailVideo[]\n /** Shopify-shaped product/card image, resolved from the first product image. */\n featuredImage?: ProductDetailMedia | null\n /** Shopify-shaped product price range derived from active variants. */\n priceRange?: ProductPriceRange\n /** Shopify-shaped compare-at price range derived from active variants. */\n compareAtPriceRange?: ProductMoneyRange\n /** Product-level sellability derived from active variants and inventory. */\n availableForSale?: boolean | null\n /** Default variant for PDP/card selection, equivalent to Shopify selectedOrFirstAvailableVariant. */\n selectedOrFirstAvailableVariant?:\n | ProductDetailVariant\n | string\n | number\n | null\n}\n\nexport type ProductDetailUnavailableReason =\n | 'not_found'\n | 'not_published'\n | 'feature_disabled'\n\nexport type ProductDetailResult =\n | { found: true; product: ProductDetail }\n | { found: false; reason: ProductDetailUnavailableReason }\n\nexport type ProductDetailCatalogResult =\n | { found: true; product: ProductDetailCatalog }\n | { found: false; reason: ProductDetailUnavailableReason }\n\nconst PRODUCT_DETAIL_UNAVAILABLE_REASONS = new Set<string>([\n 'not_found',\n 'not_published',\n 'feature_disabled',\n])\n\nexport function productDetailResultFromError(\n error: unknown,\n): ProductDetailResult | undefined {\n if (!(error instanceof SDKError) || error.status !== 404) return undefined\n\n const reason = getSDKErrorReason(error)\n if (!reason || !PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(reason))\n return undefined\n\n return { found: false, reason: reason as ProductDetailUnavailableReason }\n}\n\ntype ProductListingPageWhere = Record<string, unknown>\nconst MARKET_PRICE_QUERY_UNSUPPORTED_MESSAGE =\n 'Market listing pages do not support base price filters or price sorts.'\nconst BASE_PRICE_RANGE_SORT_FIELDS = new Set([\n 'priceRange.minVariantPrice.amount',\n 'priceRange.maxVariantPrice.amount',\n])\n\nfunction nonEmpty(values: string[] | undefined): string[] | undefined {\n return values?.length ? values : undefined\n}\n\nfunction buildProductListingPageWhere(\n params: ProductListingPageParams,\n): ProductListingPageWhere | undefined {\n const clauses: ProductListingPageWhere[] = []\n const search = params.search?.trim()\n if (search) {\n clauses.push({\n or: [{ title: { like: search } }, { slug: { like: search } }],\n })\n }\n\n const filters = params.filters\n const ids = nonEmpty(filters?.ids)\n if (ids) clauses.push({ id: { in: ids } })\n const slugs = nonEmpty(filters?.slugs)\n if (slugs) clauses.push({ slug: { in: slugs } })\n const handles = nonEmpty(filters?.handles)\n if (handles) clauses.push({ handle: { in: handles } })\n const categoryIds = nonEmpty(filters?.categoryIds)\n if (categoryIds) clauses.push({ categories: { in: categoryIds } })\n const tagIds = nonEmpty(filters?.tagIds)\n if (tagIds) clauses.push({ tags: { in: tagIds } })\n\n const minPrice = filters?.price?.min\n if (minPrice != null) {\n clauses.push({\n 'priceRange.maxVariantPrice.amount': { greater_than_equal: minPrice },\n })\n }\n const maxPrice = filters?.price?.max\n if (maxPrice != null) {\n clauses.push({\n 'priceRange.minVariantPrice.amount': { less_than_equal: maxPrice },\n })\n }\n\n if (filters?.availableForSale != null) {\n clauses.push({\n availableForSale: { equals: filters.availableForSale },\n })\n }\n\n if (clauses.length === 0) return undefined\n if (clauses.length === 1) return clauses[0]\n return { and: clauses }\n}\n\nfunction productListingPageUsesBasePriceSort(\n sort: ProductListingPageParams['sort'],\n): boolean {\n const values = Array.isArray(sort) ? sort : sort ? [sort] : []\n return values.some((value) =>\n BASE_PRICE_RANGE_SORT_FIELDS.has(String(value).replace(/^-/, '')),\n )\n}\n\nfunction assertMarketListingPageQuerySupported(\n params: ProductListingPageParams,\n): void {\n if (!params.market?.trim()) return\n const priceFilter = params.filters?.price\n if (\n priceFilter?.min != null ||\n priceFilter?.max != null ||\n productListingPageUsesBasePriceSort(params.sort)\n ) {\n throw new TypeError(MARKET_PRICE_QUERY_UNSUPPORTED_MESSAGE)\n }\n}\n\nexport function buildProductListingPageRequest(\n params: ProductListingPageParams,\n): {\n operation:\n | typeof COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryGet\n | typeof COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryCatalog\n query: string\n} {\n assertMarketListingPageQuerySupported(params)\n const options = {\n market: params.market,\n locale: params.locale,\n fallbackLocale: params.fallbackLocale,\n page: params.page,\n limit: params.limit,\n sort: params.sort,\n where: buildProductListingPageWhere(params),\n }\n\n return {\n operation:\n params.mode === 'full'\n ? COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryGet\n : COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryCatalog,\n query: listingPageSearchParams(options),\n }\n}\n\nexport function withProductListingCards<\n TItem extends ProductListingGroupsCatalogItem,\n>(\n response: PayloadFindResponse<TItem>,\n options: ProductListingCardOptions,\n): ProductListingPageResult<TItem>\nexport function withProductListingCards<TItem extends ProductListingGroupsItem>(\n response: PayloadFindResponse<TItem>,\n options: ProductListingCardOptions,\n): ProductListingPageResult<TItem>\nexport function withProductListingCards<\n TItem extends ProductListingGroupsCatalogItem | ProductListingGroupsItem,\n>(\n response: PayloadFindResponse<TItem>,\n options: ProductListingCardOptions,\n): ProductListingPageResult<TItem> {\n return {\n ...response,\n cards: response.docs.map((item) => buildProductListingCard(item, options)),\n }\n}\n\nexport type ProductUpsertOptionSwatchInput = ProductUpsertSwatchInput\n\nexport type ProductUpsertOptionValueInput = {\n id?: string\n value: string\n slug?: string\n swatch?: ProductUpsertSwatchInput | null\n metadata?: unknown\n}\n\nexport type ProductUpsertOptionValuePayload = ProductUpsertOptionValueInput\n\nfunction rejectLegacyOptionValueSwatchColor(\n value: ProductUpsertOptionValueInput,\n): void {\n if (\n Object.prototype.hasOwnProperty.call(\n value as Record<string, unknown>,\n 'swatchColor',\n )\n ) {\n throw new TypeError(\n 'Product upsert option values no longer accept removed flat \"swatchColor\"; use nested \"swatch\" instead.',\n )\n }\n}\n\nfunction normalizeProductUpsertOptionValue(\n value: ProductUpsertOptionValueInput,\n): ProductUpsertOptionValuePayload {\n rejectLegacyOptionValueSwatchColor(value)\n return value\n}\n\nfunction normalizeProductUpsertParams(\n params: ProductUpsertParams,\n): ProductUpsertInput {\n const options = params.options ?? []\n const variants = params.variants ?? []\n if (!options.length) {\n return { ...params, options, variants } as ProductUpsertInput\n }\n return {\n ...params,\n options: options.map((option) => ({\n ...option,\n values: option.values.map((value) =>\n normalizeProductUpsertOptionValue(value),\n ),\n })),\n variants,\n } as ProductUpsertInput\n}\n\nexport type ProductUpsertOptionInput = {\n id?: string\n title: string\n slug?: string\n values: ProductUpsertOptionValueInput[]\n}\n\nexport type ProductUpsertVariantOptionValue =\n | string\n | {\n valueSlug?: string\n valueId?: string\n value?: string\n }\n\nexport type ProductUpsertVariantInput = {\n id?: string\n optionValues?: Record<string, ProductUpsertVariantOptionValue> | string[]\n sku?: string | null\n title?: string | null\n price: number\n compareAtPrice?: number | null\n stock?: number\n isUnlimited?: boolean\n inventoryPolicy?: 'deny' | 'continue'\n weight?: number | null\n requiresShipping?: boolean\n barcode?: string | null\n externalId?: string | null\n isActive?: boolean\n images?: string[]\n marketPrices?: Array<{\n market: string\n price: number\n compareAtPrice?: number | null\n }>\n metadata?: unknown\n}\n\nexport type ProductUpsertParams = ProductUpsertInput\n\n/** Console `POST /api/products/upsert` field allowlist error reasons. */\nexport const PRODUCT_UPSERT_UNKNOWN_FIELD_REASON = 'unknown_field' as const\nexport const PRODUCT_UPSERT_READONLY_FIELD_REASON =\n 'product_field_readonly' as const\nexport const PRODUCT_GRAPH_CONFLICT_REASON = 'graph_conflict' as const\nexport const PRODUCT_GRAPH_REVISION_REQUIRED_REASON =\n 'graph_revision_required' as const\n\nexport type ProductUpsertFieldValidationErrorReason =\n | typeof PRODUCT_UPSERT_UNKNOWN_FIELD_REASON\n | typeof PRODUCT_UPSERT_READONLY_FIELD_REASON\n\n/** 400 response body when upsert rejects unknown or server-managed product fields. */\nexport type ProductUpsertFieldValidationErrorBody = {\n error: string\n reason: ProductUpsertFieldValidationErrorReason\n field: string\n requestId?: string\n}\n\nexport function isProductUpsertFieldValidationErrorBody(\n value: unknown,\n): value is ProductUpsertFieldValidationErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n const reason = body.reason\n return (\n typeof body.error === 'string' &&\n typeof body.field === 'string' &&\n (reason === PRODUCT_UPSERT_UNKNOWN_FIELD_REASON ||\n reason === PRODUCT_UPSERT_READONLY_FIELD_REASON)\n )\n}\n\nexport type ProductUpsertGraphConflictErrorBody = {\n error: string\n reason: typeof PRODUCT_GRAPH_CONFLICT_REASON\n currentGraphRevision: string\n currentGraphUpdatedAt: string\n requestId?: string\n}\n\nexport function isProductUpsertGraphConflictErrorBody(\n value: unknown,\n): value is ProductUpsertGraphConflictErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n return (\n typeof body.error === 'string' &&\n body.reason === PRODUCT_GRAPH_CONFLICT_REASON &&\n typeof body.currentGraphRevision === 'string' &&\n typeof body.currentGraphUpdatedAt === 'string'\n )\n}\n\nexport type ProductUpsertGraphRevisionRequiredErrorBody = {\n error: string\n reason: typeof PRODUCT_GRAPH_REVISION_REQUIRED_REASON\n requestId?: string\n}\n\nexport function isProductUpsertGraphRevisionRequiredErrorBody(\n value: unknown,\n): value is ProductUpsertGraphRevisionRequiredErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n return (\n typeof body.error === 'string' &&\n body.reason === PRODUCT_GRAPH_REVISION_REQUIRED_REASON\n )\n}\n\nexport type ProductUpsertResponse =\n | { ok: true; product: PublicProduct; productProjectionStale: boolean }\n | {\n ok: false\n failedEntity: 'product' | 'option' | 'option-value' | 'variant'\n failedIndex?: number\n message: string\n }\n\nexport type ProductGraphRevisionParams = {\n productId: string\n locale?: 'ko' | 'en'\n}\n\nexport type ProductGraphRevisionResponse = {\n productId: string\n graphRevision: string\n}\n\nexport type VariantPricesUpdateInput = {\n graphRevision: string\n updates: Array<{ id: string; price: number }>\n}\n\nexport type VariantPricesUpdateParams = ProductGraphRevisionParams &\n VariantPricesUpdateInput\n\nexport type VariantPricesUpdateResponse = {\n ok: true\n productId: string\n updated: number\n deleted: number\n productProjectionStale: boolean\n}\n\nfunction assertPriceOperationObject(\n value: unknown,\n allowed: readonly string[],\n): asserts value is Record<string, unknown> {\n if (\n !value ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n Object.keys(value).some((key) => !allowed.includes(key))\n ) {\n throw createValidationError(\n 'Product price operations accept only their declared fields.',\n )\n }\n}\n\nfunction productGraphQuery(\n params: ProductGraphRevisionParams,\n): URLSearchParams {\n if (\n typeof params.productId !== 'string' ||\n !params.productId.trim() ||\n (params.locale !== undefined &&\n params.locale !== 'ko' &&\n params.locale !== 'en')\n ) {\n throw createValidationError(\n 'Provide a productId and, when specified, a ko or en content locale.',\n )\n }\n return new URLSearchParams(\n params.locale ? { locale: params.locale } : undefined,\n )\n}\n\nexport class ProductApi extends BaseApi {\n constructor(options: ProductApiOptions) {\n super('ProductApi', options)\n }\n\n /** Read a baseline before reviewing values in the same content locale. */\n async graphRevision(\n params: ProductGraphRevisionParams,\n ): Promise<ProductGraphRevisionResponse> {\n assertPriceOperationObject(params, ['productId', 'locale'])\n return this.requestEndpoint<ProductGraphRevisionResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.graphRevision,\n undefined,\n {\n pathParams: { id: params.productId },\n query: productGraphQuery(params),\n },\n )\n }\n\n /** Update existing base prices only; conflicts never trigger a rebase or full upsert. */\n async updateVariantPrices(\n params: VariantPricesUpdateParams,\n ): Promise<VariantPricesUpdateResponse> {\n assertPriceOperationObject(params, [\n 'productId',\n 'locale',\n 'graphRevision',\n 'updates',\n ])\n const query = productGraphQuery(params)\n if (\n typeof params.graphRevision !== 'string' ||\n !params.graphRevision.length ||\n !Array.isArray(params.updates) ||\n params.updates.length < 1 ||\n params.updates.length > 250\n ) {\n throw createValidationError(\n 'Provide graphRevision and between 1 and 250 price updates.',\n )\n }\n const updates = params.updates.map((row) => {\n assertPriceOperationObject(row, ['id', 'price'])\n if (\n typeof row.id !== 'string' ||\n !row.id.trim() ||\n typeof row.price !== 'number' ||\n !Number.isFinite(row.price)\n ) {\n throw createValidationError(\n 'Each price update requires an existing variant id and numeric price.',\n )\n }\n // Amount/currency validation remains server-owned. Never forward other fields.\n return { id: row.id, price: row.price }\n })\n return this.requestEndpoint<VariantPricesUpdateResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.variantsPatch,\n { graphRevision: params.graphRevision, updates },\n { pathParams: { id: params.productId }, query },\n )\n }\n\n /**\n * Check point-in-time stock availability for one or more product variants.\n * Results reflect available stock at the moment of the call and are not guaranteed\n * to remain available by the time an order is placed.\n */\n stockCheck(params: StockCheckParams): Promise<StockCheckResponse> {\n return this.requestEndpoint<StockCheckResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockCheck,\n params,\n )\n }\n\n stockSnapshot(params: StockSnapshotParams): Promise<StockSnapshotResponse> {\n return this.requestEndpoint<StockSnapshotResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockSnapshot,\n undefined,\n { query: stockSnapshotSearchParams(params) },\n )\n }\n\n listingGroups(\n params: ListingGroupsParams,\n ): Promise<ProductListingGroupsResponse> {\n return this.requestEndpoint<ProductListingGroupsResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroups,\n undefined,\n { query: listingGroupsSearchParams(params) },\n )\n }\n\n listingGroupsCatalog(\n params: ListingGroupsParams,\n ): Promise<ProductListingGroupsCatalogResponse> {\n return this.requestEndpoint<ProductListingGroupsCatalogResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,\n undefined,\n { query: listingGroupsSearchParams(params) },\n )\n }\n\n async listingPage(\n params?: ProductListingPageCatalogParams,\n ): Promise<ProductListingPageResult<ProductListingGroupsCatalogItem>>\n async listingPage(\n params: ProductListingPageFullParams,\n ): Promise<ProductListingPageResult<ProductListingGroupsItem>>\n async listingPage(\n params: ProductListingPageParams,\n ): Promise<\n | ProductListingPageResult<ProductListingGroupsCatalogItem>\n | ProductListingPageResult<ProductListingGroupsItem>\n >\n async listingPage(\n params: ProductListingPageParams = {},\n ): Promise<\n | ProductListingPageResult<ProductListingGroupsCatalogItem>\n | ProductListingPageResult<ProductListingGroupsItem>\n > {\n if (params.mode === 'full') {\n const request = buildProductListingPageRequest(params)\n const response = await this.requestEndpoint<\n PayloadFindResponse<ProductListingGroupsItem>\n >(request.operation, undefined, { query: request.query })\n return withProductListingCards(response, params)\n }\n\n const request = buildProductListingPageRequest(params)\n const response = await this.requestEndpoint<\n PayloadFindResponse<ProductListingGroupsCatalogItem>\n >(request.operation, undefined, { query: request.query })\n return withProductListingCards(response, params)\n }\n\n /**\n * Fetch full product detail by slug or id.\n * Returns a discriminated result so storefronts can distinguish missing,\n * unpublished, and feature-disabled products.\n *\n * Only product-detail 404 responses carrying one of those allowlisted reasons\n * are mapped to `{ found: false, reason }`. Unknown or uncoded 404s, plus\n * permission/auth errors such as tenant mismatch, continue to throw typed SDK\n * errors instead of being collapsed into a storefront absence result.\n */\n async detail(params: ProductDetailParams): Promise<ProductDetailResult> {\n try {\n const product = await this.requestEndpoint<ProductDetail>(\n COMMERCE_ENDPOINT_OPERATIONS.products.detail,\n undefined,\n { query: productDetailSearchParams(params) },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult) return notFoundResult\n throw err\n }\n }\n\n async detailCatalog(\n params: ProductDetailParams,\n ): Promise<ProductDetailCatalogResult> {\n try {\n const product = await this.requestEndpoint<ProductDetailCatalog>(\n COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,\n undefined,\n { query: productDetailSearchParams(params) },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult?.found === false) return notFoundResult\n throw err\n }\n }\n\n /**\n * Atomically create or update a product together with its options,\n * option-values, and variants in a single transaction. Mirrors Shopify's\n * `productSet` shape and is the canonical write path for the MCP\n * `product-upsert` tool.\n */\n upsert(params: ProductUpsertParams): Promise<ProductUpsertResponse> {\n return this.requestEndpoint<ProductUpsertResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.upsert,\n normalizeProductUpsertParams(params),\n )\n }\n}\n","import { CartApi } from '../api/cart-api'\nimport { CheckoutApi } from '../api/checkout-api'\nimport { PaymentSessionApi } from '../api/payment-session-api'\nimport { CustomerScopedApi } from '../api/customer-scoped-api'\nimport {\n COMMERCE_ENDPOINT_OPERATIONS,\n type CommerceEndpointDescriptor,\n} from '../api/endpoints'\nimport {\n buildProductListingPageRequest,\n productDetailResultFromError,\n withProductListingCards,\n} from '../api/product-api'\nimport {\n listingGroupsSearchParams,\n productDetailSearchParams,\n stockSnapshotSearchParams,\n} from '../internal/utils/query-string'\nimport type {\n CustomerAuth,\n CustomerOrderListOptions,\n} from '../customer/customer-auth'\nimport type {\n CreateCartParams,\n CreateCartResult,\n AddItemParams,\n UpdateItemParams,\n RemoveItemParams,\n UpdateDiscountCodesParams,\n UpdateCartAttributesParams,\n ClearCartParams,\n RetrieveCartParams,\n CartMergeParams,\n CartMergeResult,\n CartMineResult,\n CartMutationResult,\n PublicCart,\n} from '../api/cart-api'\nimport type {\n StockCheckParams,\n StockCheckResponse,\n StockSnapshotParams,\n StockSnapshotResponse,\n ListingGroupsParams,\n ProductListingGroupsCatalogItem,\n ProductListingGroupsCatalogResponse,\n ProductListingPageCatalogParams,\n ProductListingPageResult,\n ProductDetailParams,\n ProductDetailCatalog,\n ProductDetailCatalogResult,\n} from '../api/product-api'\nimport type {\n ValidateDiscountParams,\n ValidateDiscountResult,\n} from '../api/discount-api'\nimport type {\n CalculateShippingParams,\n CalculateShippingResult,\n} from '../api/shipping-api'\nimport type { PublicOrder } from '../api/order-api'\nimport type {\n CreateCheckoutParams,\n CreateCheckoutResult,\n PublicCheckout,\n RetrieveCheckoutParams,\n} from '../api/checkout-api'\nimport type {\n CancelBrowserPaymentSessionParams,\n CreatePortOnePaymentSessionParams,\n CreatePaymentSessionParams,\n PortOnePublicPaymentSession,\n PublicPaymentSession,\n RetrieveBrowserPaymentSessionParams,\n} from '../api/payment-session-api'\nimport type { PayloadFindResponse } from '../client/types'\n\nclass BrowserCommerceApi extends CustomerScopedApi {\n requestEndpoint<T>(\n endpoint: CommerceEndpointDescriptor,\n body?: unknown,\n options?: {\n query?: string | URLSearchParams\n headers?: Record<string, string>\n },\n ): Promise<T> {\n return super.requestEndpoint<T>(endpoint, body, options)\n }\n}\n\nexport interface CommerceClientOptions {\n publishableKey: string\n apiUrl?: string\n market?: string\n customerToken: () => string | null\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n customerAuth: CustomerAuth\n}\n\nexport class CommerceClient {\n private readonly market?: string\n\n readonly product: {\n stockCheck: (params: StockCheckParams) => Promise<StockCheckResponse>\n stockSnapshot: (\n params: StockSnapshotParams,\n ) => Promise<StockSnapshotResponse>\n listingGroups: (\n params: ListingGroupsParams,\n ) => Promise<ProductListingGroupsCatalogResponse>\n listingGroupsCatalog: (\n params: ListingGroupsParams,\n ) => Promise<ProductListingGroupsCatalogResponse>\n listingPage: {\n (\n params?: ProductListingPageCatalogParams,\n ): Promise<ProductListingPageResult<ProductListingGroupsCatalogItem>>\n }\n detail: (params: ProductDetailParams) => Promise<ProductDetailCatalogResult>\n detailCatalog: (\n params: ProductDetailParams,\n ) => Promise<ProductDetailCatalogResult>\n }\n\n readonly carts: {\n create: (params?: CreateCartParams) => Promise<CreateCartResult>\n retrieve: (params: RetrieveCartParams) => Promise<PublicCart>\n addItem: (params: AddItemParams) => Promise<CartMutationResult>\n updateItem: (params: UpdateItemParams) => Promise<CartMutationResult>\n removeItem: (params: RemoveItemParams) => Promise<CartMutationResult>\n updateDiscountCodes: (\n params: UpdateDiscountCodesParams,\n ) => Promise<CartMutationResult>\n updateAttributes: (\n params: UpdateCartAttributesParams,\n ) => Promise<CartMutationResult>\n clear: (params: ClearCartParams) => Promise<CartMutationResult>\n /**\n * Union/claim a pre-login guest cart into the authenticated customer's cart\n * (customer JWT required). Returns the resolved customer cart's `cartToken`\n * so the caller can persist it and keep operating the cart.\n */\n merge: (params: CartMergeParams) => Promise<CartMergeResult>\n /**\n * Load the authenticated customer's active cart by JWT (no `cartToken`\n * needed). `cart`/`cartToken` are both `null` when there is no active cart.\n */\n mine: () => Promise<CartMineResult>\n }\n\n readonly orders: {\n listMine: (\n options?: CustomerOrderListOptions,\n ) => Promise<PayloadFindResponse<PublicOrder>>\n }\n\n readonly checkouts: {\n create: (params: CreateCheckoutParams) => Promise<CreateCheckoutResult>\n retrieve: (params: RetrieveCheckoutParams) => Promise<PublicCheckout>\n }\n\n readonly paymentSessions: {\n create: (\n params: CreatePaymentSessionParams,\n ) => Promise<PublicPaymentSession>\n createPortOne: (\n params: CreatePortOnePaymentSessionParams,\n ) => Promise<PortOnePublicPaymentSession>\n retrieve: (\n params: RetrieveBrowserPaymentSessionParams,\n ) => Promise<PublicPaymentSession>\n retrievePortOne: (\n params: RetrieveBrowserPaymentSessionParams,\n ) => Promise<PortOnePublicPaymentSession>\n cancel: (\n params: CancelBrowserPaymentSessionParams,\n ) => Promise<PublicPaymentSession>\n cancelPortOne: (\n params: CancelBrowserPaymentSessionParams,\n ) => Promise<PortOnePublicPaymentSession>\n }\n\n readonly discounts: {\n validate: (\n params: ValidateDiscountParams,\n ) => Promise<ValidateDiscountResult>\n }\n\n readonly shipping: {\n calculate: (\n params: CalculateShippingParams,\n ) => Promise<CalculateShippingResult>\n }\n\n constructor(options: CommerceClientOptions) {\n this.market = options.market\n\n const cartApi = new CartApi({\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n const checkoutApi = new CheckoutApi({\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n const paymentSessionApi = new PaymentSessionApi({\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n const api = new BrowserCommerceApi('CommerceClient', {\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n\n this.product = {\n stockCheck: (params) =>\n api.requestEndpoint<StockCheckResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockCheck,\n params,\n ),\n stockSnapshot: (params) =>\n api.requestEndpoint<StockSnapshotResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.stockSnapshot,\n undefined,\n { query: stockSnapshotSearchParams(params) },\n ),\n listingGroups: (params) =>\n api.requestEndpoint<ProductListingGroupsCatalogResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,\n undefined,\n { query: listingGroupsSearchParams(this.withMarket(params)) },\n ),\n listingGroupsCatalog: (params) =>\n api.requestEndpoint<ProductListingGroupsCatalogResponse>(\n COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,\n undefined,\n { query: listingGroupsSearchParams(this.withMarket(params)) },\n ),\n listingPage: async (params = {}) => {\n const catalogParams: ProductListingPageCatalogParams = {\n ...params,\n mode: 'catalog',\n }\n const request = buildProductListingPageRequest(\n this.withMarket(catalogParams),\n )\n const response = await api.requestEndpoint<\n PayloadFindResponse<ProductListingGroupsCatalogItem>\n >(request.operation, undefined, { query: request.query })\n return withProductListingCards(response, this.withMarket(catalogParams))\n },\n detail: async (params) => {\n try {\n const product = await api.requestEndpoint<ProductDetailCatalog>(\n COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,\n undefined,\n { query: productDetailSearchParams(this.withMarket(params)) },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult) return notFoundResult\n throw err\n }\n },\n detailCatalog: async (params) => {\n try {\n const product = await api.requestEndpoint<ProductDetailCatalog>(\n COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,\n undefined,\n { query: productDetailSearchParams(this.withMarket(params)) },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult?.found === false) return notFoundResult\n throw err\n }\n },\n }\n\n this.carts = {\n create: (params) => cartApi.create(this.withMarket(params ?? {})),\n retrieve: cartApi.retrieve.bind(cartApi),\n addItem: cartApi.addItem.bind(cartApi),\n updateItem: cartApi.updateItem.bind(cartApi),\n removeItem: cartApi.removeItem.bind(cartApi),\n updateDiscountCodes: cartApi.updateDiscountCodes.bind(cartApi),\n updateAttributes: cartApi.updateAttributes.bind(cartApi),\n clear: cartApi.clear.bind(cartApi),\n merge: cartApi.merge.bind(cartApi),\n mine: cartApi.mine.bind(cartApi),\n }\n\n this.orders = {\n listMine: (params) => options.customerAuth.getMyOrders(params),\n }\n\n this.checkouts = {\n create: checkoutApi.create.bind(checkoutApi),\n retrieve: checkoutApi.retrieve.bind(checkoutApi),\n }\n\n this.paymentSessions = {\n create: paymentSessionApi.create.bind(paymentSessionApi),\n createPortOne: paymentSessionApi.createPortOne.bind(paymentSessionApi),\n retrieve: (params) => paymentSessionApi.retrieve(params),\n retrievePortOne: (params) => paymentSessionApi.retrievePortOne(params),\n cancel: (params) => paymentSessionApi.cancel(params),\n cancelPortOne: (params) => paymentSessionApi.cancelPortOne(params),\n }\n\n this.discounts = {\n validate: (params) =>\n api.requestEndpoint<ValidateDiscountResult>(\n COMMERCE_ENDPOINT_OPERATIONS.discounts.validate,\n params,\n ),\n }\n\n this.shipping = {\n calculate: (params) =>\n api.requestEndpoint<CalculateShippingResult>(\n COMMERCE_ENDPOINT_OPERATIONS.shippingPolicies.calculate,\n params,\n ),\n }\n }\n\n getDefaultMarket(): string | undefined {\n return this.market\n }\n\n private withMarket<T extends { market?: string }>(params: T): T {\n const defaultMarket = this.market?.trim()\n if (!defaultMarket || params.market?.trim()) return params\n return { ...params, market: defaultMarket }\n }\n}\n","import { parseApiResponse } from '../api/parse-response'\nimport { SDKError } from '../internal/errors'\nimport { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\nimport {\n EVENTS_ENDPOINT_OPERATIONS,\n resolveOperationMethod,\n resolveOperationPath,\n} from '@01.software/http-contracts'\n\nexport interface EventsClientOptions {\n publishableKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport type EventsDateParam = string | Date\n\nexport interface EventsRangeParams {\n start?: EventsDateParam\n end?: EventsDateParam\n limit?: number\n page?: number\n calendar?: string\n calendarSlug?: string\n category?: string | string[]\n categorySlug?: string | string[]\n tag?: string | string[]\n tagSlug?: string | string[]\n}\n\nexport interface EventsTaxonomyItem {\n id: string | number\n title?: string | null\n slug?: string | null\n description?: string | null\n color?: string | null\n}\n\nexport interface EventsCalendarItem extends EventsTaxonomyItem {\n timezone?: string | null\n visibility?: string | null\n}\n\nexport interface EventsLocation {\n type?: string | null\n name?: string | null\n address?: string | null\n onlineUrl?: string | null\n onlineNote?: string | null\n}\n\nexport interface EventsOccurrenceLocation {\n name?: string | null\n address?: string | null\n onlineUrl?: string | null\n note?: string | null\n}\n\nexport interface EventsExternalSource {\n provider?: string | null\n url?: string | null\n}\n\nexport interface EventsRangeEvent {\n id: string | number\n title?: string | null\n slug?: string | null\n description?: string | null\n startsAt?: string | null\n endsAt?: string | null\n timezone?: string | null\n isAllDay: boolean\n allDayStartDate?: string | null\n allDayEndDateExclusive?: string | null\n visibility?: string | null\n sourceType?: string | null\n registrationPolicy?: string | null\n externalRegistrationUrl?: string | null\n externalSource: EventsExternalSource | null\n location: EventsLocation | null\n calendar: EventsCalendarItem\n categories: EventsTaxonomyItem[]\n tags: EventsTaxonomyItem[]\n}\n\nexport interface EventsRangeOccurrence {\n id: string | number\n instanceKey?: string | null\n startsAt?: string | null\n endsAt?: string | null\n timezone?: string | null\n isAllDay: boolean\n allDayStartDate?: string | null\n allDayEndDateExclusive?: string | null\n status?: string | null\n capacity?: number\n registrationCount?: number\n waitlistCount?: number\n locationOverride: EventsOccurrenceLocation | null\n event: EventsRangeEvent\n}\n\nexport interface EventsRangeResponse {\n range: {\n start: string\n end: string\n }\n docs: EventsRangeOccurrence[]\n calendar: EventsCalendarItem | null\n events: EventsRangeEvent[]\n categories: EventsTaxonomyItem[]\n tags: EventsTaxonomyItem[]\n totalDocs: number\n limit: number\n page: number\n totalPages: number\n hasNextPage: boolean\n hasPrevPage: boolean\n}\n\nexport interface EventAdmissionAvailabilityParams {\n occurrence: string\n /** Active market handle or id; omitted uses the tenant's default market. */\n market?: string\n}\n\nexport interface EventAdmissionPricePresentment {\n amount: number\n compareAtPrice: number | null\n currency: string | null\n marketId: string | null\n}\n\nexport interface EventAdmissionAvailabilityType {\n id: string | number\n label?: string | null\n description?: string | null\n eventId: string | number\n occurrenceId: string | number\n productId: string | number | null\n variantId: string | number | null\n price: EventAdmissionPricePresentment | null\n remainingCapacityHint: number | null\n available: boolean\n}\n\nexport interface EventAdmissionAvailabilityResponse {\n occurrenceId: string | number\n eventId: string | number\n remainingCapacityHint: number | null\n admissionTypes: EventAdmissionAvailabilityType[]\n}\n\nexport interface EventRegistrationAttendeeInput {\n name?: string\n email?: string\n phone?: string\n}\n\nexport interface EventRegistrationAnswerInput {\n question: string\n answer?: string\n}\n\nexport interface EventRegistrationRegisterParams {\n event: string\n occurrence: string\n quantity?: number\n attendee?: EventRegistrationAttendeeInput\n answers?: EventRegistrationAnswerInput[]\n}\n\nexport interface EventRegistrationPublic {\n id?: string | number\n event?: unknown\n occurrence?: unknown\n registrationStatus?: string | null\n attendanceStatus?: string | null\n quantity?: number | null\n guestTokenExpiresAt?: string | null\n}\n\nexport interface EventGuestRegistration extends EventRegistrationPublic {\n attendee: {\n name: string | null\n email: string | null\n phone: string | null\n } | null\n attendeeEmail: string | null\n answers: Array<{ question: string; answer?: string }>\n}\n\nexport interface EventRegistrationRegisterResponse {\n registration: EventRegistrationPublic\n guestToken: string\n guestTokenExpiresAt: string\n}\n\nexport interface EventGuestRegistrationResponse {\n registration: EventGuestRegistration\n}\n\nexport interface EventMyRegistrationsParams {\n page?: number\n limit?: number\n}\n\nexport interface EventMyRegistration {\n id: string\n event: { id: string | null; title: string | null }\n occurrence: {\n id: string | null\n startsAt: string | null\n endsAt: string | null\n timezone: string | null\n isAllDay: boolean | null\n allDayStartDate: string | null\n allDayEndDateExclusive: string | null\n }\n registrationStatus: string | null\n attendanceStatus: string | null\n quantity: number | null\n createdAt: string | null\n}\n\nexport interface EventMyRegistrationsResponse {\n docs: EventMyRegistration[]\n totalDocs: number\n limit: number\n page: number\n totalPages: number\n hasNextPage: boolean\n hasPrevPage: boolean\n}\n\nexport interface EventGuestCancelParams {\n reason?: string\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\n\nexport class EventsClient {\n private readonly publishableKey: string\n private readonly apiUrl?: string\n private readonly customerToken?: string | (() => string | null)\n private readonly onUnauthorized?: () => Promise<string | null>\n private readonly onRequestId?: (id: string | null) => void\n\n constructor(options: EventsClientOptions) {\n const secretKey = (options as { secretKey?: string }).secretKey\n this.publishableKey = requirePublishableKeyForSecret(\n 'EventsClient',\n options.publishableKey,\n secretKey,\n )\n this.apiUrl = options.apiUrl\n this.customerToken = options.customerToken\n this.onUnauthorized = options.onUnauthorized\n this.onRequestId = options.onRequestId\n }\n\n getRange(params: EventsRangeParams): Promise<EventsRangeResponse> {\n return this.execute<EventsRangeResponse>(\n buildRangeEndpoint(params),\n resolveOperationMethod(EVENTS_ENDPOINT_OPERATIONS.occurrences.range),\n undefined,\n { useCustomerAuth: false },\n )\n }\n\n getAdmissionAvailability(\n params: EventAdmissionAvailabilityParams,\n ): Promise<EventAdmissionAvailabilityResponse> {\n return this.execute<EventAdmissionAvailabilityResponse>(\n buildAdmissionAvailabilityEndpoint(params),\n resolveOperationMethod(\n EVENTS_ENDPOINT_OPERATIONS.occurrences.admissionAvailability,\n ),\n undefined,\n { useCustomerAuth: false },\n )\n }\n\n listMyRegistrations(\n params: EventMyRegistrationsParams = {},\n ): Promise<EventMyRegistrationsResponse> {\n const query = new URLSearchParams()\n if (params.page !== undefined) query.set('page', String(params.page))\n if (params.limit !== undefined) query.set('limit', String(params.limit))\n const operation = EVENTS_ENDPOINT_OPERATIONS.registrations.listMine\n return this.execute<EventMyRegistrationsResponse>(\n resolveOperationPath(operation, { query }),\n resolveOperationMethod(operation),\n undefined,\n { useCustomerAuth: true, noStore: true },\n )\n }\n\n register(\n params: EventRegistrationRegisterParams,\n ): Promise<EventRegistrationRegisterResponse> {\n return this.execute<EventRegistrationRegisterResponse>(\n resolveOperationPath(EVENTS_ENDPOINT_OPERATIONS.registrations.register),\n resolveOperationMethod(EVENTS_ENDPOINT_OPERATIONS.registrations.register),\n buildRegistrationRequestBody(params),\n { useCustomerAuth: true },\n )\n }\n\n getGuestRegistration(token: string): Promise<EventGuestRegistrationResponse> {\n return this.execute<EventGuestRegistrationResponse>(\n resolveOperationPath(\n EVENTS_ENDPOINT_OPERATIONS.registrations.guestLookup,\n ),\n resolveOperationMethod(\n EVENTS_ENDPOINT_OPERATIONS.registrations.guestLookup,\n ),\n { token },\n { useCustomerAuth: false },\n )\n }\n\n cancelGuestRegistration(\n token: string,\n params: EventGuestCancelParams = {},\n ): Promise<EventGuestRegistrationResponse> {\n return this.execute<EventGuestRegistrationResponse>(\n resolveOperationPath(\n EVENTS_ENDPOINT_OPERATIONS.registrations.guestCancel,\n ),\n resolveOperationMethod(\n EVENTS_ENDPOINT_OPERATIONS.registrations.guestCancel,\n ),\n buildGuestCancelRequestBody(token, params),\n { useCustomerAuth: false },\n )\n }\n\n private async execute<T>(\n endpoint: string,\n method: HttpMethod,\n body?: unknown,\n options: { useCustomerAuth?: boolean; noStore?: boolean } = {},\n ): Promise<T> {\n const useCustomerAuth = options.useCustomerAuth === true\n const token = useCustomerAuth\n ? typeof this.customerToken === 'function'\n ? this.customerToken()\n : this.customerToken\n : undefined\n\n try {\n const response = await httpFetch(endpoint, {\n method,\n ...(options.noStore && { cache: 'no-store' as const }),\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n ...(useCustomerAuth && token ? { customerToken: token } : {}),\n ...(useCustomerAuth &&\n token &&\n this.onUnauthorized && { onUnauthorized: this.onUnauthorized }),\n ...(body !== undefined && { body: JSON.stringify(body) }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n}\n\nfunction buildRegistrationRequestBody(\n params: EventRegistrationRegisterParams,\n): EventRegistrationRegisterParams {\n return {\n event: params.event,\n occurrence: params.occurrence,\n ...(params.quantity !== undefined && { quantity: params.quantity }),\n ...(params.attendee !== undefined && { attendee: params.attendee }),\n ...(params.answers !== undefined && { answers: params.answers }),\n }\n}\n\nfunction buildGuestCancelRequestBody(\n token: string,\n params: EventGuestCancelParams,\n): { token: string; reason?: string } {\n return {\n token,\n ...(params.reason !== undefined && { reason: params.reason }),\n }\n}\n\nfunction buildRangeEndpoint(params: EventsRangeParams): string {\n const urlParams = new URLSearchParams()\n if (params.start !== undefined) {\n urlParams.set('start', formatDateParam(params.start))\n }\n if (params.end !== undefined) {\n urlParams.set('end', formatDateParam(params.end))\n }\n if (params.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params.page !== undefined) urlParams.set('page', String(params.page))\n appendValues(urlParams, 'calendar', params.calendar)\n appendValues(urlParams, 'calendarSlug', params.calendarSlug)\n appendValues(urlParams, 'category', params.category)\n appendValues(urlParams, 'categorySlug', params.categorySlug)\n appendValues(urlParams, 'tag', params.tag)\n appendValues(urlParams, 'tagSlug', params.tagSlug)\n return resolveOperationPath(EVENTS_ENDPOINT_OPERATIONS.occurrences.range, {\n query: urlParams,\n })\n}\n\nfunction buildAdmissionAvailabilityEndpoint(\n params: EventAdmissionAvailabilityParams,\n): string {\n const urlParams = new URLSearchParams()\n urlParams.set('occurrence', params.occurrence)\n const normalizedMarket = params.market?.trim()\n if (normalizedMarket) urlParams.set('market', normalizedMarket)\n return resolveOperationPath(\n EVENTS_ENDPOINT_OPERATIONS.occurrences.admissionAvailability,\n { query: urlParams },\n )\n}\n\nfunction formatDateParam(value: EventsDateParam): string {\n return value instanceof Date ? value.toISOString() : value\n}\n\nfunction appendValues(\n params: URLSearchParams,\n key: string,\n value: string | string[] | undefined,\n): void {\n if (value === undefined) return\n const values = Array.isArray(value) ? value : [value]\n for (const entry of values) {\n if (entry) params.append(key, entry)\n }\n}\n","import type { PublicMarket } from '../collection/types'\nimport type { PayloadFindResponse, Where } from '../client/types'\n\n/**\n * Client-safe market discovery shape (Shopify-like). Structural copy of the\n * private contracts package's `PublicMarketDTO` — the public SDK must not import\n * private contracts, so a parity `test-d` keeps the two in lockstep. The\n * `toMarketDTO` return annotation ties this shape back to the real `PublicMarket`\n * row (which the parity test alone cannot check).\n */\nexport type MarketDTO = {\n id: string\n handle: string\n name: string\n countryCode: string\n targetCountries: string[]\n currency: string\n isPrimary: boolean\n isActive: boolean\n}\n\n/**\n * Minimal reader the discovery helper depends on: the shape of\n * `collections.from('markets').find`. Kept narrow so the helper is\n * transport-agnostic and unit-testable against a mock.\n */\nexport type MarketRowReader = (options: {\n where: Where\n limit: number\n}) => Promise<PayloadFindResponse<PublicMarket>>\n\n/**\n * Allow-list mapper: selects only stable, client-safe fields, so server-only\n * fields (FX/adjustment/rounding/metadata) and `tenant`/timestamps are dropped\n * even when a secret-key read returns them. The explicit `: MarketDTO` return\n * annotation is the source-of-truth tie to the generated row shape.\n */\nexport function toMarketDTO(row: PublicMarket): MarketDTO {\n return {\n id: row.id,\n handle: row.handle,\n name: row.name,\n countryCode: row.countryCode,\n targetCountries: (row.targetCountries ?? []).map((c) => c.countryCode),\n currency: row.currency,\n isPrimary: row.isPrimary === true,\n isActive: row.isActive === true,\n }\n}\n\nexport interface MarketDiscoveryClient {\n /** List the tenant's active buyer markets. */\n list(): Promise<MarketDTO[]>\n /** Resolve the tenant's default (active primary) market, or `null`. */\n default(): Promise<MarketDTO | null>\n}\n\n/** Read-side helper for public market discovery. */\nexport class MarketDiscovery implements MarketDiscoveryClient {\n constructor(private readonly read: MarketRowReader) {}\n\n async list(): Promise<MarketDTO[]> {\n const res = await this.read({\n where: { isActive: { equals: true } },\n limit: 100,\n })\n if (res.hasNextPage) {\n console.warn(\n '[markets.list] more than 100 active markets; results truncated to 100.',\n )\n }\n return res.docs.map(toMarketDTO)\n }\n\n async default(): Promise<MarketDTO | null> {\n const res = await this.read({\n where: { isPrimary: { equals: true }, isActive: { equals: true } },\n limit: 1,\n })\n const row = res.docs[0]\n return row ? toMarketDTO(row) : null\n }\n}\n","import { CustomerBenefitVouchersApi } from '../api/customer-benefit-vouchers-api'\nimport { CustomerCreditsApi } from '../api/customer-credits-api'\nimport { ReadOnlyCollectionClient } from '../collection/collection-client'\nimport { CommunityClient } from '../community/community-client'\nimport { ContentClient } from '../content/content-client'\nimport { CustomerNamespace } from '../customer/customer-namespace'\nimport { CommerceClient } from '../commerce/commerce-client'\nimport { EventsClient } from '../events/events-client'\nimport { MarketDiscovery } from '../market/market-discovery'\nimport { CustomerScopedApi } from '../api/customer-scoped-api'\nimport { createConfigError } from '../internal/errors'\nimport { MEMBERSHIP_ENDPOINT_OPERATIONS } from '../api/endpoints'\nimport type {\n CancelMembershipParams,\n CancelMembershipResponse,\n CustomerMembershipView,\n} from '../api/membership-types'\nimport {\n type ClientConfig,\n type ClientState,\n type ClientMetadata,\n} from './types'\n\nclass BrowserMembershipApi extends CustomerScopedApi {\n me(): Promise<CustomerMembershipView | null> {\n return this.requestEndpoint<CustomerMembershipView | null>(\n MEMBERSHIP_ENDPOINT_OPERATIONS.me,\n )\n }\n\n cancel(params: CancelMembershipParams): Promise<CancelMembershipResponse> {\n const { id, immediate } = params\n return this.requestEndpoint<CancelMembershipResponse>(\n MEMBERSHIP_ENDPOINT_OPERATIONS.cancel,\n immediate !== undefined ? { immediate } : {},\n { pathParams: { id } },\n )\n }\n}\n\nexport default class Client {\n credits: Pick<CustomerCreditsApi, 'mine' | 'history'>\n benefitVouchers: Pick<CustomerBenefitVouchersApi, 'listMine'>\n commerce: CommerceClient\n community: CommunityClient\n content: ContentClient\n events: EventsClient\n customer: CustomerNamespace\n collections: ReadOnlyCollectionClient\n markets: MarketDiscovery\n memberships: {\n me: () => Promise<CustomerMembershipView | null>\n cancel: (\n params: CancelMembershipParams,\n ) => Promise<CancelMembershipResponse>\n }\n\n lastRequestId: string | null = null\n\n protected state: ClientState\n protected config: ClientConfig\n\n constructor(options: ClientConfig) {\n const publishableKey = options.publishableKey\n if (!publishableKey) {\n throw createConfigError('publishableKey is required.')\n }\n\n this.config = { ...options, publishableKey }\n\n const metadata: ClientMetadata = {\n timestamp: Date.now(),\n userAgent:\n typeof window !== 'undefined' ? window.navigator?.userAgent : 'Node.js',\n }\n\n this.state = { metadata }\n\n this.customer = new CustomerNamespace(\n this.config.publishableKey,\n options.customer,\n this.config.apiUrl,\n )\n\n const onUnauthorized = async (): Promise<string | null> => {\n try {\n const result = await this.customer.auth.refreshToken()\n return result.token ?? null\n } catch {\n return null\n }\n }\n\n const onRequestId = (id: string | null) => {\n this.lastRequestId = id\n }\n\n this.commerce = new CommerceClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n market: this.config.market,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n customerAuth: this.customer.auth,\n })\n\n this.community = new CommunityClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.content = new ContentClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n onRequestId,\n })\n\n this.events = new EventsClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.collections = new ReadOnlyCollectionClient(\n this.config.publishableKey,\n undefined,\n () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n this.config.apiUrl,\n )\n\n this.markets = new MarketDiscovery((options) =>\n this.collections.from('markets').find(options),\n )\n\n this.credits = new CustomerCreditsApi('CustomerCreditsApi', {\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.benefitVouchers = new CustomerBenefitVouchersApi(\n 'CustomerBenefitVouchersApi',\n {\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n },\n )\n\n const membershipApi = new BrowserMembershipApi('MembershipApi', {\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n this.memberships = {\n me: membershipApi.me.bind(membershipApi),\n cancel: membershipApi.cancel.bind(membershipApi),\n }\n }\n\n getState(): ClientState {\n return { ...this.state }\n }\n\n withMarket(market: string): Client {\n return new Client({\n ...this.config,\n customer:\n this.config.customer?.persist === false\n ? {\n ...this.config.customer,\n token: this.customer.auth.getToken() ?? undefined,\n refreshToken: this.customer.auth.getRefreshToken() ?? undefined,\n }\n : this.config.customer,\n market,\n })\n }\n\n getConfig(): ClientConfig {\n return { ...this.config }\n }\n}\n\n/**\n * Create an SDK client. Works in both browser and server environments.\n * Read-only collection queries + customer auth (cart, login, profile).\n * Use the server subpath when you need full CRUD with server credentials.\n */\nexport function createClient(options: ClientConfig): Client {\n return new Client(options)\n}\n","import type {\n ProductDetail,\n ProductDetailCatalog,\n ProductDetailVariant,\n} from '../api/product-api'\nimport type { StockSnapshotResponse } from '../api/product-api'\n\nexport type ProductDetailStockMergeStatus = 'complete' | 'partial'\n\nexport interface MergedProductDetailResult {\n stockMergeStatus: ProductDetailStockMergeStatus\n product: ProductDetail\n}\n\nexport function mergeProductDetailWithStock(\n catalog: ProductDetailCatalog,\n snapshot: StockSnapshotResponse,\n): MergedProductDetailResult {\n const snapshotByVariantId = new Map(\n snapshot.snapshots.map((item) => [item.variantId, item]),\n )\n\n let missingSnapshotCount = 0\n const variants: ProductDetailVariant[] = catalog.variants.map((variant) => {\n const snap = snapshotByVariantId.get(String(variant.id))\n if (!snap) {\n missingSnapshotCount += 1\n return { ...variant, stock: 0, reservedStock: 0 }\n }\n\n return {\n ...variant,\n stock: snap.isUnlimited ? 0 : snap.availableStock,\n reservedStock: 0,\n }\n })\n\n const trackedVariants = variants.filter((variant) => !variant.isUnlimited)\n const totalInventory =\n trackedVariants.length === 0\n ? null\n : trackedVariants.reduce(\n (sum, variant) =>\n sum + Math.max(0, (variant.stock ?? 0) - (variant.reservedStock ?? 0)),\n 0,\n )\n\n const availableForSale = snapshot.snapshots.some(\n (item) => item.status === 'available' && item.availableForSale,\n )\n const selectedVariantId =\n typeof catalog.selectedOrFirstAvailableVariant === 'object' &&\n catalog.selectedOrFirstAvailableVariant !== null\n ? String(catalog.selectedOrFirstAvailableVariant.id)\n : catalog.selectedOrFirstAvailableVariant != null\n ? String(catalog.selectedOrFirstAvailableVariant)\n : null\n const selectedOrFirstAvailableVariant =\n selectedVariantId != null\n ? (variants.find((variant) => String(variant.id) === selectedVariantId) ??\n selectedVariantId)\n : null\n\n return {\n stockMergeStatus: missingSnapshotCount === 0 ? 'complete' : 'partial',\n product: {\n ...catalog,\n product: { ...catalog.product, totalInventory },\n variants,\n availableForSale,\n selectedOrFirstAvailableVariant,\n },\n }\n}\n","export function isValidWebhookEventData(data: unknown): boolean {\n if (typeof data !== 'object' || data === null) return false\n const event = data as Record<string, unknown>\n return (\n typeof event.collection === 'string' &&\n typeof event.operation === 'string' &&\n event.operation.length > 0 &&\n typeof event.data === 'object' &&\n event.data !== null\n )\n}\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\nimport type { WebhookEvent, WebhookHandler } from './index'\nimport { isValidWebhookEventData } from './validation'\n\nexport interface SignedWebhookOptions {\n /** Nonblank HMAC-SHA256 signing secret for this receiver. */\n secret: string\n /**\n * Max accepted skew for signed webhook delivery timestamps. Default: 300s.\n * Must be a number between 0 and 86400 inclusive; anything else is a\n * configuration error, because an unbounded or effectively unbounded window\n * would accept an arbitrarily old replay.\n */\n toleranceSeconds?: number\n}\n\nasync function verifySignature(\n rawBody: Uint8Array,\n secret: string,\n signature: string,\n timestamp: string,\n deliveryId: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const signedPrefix = encoder.encode(`${timestamp}.${deliveryId}.`)\n const signedPayload = new Uint8Array(signedPrefix.length + rawBody.length)\n signedPayload.set(signedPrefix)\n signedPayload.set(rawBody, signedPrefix.length)\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['verify'],\n )\n if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {\n return false\n }\n const sigBytes = new Uint8Array(\n (signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16)),\n )\n return crypto.subtle.verify('HMAC', key, sigBytes, signedPayload)\n}\n\nfunction timestampIsFresh(\n timestamp: string,\n toleranceSeconds: number,\n): boolean {\n if (!/^\\d+$/.test(timestamp)) return false\n const timestampMs = Number(timestamp)\n if (!Number.isFinite(timestampMs)) return false\n const skewMs = Math.abs(Date.now() - timestampMs)\n return skewMs <= toleranceSeconds * 1000\n}\n\n/**\n * Upper bound for the signed replay window. A merely finite tolerance is not\n * enough: `Number.MAX_VALUE * 1000` overflows to `Infinity`, and even without\n * overflow a value of that size accepts an arbitrarily old capture. The sender's\n * retry and dead-letter lifecycle completes far inside a day, so anything beyond\n * this is a misconfiguration rather than clock-skew tolerance.\n */\nconst MAX_TOLERANCE_SECONDS = 86_400\n\n/**\n * A signed receiver's replay window must stay bounded. A non-finite, negative,\n * or over-bound tolerance would silently accept an old capture, so it is a\n * configuration error rather than a request-authentication failure.\n */\nfunction toleranceIsValid(\n toleranceSeconds: unknown,\n): toleranceSeconds is number {\n return (\n typeof toleranceSeconds === 'number' &&\n Number.isFinite(toleranceSeconds) &&\n toleranceSeconds >= 0 &&\n toleranceSeconds <= MAX_TOLERANCE_SECONDS\n )\n}\n\nasync function processWebhookRequest<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n verify?: (rawBody: Uint8Array) => Promise<Response | undefined>,\n): Promise<Response> {\n try {\n const rawBody = new Uint8Array(await request.arrayBuffer())\n const verificationFailure = await verify?.(rawBody)\n if (verificationFailure) return verificationFailure\n\n const body = JSON.parse(new TextDecoder().decode(rawBody))\n if (!isValidWebhookEventData(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T, TData>)\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n return new Response(JSON.stringify({ error: 'Internal server error' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n\nexport async function handleSignedWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n options: SignedWebhookOptions,\n): Promise<Response> {\n // Read each configuration value exactly once. Re-reading `options` would let\n // a getter return a valid secret to the guard and a different one to the\n // verifier, so the validated bytes are the only bytes this receiver uses.\n const secret: unknown = options?.secret\n const configuredTolerance: unknown = options?.toleranceSeconds\n // `??` so an absent or null tolerance keeps the documented default, exactly as\n // before this change; only a present, out-of-contract value is rejected.\n const toleranceSeconds = configuredTolerance ?? 300\n\n if (typeof secret !== 'string' || secret.trim().length === 0) {\n return new Response(\n JSON.stringify({ error: 'Webhook signing secret is not configured' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n // Reported separately so a tolerance mistake is not misdiagnosed as a bad secret.\n if (!toleranceIsValid(toleranceSeconds)) {\n return new Response(\n JSON.stringify({ error: 'Webhook signature tolerance is not valid' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n return processWebhookRequest(request, handler, async (rawBody) => {\n const signature = request.headers.get('x-webhook-signature') || ''\n const timestamp = request.headers.get('x-webhook-timestamp') || ''\n const deliveryId = request.headers.get('x-webhook-delivery-id') || ''\n const valid =\n Boolean(timestamp && deliveryId) &&\n timestampIsFresh(timestamp, toleranceSeconds) &&\n (await verifySignature(rawBody, secret, signature, timestamp, deliveryId))\n\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n })\n}\n\n/** Process a webhook only when its endpoint is intentionally unsigned. */\nexport async function handleUnsignedWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(request: Request, handler: WebhookHandler<T, TData>): Promise<Response> {\n return processWebhookRequest(request, handler)\n}\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\nimport { handleSignedWebhook as handleSignedWebhookInternal } from './receiver'\nimport { isValidWebhookEventData } from './validation'\n\nexport type WebhookOperation = string\n\n/**\n * Semantic event type for manual Admin Panel ordering changes.\n *\n * Order-change webhooks remain `operation: \"update\"` events for compatibility.\n * Do not filter on or emit `operation: \"reorder\"`; use this event type with\n * `isOrderChangedWebhookEvent()` to distinguish ordering from normal content\n * updates.\n */\nexport const ORDER_CHANGED_EVENT_TYPE = 'collection.orderChanged' as const\n\n/** Semantic event type for v1 commerce notification webhooks. */\nexport const COMMERCE_NOTIFICATION_EVENT_TYPE = 'commerce.notification' as const\n\n/** Collection webhook operations emitted for tenant collection writes. */\nexport type CollectionWebhookOperation = 'create' | 'update'\n\n/** Describes the ordered area affected by an order-change webhook. */\nexport type WebhookOrderScope =\n | { kind: 'collection'; collection: string }\n | { kind: 'join'; collection: string; field: string; id: string | number }\n\n/** Identifies the public moved document for the ordered scope. */\nexport type WebhookOrderMoved = {\n collection: string\n id: string | number\n relatedCollection?: string\n relatedId?: string | number\n}\n\n/** Metadata attached to `collection.orderChanged` webhook events. */\nexport type WebhookOrderChange = {\n type: 'order'\n source: 'payload-orderable'\n /**\n * Diagnostic Payload order field name.\n *\n * This may contain hidden implementation field names. Application routing\n * should use `change.scope` and `change.moved` instead.\n */\n orderableFieldName?: string\n previousOrder?: string | null\n nextOrder?: string | null\n scope: WebhookOrderScope\n moved: WebhookOrderMoved\n}\n\n/** Known semantic webhook change metadata. */\nexport type WebhookChange =\n | WebhookOrderChange\n | WebhookCommerceNotificationChange\n\nexport interface WebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> {\n collection: T\n operation: WebhookOperation\n data: TData\n eventType?: string\n change?: unknown\n timestamp?: string\n deliveryId?: string\n}\n\nexport type WebhookHandler<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = (event: WebhookEvent<T, TData>) => Promise<void> | void\n\n/** @deprecated Use the signed receiver options from `@01.software/sdk/webhook`. */\nexport interface WebhookOptions {\n /** Nonblank HMAC-SHA256 signing secret for this receiver. */\n secret: string\n /** Max accepted skew for signed webhook delivery timestamps. Default: 300s. */\n toleranceSeconds?: number\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n return isValidWebhookEventData(data)\n}\n\n/** Webhook event emitted when manual Admin Panel ordering changes. */\nexport type OrderChangedWebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = WebhookEvent<T, TData> & {\n operation: 'update'\n eventType: typeof ORDER_CHANGED_EVENT_TYPE\n change: WebhookOrderChange\n}\n\nexport const COMMERCE_NOTIFICATION_OPERATION = 'notification' as const\n\nexport const COMMERCE_NOTIFICATION_EVENTS = [\n 'orderPaid',\n 'orderCanceled',\n 'fulfillmentShipped',\n 'orderDelivered',\n 'returnRequested',\n 'returnApproved',\n 'returnRejected',\n 'returnCanceled',\n 'returnCompleted',\n 'paymentReconciliationRequired',\n 'paymentRefundRequiresAttention',\n 'membershipActivated',\n 'membershipPastDue',\n 'membershipExpired',\n 'membershipCancelled',\n] as const\n\nexport type CommerceNotificationEventName =\n (typeof COMMERCE_NOTIFICATION_EVENTS)[number]\n\nexport type CustomerCommerceNotificationEventName = Exclude<\n CommerceNotificationEventName,\n PaymentIncidentNotificationEventName | MembershipNotificationEventName\n>\n\nexport type CommerceNotificationSourceCollection =\n | 'orders'\n | 'fulfillments'\n | 'returns'\n | 'payment-sessions'\n | 'payment-refund-attempts'\n | 'customer-memberships'\n\nexport type CommerceNotificationSource = {\n collection: CommerceNotificationSourceCollection\n id: string | number\n}\n\nexport type PaymentIncidentNotificationEventName =\n | 'paymentReconciliationRequired'\n | 'paymentRefundRequiresAttention'\n\nexport type MembershipNotificationEventName =\n | 'membershipActivated'\n | 'membershipPastDue'\n | 'membershipExpired'\n | 'membershipCancelled'\n\nexport type MembershipNotificationData = {\n membershipId: string\n planId: string\n /** Tenant-scoped pseudonymous identifier; this is not a PII-free claim. */\n customerId: string\n fromStatus: string\n toStatus: 'active' | 'past_due' | 'expired' | 'cancelled'\n occurredAt: string\n}\n\nexport type PaymentIncidentNotificationSourceCollection =\n | 'payment-sessions'\n | 'payment-refund-attempts'\n\nexport type PaymentIncidentNotificationReason =\n | 'orderless_capture'\n | 'local_commit_ambiguous'\n\nexport type PaymentIncidentNotificationStatus =\n | 'reconciliation_required'\n | 'requires_attention'\n\nexport type PaymentIncidentProviderObject = {\n provider: string\n kind: 'payment' | 'refund'\n id: string\n}\n\nexport type PaymentIncidentMoney = {\n amountMinor: number\n currency: string\n}\n\ntype PaymentIncidentNotificationBase = {\n paymentSessionId: string\n checkoutId?: string\n orderId?: string\n providerObject: PaymentIncidentProviderObject\n money: PaymentIncidentMoney\n observedAt: string\n}\n\nexport type PaymentReconciliationRequiredNotificationData =\n PaymentIncidentNotificationBase & {\n source: {\n collection: 'payment-sessions'\n id: string\n }\n providerObject: PaymentIncidentProviderObject & { kind: 'payment' }\n status: 'reconciliation_required'\n reason: 'orderless_capture'\n refundAttemptId?: never\n }\n\nexport type PaymentRefundRequiresAttentionNotificationData =\n PaymentIncidentNotificationBase & {\n source: { collection: 'payment-refund-attempts'; id: string }\n refundAttemptId: string\n status: 'requires_attention'\n reason: 'local_commit_ambiguous'\n }\n\nexport type PaymentIncidentNotificationData =\n | PaymentReconciliationRequiredNotificationData\n | PaymentRefundRequiresAttentionNotificationData\n\nexport type CommerceNotificationData = {\n source?: CommerceNotificationSource\n orderId?: string | number\n orderNumber?: string\n status?: string\n totalAmount?: number\n currency?: string\n fulfillmentId?: string | number\n fulfillmentStatus?: string\n shippedAt?: string\n returnId?: string | number\n returnStatus?: string\n refundAmount?: number\n completedAt?: string\n paymentSessionId?: string\n checkoutId?: string\n refundAttemptId?: string\n providerObject?: PaymentIncidentProviderObject\n money?: PaymentIncidentMoney\n reason?: PaymentIncidentNotificationReason\n observedAt?: string\n membershipId?: string\n planId?: string\n customerId?: string\n fromStatus?: string\n toStatus?: string\n occurredAt?: string\n}\n\nexport type CommerceNotification = {\n event: CommerceNotificationEventName\n intentId: string\n dedupeKey: string\n orderId?: string\n fulfillmentId?: string\n returnId?: string\n paymentSessionId?: string\n refundAttemptId?: string\n membershipId?: string\n}\n\nexport type WebhookCommerceNotificationChange = {\n type: 'notification'\n source: 'commerce-notifications'\n event: CommerceNotificationEventName\n sourceCollection: CommerceNotificationSourceCollection\n sourceId: string | number\n}\n\n/** Webhook event emitted for v1 commerce notification deliveries. */\nexport type CommerceNotificationWebhookEvent = WebhookEvent<\n CommerceNotificationSourceCollection,\n CommerceNotificationData\n> & {\n operation: typeof COMMERCE_NOTIFICATION_OPERATION\n eventType: typeof COMMERCE_NOTIFICATION_EVENT_TYPE\n change?: WebhookCommerceNotificationChange\n notification: CommerceNotification\n}\n\nexport type CommerceEmailChannel = 'webhook' | 'provider'\n\nexport type CommerceEmailEventConfig = {\n enabled: boolean\n channel: CommerceEmailChannel\n template?: string\n}\n\nexport type CommerceEmailConfig = {\n version: 1\n commerceNotifications: Partial<\n Record<CustomerCommerceNotificationEventName, CommerceEmailEventConfig>\n >\n}\n\nexport type CommerceNotificationHandlerContext = {\n event: CommerceNotificationWebhookEvent\n idempotencyKey: string\n}\n\ntype MaybePromise<T> = T | Promise<T>\n\nexport type CommerceNotificationEventHandlers = Partial<\n Record<\n CommerceNotificationEventName,\n (context: CommerceNotificationHandlerContext) => MaybePromise<void>\n >\n> & {\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nexport type CommerceEmailHandlerContext = CommerceNotificationHandlerContext\n\nexport type CommerceEmailEventHandlers = Partial<\n Record<\n CustomerCommerceNotificationEventName,\n (context: CommerceEmailHandlerContext) => MaybePromise<void>\n >\n> & {\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isStringOrNumber(value: unknown): value is string | number {\n return typeof value === 'string' || typeof value === 'number'\n}\n\nfunction isWebhookOrderScope(value: unknown): value is WebhookOrderScope {\n if (!isRecord(value)) return false\n\n if (value.kind === 'collection') {\n return typeof value.collection === 'string'\n }\n\n if (value.kind === 'join') {\n return (\n typeof value.collection === 'string' &&\n typeof value.field === 'string' &&\n isStringOrNumber(value.id)\n )\n }\n\n return false\n}\n\nfunction isWebhookOrderMoved(value: unknown): value is WebhookOrderMoved {\n if (!isRecord(value)) return false\n\n return (\n typeof value.collection === 'string' &&\n isStringOrNumber(value.id) &&\n (value.relatedCollection === undefined ||\n typeof value.relatedCollection === 'string') &&\n (value.relatedId === undefined || isStringOrNumber(value.relatedId))\n )\n}\n\nfunction hasOptionalOrderValue(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return (\n value[key] === undefined ||\n value[key] === null ||\n typeof value[key] === 'string'\n )\n}\n\nfunction isWebhookOrderChange(value: unknown): value is WebhookOrderChange {\n if (!isRecord(value)) return false\n\n return (\n value.type === 'order' &&\n value.source === 'payload-orderable' &&\n (value.orderableFieldName === undefined ||\n typeof value.orderableFieldName === 'string') &&\n hasOptionalOrderValue(value, 'previousOrder') &&\n hasOptionalOrderValue(value, 'nextOrder') &&\n isWebhookOrderScope(value.scope) &&\n isWebhookOrderMoved(value.moved)\n )\n}\n\nfunction isCommerceNotificationEventName(\n value: unknown,\n): value is CommerceNotificationEventName {\n return (\n typeof value === 'string' &&\n (COMMERCE_NOTIFICATION_EVENTS as readonly string[]).includes(value)\n )\n}\n\nfunction isCommerceNotificationSourceCollection(\n value: unknown,\n): value is CommerceNotificationSourceCollection {\n return (\n value === 'orders' ||\n value === 'fulfillments' ||\n value === 'returns' ||\n value === 'payment-sessions' ||\n value === 'payment-refund-attempts' ||\n value === 'customer-memberships'\n )\n}\n\nfunction isCommerceNotificationData(\n value: unknown,\n): value is CommerceNotificationData {\n if (!isRecord(value)) return false\n if (\n value.source !== undefined &&\n (!isRecord(value.source) ||\n !isCommerceNotificationSourceCollection(value.source.collection) ||\n !isStringOrNumber(value.source.id))\n ) {\n return false\n }\n\n return (\n (value.orderId === undefined || isStringOrNumber(value.orderId)) &&\n (value.orderNumber === undefined ||\n typeof value.orderNumber === 'string') &&\n (value.status === undefined || typeof value.status === 'string') &&\n (value.totalAmount === undefined ||\n typeof value.totalAmount === 'number') &&\n (value.currency === undefined || typeof value.currency === 'string') &&\n (value.fulfillmentId === undefined ||\n isStringOrNumber(value.fulfillmentId)) &&\n (value.fulfillmentStatus === undefined ||\n typeof value.fulfillmentStatus === 'string') &&\n (value.shippedAt === undefined || typeof value.shippedAt === 'string') &&\n (value.returnId === undefined || isStringOrNumber(value.returnId)) &&\n (value.returnStatus === undefined ||\n typeof value.returnStatus === 'string') &&\n (value.refundAmount === undefined ||\n typeof value.refundAmount === 'number') &&\n (value.completedAt === undefined ||\n typeof value.completedAt === 'string') &&\n (value.paymentSessionId === undefined ||\n typeof value.paymentSessionId === 'string') &&\n (value.checkoutId === undefined || typeof value.checkoutId === 'string') &&\n (value.refundAttemptId === undefined ||\n typeof value.refundAttemptId === 'string') &&\n (value.reason === undefined || typeof value.reason === 'string') &&\n (value.observedAt === undefined || typeof value.observedAt === 'string') &&\n (value.providerObject === undefined ||\n (isRecord(value.providerObject) &&\n typeof value.providerObject.provider === 'string' &&\n (value.providerObject.kind === 'payment' ||\n value.providerObject.kind === 'refund') &&\n typeof value.providerObject.id === 'string')) &&\n (value.money === undefined ||\n (isRecord(value.money) &&\n Number.isSafeInteger(value.money.amountMinor) &&\n Number(value.money.amountMinor) > 0 &&\n typeof value.money.currency === 'string'))\n )\n}\n\nfunction isCommerceNotification(value: unknown): value is CommerceNotification {\n if (!isRecord(value)) return false\n return (\n isCommerceNotificationEventName(value.event) &&\n typeof value.intentId === 'string' &&\n value.intentId.length > 0 &&\n typeof value.dedupeKey === 'string' &&\n value.dedupeKey.length > 0 &&\n (value.orderId === undefined || typeof value.orderId === 'string') &&\n (value.fulfillmentId === undefined ||\n typeof value.fulfillmentId === 'string') &&\n (value.returnId === undefined || typeof value.returnId === 'string') &&\n (value.paymentSessionId === undefined ||\n typeof value.paymentSessionId === 'string') &&\n (value.refundAttemptId === undefined ||\n typeof value.refundAttemptId === 'string')\n )\n}\n\nfunction isPaymentIncidentNotificationData(\n value: CommerceNotificationData,\n event: PaymentIncidentNotificationEventName,\n): boolean {\n const reconciliation = event === 'paymentReconciliationRequired'\n const expectedCollection = reconciliation\n ? 'payment-sessions'\n : 'payment-refund-attempts'\n const expectedStatus = reconciliation\n ? 'reconciliation_required'\n : 'requires_attention'\n const expectedReason = reconciliation\n ? 'orderless_capture'\n : 'local_commit_ambiguous'\n\n return (\n value.source?.collection === expectedCollection &&\n typeof value.source.id === 'string' &&\n value.source.id.length > 0 &&\n typeof value.paymentSessionId === 'string' &&\n value.paymentSessionId.length > 0 &&\n isRecord(value.providerObject) &&\n typeof value.providerObject.provider === 'string' &&\n value.providerObject.provider.length > 0 &&\n (value.providerObject.kind === 'payment' ||\n value.providerObject.kind === 'refund') &&\n typeof value.providerObject.id === 'string' &&\n value.providerObject.id.length > 0 &&\n isRecord(value.money) &&\n Number.isSafeInteger(value.money.amountMinor) &&\n Number(value.money.amountMinor) > 0 &&\n typeof value.money.currency === 'string' &&\n value.money.currency.length > 0 &&\n value.status === expectedStatus &&\n value.reason === expectedReason &&\n typeof value.observedAt === 'string' &&\n value.observedAt.length > 0 &&\n !Number.isNaN(Date.parse(value.observedAt)) &&\n (value.checkoutId === undefined ||\n (typeof value.checkoutId === 'string' && value.checkoutId.length > 0)) &&\n (value.orderId === undefined ||\n (typeof value.orderId === 'string' && value.orderId.length > 0)) &&\n (reconciliation\n ? value.source.id === value.paymentSessionId &&\n value.providerObject.kind === 'payment' &&\n value.refundAttemptId === undefined\n : typeof value.refundAttemptId === 'string' &&\n value.refundAttemptId.length > 0 &&\n value.source.id === value.refundAttemptId)\n )\n}\n\nfunction isMembershipNotificationData(\n value: CommerceNotificationData,\n event: MembershipNotificationEventName,\n): boolean {\n const expectedStatus =\n event === 'membershipActivated'\n ? 'active'\n : event === 'membershipPastDue'\n ? 'past_due'\n : event === 'membershipExpired'\n ? 'expired'\n : 'cancelled'\n return (\n typeof value.membershipId === 'string' &&\n value.membershipId.length > 0 &&\n typeof value.planId === 'string' &&\n value.planId.length > 0 &&\n typeof value.customerId === 'string' &&\n value.customerId.length > 0 &&\n typeof value.fromStatus === 'string' &&\n value.fromStatus.length > 0 &&\n value.fromStatus !== value.toStatus &&\n value.toStatus === expectedStatus &&\n typeof value.occurredAt === 'string' &&\n !Number.isNaN(Date.parse(value.occurredAt))\n )\n}\n\nfunction isWebhookCommerceNotificationChange(\n value: unknown,\n): value is WebhookCommerceNotificationChange {\n if (!isRecord(value)) return false\n return (\n value.type === 'notification' &&\n value.source === 'commerce-notifications' &&\n isCommerceNotificationEventName(value.event) &&\n isCommerceNotificationSourceCollection(value.sourceCollection) &&\n isStringOrNumber(value.sourceId)\n )\n}\n\nfunction matchesOptionalId(\n actual: string | number | undefined,\n expected: string | number | undefined,\n): boolean {\n return actual === undefined || expected === undefined || actual === expected\n}\n\n/**\n * Returns true for semantic order-change webhooks emitted as update events.\n *\n * Use this guard with `ORDER_CHANGED_EVENT_TYPE` instead of filtering on\n * `operation: \"reorder\"`. Tenant order-change webhooks intentionally keep\n * `operation: \"update\"` for compatibility with existing webhook handlers.\n */\nexport function isOrderChangedWebhookEvent(\n event: unknown,\n): event is OrderChangedWebhookEvent<string, unknown> {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== 'update' ||\n event.eventType !== ORDER_CHANGED_EVENT_TYPE ||\n !isWebhookOrderChange(event.change)\n ) {\n return false\n }\n\n if (event.collection !== event.change.scope.collection) {\n return false\n }\n\n if (\n event.change.scope.kind === 'collection' &&\n event.change.moved.collection !== event.change.scope.collection\n ) {\n return false\n }\n\n return true\n}\n\n/**\n * Returns true for semantic commerce notification webhooks.\n *\n * Use `notification.intentId` and `notification.dedupeKey` for semantic\n * idempotency. `deliveryId`, when present, identifies a delivery attempt for\n * observability and is not the semantic notification identity.\n */\nexport function isCommerceNotificationWebhookEvent(\n event: unknown,\n): event is CommerceNotificationWebhookEvent {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== COMMERCE_NOTIFICATION_OPERATION ||\n event.eventType !== COMMERCE_NOTIFICATION_EVENT_TYPE ||\n !isCommerceNotificationData(event.data) ||\n !isCommerceNotification((event as { notification?: unknown }).notification)\n ) {\n return false\n }\n\n const notification = (event as unknown as CommerceNotificationWebhookEvent)\n .notification\n const data = event.data\n const change = event.change\n const sourceCollection = data.source?.collection ?? event.collection\n const sourceId = data.source?.id\n\n if (!isCommerceNotificationSourceCollection(sourceCollection)) return false\n if (\n data.source !== undefined &&\n event.collection !== data.source.collection\n ) {\n return false\n }\n\n if (change !== undefined) {\n if (!isWebhookCommerceNotificationChange(change)) return false\n if (change.sourceCollection !== sourceCollection) return false\n if (change.event !== notification.event) return false\n if (!matchesOptionalId(change.sourceId, sourceId)) return false\n }\n const changeSourceId = isWebhookCommerceNotificationChange(change)\n ? change.sourceId\n : undefined\n\n if (\n notification.event === 'paymentReconciliationRequired' ||\n notification.event === 'paymentRefundRequiresAttention'\n ) {\n if (!isPaymentIncidentNotificationData(data, notification.event)) {\n return false\n }\n const incidentData = data as PaymentIncidentNotificationData\n const expectedCollection =\n notification.event === 'paymentReconciliationRequired'\n ? 'payment-sessions'\n : 'payment-refund-attempts'\n const notificationSourceId =\n notification.event === 'paymentReconciliationRequired'\n ? notification.paymentSessionId\n : notification.refundAttemptId\n return (\n sourceCollection === expectedCollection &&\n typeof notification.paymentSessionId === 'string' &&\n notification.paymentSessionId === incidentData.paymentSessionId &&\n typeof notificationSourceId === 'string' &&\n notificationSourceId === incidentData.source.id &&\n matchesOptionalId(changeSourceId, incidentData.source.id)\n )\n }\n\n if (\n notification.event === 'membershipActivated' ||\n notification.event === 'membershipPastDue' ||\n notification.event === 'membershipExpired' ||\n notification.event === 'membershipCancelled'\n ) {\n return (\n sourceCollection === 'customer-memberships' &&\n isMembershipNotificationData(data, notification.event) &&\n typeof notification.membershipId === 'string' &&\n notification.membershipId === data.membershipId &&\n matchesOptionalId(changeSourceId, data.membershipId)\n )\n }\n\n if (\n notification.event === 'orderPaid' ||\n notification.event === 'orderCanceled' ||\n notification.event === 'orderDelivered'\n ) {\n return (\n sourceCollection === 'orders' &&\n typeof notification.orderId === 'string' &&\n notification.orderId.length > 0 &&\n matchesOptionalId(data.orderId, sourceId) &&\n matchesOptionalId(notification.orderId, sourceId) &&\n matchesOptionalId(data.orderId, notification.orderId) &&\n matchesOptionalId(changeSourceId, data.orderId ?? notification.orderId)\n )\n }\n\n if (notification.event === 'fulfillmentShipped') {\n return (\n sourceCollection === 'fulfillments' &&\n matchesOptionalId(data.fulfillmentId, sourceId) &&\n typeof notification.fulfillmentId === 'string' &&\n notification.fulfillmentId.length > 0 &&\n matchesOptionalId(notification.fulfillmentId, sourceId) &&\n matchesOptionalId(data.fulfillmentId, notification.fulfillmentId) &&\n matchesOptionalId(changeSourceId, notification.fulfillmentId)\n )\n }\n\n if (\n notification.event === 'returnRequested' ||\n notification.event === 'returnApproved' ||\n notification.event === 'returnRejected' ||\n notification.event === 'returnCanceled' ||\n notification.event === 'returnCompleted'\n ) {\n return (\n sourceCollection === 'returns' &&\n matchesOptionalId(data.returnId, sourceId) &&\n typeof notification.returnId === 'string' &&\n notification.returnId.length > 0 &&\n matchesOptionalId(notification.returnId, sourceId) &&\n matchesOptionalId(data.returnId, notification.returnId) &&\n matchesOptionalId(changeSourceId, notification.returnId)\n )\n }\n\n return false\n}\n\nexport function getCommerceNotificationIdempotencyKey(\n event: Pick<CommerceNotificationWebhookEvent, 'notification'>,\n): string {\n return `${event.notification.intentId}:${event.notification.dedupeKey}`\n}\n\nexport function defineCommerceEmailConfig<TConfig extends CommerceEmailConfig>(\n config: TConfig,\n): TConfig {\n return config\n}\n\nexport function createCommerceNotificationWebhookHandler(\n handlers: CommerceNotificationEventHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (!isCommerceNotificationWebhookEvent(event)) {\n await handlers.unhandled?.(event)\n return\n }\n\n const handler = handlers[event.notification.event]\n if (!handler) {\n await handlers.unhandled?.(event)\n return\n }\n\n await handler({\n event,\n idempotencyKey: getCommerceNotificationIdempotencyKey(event),\n })\n }\n}\n\nexport function createCommerceEmailWebhookHandler(\n handlers: CommerceEmailEventHandlers,\n): WebhookHandler<string, unknown> {\n return createCommerceNotificationWebhookHandler(handlers)\n}\n\n/** Narrows a webhook event to a specific collection. */\nexport function isWebhookCollection<TCollection extends string>(\n event: unknown,\n collection: TCollection,\n): event is WebhookEvent<TCollection, unknown> {\n return isValidWebhookEvent(event) && event.collection === collection\n}\n\n/** Narrows a webhook event to a specific operation. */\nexport function isWebhookOperation<TOperation extends string>(\n event: unknown,\n operation: TOperation,\n): event is WebhookEvent<string, unknown> & { operation: TOperation } {\n return isValidWebhookEvent(event) && event.operation === operation\n}\n\nexport const CUSTOMER_PASSWORD_RESET_OPERATION = 'password-reset' as const\n\nexport type WebhookKnownOperation =\n | CollectionWebhookOperation\n | typeof CUSTOMER_PASSWORD_RESET_OPERATION\n | typeof COMMERCE_NOTIFICATION_OPERATION\n\nexport interface CustomerPasswordResetWebhookData {\n customerId: string | number\n email: string\n name: string\n resetPasswordToken: string\n resetPasswordExpiresAt: string\n}\n\nexport type CustomerPasswordResetWebhookEvent = WebhookEvent<\n 'customers',\n CustomerPasswordResetWebhookData\n> & {\n operation: typeof CUSTOMER_PASSWORD_RESET_OPERATION\n}\n\nexport type CustomerAuthWebhookEvent = CustomerPasswordResetWebhookEvent\n\nexport interface CustomerAuthWebhookHandlers {\n passwordReset?: (\n data: CustomerPasswordResetWebhookData,\n event: CustomerPasswordResetWebhookEvent,\n ) => MaybePromise<void>\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction hasString(value: Record<string, unknown>, key: string): boolean {\n return typeof value[key] === 'string'\n}\n\nfunction hasStringOrNumber(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return typeof value[key] === 'string' || typeof value[key] === 'number'\n}\n\nexport function isCustomerPasswordResetWebhookEvent(\n event: WebhookEvent<string, unknown>,\n): event is CustomerPasswordResetWebhookEvent {\n if (\n event.collection !== 'customers' ||\n event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION ||\n !isRecord(event.data)\n ) {\n return false\n }\n\n return (\n hasStringOrNumber(event.data, 'customerId') &&\n hasString(event.data, 'email') &&\n hasString(event.data, 'name') &&\n hasString(event.data, 'resetPasswordToken') &&\n hasString(event.data, 'resetPasswordExpiresAt')\n )\n}\n\nexport function createCustomerAuthWebhookHandler(\n handlers: CustomerAuthWebhookHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (isCustomerPasswordResetWebhookEvent(event) && handlers.passwordReset) {\n await handlers.passwordReset(event.data, event)\n return\n }\n\n await handlers.unhandled?.(event)\n }\n}\n\n/**\n * @deprecated Import `handleSignedWebhook()` from `@01.software/sdk/webhook`.\n * This compatibility alias is signed and fails closed when its required secret\n * is missing or blank.\n */\nexport async function handleWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n options: WebhookOptions,\n): Promise<Response> {\n return handleSignedWebhookInternal(request, handler, options)\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(\n `Expected collection \"${collection}\", got \"${event.collection}\"`,\n )\n }\n return handler(event)\n }\n}\n","import type { Config } from '../../payload-types'\n\n/**\n * Internal collections that should not be exposed via SDK.\n * Includes Payload system collections and admin-only collections.\n */\nexport const INTERNAL_COLLECTIONS = [\n 'benefit-voucher-definitions',\n 'users',\n 'payload-kv',\n 'payload-locked-documents',\n 'payload-preferences',\n 'payload-migrations',\n 'payload-folders',\n 'field-configs',\n 'system-media',\n 'track-assets',\n 'audiences',\n 'email-logs',\n 'api-usage',\n 'tenant-mcp-usage-daily',\n 'subscriptions',\n 'billing-history',\n 'billing-consent-receipts',\n 'usage-rate-cards',\n 'usage-invoices',\n 'inventory-reservations',\n 'inventory-adjustments',\n 'payment-sessions',\n 'payment-event-inbox',\n 'payment-refund-attempts',\n 'portone-payment-interactions',\n 'commerce-payment-webhook-routes',\n 'commerce-notification-intents',\n 'commerce-idempotency-records',\n 'product-collection-items',\n 'order-status-logs',\n 'fulfillment-events',\n 'tenant-commerce-config',\n 'customer-oauth-clients',\n 'customer-consent-receipts',\n 'customer-group-grants',\n 'api-keys',\n 'personal-access-tokens',\n 'tenant-entitlements',\n 'tenant-purge-jobs',\n 'direct-upload-sessions',\n 'webhook-events',\n 'webhook-deliveries',\n 'webhook-outbox-deliveries',\n 'audit-logs',\n 'plans',\n 'webhooks',\n 'custom-field-definitions',\n 'event-registrations',\n 'event-admission-holds',\n 'event-admission-types',\n 'customer-payment-methods',\n 'tenant-payment-credentials',\n 'membership-unapplied-paid-evidence',\n 'commerce-payment-accounts',\n 'payment-provider-customer-aliases',\n] as const\n\nexport type InternalCollection = (typeof INTERNAL_COLLECTIONS)[number]\n\n/**\n * Array of browser-public collection names for runtime use (e.g., Zod enum validation).\n * This is the single source of truth for publishable-key collection discovery.\n */\nexport const COLLECTIONS = [\n 'tenant-metadata',\n 'products',\n 'product-variants',\n 'product-options',\n 'product-option-values',\n 'product-categories',\n 'product-tags',\n 'product-collections',\n 'markets',\n 'brands',\n 'customer-profiles',\n 'customer-profile-stats',\n 'shipping-policies',\n 'shipping-zones',\n 'documents',\n 'document-categories',\n 'document-types',\n 'articles',\n 'article-authors',\n 'article-categories',\n 'article-tags',\n 'playlists',\n 'playlist-categories',\n 'playlist-tags',\n 'tracks',\n 'track-categories',\n 'track-tags',\n 'galleries',\n 'gallery-categories',\n 'gallery-tags',\n 'gallery-items',\n 'links',\n 'link-categories',\n 'link-tags',\n 'canvases',\n 'canvas-node-types',\n 'canvas-edge-types',\n 'canvas-categories',\n 'canvas-tags',\n 'video-categories',\n 'video-tags',\n 'forms',\n // Community\n 'reaction-types',\n 'post-categories',\n 'post-tags',\n 'customer-profile-lists',\n // Events\n 'event-calendars',\n 'events',\n 'event-categories',\n 'event-occurrences',\n 'event-tags',\n 'membership-plans',\n 'membership-plan-prices',\n 'customer-memberships',\n] as const\n\n/**\n * Server-auth collection names for runtime use. These collections are safe for\n * secret-key/PAT SDK and MCP server tools, but must not appear in browser or\n * publishable-key collection discovery.\n */\nexport const SERVER_ONLY_COLLECTIONS = [\n // The tenant record itself denies reads without an authenticated user, so a\n // publishable key never reaches it; `tenant-metadata` is the browser-public\n // tenant identity surface.\n 'tenants',\n 'tenant-logos',\n 'brand-logos',\n 'images',\n 'videos',\n 'orders',\n 'order-tags',\n 'order-items',\n 'returns',\n 'return-items',\n 'refunds',\n 'refund-line-items',\n 'order-edit-sessions',\n 'order-staged-changes',\n 'fulfillment-orders',\n 'fulfillment-order-items',\n 'fulfillments',\n 'fulfillment-items',\n 'transactions',\n 'customers',\n 'customer-addresses',\n 'form-submissions',\n 'carts',\n 'cart-items',\n 'checkouts',\n 'checkout-items',\n // Raw discount definitions require a server credential. Browser discount\n // validation is exposed through the shaped POST /api/discounts/validate path.\n 'discounts',\n 'draft-orders',\n 'draft-order-items',\n 'posts',\n 'comments',\n 'reactions',\n 'bookmarks',\n 'live-streams',\n 'canvas-nodes',\n 'canvas-edges',\n 'customer-groups',\n 'reports',\n 'community-bans',\n 'order-export-profiles',\n 'membership-charges',\n] as const\n\n/**\n * Browser-public collections available for publishable-key SDK access.\n * Derived from the COLLECTIONS array (single source of truth).\n */\nexport type PublicCollection = (typeof COLLECTIONS)[number]\n\nexport type ServerOnlyCollection = (typeof SERVER_ONLY_COLLECTIONS)[number]\n\nexport const SERVER_COLLECTIONS = [\n ...COLLECTIONS,\n ...SERVER_ONLY_COLLECTIONS,\n] as const\n\nexport type ServerCollection = (typeof SERVER_COLLECTIONS)[number]\n\n/**\n * The published SDK collection universe is exactly the union of its three\n * existing addressability buckets. Generated Payload Config entries may also\n * contain Console-only collections that are intentionally outside this type.\n */\nexport type Collection =\n | PublicCollection\n | ServerOnlyCollection\n | InternalCollection\n\n/**\n * Compile-time classification checks: every published SDK collection belongs\n * to one of the three buckets, each bucket entry exists in generated Config,\n * and no collection is categorized more than once.\n */\ntype _Uncategorized = Exclude<\n Collection,\n PublicCollection | ServerOnlyCollection | InternalCollection\n>\nexport const _assertAllCategorized: [_Uncategorized] extends [never]\n ? true\n : _Uncategorized = true\n\ntype _UnknownGeneratedCollection = Exclude<\n Collection,\n keyof Config['collections']\n>\nexport const _assertAllSdkCollectionsExist: [\n _UnknownGeneratedCollection,\n] extends [never]\n ? true\n : _UnknownGeneratedCollection = true\n\ntype _Overcategorized =\n | Extract<PublicCollection, ServerOnlyCollection | InternalCollection>\n | Extract<ServerOnlyCollection, InternalCollection>\nexport const _assertNoDuplicateCategorization: [_Overcategorized] extends [\n never,\n]\n ? true\n : _Overcategorized = true\n","/**\n * Fetch-based SSE connection manager for real-time collection change events.\n * Uses fetch + ReadableStream to support custom auth headers (unlike native EventSource).\n */\n\nexport interface RealtimeEvent {\n collection: string\n operation: string\n id: string | null\n timestamp: string\n}\n\nexport type RealtimeListener = (event: RealtimeEvent) => void\n\nconst INITIAL_RECONNECT_DELAY = 1_000\nconst MAX_RECONNECT_DELAY = 30_000\nconst RECONNECT_BACKOFF_FACTOR = 2\nconst MAX_NO_TOKEN_RETRIES = 5\n\nexport class RealtimeConnection {\n private abortController: AbortController | null = null\n private reconnectAttempt = 0\n private noTokenAttempts = 0\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null\n private listeners = new Set<RealtimeListener>()\n private _connected = false\n\n constructor(\n private baseUrl: string,\n private publishableKey: string,\n private getToken: () => string | null,\n private collections?: string[],\n ) {}\n\n get connected(): boolean {\n return this._connected\n }\n\n addListener(fn: RealtimeListener): () => void {\n this.listeners.add(fn)\n return () => this.listeners.delete(fn)\n }\n\n connect(): void {\n if (this.abortController) return // Already connecting/connected\n\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }\n\n disconnect(): void {\n this._connected = false\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer)\n this.reconnectTimer = null\n }\n if (this.abortController) {\n this.abortController.abort()\n this.abortController = null\n }\n this.reconnectAttempt = 0\n this.noTokenAttempts = 0\n }\n\n private async startStream(signal: AbortSignal): Promise<void> {\n const token = this.getToken()\n if (!token) {\n this.noTokenAttempts++\n if (this.noTokenAttempts >= MAX_NO_TOKEN_RETRIES) {\n // Stop reconnecting — no token available after multiple attempts\n this._connected = false\n this.abortController = null\n return\n }\n this.scheduleReconnect()\n return\n }\n this.noTokenAttempts = 0\n\n const params = this.collections?.length\n ? `?collections=${this.collections.join(',')}`\n : ''\n const url = `${this.baseUrl}/api/events/stream${params}`\n\n try {\n const response = await fetch(url, {\n headers: {\n 'X-Publishable-Key': this.publishableKey,\n Authorization: `Bearer ${token}`,\n },\n signal,\n })\n\n if (!response.ok) {\n if (response.status === 401) {\n // Token expired — try reconnecting (will get fresh token)\n this.scheduleReconnect()\n return\n }\n throw new Error(`SSE connection failed: ${response.status}`)\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body')\n }\n\n this._connected = true\n this.reconnectAttempt = 0\n\n await this.readStream(response.body, signal)\n } catch {\n if (signal.aborted) return // Intentional disconnect\n this._connected = false\n this.scheduleReconnect()\n }\n }\n\n private async readStream(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n ): Promise<void> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent = ''\n let currentData = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done || signal.aborted) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? '' // Keep incomplete last line in buffer\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7)\n } else if (line.startsWith('data: ')) {\n currentData += (currentData ? '\\n' : '') + line.slice(6)\n } else if (line === '') {\n // Empty line = end of event\n if (currentEvent === 'collection:change' && currentData) {\n try {\n const event: RealtimeEvent = JSON.parse(currentData)\n for (const listener of this.listeners) {\n try {\n listener(event)\n } catch {\n // Listener error — ignore\n }\n }\n } catch {\n // Malformed JSON — ignore\n }\n }\n currentEvent = ''\n currentData = ''\n }\n // Ignore comment lines (: heartbeat)\n }\n }\n } catch {\n // Stream read error\n } finally {\n reader.releaseLock()\n this._connected = false\n if (!signal.aborted) {\n this.scheduleReconnect()\n }\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return\n\n const delay = Math.min(\n INITIAL_RECONNECT_DELAY *\n Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),\n MAX_RECONNECT_DELAY,\n )\n this.reconnectAttempt++\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }, delay)\n }\n}\n","/** Palette colors extracted from an image */\nexport interface ImagePalette {\n vibrant?: string | null\n muted?: string | null\n darkVibrant?: string | null\n darkMuted?: string | null\n lightVibrant?: string | null\n lightMuted?: string | null\n}\n\n/** Structural image size entry accepted by public image helpers. */\nexport interface ImageDataSizeEntry {\n url?: string | null\n width?: number | null\n height?: number | null\n}\n\n/** Structural image sizes accepted from Payload upload-like collections. */\nexport type ImageDataSizes = Partial<\n Record<string, ImageDataSizeEntry | null | undefined>\n>\n\n/** Common image data shape from Payload CMS upload collections */\nexport interface ImageData {\n url?: string | null\n width?: number | null\n height?: number | null\n alt?: string | null\n lqip?: string | null\n palette?: ImagePalette | null\n sizes?: ImageDataSizes\n}\n\n/** Pre-generated image size breakpoints (px), aligned with Payload Image.sizes. */\nexport const IMAGE_SIZES = [200, 400, 800, 1200, 1600] as const\n\n/** Numeric rendition keys from `IMAGE_SIZES` plus any numeric keys on the image. */\nfunction imageSizeCandidates(sizes: ImageDataSizes): number[] {\n const keys = new Set<number>(IMAGE_SIZES)\n for (const key of Object.keys(sizes)) {\n const value = Number(key)\n if (Number.isFinite(value) && value > 0) keys.add(value)\n }\n return [...keys].sort((a, b) => a - b)\n}\n\n/**\n * Returns the optimal image URL for a given display width.\n *\n * Picks the smallest pre-generated size whose width >= displayWidth × dpr.\n * Falls back to the original URL when no matching size exists.\n *\n * @param image - Payload image document\n * @param displayWidth - CSS pixel width the image will be displayed at\n * @param dpr - Device pixel ratio (default: 1)\n * @returns URL string, or empty string if no URL is available\n */\nexport function getImageUrl(\n image: ImageData,\n displayWidth: number,\n dpr: number = 1,\n): string {\n const target = displayWidth * dpr\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of imageSizeCandidates(sizes)) {\n if (size >= target) {\n const entry = sizes[`${size}`]\n if (entry?.url) return entry.url\n }\n }\n }\n\n return image.url ?? ''\n}\n\n/**\n * Generates an HTML `srcset` attribute string from pre-generated sizes.\n *\n * Includes all available sizes plus the original image.\n * Example output: `\"url-200 200w, url-400 400w, url-800 800w, url-1200 1200w, url-1600 1600w, url-original 2000w\"`\n *\n * @param image - Payload image document\n * @returns srcset string, or empty string if no URLs are available\n */\nexport function getImageSrcSet(image: ImageData): string {\n const parts: string[] = []\n const emittedWidths = new Set<number>()\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of imageSizeCandidates(sizes)) {\n const entry = sizes[`${size}`]\n if (entry?.url && entry.width && !emittedWidths.has(entry.width)) {\n emittedWidths.add(entry.width)\n parts.push(`${entry.url} ${entry.width}w`)\n }\n }\n }\n\n if (image.url && image.width && !emittedWidths.has(image.width)) {\n parts.push(`${image.url} ${image.width}w`)\n }\n\n return parts.join(', ')\n}\n\n/**\n * Returns the LQIP (Low Quality Image Placeholder) data URL for an image.\n *\n * @param image - Payload image document\n * @returns LQIP data URL string, or undefined if not available\n */\nexport function getImageLqip(image: ImageData): string | undefined {\n return image.lqip ?? undefined\n}\n\n/**\n * Returns the extracted color palette for an image.\n *\n * @param image - Payload image document\n * @returns ImagePalette object, or undefined if not available\n */\nexport function getImagePalette(image: ImageData): ImagePalette | undefined {\n return image.palette ?? undefined\n}\n\n/** Options for `getImagePlaceholderStyle` */\nexport interface ImagePlaceholderOptions {\n /** Placeholder strategy (default: 'blur') */\n type?: 'blur' | 'color' | 'none'\n /** Which palette color to use for 'color' strategy (default: 'muted') */\n paletteColor?: keyof ImagePalette\n}\n\n/**\n * Returns inline CSS styles for an image placeholder.\n *\n * - `blur`: uses LQIP as background, falls back to palette color, then empty\n * - `color`: uses palette color as background, falls back to empty\n * - `none`: always returns empty\n *\n * @param image - Payload image document\n * @param options - Placeholder options\n * @returns CSS style object compatible with React CSSProperties\n */\nexport function getImagePlaceholderStyle(\n image: ImageData,\n options?: ImagePlaceholderOptions,\n): Record<string, string> {\n const type = options?.type ?? 'blur'\n const paletteColor = options?.paletteColor ?? 'muted'\n\n if (type === 'none') return {}\n\n const color = image.palette?.[paletteColor]\n\n if (type === 'blur') {\n const lqip = image.lqip\n if (lqip) {\n return {\n backgroundImage: `url(${lqip})`,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }\n }\n // Cascade: fall back to color\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n }\n\n // type === 'color'\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n}\n","export const generateOrderNumber = () => {\n // YYMMDDRRRRRR\n const now = new Date()\n const year = now.getFullYear().toString().slice(-2)\n const month = (now.getMonth() + 1).toString().padStart(2, '0')\n const day = now.getDate().toString().padStart(2, '0')\n // Use crypto.getRandomValues for cryptographically secure randomness (works in both browser and Node.js)\n const array = new Uint32Array(1)\n globalThis.crypto.getRandomValues(array)\n const random = ((array[0] ?? 0) % 1000000).toString().padStart(6, '0')\n\n return `${year}${month}${day}${random}`\n}\n","import { Product } from '../../payload-types'\nimport { resolveRelation } from '../types'\n\ntype OrderItem = {\n product: Product | string | null | undefined\n}\n\nexport const formatOrderName = (items: OrderItem[]) => {\n if (items.length === 0) return ''\n\n const firstTitle = resolveRelation(items[0]?.product)?.title || ''\n\n return items.length === 1\n ? firstTitle\n : `${firstTitle} 외 ${items.length - 1}건`\n}\n","const MUX_IMAGE_BASE = 'https://image.mux.com'\nconst MUX_STREAM_BASE = 'https://stream.mux.com'\n\n// ── Thumbnail ──\n\nexport interface VideoThumbnailOptions {\n /** Width in pixels (default: 640) */\n width?: number\n /** Height in pixels (auto if omitted) */\n height?: number\n /** Time offset in seconds (default: 0) */\n time?: number\n /** Fit mode (default: 'smartcrop') */\n fitMode?: 'preserve' | 'stretch' | 'crop' | 'smartcrop' | 'pad'\n /** Flip horizontally */\n flipH?: boolean\n /** Flip vertically */\n flipV?: boolean\n /** Rotation in degrees (90, 180, 270) */\n rotate?: 90 | 180 | 270\n}\n\n/**\n * Returns a Mux thumbnail URL for a video.\n *\n * @example\n * ```ts\n * getVideoThumbnail('abc123')\n * // => 'https://image.mux.com/abc123/thumbnail.jpg?width=640'\n *\n * getVideoThumbnail('abc123', { width: 320, time: 5 })\n * // => 'https://image.mux.com/abc123/thumbnail.jpg?width=320&time=5'\n * ```\n */\nexport function getVideoThumbnail(\n playbackId: string,\n options?: VideoThumbnailOptions,\n): string {\n const params = new URLSearchParams()\n params.set('width', String(options?.width ?? 640))\n if (options?.height) params.set('height', String(options.height))\n if (options?.time != null) params.set('time', String(options.time))\n if (options?.fitMode) params.set('fit_mode', options.fitMode)\n if (options?.flipH) params.set('flip_h', 'true')\n if (options?.flipV) params.set('flip_v', 'true')\n if (options?.rotate) params.set('rotate', String(options.rotate))\n return `${MUX_IMAGE_BASE}/${playbackId}/thumbnail.jpg?${params}`\n}\n\n// ── Animated GIF ──\n\nexport interface VideoGifOptions {\n /** Width in pixels (default: 320) */\n width?: number\n /** Start time in seconds (default: 0) */\n start?: number\n /** End time in seconds (default: start + 5) */\n end?: number\n /** Frames per second (default: 15) */\n fps?: number\n}\n\n/**\n * Returns a Mux animated GIF URL for a video.\n *\n * @example\n * ```ts\n * getVideoGif('abc123')\n * // => 'https://image.mux.com/abc123/animated.gif?width=320'\n *\n * getVideoGif('abc123', { width: 240, start: 2, end: 6 })\n * // => 'https://image.mux.com/abc123/animated.gif?width=240&start=2&end=6'\n * ```\n */\nexport function getVideoGif(\n playbackId: string,\n options?: VideoGifOptions,\n): string {\n const params = new URLSearchParams()\n params.set('width', String(options?.width ?? 320))\n if (options?.start != null) params.set('start', String(options.start))\n if (options?.end != null) params.set('end', String(options.end))\n if (options?.fps) params.set('fps', String(options.fps))\n return `${MUX_IMAGE_BASE}/${playbackId}/animated.gif?${params}`\n}\n\n// ── Storyboard ──\n\n/**\n * Returns a Mux storyboard VTT URL for timeline hover previews.\n *\n * @example\n * ```ts\n * getVideoStoryboard('abc123')\n * // => 'https://image.mux.com/abc123/storyboard.vtt'\n * ```\n */\nexport function getVideoStoryboard(playbackId: string): string {\n return `${MUX_IMAGE_BASE}/${playbackId}/storyboard.vtt`\n}\n\n// ── Stream / Playback URLs ──\n\n/**\n * Returns the HLS stream URL for a video.\n *\n * @example\n * ```ts\n * getVideoStreamUrl('abc123')\n * // => 'https://stream.mux.com/abc123.m3u8'\n * ```\n */\nexport function getVideoStreamUrl(playbackId: string): string {\n return `${MUX_STREAM_BASE}/${playbackId}.m3u8`\n}\n\n/**\n * Returns a Mux MP4 download URL for a video.\n * Only available if the asset was created with `mp4_support` enabled.\n *\n * @example\n * ```ts\n * getVideoMp4Url('abc123', 'high')\n * // => 'https://stream.mux.com/abc123/high.mp4'\n * ```\n */\nexport function getVideoMp4Url(\n playbackId: string,\n resolution: 'high' | 'medium' | 'low' = 'high',\n): string {\n return `${MUX_STREAM_BASE}/${playbackId}/${resolution}.mp4`\n}\n"],"mappings":"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","names":["createClient","method","object","uuid","time","object","value","uuid","time","key","page","operation","operation","value","value","money","operation","DEFAULT_TIMEOUT","operation","DEFAULT_TIMEOUT","operation","mediaArray","item","operation","normalizedMarket","options","timestamp","operation","delay","array","createClient"]}