modelence 0.15.2-dev.0 → 0.15.2
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.
- package/dist/chunk-Z6AXX2IR.js +3 -0
- package/dist/chunk-Z6AXX2IR.js.map +1 -0
- package/dist/client.d.ts +1 -13
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/{package-O4GYADO2.js → package-FKRLR6XH.js} +2 -2
- package/dist/{package-O4GYADO2.js.map → package-FKRLR6XH.js.map} +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +7 -7
- package/dist/server.js.map +1 -1
- package/dist/{types-CoDMtVYU.d.ts → types-CIL2Bj_2.d.ts} +21 -3
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-MF6PQMFH.js +0 -3
- package/dist/chunk-MF6PQMFH.js.map +0 -1
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app/module.ts","../src/data/schemaSerializer.ts","../src/data/store.ts","../src/data/types.ts","../src/auth/session.ts","../src/auth/db.ts","../src/auth/role.ts","../src/auth/index.ts","../src/system/index.ts","../src/db/client.ts","../src/live-query/context.ts","../src/utils/index.ts","../src/methods/index.ts","../src/live-query/handlers.ts","../src/websocket/socketio/server.ts","../src/auth/disposableEmails.ts","../src/app/emailConfig.ts","../src/auth/validators.ts","../src/app/authConfig.ts","../src/auth/login.ts","../src/auth/profile.ts","../src/auth/types.ts","../src/auth/unlinkOAuthProvider.ts","../src/rate-limit/db.ts","../src/rate-limit/rules.ts","../src/auth/templates/emailVerficationTemplate.ts","../src/auth/verification.ts","../src/auth/utils.ts","../src/auth/signup.ts","../src/auth/resetPassword.ts","../src/auth/user.ts","../src/config/local.ts","../src/app/backendApi.ts","../src/config/sync.ts","../src/lock/db.ts","../src/lock/helpers.ts","../src/cron/jobs.ts","../src/lock/module.ts","../src/migration/db.ts","../src/migration/index.ts","../src/rate-limit/index.ts","../src/files/index.ts","../src/viteServer.ts","../src/auth/providers/oauth-common.ts","../src/auth/providers/google.ts","../src/auth/providers/github.ts","../src/routes/handler.ts","../src/app/securityConfig.ts","../src/app/websocketConfig.ts","../src/app/server.ts","../src/app/index.ts","../src/auth/deleteUser.ts","../src/websocket/serverChannel.ts","../src/app/email.ts"],"names":["Module","name","stores","queries","mutations","routes","cronJobs","configSchema","rateLimits","channels","key","getConfig","serializeZodSchema","zodType","def","shape","serializedShape","value","effectsDef","serializeModelSchema","schema","serialized","item","COMPARABLE_INDEX_OPTION_FIELDS","isDocumentRecord","hasModelencePrefix","getComparableIndexOptions","index","options","field","isSameIndexKey","left","right","leftEntries","rightEntries","leftField","leftDirection","rightField","rightDirection","isDeepStrictEqual","isSameIndexDefinition","existing","desired","getIndexKeySignature","direction","listIndexes","collection","error","MongoError","generateAutoIndexName","normalizeIndexName","autoName","Store","_Store","config","extendedSchema","extendedIndexes","extendedSearchIndexes","combinedMethods","extendedStore","client","existingIndexes","indexByName","indexNamesByKey","droppedIndexNames","addIndexToLookup","existingIndex","keySignature","names","removeIndexFromLookup","indexName","dropIndexIfNeeded","currentIndexNames","idx","orphanedIndexes","existingIdx","orphanedIndex","existingByName","existingNamesForKey","existingName","alignedIndex","searchIndex","document","selector","ObjectId","query","errorHandler","result","cursor","id","idSelector","documents","update","replacement","filter","f","pipeline","operations","oldName","db","embedding","numCandidates","limit","projection","dimensions","similarity","schemaString","z","schemaNumber","schemaDate","schemaBoolean","schemaArray","schemaObject","schemaEnum","_collection","_schema","sessionsCollection","obtainSession","authToken","existingSession","createSession","setSessionUser","userId","clearSessionUser","randomBytes","now","expiresAt","time","processSessionHeartbeat","session","newExpiresAt","session_default","args","user","getPublicConfigs","usersCollection","dbDisposableEmailDomains","emailVerificationTokensCollection","resetPasswordTokensCollection","roleMap","defaultRoles","initRoles","roles","_defaultRoles","definition","getUnauthenticatedRoles","getDefaultAuthenticatedRoles","requireAccess","requiredPermissions","missingPermission","permission","hasPermission","role","authenticate","userDoc","system_default","connect","mongodbUri","getMongodbUri","maxPoolSize","MongoClient","package_default","err","getClient","LiveData","isServer","requireServer","htmlToText","html","methods","createQuery","methodDef","validateMethodName","_createMethodInternal","createMutation","_createSystemQuery","validateSystemMethodName","_createSystemMutation","type","handler","permissions","runMethod","context","method","transaction","startTransaction","response","runLiveMethod","socketSubscriptions","getSocketSubs","socket","subs","handleSubscribeLiveQuery","payload","parsed","subscriptionId","clientInfo","existingSub","subscription","liveData","fetchAndEmit","data","sanitizeResult","getResponseTypeMap","isPendingPublish","isFetching","processPendingPublish","cleanup","handleUnsubscribeLiveQuery","sub","handleLiveQueryDisconnect","socketServer","COLLECTION","init","httpServer","mongodbClient","mongoCollection","SocketServer","createAdapter","next","token","channelName","category","authorized","channel","broadcast","server_default","isDisposableEmail","email","emailParts","domain","updateDisposableEmailListCron","domains","batchSize","batch","emailConfig","setEmailConfig","newEmailConfig","getEmailConfig","MIN_HANDLE_LENGTH","MAX_HANDLE_LENGTH","trimmedNonEmptyString","opts","trimmedOptionalString","val","profileFieldsSchema","validateProfileFields","fields","issue","path","msg","validatePassword","validateEmail","validateHandle","authConfig","setAuthConfig","newAuthConfig","getAuthConfig","handleLoginWithPassword","connectionInfo","ip","consumeRateLimit","password","passwordHash","incorrectCredentialsError","e","bcrypt","handleLogout","getOwnProfile","props","profile","handleUpdateProfile","setFields","unsetFields","mongoUpdate","clearedFields","SUPPORTED_OAUTH_PROVIDERS","handleUnlinkOAuthProvider","provider","otherMethods","otherMethodGuard","dbRateLimits","allRules","initRateLimits","bucket","message","rules","rule","createError","RateLimitError","checkRateLimitRule","createRateLimitError","record","currentWindowStart","count","modifier","getCount","prevWindowStart","currentWindowCount","prevWindowCount","prevWindowWeight","weight","emailVerificationTemplate","verificationUrl","handleVerifyEmail","params","baseUrl","emailVerifiedRedirectUrl","tokenDoc","sendVerificationEmail","emailProvider","verificationToken","htmlTemplate","textContent","resendVerificationResponse","handleResendEmailVerification","emailDoc","findAvailableHandle","baseHandle","truncatedBase","MAX_SUFFIX_VALUE","suffix","suffixStr","candidate","MAX_RANDOM_ATTEMPTS","attempt","randomSuffix","resolveUniqueHandle","rawHandle","throwOnConflict","handle","handleSignupWithPassword","signupProps","firstName","lastName","avatarUrl","existingUser","existingEmail","profileFields","resolvedHandle","generated","hash","userDocument","resolveUrl","configuredUrl","defaultPasswordResetTemplate","resetUrl","passwordResetSent","handleSendResetPasswordToken","resetToken","createdAt","handleResetPassword","resetTokenDoc","user_default","localConfigMap","formatLocalConfigValue","numValue","getConfigsFromEnvMap","configMap","configs","envVar","configKey","configSchemaEntry","getLocalConfigs","variant","connectCloudBackend","cronJobsMetadata","containerId","dataModels","store","callApi","os","fetchConfigs","syncStatus","endpoint","callCloudApi","body","extraHeaders","MODELENCE_SERVICE_ENDPOINT","MODELENCE_SERVICE_TOKEN","json","isSyncing","SYNC_INTERVAL","startConfigSync","syncConfig","loadRemoteConfigs","loadConfigs","getSchema","locksCollection","lockCache","DEFAULT_CACHE_DURATION","INSTANCE_ID","DEFAULT_LOCK_DURATION","lockHeartbeats","isDuplicateKeyError","hasKeyPatternField","shouldFallbackToLegacyStrategy","resource","existingLock","tryAcquireLockById","staleThresholdDate","instanceId","deleteLegacyLock","stopLockHeartbeat","heartbeatKey","heartbeat","startLockHeartbeat","lockDuration","heartbeatInterval","existingHeartbeat","scheduleRefresh","acquireLock","isLockAcquired","logDebug","successfulLockCacheDuration","failedLockCacheDuration","bypassCache","acquireLockById","retryError","releaseLock","cronJobsInterval","cronJobsCollection","defineCronJob","alias","description","interval","timeout","startCronJobs","aliasList","aliasSelector","cronJobRecords","job","tickCronJobs","state","runCronJob","handleCronJobCompletion","captureError","getCronJobsMetadata","jobs_default","module_default","dbMigrations","runMigrations","migrations","logInfo","versions","version","existingVersions","existingVersionSet","pendingMigrations","outputStr","maxSize","truncatedOutput","startMigrations","migration_default","rate_limit_default","getUploadUrl","filePath","contentType","visibility","deleteFile","downloadFile","getFileUrl","files_default","ViteServer","createServer","staticFolders","express","req","res","loadUserViteConfig","appDir","loadConfigFromFile","safelyMergeConfig","baseConfig","userConfig","mergedConfig","mergeConfig","seenPlugins","plugin","pluginName","eslintConfigFile","file","fs","plugins","reactPlugin","modelenceAssetPlugin","eslintPlugin","defineConfig","code","viteServer","authenticateUser","handleExistingProviderLogin","userData","handleExistingEmailLogin","existingUserByEmail","profileUpdate","updatedUser","handleNewUserSignup","newUser","getRedirectUri","handleOAuthUserAuthentication","getCallContext","clearOAuthLinkCookie","safelyCallHook","hook","validateOAuthStateAndGetMode","stateCookieName","storedState","storedStateValue","storedMode","handleOAuthProviderLink","providerField","currentUser","existingProviderId","MongoServerError","validateOAuthCode","exchangeCodeForToken","clientId","clientSecret","redirectUri","tokenResponse","fetchGoogleUserInfo","accessToken","userInfoResponse","handleGoogleAuthenticationCallback","mode","googleClientId","googleClientSecret","tokenData","googleUser","getRouter","googleAuthRouter","Router","checkGoogleEnabled","_req","googleEnabled","authUrl","google_default","fetchGitHubUserInfo","fetchGitHubUserEmails","getGitHubUserEmail","githubUser","handleGitHubAuthenticationCallback","githubClientId","githubClientSecret","githubEmail","nameParts","githubAuthRouter","checkGitHubEnabled","githubEnabled","githubScopes","scopes","s","github_default","createRouteHandler","ModelenceError","securityConfig","setSecurityConfig","newSecurityConfig","getSecurityConfig","websocketConfig","setWebsocketConfig","newWebsocketConfig","getWebsocketConfig","getBodyParserMiddleware","middlewares","jsonOptions","urlencodedOptions","rawOptions","defaultRawOptions","registerModuleRoutes","app","modules","module","route","handlers","startServer","server","combinedModules","cookieParser","securityHeadersMiddleware","methodName","handleMethodError","http","reason","promise","websocketProvider","port","siteUrl","isOAuthCallback","getClientIp","errorMessage","parseZodError","parsingError","zodError","flattened","fieldMessages","errors","formMessages","frameAncestors","hasCustomAncestors","ancestors","forwardedFor","directIp","startApp","auth","security","websocket","dotenv","hasRemoteBackend","trackAppStart","systemModules","markAppStarted","initSystemMethods","initCustomMethods","getConfigSchema","setSchema","getStores","getChannels","defineCronJobs","getRateLimits","environmentId","appAlias","environmentAlias","telemetry","setMetadata","initStores","createIndexesWithLock","initMetrics","warnIndexCreationFailure","storeName","INDEXES_LOCK_RESOURCE","releaseHandledByBackgroundTask","blockingStores","backgroundStores","createStoreIndexes","merged","absoluteKey","cronAlias","cronJobParams","serviceEndpoint","appDetails","getAppDetails","modelencePackageJson","packageJsonPath","packageJsonContent","clearTokens","disableUser","deleteUser","randomUUID","ServerChannel","canAccessChannel","logError","sendEmail"],"mappings":"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","file":"server.js","sourcesContent":["import { ConfigSchema, ConfigParams, ValueType } from '../config/types';\nimport { getConfig as _getConfig } from '../config/server';\nimport { CronJobInputParams } from '../cron/types';\nimport { Store } from '../data/store';\nimport { AnyMethodShape } from '../methods/types';\nimport { RouteDefinition } from '../routes/types';\nimport { RateLimitRule } from '../rate-limit/types';\nimport { ServerChannel } from '@/websocket/serverChannel';\n\n/** Array of Store instances that will be provisioned when the module is loaded */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Stores = Store<any, any>[];\n\n/** Record of query methods that can be called from the client */\ntype Queries = Record<string, AnyMethodShape>;\n\n/** Record of mutation methods that can be called from the client */\ntype Mutations = Record<string, AnyMethodShape>;\n\n/**\n * The Module class is a core building block of a Modelence application that encapsulates related functionality.\n * Modules can contain stores, queries, mutations, routes, cron jobs and configurations.\n *\n * @category Module\n *\n * @example\n * ```ts\n * const todoModule = new Module('todo', {\n * stores: [dbTodos],\n * queries: {\n * async getAll() {\n * // Fetch and return all Todo items\n * }\n * },\n * mutations: {\n * async create({ title }, { user }) {\n * // Create a new Todo item\n * }\n * }\n * });\n * ```\n */\nexport class Module<\n TName extends string = string,\n TSchema extends Record<string, ConfigParams> = ConfigSchema,\n TQueries extends Queries = Queries,\n TMutations extends Mutations = Mutations,\n> {\n /** @internal */\n public readonly name: TName;\n\n /** @internal */\n public readonly stores: Stores;\n\n /** @internal */\n public readonly queries: TQueries;\n\n /** @internal */\n public readonly mutations: TMutations;\n\n /** @internal */\n public readonly routes: RouteDefinition[];\n\n /** @internal */\n public readonly cronJobs: Record<string, CronJobInputParams>;\n\n /** @internal */\n public readonly configSchema: TSchema;\n\n /** @internal */\n public readonly rateLimits: RateLimitRule[];\n\n /** @internal */\n public readonly channels: ServerChannel[];\n\n /**\n * Creates a new Module instance\n *\n * @param name - The unique name of the module.\n * This name is used to namespace queries, mutations,\n * cron jobs and configuration values with a prefix (e.g. \"todo.create\")\n *\n * @param options - Module configuration options\n */\n constructor(\n name: TName,\n {\n stores = [],\n queries = {} as TQueries,\n mutations = {} as TMutations,\n routes = [],\n cronJobs = {},\n configSchema = {} as TSchema,\n rateLimits = [],\n channels = [],\n }: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stores?: Store<any, any>[];\n queries?: TQueries;\n mutations?: TMutations;\n routes?: RouteDefinition[];\n cronJobs?: Record<string, CronJobInputParams>;\n configSchema?: TSchema;\n rateLimits?: RateLimitRule[];\n channels?: ServerChannel[];\n } = {}\n ) {\n this.name = name;\n this.stores = stores;\n this.queries = queries;\n this.mutations = mutations;\n this.routes = routes;\n this.cronJobs = cronJobs;\n this.configSchema = configSchema;\n this.rateLimits = rateLimits;\n this.channels = channels;\n }\n\n /**\n * Retrieves a typed configuration value for this module.\n * The return type is inferred from the schema — no casts needed.\n *\n * @example\n * ```ts\n * const myModule = new Module('payments', {\n * configSchema: {\n * apiKey: { type: 'secret', default: '', isPublic: false },\n * maxRetries: { type: 'number', default: 3, isPublic: false },\n * },\n * mutations: {\n * async charge({ amount }) {\n * const apiKey = myModule.getConfig('apiKey'); // string\n * const maxRetries = myModule.getConfig('maxRetries'); // number\n * },\n * },\n * });\n * ```\n */\n getConfig<K extends keyof TSchema & string>(key: K): ValueType<TSchema[K]['type']> {\n return _getConfig(`${this.name}.${key}`) as ValueType<TSchema[K]['type']>;\n }\n}\n","import { z } from 'zod';\nimport { ModelSchema } from './types';\n\ntype ObjectTypeDefinition = {\n [key: string]: z.ZodType | ObjectTypeDefinition | Array<z.ZodType | ObjectTypeDefinition>;\n};\n\nexport interface SerializedModelSchema {\n [key: string]:\n | SerializedSchema\n | (SerializedSchema | SerializedModelSchema)[]\n | SerializedModelSchema\n | 'v2';\n}\n\n// Type guards for Zod schema types\ntype ZodDefWithTypeName = {\n typeName: z.ZodFirstPartyTypeKind;\n};\n\ntype ZodArrayDef = ZodDefWithTypeName & {\n type: z.ZodType;\n};\n\ntype ZodObjectDef = ZodDefWithTypeName & {\n shape: () => Record<string, z.ZodType>;\n};\n\ntype ZodOptionalDef = ZodDefWithTypeName & {\n innerType: z.ZodType;\n};\n\ntype ZodNullableDef = ZodDefWithTypeName & {\n innerType: z.ZodType;\n};\n\ntype ZodEnumDef = ZodDefWithTypeName & {\n values: readonly [string, ...string[]];\n};\n\ntype ZodUnionDef = ZodDefWithTypeName & {\n options: readonly [z.ZodType, z.ZodType, ...z.ZodType[]];\n};\n\ntype ZodEffectsDef = ZodDefWithTypeName & {\n schema: z.ZodType;\n effect: { type: 'refinement' | 'transform' | 'preprocess' };\n description?: string;\n};\n\ntype BaseSerializedSchema =\n | { type: 'string' }\n | { type: 'number' }\n | { type: 'boolean' }\n | { type: 'date' }\n | { type: 'array'; items: SerializedSchema }\n | { type: 'object'; items: Record<string, SerializedSchema> }\n | { type: 'enum'; items: readonly string[] }\n | { type: 'union'; items: SerializedSchema[] }\n | { type: 'custom'; typeName: string };\n\ntype SerializedSchema = BaseSerializedSchema | (BaseSerializedSchema & { optional: true });\n\n/**\n * Serializes a Zod schema to a JSON-serializable format\n */\nfunction serializeZodSchema(zodType: z.ZodType): SerializedSchema {\n const def = zodType._def as ZodDefWithTypeName;\n\n if (def.typeName === 'ZodString') {\n return { type: 'string' };\n }\n if (def.typeName === 'ZodNumber') {\n return { type: 'number' };\n }\n if (def.typeName === 'ZodBoolean') {\n return { type: 'boolean' };\n }\n if (def.typeName === 'ZodDate') {\n return { type: 'date' };\n }\n if (def.typeName === 'ZodArray') {\n const arrayDef = def as ZodArrayDef;\n return {\n type: 'array',\n items: serializeZodSchema(arrayDef.type),\n };\n }\n if (def.typeName === 'ZodObject') {\n const objectDef = def as ZodObjectDef;\n const shape = objectDef.shape();\n const serializedShape: Record<string, SerializedSchema> = {};\n for (const [key, value] of Object.entries(shape)) {\n serializedShape[key] = serializeZodSchema(value as z.ZodType);\n }\n return {\n type: 'object',\n items: serializedShape,\n };\n }\n if (def.typeName === 'ZodOptional') {\n const optionalDef = def as ZodOptionalDef;\n return {\n ...serializeZodSchema(optionalDef.innerType),\n optional: true,\n };\n }\n if (def.typeName === 'ZodNullable') {\n const nullableDef = def as ZodNullableDef;\n return {\n ...serializeZodSchema(nullableDef.innerType),\n optional: true,\n };\n }\n if (def.typeName === 'ZodEnum') {\n const enumDef = def as ZodEnumDef;\n return {\n type: 'enum',\n items: enumDef.values,\n };\n }\n if (def.typeName === 'ZodUnion') {\n const unionDef = def as ZodUnionDef;\n return {\n type: 'union',\n items: unionDef.options.map(serializeZodSchema),\n };\n }\n if (def.typeName === 'ZodEffects') {\n // ZodEffects is used for z.instanceof(ObjectId), z.refine(), etc.\n const effectsDef = def as ZodEffectsDef;\n\n // Check description for custom types\n if (effectsDef.description) {\n return { type: 'custom', typeName: effectsDef.description } as SerializedSchema;\n }\n\n // For other effects, try to serialize the underlying schema\n return serializeZodSchema(effectsDef.schema);\n }\n\n // For custom types like ObjectId, ref, etc.\n return { type: 'custom', typeName: def.typeName };\n}\n\n/**\n * Serializes a model schema to a JSON-serializable format\n */\nexport function serializeModelSchema(schema: ModelSchema): SerializedModelSchema {\n const serialized: SerializedModelSchema = {};\n\n for (const [key, value] of Object.entries(schema)) {\n if (Array.isArray(value)) {\n // Handle array of schema definitions\n serialized[key] = value.map((item) => {\n if (typeof item === 'object' && '_def' in item) {\n return serializeZodSchema(item as z.ZodType);\n }\n return serializeModelSchema(item as ObjectTypeDefinition);\n });\n } else if (typeof value === 'object' && '_def' in value) {\n // It's a Zod type\n serialized[key] = serializeZodSchema(value as z.ZodType);\n } else {\n // It's a nested object definition\n serialized[key] = serializeModelSchema(value as ObjectTypeDefinition);\n }\n }\n\n return serialized;\n}\n","import { isDeepStrictEqual } from 'node:util';\n\nimport {\n AggregateOptions,\n AggregationCursor,\n Collection,\n DeleteResult,\n Document,\n IndexDescription,\n InsertOneResult,\n MongoClient,\n UpdateResult,\n Filter,\n WithId,\n WithoutId,\n OptionalUnlessRequiredId,\n FindOptions,\n UpdateFilter,\n ObjectId,\n BulkWriteResult,\n AnyBulkWriteOperation,\n InsertManyResult,\n ClientSession,\n SearchIndexDescription,\n MongoError,\n FilterOperators,\n SortDirection,\n FindOneAndUpdateOptions,\n FindOneAndDeleteOptions,\n FindOneAndReplaceOptions,\n ReplaceOptions,\n ChangeStream,\n ChangeStreamOptions,\n DistinctOptions,\n} from 'mongodb';\n\nimport { ModelSchema, InferDocumentType } from './types';\nimport { serializeModelSchema } from './schemaSerializer';\n\n/**\n * Top-level query operators (logical and evaluation) - custom version without Document index signature\n * Based on MongoDB's RootFilterOperators but without the [key: string]: any from Document\n * @internal\n */\ntype StrictRootFilterOperators<TSchema> = {\n $and?: TypedFilter<TSchema>[];\n $or?: TypedFilter<TSchema>[];\n $nor?: TypedFilter<TSchema>[];\n $not?: TypedFilter<TSchema>;\n $text?: {\n $search: string;\n $language?: string;\n $caseSensitive?: boolean;\n $diacriticSensitive?: boolean;\n };\n\n $where?: string | ((this: TSchema) => boolean);\n $comment?: string | Document;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n $expr?: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n $jsonSchema?: any;\n};\n\n/**\n * Helper type to extract array element type\n * @internal\n */\ntype ArrayElement<T> = T extends (infer E)[] ? E : never;\ntype Flatten<T> = T extends ReadonlyArray<infer E> ? E : T;\n\n/**\n * Helper type for $in/$nin that accepts any array/tuple where elements are assignable to T\n * This solves the issue where TypeScript infers ['a', 'b'] as a tuple instead of ('a' | 'b')[]\n * and where Array<Union> gets distributed into Union1[] | Union2[] | ...\n * We wrap the Exclude in a tuple check to prevent distribution\n * @internal\n */\ntype NonUndefined<T> = T extends undefined ? never : T;\ntype ArrayLikeOfUnion<T> = [NonUndefined<T>] extends [never]\n ? never\n : ReadonlyArray<NonUndefined<T>> | Array<NonUndefined<T>>;\n\n/**\n * Enhanced FilterOperators that fixes $in and $nin to properly accept arrays of union types\n * MongoDB's native FilterOperators has issues with union types in $in/$nin arrays\n * because TypeScript distributes Array<Union> into Array1 | Array2 | ...\n * @internal\n */\ntype EnhancedFilterOperators<T> = Omit<FilterOperators<T>, '$in' | '$nin'> & {\n $in?: ArrayLikeOfUnion<T>;\n $nin?: ArrayLikeOfUnion<T>;\n};\n\ntype ExistingIndex = Document & {\n key?: Document;\n name?: string;\n};\n\ntype TypedFieldSelection<T, TValue> = {\n [K in keyof WithId<T> & string]?: TValue;\n} & {\n [key: `${string}.${string}`]: TValue;\n};\n\ntype ProjectionValue =\n | 0\n | 1\n | boolean\n | { $meta: string }\n | { $slice: number | [number, number] }\n | { $elemMatch: Document };\n\ntype TypedSort<T> = TypedFieldSelection<T, SortDirection>;\ntype TypedProjection<T> = TypedFieldSelection<T, ProjectionValue>;\n\ntype FetchOptions<T> = {\n sort?: TypedSort<T>;\n limit?: number;\n skip?: number;\n projection?: TypedProjection<T>;\n};\n\nexport type IndexCreationMode = 'blocking' | 'background';\n\nconst COMPARABLE_INDEX_OPTION_FIELDS = [\n 'background',\n 'bits',\n 'bucketSize',\n 'collation',\n 'default_language',\n 'expireAfterSeconds',\n 'hidden',\n 'language_override',\n 'max',\n 'min',\n 'partialFilterExpression',\n 'sparse',\n 'storageEngine',\n 'textIndexVersion',\n 'unique',\n 'weights',\n 'wildcardProjection',\n '2dsphereIndexVersion',\n] as const;\n\nconst isDocumentRecord = (value: unknown): value is Document =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst hasModelencePrefix = (name: string): boolean => name.startsWith('_modelence_');\n\nconst getComparableIndexOptions = (index: ExistingIndex | IndexDescription): Document => {\n const options: Document = {};\n\n for (const field of COMPARABLE_INDEX_OPTION_FIELDS) {\n const value = (index as Document)[field];\n if (value !== undefined) {\n options[field] = value;\n }\n }\n\n return options;\n};\n\n/**\n * MongoDB index key order is significant (e.g. { a: 1, b: 1 } !== { b: 1, a: 1 }).\n */\nconst isSameIndexKey = (left: unknown, right: unknown): boolean => {\n if (!isDocumentRecord(left) || !isDocumentRecord(right)) {\n return false;\n }\n\n const leftEntries = Object.entries(left);\n const rightEntries = Object.entries(right);\n\n if (leftEntries.length !== rightEntries.length) {\n return false;\n }\n\n return leftEntries.every(([leftField, leftDirection], index) => {\n const [rightField, rightDirection] = rightEntries[index] || [];\n return leftField === rightField && isDeepStrictEqual(leftDirection, rightDirection);\n });\n};\n\nconst isSameIndexDefinition = (existing: ExistingIndex, desired: IndexDescription): boolean => {\n if (!isSameIndexKey(existing.key, desired.key)) {\n return false;\n }\n\n return isDeepStrictEqual(getComparableIndexOptions(existing), getComparableIndexOptions(desired));\n};\n\nconst getIndexKeySignature = (key: unknown): string | null => {\n if (!isDocumentRecord(key)) {\n return null;\n }\n\n return Object.entries(key)\n .map(([field, direction]) => `${field}:${JSON.stringify(direction)}`)\n .join('|');\n};\n\n/**\n * Lists all indexes in a collection, returning an empty array if collection doesn't exist\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst listIndexes = async (collection: Collection<any>): Promise<Document[]> => {\n try {\n return await collection.listIndexes().toArray();\n } catch (error) {\n // If collection doesn't exist yet, return empty array\n // It will be created when we insert data or create indexes\n if (error instanceof MongoError && error.code === 26) {\n return [];\n }\n throw error;\n }\n};\n\n/**\n * Generates an auto-generated index name from the index keys\n * Mimics MongoDB's default naming: field1_direction1_field2_direction2\n */\nconst generateAutoIndexName = (key: Document): string => {\n return Object.entries(key)\n .map(([field, direction]) => `${field}_${direction}`)\n .join('_');\n};\n\n/**\n * Normalizes an index by ensuring it has a name with _modelence_ prefix\n */\nconst normalizeIndexName = (index: IndexDescription): IndexDescription => {\n if (index.name) {\n // If name is provided, add _modelence_ prefix if not already present\n const name = index.name.startsWith('_modelence_') ? index.name : `_modelence_${index.name}`;\n return { ...index, name };\n }\n\n // Auto-generate name with _modelence_ prefix\n const autoName = generateAutoIndexName(index.key);\n return { ...index, name: `_modelence_${autoName}` };\n};\n\n/**\n * Custom filter value type that handles array fields specially:\n * - For array fields: allows element type, full array type, or FilterOperators\n * - For non-array fields: allows exact type or FilterOperators\n * We use [T] to prevent distribution when T is a union type\n * @internal\n */\ntype FilterValue<T> = [T] extends [unknown[]]\n ? ArrayElement<T> | T | EnhancedFilterOperators<T>\n : [T] extends [never]\n ? never\n : T | EnhancedFilterOperators<[T] extends [never] ? never : T>;\n\n/**\n * Type-safe MongoDB filter that ensures only schema fields can be queried\n * while supporting all MongoDB query operators and dot notation for nested fields.\n *\n * This type combines:\n * - MongoDB's native `FilterOperators<T>` for field-level operators (comprehensive operator support)\n * - Custom `StrictRootFilterOperators<T>` for top-level operators without index signature\n * - Custom array field handling: allows passing single element when field is an array\n * - Custom restriction: only strings containing dots are allowed for nested field queries\n *\n * @example\n * ```ts\n * const dbUsers = new Store('users', {\n * schema: {\n * name: schema.string(),\n * age: schema.number(),\n * tags: schema.array(schema.string()),\n * collections: schema.array(schema.string()),\n * address: schema.object({\n * street: schema.string(),\n * city: schema.string(),\n * }),\n * },\n * indexes: []\n * });\n *\n * // ✅ Valid - field exists in schema\n * await dbUsers.findOne({ name: 'John' });\n *\n * // ✅ Valid - using MongoDB operators (from FilterOperators)\n * await dbUsers.findOne({ age: { $gt: 18 } });\n * await dbUsers.findOne({ tags: { $in: ['typescript', 'mongodb'] } });\n * await dbUsers.findOne({ $or: [{ name: 'John' }, { name: 'Jane' }] });\n *\n * // ✅ Valid - array field with single element (checks if array contains the element)\n * await dbUsers.findOne({ collections: 'users' });\n *\n * // ✅ Valid - dot notation for nested fields (must contain a dot)\n * await dbUsers.findOne({ 'address.city': 'New York' });\n * await dbUsers.findOne({ 'emails.0.address': 'test@example.com' });\n *\n * // ❌ TypeScript error - 'id' is not in schema and doesn't contain a dot\n * await dbUsers.findOne({ id: '123' });\n * ```\n */\nexport type TypedFilter<T> = {\n [K in keyof WithId<T>]?: FilterValue<WithId<T>[K]>;\n} & StrictRootFilterOperators<T> & {\n // Support for MongoDB dot notation (e.g., 'emails.address', 'profile.settings.theme')\n // Only strings containing dots are allowed, which provides better type safety\n // while still enabling MongoDB's nested field query syntax\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K: `${string}.${string}`]: any;\n };\n\n/**\n * Helper type to preserve method types when extending a store.\n * Maps each method to work with the extended schema while preserving signatures.\n * @internal\n */\ntype PreserveMethodsForExtendedSchema<\n TBaseMethods extends Record<string, (...args: never[]) => unknown>,\n TExtendedSchema extends ModelSchema,\n> = {\n [K in keyof TBaseMethods]: TBaseMethods[K] extends (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this: any,\n ...args: infer Args\n ) => infer Return\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this: WithId<InferDocumentType<TExtendedSchema>> & any, ...args: Args) => Return\n : never;\n};\n\n/**\n * The Store class provides a type-safe interface for MongoDB collections with built-in schema validation and helper methods.\n *\n * @category Store\n * @typeParam TSchema - The document schema type\n * @typeParam TMethods - Custom methods that will be added to documents\n *\n * @example\n * ```ts\n * const dbTodos = new Store('todos', {\n * schema: {\n * title: schema.string(),\n * completed: schema.boolean(),\n * dueDate: schema.date().optional(),\n * userId: schema.userId(),\n * },\n * methods: {\n * isOverdue() {\n * return this.dueDate < new Date();\n * }\n * }\n * });\n * ```\n */\nexport class Store<\n TSchema extends ModelSchema,\n TMethods extends Record<\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this: WithId<InferDocumentType<TSchema>> & TMethods, ...args: any[]) => any\n >,\n> {\n /** @internal */\n readonly _type!: InferDocumentType<TSchema>;\n /** @internal */\n readonly _rawDoc!: WithId<this['_type']>;\n /** @internal */\n readonly _doc!: this['_rawDoc'] & TMethods;\n\n readonly Doc!: this['_doc'];\n\n private name: string;\n private readonly schema: TSchema;\n private readonly methods?: TMethods;\n private readonly indexes: IndexDescription[];\n private readonly searchIndexes: SearchIndexDescription[];\n private readonly indexCreationMode: IndexCreationMode;\n private collection?: Collection<this['_type']>;\n private client?: MongoClient;\n\n /**\n * Creates a new Store instance\n *\n * @param name - The collection name in MongoDB\n * @param options - Store configuration (schema, indexes, methods, search indexes, and optional index creation mode)\n */\n constructor(\n name: string,\n options: {\n /** Document schema using Modelence schema types */\n schema: TSchema;\n /** Custom methods to add to documents */\n methods?: TMethods;\n /** MongoDB indexes to create */\n indexes: IndexDescription[];\n /** MongoDB Atlas Search */\n searchIndexes?: SearchIndexDescription[];\n /** Whether index creation should block startup or run in background (default: 'background') */\n indexCreationMode?: IndexCreationMode;\n }\n ) {\n this.name = name;\n this.schema = options.schema;\n this.methods = options.methods;\n // Normalize all indexes to have _modelence_ prefix\n this.indexes = options.indexes.map(normalizeIndexName);\n this.searchIndexes = options.searchIndexes || [];\n this.indexCreationMode = options.indexCreationMode ?? 'background';\n }\n\n getName() {\n return this.name;\n }\n\n getIndexCreationMode() {\n return this.indexCreationMode;\n }\n\n /** @internal */\n getSchema() {\n return this.schema;\n }\n\n /** @internal */\n getSerializedSchema() {\n return serializeModelSchema(this.schema);\n }\n\n /**\n * Extends the store with additional schema fields, indexes, methods, and search indexes.\n * Returns a new Store instance with the extended schema and updated types.\n * Methods from the original store are preserved with updated type signatures.\n *\n * @param config - Additional schema fields, indexes, methods, search indexes, and optional index creation mode to add\n * @returns A new Store instance with the extended schema\n *\n * @example\n * ```ts\n * // Extend the users collection\n * export const dbUsers = baseUsersCollection.extend({\n * schema: {\n * firstName: schema.string(),\n * lastName: schema.string(),\n * companyId: schema.objectId().optional(),\n * },\n * indexes: [\n * { key: { companyId: 1 } },\n * { key: { lastName: 1, firstName: 1 } },\n * ],\n * methods: {\n * getFullName() {\n * return `${this.firstName} ${this.lastName}`;\n * }\n * }\n * });\n *\n * // Now fully typed with new fields\n * const user = await dbUsers.findOne({ firstName: 'John' });\n * console.log(user?.getFullName());\n * ```\n */\n extend<\n TExtendedSchema extends ModelSchema,\n TExtendedMethods extends Record<\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this: WithId<InferDocumentType<TSchema & TExtendedSchema>> & any, ...args: any[]) => any\n > = Record<string, never>,\n >(config: {\n schema?: TExtendedSchema;\n indexes?: IndexDescription[];\n methods?: TExtendedMethods;\n searchIndexes?: SearchIndexDescription[];\n /** Whether index creation should block startup or run in background */\n indexCreationMode?: IndexCreationMode;\n }): Store<\n TSchema & TExtendedSchema,\n PreserveMethodsForExtendedSchema<TMethods, TSchema & TExtendedSchema> & TExtendedMethods\n > {\n const extendedSchema = {\n ...this.schema,\n ...(config.schema || {}),\n } as TSchema & TExtendedSchema;\n\n const extendedIndexes = [...this.indexes, ...(config.indexes || [])];\n const extendedSearchIndexes = [...this.searchIndexes, ...(config.searchIndexes || [])];\n\n type CombinedMethods = PreserveMethodsForExtendedSchema<TMethods, TSchema & TExtendedSchema> &\n TExtendedMethods;\n\n const combinedMethods = {\n ...(this.methods || {}),\n ...(config.methods || {}),\n } as CombinedMethods | undefined;\n\n const extendedStore = new Store<TSchema & TExtendedSchema, CombinedMethods>(this.name, {\n schema: extendedSchema,\n methods: combinedMethods as unknown as CombinedMethods | undefined,\n indexes: extendedIndexes,\n searchIndexes: extendedSearchIndexes,\n indexCreationMode: config.indexCreationMode ?? this.indexCreationMode,\n });\n\n if (this.client) {\n throw new Error(\n `Store.extend() must be called before startApp(). Store '${this.name}' has already been initialized and cannot be extended.`\n );\n }\n\n return extendedStore;\n }\n\n /** @internal */\n init(client: MongoClient) {\n if (this.collection) {\n throw new Error(`Collection ${this.name} is already initialized`);\n }\n\n this.client = client;\n this.collection = this.client.db().collection<this['_type']>(this.name);\n }\n\n /** @internal */\n async createIndexes() {\n const collection = this.requireCollection();\n\n // Get all existing indexes in the collection (returns [] if collection doesn't exist)\n const existingIndexes = await listIndexes(collection);\n const indexByName = new Map<string, ExistingIndex & { name: string }>();\n const indexNamesByKey = new Map<string, Set<string>>();\n const droppedIndexNames = new Set<string>();\n\n const addIndexToLookup = (existingIndex: ExistingIndex & { name: string }) => {\n indexByName.set(existingIndex.name, existingIndex);\n\n const keySignature = getIndexKeySignature(existingIndex.key);\n if (!keySignature) {\n return;\n }\n\n const names = indexNamesByKey.get(keySignature);\n if (names) {\n names.add(existingIndex.name);\n } else {\n indexNamesByKey.set(keySignature, new Set([existingIndex.name]));\n }\n };\n\n const removeIndexFromLookup = (indexName: string) => {\n const existingIndex = indexByName.get(indexName);\n if (!existingIndex) {\n return;\n }\n\n indexByName.delete(indexName);\n\n const keySignature = getIndexKeySignature(existingIndex.key);\n if (!keySignature) {\n return;\n }\n\n const names = indexNamesByKey.get(keySignature);\n if (!names) {\n return;\n }\n\n names.delete(indexName);\n if (names.size === 0) {\n indexNamesByKey.delete(keySignature);\n }\n };\n\n for (const existingIndex of existingIndexes) {\n if (typeof existingIndex.name === 'string') {\n addIndexToLookup({\n ...existingIndex,\n name: existingIndex.name,\n });\n }\n }\n\n const dropIndexIfNeeded = async (indexName: string) => {\n if (indexName === '_id_' || droppedIndexNames.has(indexName)) {\n return;\n }\n try {\n await collection.dropIndex(indexName);\n } catch (error) {\n // Another concurrent reconciler may have already dropped it.\n if (!(error instanceof MongoError && error.code === 27)) {\n throw error;\n }\n }\n droppedIndexNames.add(indexName);\n removeIndexFromLookup(indexName);\n };\n\n // Find all _modelence_ prefixed indexes that are not in the current schema\n const currentIndexNames = new Set(\n this.indexes.map((idx) => idx.name).filter((name): name is string => typeof name === 'string')\n );\n const orphanedIndexes = [...indexByName.values()].filter(\n (existingIdx) =>\n hasModelencePrefix(existingIdx.name) && !currentIndexNames.has(existingIdx.name)\n );\n\n // Drop orphaned indexes\n for (const orphanedIndex of orphanedIndexes) {\n await dropIndexIfNeeded(orphanedIndex.name);\n }\n\n // Reconcile code-defined indexes against the current DB metadata.\n // Code wins on conflicts; non-conflicting manual indexes are preserved.\n if (this.indexes.length > 0) {\n for (const index of this.indexes) {\n if (!index.name) {\n continue;\n }\n\n const existingByName = indexByName.get(index.name);\n if (existingByName && !isSameIndexDefinition(existingByName, index)) {\n await dropIndexIfNeeded(existingByName.name);\n }\n\n const keySignature = getIndexKeySignature(index.key);\n if (keySignature) {\n const existingNamesForKey = [...(indexNamesByKey.get(keySignature) || [])];\n for (const existingName of existingNamesForKey) {\n if (existingName !== index.name) {\n await dropIndexIfNeeded(existingName);\n }\n }\n }\n\n const alignedIndex = indexByName.get(index.name);\n const hasAlignedIndex = !!alignedIndex && isSameIndexDefinition(alignedIndex, index);\n\n if (!hasAlignedIndex) {\n await collection.createIndexes([index]);\n addIndexToLookup({\n name: index.name,\n key: index.key,\n ...getComparableIndexOptions(index),\n });\n }\n }\n }\n if (this.searchIndexes.length > 0) {\n for (const searchIndex of this.searchIndexes) {\n try {\n await collection.createSearchIndexes([searchIndex]);\n } catch (error) {\n if (error instanceof MongoError && error.code === 68 && searchIndex.name) {\n await collection.dropSearchIndex(searchIndex.name);\n await collection.createSearchIndexes([searchIndex]);\n } else {\n throw error;\n }\n }\n }\n }\n }\n\n private wrapDocument(document: this['_rawDoc']): this['_doc'] {\n if (!this.methods) {\n return document as unknown as this['_doc'];\n }\n\n const result = Object.create(\n null,\n Object.getOwnPropertyDescriptors({\n ...document,\n ...this.methods,\n })\n );\n\n return result as this['_doc'];\n }\n\n /**\n * For convenience, to also allow directy passing a string or ObjectId as the selector\n */\n private getSelector(selector: TypedFilter<this['_type']> | string | ObjectId) {\n if (typeof selector === 'string') {\n return { _id: new ObjectId(selector) } as Filter<this['_type']>;\n }\n\n if (selector instanceof ObjectId) {\n return { _id: selector } as Filter<this['_type']>;\n }\n\n return selector as Filter<this['_type']>;\n }\n\n /** @internal */\n requireCollection() {\n if (!this.collection) {\n throw new Error(`Collection ${this.name} is not provisioned`);\n }\n\n return this.collection;\n }\n\n /** @internal */\n requireClient() {\n if (!this.client) {\n throw new Error(`Database is not connected`);\n }\n\n return this.client;\n }\n\n /**\n * Finds a single document matching the query\n *\n * @param query - Type-safe query filter. Only schema fields, MongoDB operators, and dot notation are allowed.\n * @param options - Find options\n * @returns The document, or null if not found\n *\n * @example\n * ```ts\n * // ✅ Valid queries:\n * await store.findOne({ name: 'John' })\n * await store.findOne({ age: { $gt: 18 } })\n * await store.findOne({ _id: new ObjectId('...') })\n * await store.findOne({ tags: { $in: ['typescript', 'mongodb'] } })\n * await store.findOne({ $or: [{ name: 'John' }, { name: 'Jane' }] })\n * await store.findOne({ 'emails.address': 'test@example.com' }) // dot notation\n *\n * // ❌ TypeScript error - 'id' is not in schema:\n * await store.findOne({ id: '123' })\n * ```\n */\n async findOne(query: TypedFilter<this['_type']>, options?: FindOptions) {\n const document = await this.requireCollection().findOne<this['_rawDoc']>(\n query as Filter<this['_type']>,\n options\n );\n return document ? this.wrapDocument(document) : null;\n }\n\n async requireOne(\n query: TypedFilter<this['_type']>,\n options?: FindOptions,\n errorHandler?: () => Error\n ): Promise<this['_doc']> {\n const result = await this.findOne(query, options);\n if (!result) {\n throw errorHandler ? errorHandler() : new Error(`Record not found in ${this.name}`);\n }\n return result;\n }\n\n private find(query: TypedFilter<this['_type']>, options?: FetchOptions<this['_type']>) {\n const cursor = this.requireCollection().find(\n query as Filter<this['_type']>,\n options?.projection ? { projection: options.projection } : undefined\n );\n if (options?.sort) {\n cursor.sort(options.sort);\n }\n if (options?.limit) {\n cursor.limit(options.limit);\n }\n if (options?.skip) {\n cursor.skip(options.skip);\n }\n return cursor;\n }\n\n /**\n * Fetches a single document by its ID\n *\n * @param id - The ID of the document to find\n * @returns The document, or null if not found\n */\n async findById(id: string | ObjectId): Promise<this['_doc'] | null> {\n const idSelector = typeof id === 'string' ? { _id: new ObjectId(id) } : { _id: id };\n return await this.findOne(idSelector as TypedFilter<this['_type']>);\n }\n\n /**\n * Fetches a single document by its ID, or throws an error if not found\n *\n * @param id - The ID of the document to find\n * @param errorHandler - Optional error handler to return a custom error if the document is not found\n * @returns The document\n */\n async requireById(id: string | ObjectId, errorHandler?: () => Error): Promise<this['_doc']> {\n const result = await this.findById(id);\n if (!result) {\n throw errorHandler\n ? errorHandler()\n : new Error(`Record with id ${id} not found in ${this.name}`);\n }\n return result;\n }\n\n /**\n * Counts the number of documents that match a query\n *\n * @param query - The query to filter documents\n * @returns The number of documents that match the query\n */\n countDocuments(query: TypedFilter<this['_type']>): Promise<number> {\n return this.requireCollection().countDocuments(query as Filter<this['_type']>);\n }\n\n /**\n * Fetches multiple documents, equivalent to Node.js MongoDB driver's `find` and `toArray` methods combined.\n *\n * @param query - The query to filter documents\n * @param options - Optional fetch options\n * @param options.projection - Fields to include or exclude in the result documents\n * @param options.sort - Sort order for matching documents\n * @param options.limit - Maximum number of documents to return\n * @param options.skip - Number of matching documents to skip\n * @returns The documents\n *\n * @example\n * ```ts\n * // Include only selected fields\n * const docs = await store.fetch(\n * { userId: user.id },\n * { projection: { framework: 1, title: 1 }, sort: { createdAt: -1 }, limit: 50 }\n * );\n *\n * // Exclude large fields when not needed\n * const chunks = await store.fetch(\n * { documentId },\n * { projection: { embedding: 0 } }\n * );\n * ```\n */\n async fetch(\n query: TypedFilter<this['_type']>,\n options?: FetchOptions<this['_type']>\n ): Promise<this['_doc'][]> {\n const cursor = this.find(query, options);\n return (await cursor.toArray()).map(this.wrapDocument.bind(this));\n }\n\n /**\n * Inserts a single document\n *\n * @param document - The document to insert\n * @returns The result of the insert operation\n */\n async insertOne(\n document: OptionalUnlessRequiredId<InferDocumentType<TSchema>>,\n options?: { session?: ClientSession }\n ): Promise<InsertOneResult> {\n return await this.requireCollection().insertOne(document, options);\n }\n\n /**\n * Inserts multiple documents\n *\n * @param documents - The documents to insert\n * @returns The result of the insert operation\n */\n async insertMany(\n documents: OptionalUnlessRequiredId<InferDocumentType<TSchema>>[],\n options?: { session?: ClientSession }\n ): Promise<InsertManyResult> {\n return await this.requireCollection().insertMany(documents, options);\n }\n\n /**\n * Updates a single document\n *\n * @param selector - The selector to find the document to update\n * @param update - The update to apply to the document\n * @returns The result of the update operation\n */\n async updateOne(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n update: UpdateFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<UpdateResult> {\n return await this.requireCollection().updateOne(this.getSelector(selector), update, options);\n }\n\n /**\n * Updates a single document, or inserts it if it doesn't exist\n *\n * @param selector - The selector to find the document to update\n * @param update - The MongoDB modifier to apply to the document\n * @returns The result of the update operation\n */\n async upsertOne(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n update: UpdateFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<UpdateResult> {\n return await this.requireCollection().updateOne(this.getSelector(selector), update, {\n upsert: true,\n ...options,\n });\n }\n\n /**\n * Updates multiple documents\n *\n * @param selector - The selector to find the documents to update\n * @param update - The MongoDB modifier to apply to the documents\n * @returns The result of the update operation\n */\n async updateMany(\n selector: TypedFilter<this['_type']>,\n update: UpdateFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<UpdateResult> {\n return await this.requireCollection().updateMany(\n selector as Filter<this['_type']>,\n update,\n options\n );\n }\n\n /**\n * Updates multiple documents, or inserts them if they don't exist\n *\n * @param selector - The selector to find the documents to update\n * @param update - The MongoDB modifier to apply to the documents\n * @returns The result of the update operation\n */\n async upsertMany(\n selector: TypedFilter<this['_type']>,\n update: UpdateFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<UpdateResult> {\n return await this.requireCollection().updateMany(selector as Filter<this['_type']>, update, {\n upsert: true,\n ...options,\n });\n }\n\n /**\n * Deletes a single document\n *\n * @param selector - The selector to find the document to delete\n * @returns The result of the delete operation\n */\n async deleteOne(\n selector: TypedFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<DeleteResult> {\n return await this.requireCollection().deleteOne(selector as Filter<this['_type']>, options);\n }\n\n /**\n * Deletes multiple documents\n *\n * @param selector - The selector to find the documents to delete\n * @returns The result of the delete operation\n */\n async deleteMany(\n selector: TypedFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<DeleteResult> {\n return await this.requireCollection().deleteMany(selector as Filter<this['_type']>, options);\n }\n\n /**\n * Atomically finds a document and updates it, returning the document\n *\n * @param selector - The selector to find the document\n * @param update - The update to apply\n * @param options - Options including `returnDocument` ('before' or 'after'), `upsert`, `session`, etc.\n * @returns The document (before or after update, depending on options), or null if not found\n */\n async findOneAndUpdate(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n update: UpdateFilter<this['_type']>,\n options?: Omit<FindOneAndUpdateOptions, 'includeResultMetadata'>\n ): Promise<this['_doc'] | null> {\n const result = await this.requireCollection().findOneAndUpdate(\n this.getSelector(selector),\n update,\n options ?? {}\n );\n return result ? this.wrapDocument(result as this['_rawDoc']) : null;\n }\n\n /**\n * Atomically finds a document and deletes it, returning the deleted document\n *\n * @param selector - The selector to find the document\n * @param options - Options including `session`, `projection`, etc.\n * @returns The deleted document, or null if not found\n */\n async findOneAndDelete(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n options?: Omit<FindOneAndDeleteOptions, 'includeResultMetadata'>\n ): Promise<this['_doc'] | null> {\n const result = await this.requireCollection().findOneAndDelete(\n this.getSelector(selector),\n options ?? {}\n );\n return result ? this.wrapDocument(result as this['_rawDoc']) : null;\n }\n\n /**\n * Atomically finds a document and replaces it, returning the document\n *\n * @param selector - The selector to find the document\n * @param replacement - The replacement document\n * @param options - Options including `returnDocument` ('before' or 'after'), `upsert`, `session`, etc.\n * @returns The document (before or after replacement, depending on options), or null if not found\n */\n async findOneAndReplace(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n replacement: WithoutId<this['_type']>,\n options?: Omit<FindOneAndReplaceOptions, 'includeResultMetadata'>\n ): Promise<this['_doc'] | null> {\n const result = await this.requireCollection().findOneAndReplace(\n this.getSelector(selector),\n replacement,\n options ?? {}\n );\n return result ? this.wrapDocument(result as this['_rawDoc']) : null;\n }\n\n /**\n * Replaces a single document\n *\n * @param selector - The selector to find the document to replace\n * @param replacement - The replacement document (must not contain update operators)\n * @param options - Options including `upsert`, `session`, etc.\n * @returns The result of the replace operation\n */\n async replaceOne(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n replacement: WithoutId<this['_type']>,\n options?: ReplaceOptions\n ): Promise<UpdateResult> {\n return await this.requireCollection().replaceOne(\n this.getSelector(selector),\n replacement,\n options\n );\n }\n\n /**\n * Returns an array of distinct values for a field across the collection\n *\n * @param key - The field name (supports dot notation for nested fields)\n * @param filter - Optional filter to narrow the documents\n * @param options - Optional distinct options\n * @returns An array of distinct values\n */\n\n async distinct<K extends keyof this['_rawDoc'] & string>(\n key: K,\n filter?: TypedFilter<this['_type']>,\n options?: DistinctOptions\n ): Promise<Array<Flatten<this['_rawDoc'][K]>>> {\n const f = (filter ?? {}) as Filter<this['_type']>;\n return options !== undefined\n ? await this.requireCollection().distinct(key, f, options)\n : await this.requireCollection().distinct(key, f);\n }\n\n /**\n * Opens a change stream on the collection to watch for real-time changes\n *\n * @param pipeline - Optional aggregation pipeline to filter/transform change events\n * @param options - Optional change stream options\n * @returns A ChangeStream instance\n */\n watch(pipeline?: Document[], options?: ChangeStreamOptions): ChangeStream {\n return this.requireCollection().watch(pipeline, options);\n }\n\n /**\n * Aggregates documents using MongoDB's aggregation framework\n *\n * @param pipeline - The aggregation pipeline\n * @param options - Optional options\n * @returns The aggregation cursor\n */\n aggregate(pipeline: Document[], options?: AggregateOptions): AggregationCursor<Document> {\n return this.requireCollection().aggregate(pipeline, options);\n }\n\n /**\n * Performs a bulk write operation on the collection\n *\n * @param operations - The operations to perform\n * @returns The result of the bulk write operation\n */\n bulkWrite(operations: AnyBulkWriteOperation<this['_type']>[]): Promise<BulkWriteResult> {\n return this.requireCollection().bulkWrite(operations);\n }\n\n /**\n * Returns the raw MongoDB database instance for advanced operations\n * @returns The MongoDB database instance\n * @throws Error if the store is not provisioned\n */\n getDatabase() {\n return this.requireClient().db();\n }\n\n /**\n * Returns the raw MongoDB collection instance for advanced operations\n * @returns The MongoDB collection instance\n * @throws Error if the store is not provisioned\n */\n rawCollection() {\n return this.requireCollection();\n }\n\n /**\n * Renames an existing collection to this store's name, used for migrations\n * @param oldName - The previous name of the collection\n * @throws Error if the old collection doesn't exist or if this store's collection already exists\n */\n async renameFrom(oldName: string, options?: { session?: ClientSession }) {\n const db = this.getDatabase();\n\n if (!this.collection || !db) {\n throw new Error(`Store ${this.name} is not provisioned`);\n }\n\n const oldCollections = await db.listCollections({ name: oldName }).toArray();\n if (oldCollections.length === 0) {\n throw new Error(`Collection ${oldName} not found`);\n }\n\n const newCollections = await db.listCollections({ name: this.name }).toArray();\n if (newCollections.length > 0) {\n throw new Error(`Collection ${this.name} already exists`);\n }\n\n const existingCollection = db.collection<this['_type']>(oldName);\n\n await existingCollection.rename(this.name, options);\n }\n\n /**\n * Performs a vector similarity search using MongoDB Atlas Vector Search\n *\n * @param params - Vector search parameters\n * @param params.field - The field name containing the vector embeddings\n * @param params.embedding - The query vector to search for\n * @param params.numCandidates - Number of nearest neighbors to consider (default: 100)\n * @param params.limit - Maximum number of results to return (default: 10)\n * @param params.projection - Additional fields to include in the results\n * @param params.indexName - Name of index (default: field + VectorSearch)\n * @returns An aggregation cursor with search results and scores\n *\n * @example\n * ```ts\n * const results = await store.vectorSearch({\n * field: 'embedding',\n * embedding: [0.1, 0.2, 0.3, ...],\n * numCandidates: 100,\n * limit: 10,\n * projection: { title: 1, description: 1 }\n * });\n * ```\n */\n async vectorSearch({\n field,\n embedding,\n numCandidates,\n limit,\n projection,\n indexName,\n }: {\n field: string;\n embedding: number[];\n numCandidates?: number;\n limit?: number;\n projection?: Document;\n indexName?: string;\n }) {\n return this.aggregate([\n {\n $vectorSearch: {\n index: indexName || field + 'VectorSearch',\n path: field,\n queryVector: embedding,\n numCandidates: numCandidates || 100,\n limit: limit || 10,\n },\n },\n {\n $project: {\n _id: 1,\n score: { $meta: 'vectorSearchScore' },\n ...projection,\n },\n },\n ]);\n }\n\n /**\n * Creates a MongoDB Atlas Vector Search index definition\n *\n * @param params - Vector index parameters\n * @param params.field - The field name to create the vector index on\n * @param params.dimensions - The number of dimensions in the vector embeddings\n * @param params.similarity - The similarity metric to use (default: 'cosine')\n * @param params.indexName - Name of index (default: field + VectorSearch)\n * @returns A search index description object\n *\n * @example\n * ```ts\n * const store = new Store('documents', {\n * schema: {\n * title: schema.string(),\n * embedding: schema.array(schema.number()),\n * },\n * indexes: [],\n * searchIndexes: [\n * Store.vectorIndex({\n * field: 'embedding',\n * dimensions: 1536,\n * similarity: 'cosine'\n * })\n * ]\n * });\n * ```\n */\n static vectorIndex({\n field,\n dimensions,\n similarity = 'cosine',\n indexName,\n }: {\n field: string;\n dimensions: number;\n similarity?: 'cosine' | 'euclidean' | 'dotProduct';\n indexName?: string;\n }) {\n return {\n type: 'vectorSearch',\n name: indexName || field + 'VectorSearch',\n definition: {\n fields: [\n {\n type: 'vector',\n path: field,\n numDimensions: dimensions,\n similarity,\n },\n ],\n },\n };\n }\n}\n","import { ObjectId } from 'mongodb';\nimport { z, ZodArray, ZodNumber } from 'zod';\nimport { Store } from './store';\n\ntype ObjectTypeDefinition = {\n [key: string]: SchemaTypeDefinition;\n};\n\ntype SingularSchemaTypeDefinition = z.ZodType | ObjectTypeDefinition; // ReturnType<typeof schema[keyof typeof schema]>;\n\ntype SchemaTypeDefinition = SingularSchemaTypeDefinition | Array<SingularSchemaTypeDefinition>;\n\nexport type ModelSchema = {\n [key: string]: SchemaTypeDefinition;\n};\n\nconst schemaString: typeof z.string = z.string.bind(z);\n\nconst schemaNumber: typeof z.number = z.number.bind(z);\n\nconst schemaDate: typeof z.date = z.date.bind(z);\n\nconst schemaBoolean: typeof z.boolean = z.boolean.bind(z);\n\nconst schemaArray: typeof z.array = z.array.bind(z);\n\nconst schemaObject: typeof z.object = z.object.bind(z);\n\nconst schemaEnum: typeof z.enum = z.enum.bind(z);\n\nexport const schema = {\n string: schemaString,\n number: schemaNumber,\n date: schemaDate,\n boolean: schemaBoolean,\n array: schemaArray,\n object: schemaObject,\n enum: schemaEnum,\n embedding(): ZodArray<ZodNumber> {\n return z.array(z.number());\n },\n objectId(): z.ZodType<ObjectId> {\n return z.instanceof(ObjectId).describe('ObjectId');\n },\n userId(): z.ZodType<ObjectId> {\n return z.instanceof(ObjectId).describe('UserId');\n },\n ref<T extends ModelSchema>(\n _collection: string | Store<T, InferDocumentType<T>>\n ): z.ZodType<ObjectId> {\n return z.instanceof(ObjectId).describe('Ref');\n },\n union: z.union.bind(z),\n infer<T extends SchemaTypeDefinition>(_schema: T): InferDocumentType<T> {\n return {} as InferDocumentType<T>;\n },\n} as const;\n\nexport type InferDocumentType<T extends SchemaTypeDefinition> = {\n [K in keyof T as T[K] extends z.ZodOptional<z.ZodTypeAny> ? K : never]?: T[K] extends z.ZodType\n ? z.infer<T[K]>\n : never;\n} & {\n [K in keyof T as T[K] extends z.ZodOptional<z.ZodTypeAny> ? never : K]: T[K] extends z.ZodType\n ? z.infer<T[K]>\n : T[K] extends Array<infer ElementType extends SchemaTypeDefinition>\n ? Array<InferDocumentType<ElementType>>\n : T[K] extends ObjectTypeDefinition\n ? InferDocumentType<T[K]>\n : never;\n};\n\nexport namespace schema {\n export type infer<T extends SchemaTypeDefinition> = InferDocumentType<T>;\n}\n","import { randomBytes } from 'crypto';\nimport { ObjectId } from 'mongodb';\nimport { Module } from '../app/module';\nimport { getPublicConfigs } from '../config/server';\nimport { Store } from '../data/store';\nimport { schema } from '../data/types';\nimport { time } from '../time';\nimport { Session } from './types';\n\nexport const sessionsCollection = new Store('_modelenceSessions', {\n schema: {\n authToken: schema.string(),\n createdAt: schema.date(),\n expiresAt: schema.date(),\n userId: schema.userId().nullable(),\n },\n indexes: [{ key: { authToken: 1 }, unique: true }, { key: { expiresAt: 1 } }],\n // TODO: add TTL index on expiresAt\n});\n\nexport async function obtainSession(authToken: string | null): Promise<Session> {\n const existingSession = authToken ? await sessionsCollection.findOne({ authToken }) : null;\n\n if (existingSession) {\n return {\n authToken: String(existingSession.authToken),\n expiresAt: new Date(existingSession.expiresAt),\n userId: existingSession.userId ?? null,\n };\n }\n\n return await createSession();\n}\n\nexport async function setSessionUser(authToken: string, userId: ObjectId) {\n await sessionsCollection.updateOne(\n { authToken },\n {\n $set: { userId },\n }\n );\n}\n\nexport async function clearSessionUser(authToken: string) {\n await sessionsCollection.updateOne(\n { authToken },\n {\n $set: { userId: null },\n }\n );\n}\n\nexport async function createSession(userId: ObjectId | null = null): Promise<Session> {\n // TODO: add rate-limiting and captcha handling\n\n const authToken = randomBytes(32).toString('base64url');\n const now = Date.now();\n const expiresAt = new Date(now + time.days(7));\n\n await sessionsCollection.insertOne({\n authToken,\n createdAt: new Date(now),\n expiresAt,\n userId,\n });\n\n return {\n authToken,\n expiresAt,\n userId,\n };\n}\n\nasync function processSessionHeartbeat(session: Session) {\n const now = Date.now();\n const newExpiresAt = new Date(now + time.days(7));\n\n await sessionsCollection.updateOne(\n { authToken: session.authToken },\n {\n $set: {\n lastActiveDate: new Date(now),\n expiresAt: newExpiresAt,\n },\n }\n );\n}\n\nexport default new Module('_system.session', {\n stores: [sessionsCollection],\n mutations: {\n init: async function (args, { session, user }) {\n // TODO: mark or track app load somewhere\n\n return {\n session,\n user,\n configs: getPublicConfigs(),\n };\n },\n heartbeat: async function (args, { session }) {\n // Session might not exist if there is no database/authentication setup\n if (session) {\n await processSessionHeartbeat(session);\n }\n },\n },\n});\n","import { schema } from '../data/types';\nimport { Store } from '../data/store';\n\n/**\n * Database collection for storing user accounts with authentication methods and profile information.\n *\n * This is where **signupWithPassword** automatically creates new users.\n *\n * @example\n * ```typescript\n * // Find user by email\n * const user = await dbUsers.findOne(\n * { 'emails.address': 'john@example.com' }\n * );\n * ```\n *\n */\nexport const usersCollection = new Store('_modelenceUsers', {\n schema: {\n handle: schema.string(),\n emails: schema\n .array(\n schema.object({\n address: schema.string(),\n verified: schema.boolean(),\n })\n )\n .optional(),\n status: schema.enum(['active', 'disabled', 'deleted']).optional(),\n firstName: schema.string().optional(),\n lastName: schema.string().optional(),\n avatarUrl: schema.string().optional(),\n createdAt: schema.date(),\n disabledAt: schema.date().optional(),\n deletedAt: schema.date().optional(),\n roles: schema.array(schema.string()).optional(),\n authMethods: schema.object({\n password: schema\n .object({\n hash: schema.string(),\n })\n .optional(),\n google: schema\n .object({\n id: schema.string(),\n })\n .optional(),\n github: schema\n .object({\n id: schema.string(),\n })\n .optional(),\n }),\n },\n indexes: [\n {\n key: { handle: 1 },\n unique: true,\n collation: { locale: 'en', strength: 2 }, // Case-insensitive\n },\n {\n key: { 'emails.address': 1, status: 1 },\n },\n {\n key: { 'authMethods.google.id': 1 },\n sparse: true,\n unique: true,\n },\n {\n key: { 'authMethods.github.id': 1 },\n sparse: true,\n unique: true,\n },\n ],\n});\n\nexport const dbDisposableEmailDomains = new Store('_modelenceDisposableEmailDomains', {\n schema: {\n domain: schema.string(),\n addedAt: schema.date(),\n },\n indexes: [\n {\n key: { domain: 1 },\n unique: true,\n },\n ],\n});\n\nexport const emailVerificationTokensCollection = new Store('_modelenceEmailVerificationTokens', {\n schema: {\n userId: schema.objectId(),\n email: schema.string().optional(),\n token: schema.string(),\n createdAt: schema.date(),\n expiresAt: schema.date(),\n },\n indexes: [\n {\n key: { token: 1 },\n unique: true,\n },\n {\n key: { expiresAt: 1 },\n expireAfterSeconds: 0,\n },\n ],\n});\n\nexport const resetPasswordTokensCollection = new Store('_modelenceResetPasswordTokens', {\n schema: {\n userId: schema.objectId(),\n email: schema.string().optional(),\n token: schema.string(),\n createdAt: schema.date(),\n expiresAt: schema.date(),\n },\n indexes: [\n {\n key: { token: 1 },\n unique: true,\n },\n {\n key: { expiresAt: 1 },\n expireAfterSeconds: 0,\n },\n ],\n});\n","import { RoleDefinition, Role, DefaultRoles, Permission } from './types';\n\nconst roleMap = new Map<Role, RoleDefinition>();\nconst defaultRoles: DefaultRoles = {\n authenticated: null,\n unauthenticated: null,\n};\n\nexport function initRoles(\n roles: Record<Role, RoleDefinition>,\n _defaultRoles: Record<string, Role>\n) {\n defaultRoles.authenticated = _defaultRoles.authenticated;\n defaultRoles.unauthenticated = _defaultRoles.unauthenticated;\n\n for (const [name, definition] of Object.entries(roles)) {\n roleMap.set(name, definition);\n }\n}\n\nexport function getUnauthenticatedRoles() {\n return defaultRoles.unauthenticated ? [defaultRoles.unauthenticated] : [];\n}\n\nexport function getDefaultAuthenticatedRoles() {\n return defaultRoles.authenticated ? [defaultRoles.authenticated] : [];\n}\n\nexport function hasAccess(roles: Role[], requiredPermissions: Permission[]) {\n return requiredPermissions.every((permission) => hasPermission(roles, permission));\n}\n\nexport function requireAccess(roles: Role[], requiredPermissions: Permission[]) {\n const missingPermission = requiredPermissions.find(\n (permission) => !hasPermission(roles, permission)\n );\n\n if (missingPermission) {\n throw new Error(`Access denied - missing permission: '${missingPermission}'`);\n }\n}\n\nexport function hasPermission(roles: Role[], permission: Permission) {\n for (const role of roles) {\n const definition = roleMap.get(role);\n\n if (definition?.permissions?.includes(permission)) {\n return true;\n }\n }\n\n return false;\n}\n","import { ObjectId } from 'mongodb';\n\nimport { obtainSession } from './session';\nimport { usersCollection } from './db';\nimport { getDefaultAuthenticatedRoles, getUnauthenticatedRoles } from './role';\nimport { Role, Session, UserInfo } from './types';\n\nexport async function authenticate(\n authToken: string | null\n): Promise<{ session: Session; user: UserInfo | null; roles: Role[] }> {\n const session = await obtainSession(authToken);\n\n const userDoc = session.userId\n ? await usersCollection.findOne({\n _id: new ObjectId(session.userId),\n status: { $nin: ['deleted', 'disabled'] },\n })\n : null;\n const user = userDoc\n ? {\n id: userDoc._id.toString(),\n handle: userDoc.handle,\n roles: userDoc.roles || [],\n hasRole: (role: string) => (userDoc.roles || []).includes(role),\n requireRole: (role: string) => {\n if (!(userDoc.roles || []).includes(role)) {\n throw new Error(`Access denied - role '${role}' required`);\n }\n },\n firstName: userDoc.firstName ?? undefined,\n lastName: userDoc.lastName ?? undefined,\n avatarUrl: userDoc.avatarUrl ?? undefined,\n }\n : null;\n\n const roles = user ? getDefaultAuthenticatedRoles() : getUnauthenticatedRoles();\n\n return {\n user,\n session,\n roles,\n };\n}\n","import { Module } from '../app/module';\n\nexport default new Module('_system', {\n configSchema: {\n mongodbUri: {\n type: 'secret',\n isPublic: false,\n default: '',\n },\n mongodbPoolSize: {\n type: 'number',\n isPublic: false,\n default: 10,\n },\n 'env.type': {\n type: 'string',\n isPublic: true,\n default: '',\n },\n 'site.url': {\n type: 'string',\n isPublic: true,\n default: '',\n },\n },\n});\n","import { MongoClient } from 'mongodb';\nimport systemModule from '../system';\nimport packageJson from '../../package.json';\n\nlet client: MongoClient | null = null;\n\nexport async function connect() {\n if (client) return client;\n\n const mongodbUri = getMongodbUri();\n if (!mongodbUri) {\n throw new Error('MongoDB URI is not set');\n }\n\n const maxPoolSize = systemModule.getConfig('mongodbPoolSize');\n\n client = new MongoClient(mongodbUri, {\n driverInfo: {\n name: 'Modelence',\n version: packageJson.version,\n },\n ignoreUndefined: true,\n maxPoolSize,\n });\n\n try {\n // Connect the client to the server\n await client.connect();\n // Send a ping to confirm a successful connection\n await client.db('admin').command({ ping: 1 });\n console.log('Pinged your deployment. You successfully connected to MongoDB!');\n return client;\n } catch (err) {\n console.error(err);\n client = null;\n throw err;\n }\n}\n\nexport function getMongodbUri() {\n return systemModule.getConfig('mongodbUri') || undefined;\n}\n\nexport function getClient() {\n return client;\n}\n\n// export async function closeConnection() {\n// if (client) {\n// await client.close();\n// client = null;\n// }\n// }\n","/**\n * Publish function provided to watch handlers.\n * Call this to trigger a re-fetch and send updated data to the client.\n */\nexport type LiveQueryPublish = () => void;\n\n/**\n * Cleanup function returned by watch handlers.\n * Called when the client unsubscribes.\n */\nexport type LiveQueryCleanup = () => void;\n\n/**\n * Context passed to watch handlers.\n */\nexport interface WatchContext {\n publish: LiveQueryPublish;\n}\n\n/**\n * Watch function that sets up real-time monitoring.\n * Receives a context with publish callback to trigger re-fetches.\n * Returns a cleanup function.\n */\nexport type LiveQueryWatch = (context: WatchContext) => LiveQueryCleanup | void;\n\n/**\n * Configuration for creating LiveData.\n */\nexport interface LiveDataConfig<T = unknown> {\n /**\n * Fetches the current data. Called initially and whenever watch triggers publish.\n */\n fetch: () => Promise<T> | T;\n /**\n * Sets up watching for changes. Receives publish callback and returns cleanup.\n */\n watch: LiveQueryWatch;\n}\n\n/**\n * LiveData object returned by live query handlers.\n *\n * @example\n * ```typescript\n * import { LiveData } from 'modelence/server';\n *\n * ...\n *\n * getTodos({ userId }, context) {\n * return new LiveData({\n * fetch: async () => await dbTodos.fetch({ userId }),\n * watch: ({ publish }) => {\n * // Subscribe to changes and call publish when data changes\n * listener.onChange(publish);\n *\n * return () => {\n * // Cleanup function to unsubscribe from changes\n * };\n * }\n * });\n * }\n * ```\n */\nexport class LiveData<T = unknown> {\n readonly fetch: () => Promise<T> | T;\n readonly watch: LiveQueryWatch;\n\n constructor(config: LiveDataConfig<T>) {\n this.fetch = config.fetch;\n this.watch = config.watch;\n }\n}\n","export function isServer() {\n return typeof window !== 'object';\n}\n\nexport function requireServer() {\n if (!isServer()) {\n throw new Error('This function can only be called on the server');\n }\n}\n\nexport function htmlToText(html: string) {\n return html\n .replace(/<[^>]*>/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n","import { requireServer } from '../utils';\nimport { startTransaction } from '@/telemetry';\nimport { requireAccess } from '../auth/role';\nimport { Method, MethodDefinition, MethodType, Args, Context } from './types';\nimport { LiveData } from '../live-query';\n\nconst methods: Record<string, Method<unknown>> = {};\n\nexport function createQuery<T extends unknown[]>(name: string, methodDef: MethodDefinition<T>) {\n requireServer();\n validateMethodName(name);\n return _createMethodInternal('query', name, methodDef);\n}\n\nexport function createMutation<T extends unknown[]>(name: string, methodDef: MethodDefinition<T>) {\n requireServer();\n validateMethodName(name);\n return _createMethodInternal('mutation', name, methodDef);\n}\n\nexport function _createSystemQuery<T extends unknown[]>(\n name: string,\n methodDef: MethodDefinition<T>\n) {\n requireServer();\n validateSystemMethodName(name);\n return _createMethodInternal('query', name, methodDef);\n}\n\nexport function _createSystemMutation<T extends unknown[]>(\n name: string,\n methodDef: MethodDefinition<T>\n) {\n requireServer();\n validateSystemMethodName(name);\n return _createMethodInternal('mutation', name, methodDef);\n}\n\nfunction validateMethodName(name: string) {\n if (name.toLowerCase().startsWith('_system.')) {\n throw new Error(`Method name cannot start with a reserved prefix: '_system.' (${name})`);\n }\n}\n\nfunction validateSystemMethodName(name: string) {\n if (!name.toLowerCase().startsWith('_system.')) {\n throw new Error(`System method name must start with a prefix: '_system.' (${name})`);\n }\n}\n\nfunction _createMethodInternal<T = unknown>(\n type: MethodType,\n name: string,\n methodDef: MethodDefinition<T>\n) {\n requireServer();\n\n if (methods[name]) {\n throw new Error(`Method with name '${name}' is already defined.`);\n }\n\n const handler = typeof methodDef === 'function' ? methodDef : methodDef.handler;\n const permissions = typeof methodDef === 'function' ? [] : (methodDef.permissions ?? []);\n methods[name] = { type, name, handler, permissions };\n}\n\nexport async function runMethod(name: string, args: Args, context: Context) {\n requireServer();\n\n const method = methods[name];\n if (!method) {\n throw new Error(`Method with name '${name}' is not defined.`);\n }\n const { type, handler } = method;\n\n const transaction = startTransaction('method', `method:${name}`, { type, args });\n\n let response;\n try {\n requireAccess(context.roles, method.permissions);\n response = await handler(args, context);\n } catch (error) {\n // TODO: log error and associate it with the transaction\n transaction.end('error');\n throw error;\n }\n\n transaction.end();\n\n return response;\n}\n\n/**\n * Run a method as a live query.\n * The handler should return a LiveData object with fetch and watch functions.\n */\nexport async function runLiveMethod(name: string, args: Args, context: Context): Promise<LiveData> {\n requireServer();\n\n const method = methods[name];\n if (!method) {\n throw new Error(`Method with name '${name}' is not defined.`);\n }\n const { type, handler } = method;\n\n if (type !== 'query') {\n throw new Error(`Live methods are only supported for queries`);\n }\n\n const transaction = startTransaction('method', `method:${name}:live`, { type, args });\n\n let result;\n try {\n requireAccess(context.roles, method.permissions);\n\n result = await handler(args, context);\n\n if (!(result instanceof LiveData)) {\n throw new Error(\n `Live query handler for '${name}' must return a LiveData object with fetch and watch functions.`\n );\n }\n } catch (error) {\n transaction.end('error');\n throw error;\n }\n\n transaction.end();\n\n return result;\n}\n","import { Socket } from 'socket.io';\nimport { z } from 'zod';\nimport { authenticate } from '../auth';\nimport { runLiveMethod } from '../methods';\nimport { getResponseTypeMap, sanitizeResult } from '../methods/serialize';\nimport { LiveQueryCleanup } from './context';\nimport { Context } from '@/methods/types';\n\ninterface ActiveSubscription {\n cleanup: LiveQueryCleanup | null;\n aborted?: boolean;\n}\n\nconst socketSubscriptions = new Map<string, Map<string, ActiveSubscription>>();\n\nfunction getSocketSubs(socket: Socket): Map<string, ActiveSubscription> {\n let subs = socketSubscriptions.get(socket.id);\n if (!subs) {\n subs = new Map();\n socketSubscriptions.set(socket.id, subs);\n }\n return subs;\n}\n\nexport async function handleSubscribeLiveQuery(socket: Socket, payload: unknown) {\n const parsed = z\n .object({\n subscriptionId: z.string().min(1),\n method: z.string().min(1),\n args: z.record(z.unknown()).default({}),\n authToken: z.string().nullish(),\n clientInfo: z\n .object({\n screenWidth: z.number(),\n screenHeight: z.number(),\n windowWidth: z.number(),\n windowHeight: z.number(),\n pixelRatio: z.number(),\n orientation: z.string().nullable(),\n })\n .optional(),\n })\n .safeParse(payload);\n if (!parsed.success) {\n socket.emit('liveQueryError', {\n subscriptionId: null,\n error: `Invalid payload: ${parsed.error.message}`,\n });\n return;\n }\n const { subscriptionId, method, args, authToken, clientInfo } = parsed.data;\n\n const subs = getSocketSubs(socket);\n\n // Clean up any existing subscription with the same ID (handles reconnect race conditions)\n const existingSub = subs.get(subscriptionId);\n if (existingSub) {\n if (existingSub.cleanup) {\n try {\n existingSub.cleanup();\n } catch (err) {\n console.error('[LiveQuery] Error cleaning up existing subscription:', err);\n }\n } else {\n // Subscription is still initializing - mark it for abort so it cleans up when ready\n existingSub.aborted = true;\n }\n }\n\n // Create placeholder entry BEFORE the async call so disconnect handler can find it\n const subscription: ActiveSubscription = { cleanup: null };\n subs.set(subscriptionId, subscription);\n\n try {\n const { session, user, roles } = await authenticate(authToken ?? null);\n\n const context: Context = {\n session,\n user,\n roles,\n clientInfo: clientInfo ?? {\n screenWidth: 0,\n screenHeight: 0,\n windowWidth: 0,\n windowHeight: 0,\n pixelRatio: 1,\n orientation: null,\n },\n connectionInfo: {\n ip: socket.handshake.address,\n userAgent: socket.handshake.headers['user-agent'],\n },\n };\n\n const liveData = await runLiveMethod(method, args, context);\n\n const fetchAndEmit = async () => {\n const data = sanitizeResult(await liveData.fetch());\n if (subscription.aborted) {\n return;\n }\n socket.emit('liveQueryData', {\n subscriptionId,\n data,\n typeMap: getResponseTypeMap(data),\n });\n };\n\n // Set to true to perform initial fetch at the beginning\n let isPendingPublish = true;\n let isFetching = false;\n\n const processPendingPublish = () => {\n if (subscription.aborted || !isPendingPublish || isFetching) {\n return;\n }\n isPendingPublish = false;\n isFetching = true;\n fetchAndEmit()\n .catch((err) => {\n if (subscription.aborted) {\n return;\n }\n console.error(`[LiveQuery] Error fetching data for ${method}:`, err);\n socket.emit('liveQueryError', {\n subscriptionId,\n error: err instanceof Error ? err.message : String(err),\n });\n })\n .finally(() => {\n isFetching = false;\n // Process the next pending publish if another publish was triggered while fetching\n processPendingPublish();\n });\n };\n\n const cleanup = liveData.watch({\n publish: () => {\n /*\n Use a pending flag to ensure concurrent publishes are processed sequentially\n (and run only once if there have been multiple publishes while the previous one was processing)\n Without sequential processing, we could end up sending an older fetch after a newer one\n */\n isPendingPublish = true;\n processPendingPublish();\n },\n });\n\n if (subscription.aborted) {\n // Unsubscribe/disconnect happened during watch setup - clean up immediately\n if (cleanup) {\n try {\n cleanup();\n } catch (err) {\n console.error('[LiveQuery] Error cleaning up after disconnect during setup:', err);\n }\n }\n return;\n }\n\n subscription.cleanup = cleanup || null;\n\n // Process initial fetch\n processPendingPublish();\n } catch (error) {\n subs.delete(subscriptionId);\n console.error(`[LiveQuery] Error in ${method}:`, error);\n socket.emit('liveQueryError', {\n subscriptionId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n}\n\nexport function handleUnsubscribeLiveQuery(socket: Socket, payload: unknown) {\n const parsed = z\n .object({\n subscriptionId: z.string().min(1),\n })\n .safeParse(payload);\n if (!parsed.success) {\n console.warn(`[LiveQuery] Invalid unsubscribe payload: ${parsed.error.message}`);\n return;\n }\n const { subscriptionId } = parsed.data;\n\n const subs = socketSubscriptions.get(socket.id);\n if (!subs) return;\n\n const sub = subs.get(subscriptionId);\n if (sub) {\n if (sub.cleanup) {\n try {\n sub.cleanup();\n } catch (err) {\n console.error('[LiveQuery] Error in cleanup:', err);\n }\n } else {\n sub.aborted = true;\n }\n subs.delete(subscriptionId);\n }\n}\n\nexport function handleLiveQueryDisconnect(socket: Socket) {\n const subs = socketSubscriptions.get(socket.id);\n if (subs) {\n // Clean up all subscriptions for this socket\n for (const sub of subs.values()) {\n if (sub.cleanup) {\n try {\n sub.cleanup();\n } catch (err) {\n console.error('[LiveQuery] Error in cleanup on disconnect:', err);\n }\n } else {\n sub.aborted = true;\n }\n }\n socketSubscriptions.delete(socket.id);\n }\n}\n","import { Server } from 'http';\nimport { Server as SocketServer, Socket } from 'socket.io';\nimport { createAdapter } from '@socket.io/mongo-adapter';\nimport { authenticate } from '@/auth';\nimport { getClient } from '@/db/client';\nimport { WebsocketServerProvider } from '../types';\nimport { ServerChannel } from '../serverChannel';\nimport {\n handleSubscribeLiveQuery,\n handleUnsubscribeLiveQuery,\n handleLiveQueryDisconnect,\n} from '@/live-query';\nimport type { Collection, Document } from 'mongodb';\n\nlet socketServer: SocketServer | null = null;\n\nconst COLLECTION = '_modelenceSocketio';\n\nexport async function init({\n httpServer,\n channels,\n}: {\n httpServer: Server;\n channels: ServerChannel[];\n}) {\n const mongodbClient = getClient();\n\n console.log('Initializing Socket.IO server...');\n\n let mongoCollection: Collection<Document> | null = null;\n\n if (mongodbClient) {\n mongoCollection = mongodbClient.db().collection(COLLECTION);\n\n try {\n await mongoCollection.createIndex(\n { createdAt: 1 },\n { expireAfterSeconds: 3600, background: true }\n );\n } catch (error) {\n console.error('Failed to create index on MongoDB collection for Socket.IO:', error);\n }\n }\n\n socketServer = new SocketServer(httpServer, {\n cors: {\n origin: '*',\n methods: ['GET', 'POST'],\n },\n adapter: mongoCollection ? createAdapter(mongoCollection) : undefined,\n transports: ['websocket'],\n perMessageDeflate: false,\n });\n\n socketServer.on('error', (error) => {\n console.error('Socket.IO error:', error);\n });\n\n socketServer.use(async (socket, next) => {\n const token = socket.handshake.auth.token;\n\n try {\n socket.data = await authenticate(token);\n } finally {\n next();\n }\n });\n\n socketServer.on('connection', (socket: Socket) => {\n socket.on('disconnect', () => {\n handleLiveQueryDisconnect(socket);\n });\n\n socket.on('joinChannel', async (channelName: string) => {\n const [category] = channelName.split(':');\n let authorized = false;\n\n for (const channel of channels) {\n if (channel.category === category) {\n if (!channel.canAccessChannel || (await channel.canAccessChannel(socket.data))) {\n socket.join(channelName);\n authorized = true;\n socket.emit('joinedChannel', channelName);\n }\n break; // Found matching channel - stop searching\n }\n }\n\n if (!authorized) {\n socket.emit('joinError', { channel: channelName, error: 'Access denied' });\n }\n });\n\n socket.on('leaveChannel', (channelName: string) => {\n socket.leave(channelName);\n console.log(`User ${socket.id} left channel ${channelName}`);\n socket.emit('leftChannel', channelName);\n });\n\n socket.on('subscribeLiveQuery', (payload) => handleSubscribeLiveQuery(socket, payload));\n socket.on('unsubscribeLiveQuery', (payload) => handleUnsubscribeLiveQuery(socket, payload));\n });\n\n console.log('Socket.IO server initialized');\n}\n\nfunction broadcast<T>({ category, id, data }: { category: string; id: string; data: T }) {\n socketServer?.to(`${category}:${id}`).emit(category, data);\n}\n\nexport default {\n init,\n broadcast,\n} as WebsocketServerProvider;\n","import { time } from '../time';\nimport { dbDisposableEmailDomains } from './db';\n\nexport async function isDisposableEmail(email: string): Promise<boolean> {\n const emailParts = email.toLowerCase().trim().split('@');\n if (emailParts.length !== 2) {\n return false;\n }\n\n const domain = emailParts[1];\n const result = await dbDisposableEmailDomains.findOne({ domain });\n return Boolean(result);\n}\n\nexport const updateDisposableEmailListCron = {\n interval: time.days(1),\n async handler() {\n const response = await fetch(\n 'https://disposable.github.io/disposable-email-domains/domains.txt'\n );\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const domainsText = await response.text();\n\n const domains = domainsText\n .split('\\n')\n .map((domain) => domain.trim().toLowerCase())\n .filter((domain) => domain.length > 0);\n\n const now = new Date();\n\n // Insert domains in batches to avoid overwhelming the database\n const batchSize = 500;\n for (let i = 0; i < domains.length; i += batchSize) {\n const batch = domains.slice(i, i + batchSize);\n\n try {\n await dbDisposableEmailDomains.insertMany(\n batch.map((domain) => ({\n domain,\n addedAt: now,\n }))\n );\n } catch (error: unknown) {\n // MongoDB throws BulkWriteError when some documents are duplicates\n if (\n error &&\n typeof error === 'object' &&\n 'name' in error &&\n error.name === 'MongoBulkWriteError'\n ) {\n // console.warn(`Error inserting batch starting at index ${i}:`, error.message);\n }\n }\n }\n },\n};\n","import type { EmailProvider } from '../types';\n\nexport type EmailConfig = {\n provider?: EmailProvider;\n from?: string;\n verification?: {\n subject?: string;\n template?: (props: { name: string; email: string; verificationUrl: string }) => string;\n redirectUrl?: string;\n };\n passwordReset?: {\n subject?: string;\n template?: (props: { name: string; email: string; resetUrl: string }) => string;\n redirectUrl?: string;\n };\n // @deprecated use verification.redirectUrl instead\n emailVerifiedRedirectUrl?: string;\n};\n\nlet emailConfig: EmailConfig = Object.freeze({});\n\nexport function setEmailConfig(newEmailConfig: EmailConfig) {\n emailConfig = Object.freeze(Object.assign({}, emailConfig, newEmailConfig));\n}\n\nexport function getEmailConfig() {\n return emailConfig;\n}\n","import { z } from 'zod';\nimport { UpdateProfileProps } from '../methods/types';\n\nexport const MIN_HANDLE_LENGTH = 3;\nexport const MAX_HANDLE_LENGTH = 50;\n\n// Reusable string validators\nconst trimmedNonEmptyString = (opts: { min?: number; max: number }) =>\n z\n .string()\n .trim()\n .min(opts.min ?? 1, { message: `must be at least ${opts.min ?? 1} characters` })\n .max(opts.max, { message: `must be at most ${opts.max} characters` });\n\nconst trimmedOptionalString = (opts: { max: number }) =>\n z\n .string()\n .trim()\n .max(opts.max, { message: `must be at most ${opts.max} characters` })\n .transform((val) => (val === '' ? undefined : val))\n .optional();\n\n// Base schema (used for both full & partial validation)\nconst profileFieldsSchema = z\n .object({\n firstName: trimmedOptionalString({ max: 50 }),\n lastName: trimmedOptionalString({ max: 50 }),\n avatarUrl: trimmedOptionalString({ max: 400 }),\n handle: trimmedNonEmptyString({ min: MIN_HANDLE_LENGTH, max: MAX_HANDLE_LENGTH }),\n })\n .strict();\n\n/**\n * Validates and trims profile fields against the defined rules.\n *\n * For each field present in `fields`:\n * - Trims whitespace\n * - Sets fields to `undefined` when cleared (empty string)\n * - Enforces min/max length constraints\n *\n * @returns An object containing only the validated, trimmed fields that were provided.\n */\nexport function validateProfileFields(\n fields: Partial<UpdateProfileProps>\n): Partial<UpdateProfileProps> {\n const result = profileFieldsSchema.partial().safeParse(fields);\n\n if (!result.success) {\n const issue = result.error.issues[0];\n const path = issue.path.join('.');\n const msg = path ? `${path}: ${issue.message}` : issue.message;\n throw new Error(msg);\n }\n\n return result.data;\n}\n\nexport function validatePassword(value: string) {\n return z.string().min(8, { message: 'Password must contain at least 8 characters' }).parse(value);\n}\n\nexport function validateEmail(value: string) {\n return z.string().email({ message: 'Invalid email address' }).parse(value).toLowerCase();\n}\n\nexport function validateHandle(value: string) {\n return trimmedNonEmptyString({ min: MIN_HANDLE_LENGTH, max: MAX_HANDLE_LENGTH }).parse(value);\n}\n","import { AuthErrorProps, AuthSuccessProps, User } from '@/auth/types';\nimport { UpdateProfileProps, SignupProps } from '@/methods/types';\n\ntype GenerateHandleProps = {\n email: string;\n firstName?: string;\n lastName?: string;\n};\n\n/**\n * Callback options for authentication operations\n */\nexport type AuthOption = {\n /** Callback executed when authentication succeeds */\n onSuccess?: (user: User) => void;\n /** Callback executed when authentication fails */\n onError?: (error: Error) => void;\n};\n\n/**\n * Authentication configuration for the application\n *\n * @example\n * ```typescript\n * import { startApp } from 'modelence/server';\n *\n * startApp({\n * auth: {\n * validateSignup: ({ email, firstName, lastName, password, handle, avatarUrl }) => {\n * // Validating the signup data\n * if (!email || !password) {\n * throw new Error('Email and password are required');\n * }\n * },\n * onAfterLogin: ({ user }) => {\n * console.log('User logged in:', user.name);\n * // Redirect to dashboard\n * },\n * onLoginError: ({ error }) => {\n * console.error('Login failed:', error.message);\n * // Show error toast\n * },\n * onAfterSignup: ({ user }) => {\n * console.log('User signed up:', user.email);\n * // Send welcome email\n * },\n * onSignupError: ({ error }) => {\n * console.error('Signup failed:', error.message);\n * },\n * generateHandle: ({ email }) => {\n * console.log('Generating handle for:', email);\n * // Generate handle\n * return 'user123';\n * },\n * }\n * });\n * ```\n */\nexport type AuthConfig = {\n // Optional pre-signup validation hook.\n validateSignup?: (props: SignupProps) => void | Promise<void>;\n validateProfileUpdate?: (props: UpdateProfileProps) => void | Promise<void>;\n\n // After Authentication callbacks\n onAfterLogin?: (props: AuthSuccessProps) => void;\n onLoginError?: (props: AuthErrorProps) => void;\n onAfterSignup?: (props: AuthSuccessProps) => void;\n onSignupError?: (props: AuthErrorProps) => void;\n onAfterEmailVerification?: (props: AuthSuccessProps) => void;\n onEmailVerificationError?: (props: AuthErrorProps) => void;\n // OAuth account linking callbacks\n onAfterOAuthLink?: (props: AuthSuccessProps) => void;\n onOAuthLinkError?: (props: AuthErrorProps) => void;\n // Custom handle generator.\n // If provided, this overrides the default handle generation logic.\n generateHandle?: (props: GenerateHandleProps) => Promise<string> | string;\n\n /** deprecated: use onAfterLogin and onLoginError */\n login?: AuthOption;\n /** deprecated: user onAfterSignup and onSignupError */\n signup?: AuthOption;\n\n /**\n * Controls how OAuth providers handle existing accounts with matching email.\n * - 'manual' (default): Returns an error when an OAuth login matches an existing email.\n * - 'auto': Automatically links the OAuth provider to the existing account\n * if the provider email is verified.\n */\n oauthAccountLinking?: 'auto' | 'manual';\n};\n\nlet authConfig: AuthConfig = Object.freeze({});\n\nexport function setAuthConfig(newAuthConfig: AuthConfig) {\n authConfig = Object.freeze(Object.assign({}, authConfig, newAuthConfig));\n}\n\nexport function getAuthConfig() {\n return authConfig;\n}\n","import bcrypt from 'bcrypt';\nimport { z } from 'zod';\n\nimport { Args, Context } from '../methods/types';\nimport { usersCollection } from './db';\nimport { clearSessionUser, setSessionUser } from './session';\nimport { getEmailConfig } from '@/app/emailConfig';\nimport { consumeRateLimit } from '@/server';\nimport { validateEmail } from './validators';\nimport { getAuthConfig } from '@/app/authConfig';\n\nexport async function handleLoginWithPassword(\n args: Args,\n { user, session, connectionInfo }: Context\n) {\n try {\n if (!session) {\n throw new Error('Session is not initialized');\n }\n\n const ip = connectionInfo?.ip;\n if (ip) {\n await consumeRateLimit({\n bucket: 'signin',\n type: 'ip',\n value: ip,\n });\n }\n\n const email = validateEmail(args.email as string);\n // password is accepted just as a string, so users can still sign in if the password validation rules are changed\n const password = z.string().parse(args.password);\n\n // TODO: add rate limiting by email (and perhaps IP address overall)\n\n if (user) {\n // TODO: handle cases where a user is already logged in\n }\n\n const userDoc = await usersCollection.findOne(\n { 'emails.address': email, status: { $nin: ['deleted', 'disabled'] } },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n const passwordHash = userDoc?.authMethods?.password?.hash;\n if (!passwordHash) {\n throw incorrectCredentialsError();\n }\n\n const emailDoc = userDoc.emails?.find((e) => e.address.toLowerCase() === email);\n\n if (!emailDoc?.verified && getEmailConfig()?.provider) {\n throw new Error(\n \"Your email address hasn't been verified yet. Please check your inbox for the verification email.\"\n );\n }\n\n const isValidPassword = await bcrypt.compare(password, passwordHash);\n if (!isValidPassword) {\n throw incorrectCredentialsError();\n }\n\n await setSessionUser(session.authToken, userDoc._id);\n\n getAuthConfig().onAfterLogin?.({\n provider: 'email',\n user: userDoc,\n session,\n connectionInfo,\n });\n getAuthConfig().login?.onSuccess?.(userDoc);\n\n return {\n user: {\n id: userDoc._id,\n handle: userDoc.handle,\n roles: userDoc.roles || [],\n firstName: userDoc.firstName ?? undefined,\n lastName: userDoc.lastName ?? undefined,\n avatarUrl: userDoc.avatarUrl ?? undefined,\n },\n };\n } catch (error) {\n if (error instanceof Error) {\n getAuthConfig().onLoginError?.({\n provider: 'email',\n error,\n session,\n connectionInfo,\n });\n getAuthConfig().login?.onError?.(error);\n }\n throw error;\n }\n}\n\nexport async function handleLogout(args: Args, { session }: Context) {\n if (!session) {\n throw new Error('Session is not initialized');\n }\n\n await clearSessionUser(session.authToken);\n}\n\n/*\n It is important to return the same exact error both in case the email\n or password is incorrect so that the client cannot tell the difference,\n otherwise it would allow for an enumeration attack.\n*/\nfunction incorrectCredentialsError() {\n return new Error('Incorrect email/password combination');\n}\n","import { usersCollection } from './db';\nimport { Args, Context, UpdateProfileProps } from '../methods/types';\nimport { validateProfileFields } from './validators';\nimport { getAuthConfig } from '@/app/authConfig';\n\nexport async function getOwnProfile(props: Args, { user }: Context) {\n if (!user) {\n throw new Error('Not authenticated');\n }\n\n const profile = await usersCollection.requireById(user.id);\n\n return {\n handle: profile.handle,\n emails: profile.emails,\n authMethods: Object.keys(profile.authMethods || {}),\n firstName: profile.firstName ?? undefined,\n lastName: profile.lastName ?? undefined,\n avatarUrl: profile.avatarUrl ?? undefined,\n };\n}\n\nexport async function handleUpdateProfile(props: Args, { user }: Context) {\n if (!user) {\n throw new Error('Not authenticated');\n }\n\n let profile = await usersCollection.requireById(user.id);\n\n const update = validateProfileFields(props as UpdateProfileProps);\n\n await getAuthConfig().validateProfileUpdate?.(update);\n\n //Check if handle is already taken\n if ('handle' in update && update.handle !== undefined) {\n const existing = await usersCollection.findOne(\n {\n handle: update.handle,\n _id: { $ne: profile._id }, // excludes the current user\n },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (existing) {\n throw new Error('Handle already taken.');\n }\n }\n\n //Update profile\n if (Object.keys(update).length > 0) {\n const setFields: Record<string, unknown> = {}; //Used to set the fields\n const unsetFields: Record<string, ''> = {}; //Used to clear the fields the mongodb, because mongodb rejects undefined values when updating fields\n\n for (const [key, value] of Object.entries(update)) {\n if (value === undefined) {\n unsetFields[key] = '';\n } else {\n setFields[key] = value;\n }\n }\n\n const mongoUpdate: Record<string, unknown> = {};\n if (Object.keys(setFields).length > 0) mongoUpdate.$set = setFields;\n if (Object.keys(unsetFields).length > 0) mongoUpdate.$unset = unsetFields;\n\n try {\n await usersCollection.updateOne({ _id: profile._id }, mongoUpdate);\n\n //Also pass Cleared Fields as UNDEFINED in profile\n const clearedFields = Object.fromEntries(\n Object.keys(unsetFields).map((key) => [key, undefined])\n );\n profile = { ...profile, ...setFields, ...clearedFields } as typeof profile;\n } catch (error) {\n if (error instanceof Error && 'code' in error && (error as { code: number }).code === 11000) {\n throw new Error('Handle already taken.');\n }\n throw error;\n }\n }\n\n return {\n user: {\n id: profile._id,\n handle: profile.handle,\n roles: profile.roles || [],\n firstName: profile.firstName ?? undefined,\n lastName: profile.lastName ?? undefined,\n avatarUrl: profile.avatarUrl ?? undefined,\n },\n };\n}\n","import { Document, ObjectId } from 'mongodb';\nimport { ConnectionInfo } from '@/methods/types';\n\nexport interface UserEmail {\n address: string;\n verified: boolean;\n}\n\nexport interface User extends Document {\n _id: ObjectId;\n\n handle: string;\n\n emails?: UserEmail[];\n\n status?: 'active' | 'disabled' | 'deleted';\n\n firstName?: string;\n lastName?: string;\n avatarUrl?: string;\n\n createdAt: Date;\n disabledAt?: Date;\n deletedAt?: Date;\n\n roles?: string[];\n\n authMethods: {\n password?: {\n hash: string;\n };\n google?: {\n id: string;\n };\n github?: {\n id: string;\n };\n };\n}\n\nexport type UserInfo = {\n /** The user's unique identifier. */\n id: string;\n /** The user's display handle. */\n handle: string;\n /** The role strings assigned to this user in the database. */\n roles: string[];\n /** Returns `true` if the user has the given role. */\n hasRole: (role: string) => boolean;\n /** Throws an error if the user does not have the given role. */\n requireRole: (role: string) => void;\n firstName?: string;\n lastName?: string;\n avatarUrl?: string;\n};\n\nexport type Role = string;\n\nexport type DefaultRoles = Record<'authenticated' | 'unauthenticated', Role | null>;\n\nexport type Session = {\n authToken: string;\n expiresAt: Date;\n userId: ObjectId | null;\n};\n\nexport type Permission = string;\n\n/**\n * Defines a role that can be assigned to users.\n *\n * Roles are registered via the `roles` option in {@link AppOptions} and\n * are synced to the Modelence Cloud dashboard for user management.\n *\n * @example\n * ```typescript\n * import { startApp } from 'modelence/server';\n *\n * startApp({\n * roles: {\n * admin: { description: 'Full access to all features' },\n * editor: { description: 'Can edit content' },\n * viewer: {},\n * },\n * });\n * ```\n */\nexport type RoleDefinition = {\n /** Human-readable description of the role, shown in the Modelence Cloud dashboard. */\n description?: string;\n /** @internal */\n permissions?: Permission[];\n};\n\nexport const SUPPORTED_OAUTH_PROVIDERS = ['google', 'github'] as const;\nexport type OAuthProvider = (typeof SUPPORTED_OAUTH_PROVIDERS)[number];\n\nexport type AuthProvider = OAuthProvider | 'email';\n\nexport type AuthSuccessProps = {\n provider: AuthProvider;\n user: User;\n session: Session | null;\n connectionInfo: ConnectionInfo;\n};\n\nexport type AuthErrorProps = {\n provider: AuthProvider;\n error: Error;\n session: Session | null;\n connectionInfo: ConnectionInfo;\n};\n","import { usersCollection } from './db';\nimport { Args, Context } from '@/methods/types';\nimport { OAuthProvider, SUPPORTED_OAUTH_PROVIDERS } from './types';\n\nexport async function handleUnlinkOAuthProvider({ provider }: Args, { user }: Context) {\n if (!user) {\n throw new Error('You must be signed in to unlink a provider.');\n }\n\n if (\n typeof provider !== 'string' ||\n !SUPPORTED_OAUTH_PROVIDERS.includes(provider as OAuthProvider)\n ) {\n throw new Error(\n `Invalid provider. Supported providers are: ${SUPPORTED_OAUTH_PROVIDERS.join(', ')}.`\n );\n }\n\n // requireById throws if user is not found, so no null check needed\n const userDoc = await usersCollection.requireById(user.id);\n\n const methods = userDoc.authMethods ?? {};\n const providerKey = provider as keyof typeof methods;\n\n if (!methods[providerKey]) {\n throw new Error(`${provider} is not linked to your account.`);\n }\n\n const activeMethodsCount = Object.values(methods).filter(Boolean).length;\n if (activeMethodsCount <= 1) {\n throw new Error(\n 'Cannot unlink your only authentication method. Please add another method first.'\n );\n }\n\n // Determine the OTHER auth method fields that must still exist for lockout prevention.\n // This atomic filter ensures that between our read and write, at least one other method\n // hasn't been concurrently removed (prevents two simultaneous unlinks from both succeeding).\n const otherMethods = Object.keys(methods).filter(\n (key) => key !== provider && methods[key as keyof typeof methods]\n );\n const otherMethodGuard =\n otherMethods.length > 0\n ? { $or: otherMethods.map((key) => ({ [`authMethods.${key}`]: { $exists: true } })) }\n : {};\n\n const result = await usersCollection.updateOne(\n { _id: userDoc._id, ...otherMethodGuard },\n { $unset: { [`authMethods.${provider}`]: '' } }\n );\n\n if (result.matchedCount === 0) {\n throw new Error(\n 'Cannot unlink your only authentication method. Please add another method first.'\n );\n }\n}\n","import { Store } from '../data/store';\nimport { schema } from '../data/types';\n\n/**\n * Two-bucket sliding window approximation to track rate limits.\n * This is a trade-off between storage and accuracy.\n * We're not keeping exact event logs, so we can't track the exact number of events in a window.\n * Instead, we're adding a weighted average from the previous window to the current window.\n */\nexport const dbRateLimits = new Store('_modelenceRateLimits', {\n schema: {\n bucket: schema.string(),\n type: schema.enum(['ip', 'user', 'email']),\n value: schema.string(),\n windowMs: schema.number(),\n\n windowStart: schema.date(),\n windowCount: schema.number(),\n prevWindowCount: schema.number(),\n\n expiresAt: schema.date(),\n },\n indexes: [\n { key: { bucket: 1, type: 1, value: 1, windowMs: 1 }, unique: true },\n { key: { expiresAt: 1 }, expireAfterSeconds: 0 },\n ],\n});\n","import { RateLimitRule, RateLimitType } from './types';\nimport { dbRateLimits } from './db';\nimport { RateLimitError } from '../error';\n\nlet allRules: Array<RateLimitRule> = [];\n\nexport function initRateLimits(rateLimits: RateLimitRule[]) {\n if (allRules.length > 0) {\n throw new Error('Duplicate call to initRateLimits - already initialized');\n }\n\n allRules = rateLimits;\n}\n\n/**\n * This function will check all rate limit rules on the specified bucket and type,\n * throw an error if any of them are exceeded and increase the count of the rate limit record.\n *\n * @category Rate Limits\n *\n * @example\n * ```ts\n * await consumeRateLimit({ bucket: 'api', type: 'ip', value: '127.0.0.1' });\n * ```\n * @param options.bucket - The bucket for the rate limit.\n * @param options.type - The type of the rate limit.\n * @param options.value - The value for the rate limit.\n * @param options.message - Optional custom error message when the rate limit is exceeded.\n */\nexport async function consumeRateLimit(options: {\n bucket: string;\n type: RateLimitType;\n value: string;\n message?: string;\n}) {\n const { bucket, type, value, message } = options;\n const rules = allRules.filter((rule) => rule.bucket === bucket && rule.type === type);\n const createError = message ? () => new RateLimitError(message) : undefined;\n\n for (const rule of rules) {\n await checkRateLimitRule(rule, value, createError);\n }\n}\n\n// Two-bucket sliding window approximation to track rate limits.\nasync function checkRateLimitRule(rule: RateLimitRule, value: string, createError?: () => Error) {\n const createRateLimitError = () => {\n return createError\n ? createError()\n : new RateLimitError(`Rate limit exceeded for ${rule.bucket}`);\n };\n\n const record = await dbRateLimits.findOne({\n bucket: rule.bucket,\n type: rule.type,\n value,\n windowMs: rule.window,\n });\n\n const now = Date.now();\n const currentWindowStart = Math.floor(now / rule.window) * rule.window;\n\n const { count, modifier } = record\n ? getCount(record, currentWindowStart, now)\n : {\n count: 0,\n modifier: {\n $setOnInsert: {\n windowStart: new Date(currentWindowStart),\n windowCount: 1,\n prevWindowCount: 0,\n expiresAt: new Date(currentWindowStart + rule.window + rule.window),\n },\n },\n };\n\n if (count >= rule.limit) {\n throw createRateLimitError();\n }\n\n /*\n Always use upsert, because there is a small chance the document might be auto-removed\n based on the expiration TTL index in between the check and the update\n */\n await dbRateLimits.upsertOne(\n { bucket: rule.bucket, type: rule.type, value, windowMs: rule.window },\n modifier\n );\n}\n\nfunction getCount(record: (typeof dbRateLimits)['Doc'], currentWindowStart: number, now: number) {\n const prevWindowStart = currentWindowStart - record.windowMs;\n\n if (record.windowStart.getTime() === currentWindowStart) {\n const currentWindowCount = record.windowCount;\n const prevWindowCount = record.prevWindowCount;\n const prevWindowWeight = 1 - (now - currentWindowStart) / record.windowMs;\n return {\n count: Math.round(currentWindowCount + prevWindowCount * prevWindowWeight),\n modifier: {\n $inc: { windowCount: 1 },\n $setOnInsert: {\n windowStart: new Date(currentWindowStart),\n prevWindowCount: 0,\n expiresAt: new Date(currentWindowStart + record.windowMs + record.windowMs),\n },\n },\n };\n }\n\n if (record.windowStart.getTime() === prevWindowStart) {\n const weight = 1 - (now - currentWindowStart) / record.windowMs;\n return {\n count: Math.round(record.windowCount * weight),\n modifier: {\n $set: {\n windowStart: new Date(currentWindowStart),\n windowCount: 1,\n prevWindowCount: record.windowCount,\n expiresAt: new Date(currentWindowStart + record.windowMs + record.windowMs),\n },\n },\n };\n }\n\n return {\n count: 0,\n modifier: {\n $set: {\n windowStart: new Date(currentWindowStart),\n windowCount: 1,\n prevWindowCount: 0,\n expiresAt: new Date(currentWindowStart + record.windowMs + record.windowMs),\n },\n },\n };\n}\n","export function emailVerificationTemplate({\n name,\n email,\n verificationUrl,\n}: {\n name?: string;\n email: string;\n verificationUrl: string;\n}) {\n return `\n <p>Hi${name ? ` ${name}` : ''},</p>\n <p>Please verify your email address ${email} by clicking the link below:</p>\n <p><a href=\"${verificationUrl}\">${verificationUrl}</a></p>\n <p>If you did not request this, please ignore this email.</p>\n `;\n}\n","import { z } from 'zod';\n\nimport { usersCollection, emailVerificationTokensCollection } from './db';\nimport { ObjectId, RouteParams, RouteResponse } from '@/server';\nimport { getEmailConfig } from '@/app/emailConfig';\nimport { randomBytes } from 'crypto';\nimport { time } from '@/time';\nimport { htmlToText } from '@/utils';\nimport { emailVerificationTemplate } from './templates/emailVerficationTemplate';\nimport { getAuthConfig } from '@/app/authConfig';\nimport { User } from './types';\nimport { Args, Context } from '@/methods/types';\nimport { validateEmail } from './validators';\nimport { consumeRateLimit } from '@/rate-limit/rules';\nimport { getConfig } from '@/config/server';\n\nexport async function handleVerifyEmail(params: RouteParams): Promise<RouteResponse> {\n const baseUrl = getConfig('_system.site.url') as string | undefined;\n const emailVerifiedRedirectUrl =\n getEmailConfig().verification?.redirectUrl ||\n getEmailConfig().emailVerifiedRedirectUrl ||\n baseUrl ||\n '/';\n try {\n const token = z.string().parse(params.query.token);\n // Find token in database\n const tokenDoc = await emailVerificationTokensCollection.findOne({\n token,\n expiresAt: { $gt: new Date() },\n });\n\n if (!tokenDoc) {\n throw new Error('Invalid or expired verification token');\n }\n\n // Find user by token's userId\n const userDoc = await usersCollection.findOne({ _id: tokenDoc.userId });\n\n if (!userDoc) {\n throw new Error('User not found');\n }\n\n const email = tokenDoc.email;\n\n if (!email) {\n throw new Error('Email not found in token');\n }\n\n // Mark the specific email as verified atomically\n const updateResult = await usersCollection.updateOne(\n {\n _id: tokenDoc.userId,\n 'emails.address': email,\n 'emails.verified': { $ne: true },\n },\n { $set: { 'emails.$.verified': true } }\n );\n\n if (updateResult.matchedCount === 0) {\n // Check if email exists but is already verified\n const existingUser = await usersCollection.findOne({\n _id: tokenDoc.userId,\n 'emails.address': email,\n });\n\n if (existingUser) {\n throw new Error('Email is already verified');\n } else {\n throw new Error('Email address not found for this user');\n }\n }\n\n // Delete the used token\n await emailVerificationTokensCollection.deleteOne({ _id: tokenDoc._id });\n\n const authConfig = getAuthConfig();\n authConfig.onAfterEmailVerification?.({\n provider: 'email',\n user: (await usersCollection.findOne({ 'emails.address': tokenDoc?.email })) as User,\n session: null,\n connectionInfo: {\n baseUrl,\n ip: params.req.ip || params.req.socket.remoteAddress,\n userAgent: params.headers['user-agent'],\n acceptLanguage: params.headers['accept-language'],\n referrer: params.headers['referer'],\n },\n });\n } catch (error) {\n if (error instanceof Error) {\n const authConfig = getAuthConfig();\n authConfig.onEmailVerificationError?.({\n provider: 'email',\n error,\n session: null,\n connectionInfo: {\n baseUrl,\n ip: params.req.ip || params.req.socket.remoteAddress,\n userAgent: params.headers['user-agent'],\n acceptLanguage: params.headers['accept-language'],\n referrer: params.headers['referer'],\n },\n });\n console.error('Error verifying email:', error);\n\n return {\n status: 301,\n redirect: `${emailVerifiedRedirectUrl}?status=error&message=${encodeURIComponent(error.message)}`,\n };\n }\n }\n\n return {\n status: 301,\n redirect: `${emailVerifiedRedirectUrl}?status=verified`,\n };\n}\n\nexport async function sendVerificationEmail({\n userId,\n email,\n baseUrl = getConfig('_system.site.url') as string | undefined,\n}: {\n userId: ObjectId;\n email: string;\n baseUrl?: string;\n}) {\n if (getEmailConfig().provider) {\n const emailProvider = getEmailConfig().provider;\n\n // Generate verification token\n const verificationToken = randomBytes(32).toString('hex');\n const expiresAt = new Date(Date.now() + time.hours(24));\n\n // Store token in database\n await emailVerificationTokensCollection.insertOne({\n userId,\n email,\n token: verificationToken,\n createdAt: new Date(),\n expiresAt,\n });\n\n const verificationUrl = `${baseUrl}/api/_internal/auth/verify-email?token=${verificationToken}`;\n\n const template = getEmailConfig()?.verification?.template || emailVerificationTemplate;\n // TODO: we should have also the name on this step\n const htmlTemplate = template({ name: '', email, verificationUrl });\n const textContent = htmlToText(htmlTemplate);\n\n await emailProvider?.sendEmail({\n to: email,\n from: getEmailConfig()?.from || 'noreply@modelence.com',\n subject: getEmailConfig()?.verification?.subject || 'Verify your email address',\n text: textContent,\n html: htmlTemplate,\n });\n }\n}\n\nconst resendVerificationResponse = {\n success: true,\n message: 'If that email is registered and not yet verified, a verification email has been sent',\n};\n\nexport async function handleResendEmailVerification(args: Args, { connectionInfo }: Context) {\n const email = validateEmail(args.email as string);\n\n // Find user by email, excluding deleted/disabled accounts\n const userDoc = await usersCollection.findOne(\n { 'emails.address': email, status: { $nin: ['deleted', 'disabled'] } },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n // Return the same generic response whether the email is unknown,\n // already verified, or successfully sent — to prevent user enumeration.\n if (!userDoc) {\n return resendVerificationResponse;\n }\n\n const emailDoc = userDoc.emails?.find((e) => e.address.toLowerCase() === email);\n\n if (!emailDoc || emailDoc.verified) {\n return resendVerificationResponse;\n }\n\n if (!getEmailConfig().provider) {\n throw new Error('Email provider is not configured');\n }\n\n await consumeRateLimit({\n bucket: 'verification',\n type: 'user',\n value: userDoc._id.toString(),\n message: 'Please wait at least 60 seconds before requesting another verification email',\n });\n\n await sendVerificationEmail({\n userId: userDoc._id,\n email,\n baseUrl: connectionInfo?.baseUrl,\n });\n\n return resendVerificationResponse;\n}\n","import { randomBytes } from 'crypto';\nimport { usersCollection } from './db';\nimport { validateHandle, MAX_HANDLE_LENGTH, MIN_HANDLE_LENGTH } from './validators';\n\n/**\nFinds an available handle by appending incremental suffixes (_2, _3, …)\nto the base handle until a unique one is found.\nThe base handle is truncated so that the suffixed candidate never exceeds MAX_HANDLE_LENGTH.\n */\nasync function findAvailableHandle(baseHandle: string): Promise<string> {\n // Truncate base handle to MAX_HANDLE_LENGTH so the unsuffixed form is valid.\n const truncatedBase = baseHandle.slice(0, MAX_HANDLE_LENGTH);\n\n // Check the unsuffixed base handle first.\n try {\n const firstCheck = await usersCollection.findOne(\n { handle: truncatedBase },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (!firstCheck) {\n return truncatedBase;\n }\n } catch (err) {\n throw new Error(`Database error while checking handle availability: ${err}`);\n }\n\n // Try sequential suffixes _2 through _51 (50 attempts).\n const MAX_SUFFIX_VALUE = 51;\n\n for (let suffix = 2; suffix <= MAX_SUFFIX_VALUE; suffix++) {\n const suffixStr = `_${suffix}`;\n const candidate = `${truncatedBase.slice(0, MAX_HANDLE_LENGTH - suffixStr.length)}${suffixStr}`;\n\n try {\n const conflict = await usersCollection.findOne(\n { handle: candidate },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (!conflict) {\n return candidate;\n }\n } catch (err) {\n throw new Error(`Database error while checking handle \"${candidate}\": ${err}`);\n }\n }\n\n // Fallback: sequential suffixes exhausted — use random hex suffixes.\n // Limit the number of attempts to avoid an infinite loop in case of persistent DB issues\n const MAX_RANDOM_ATTEMPTS = 10;\n\n for (let attempt = 0; attempt < MAX_RANDOM_ATTEMPTS; attempt++) {\n const randomSuffix = `_${randomBytes(3).toString('hex')}`;\n const candidate = `${truncatedBase.slice(0, MAX_HANDLE_LENGTH - randomSuffix.length)}${randomSuffix}`;\n\n try {\n const conflict = await usersCollection.findOne(\n { handle: candidate },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (!conflict) {\n return candidate;\n }\n } catch (err) {\n throw new Error(`Database error while checking handle \"${candidate}\": ${err}`);\n }\n }\n\n throw new Error(\n `Could not generate a unique handle for base \"${baseHandle}\" after exhausting all attempts.`\n );\n}\n\n/**\n * Resolves a unique handle for a new user.\n *\n * If the caller supplied a handle it is validated and checked for uniqueness.\n * - When `throwOnConflict` is true (default), an error is thrown if the handle is taken.\n * - When `throwOnConflict` is false, a numeric suffix (_2, _3, …) is appended to make\n * it unique. This is intended for system-generated handles (e.g. from `generateHandle`).\n *\n * If no handle is supplied, the local part of the email address is used as the base handle,\n * and a numeric suffix is appended until an unused handle is found.\n */\nexport async function resolveUniqueHandle(\n rawHandle: string | undefined,\n email: string,\n { throwOnConflict = true }: { throwOnConflict?: boolean } = {}\n): Promise<string> {\n if (rawHandle !== undefined && rawHandle !== null && String(rawHandle).trim() !== '') {\n // Caller explicitly provided a handle – trim and validate it.\n const handle = validateHandle(String(rawHandle).trim());\n\n if (throwOnConflict) {\n const existing = await usersCollection.findOne(\n { handle },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (existing) {\n throw new Error('Handle already taken.');\n }\n\n return handle;\n }\n\n // System-generated handle – find an available variant with suffix if needed.\n return findAvailableHandle(handle);\n }\n\n // Derive handle from the email local-part (everything before '@').\n // Truncate to MAX_HANDLE_LENGTH since RFC 5321 allows local parts up to 64 chars.\n const baseHandle = email.split('@')[0].padEnd(MIN_HANDLE_LENGTH, '_').slice(0, MAX_HANDLE_LENGTH);\n return findAvailableHandle(baseHandle);\n}\n","import bcrypt from 'bcrypt';\nimport { SignupProps, Context, Args } from '../methods/types';\nimport { usersCollection } from './db';\nimport { isDisposableEmail } from './disposableEmails';\nimport { consumeRateLimit } from '../rate-limit/rules';\nimport { sendVerificationEmail } from './verification';\nimport { validateEmail, validatePassword, validateProfileFields } from './validators';\nimport { getAuthConfig } from '@/app/authConfig';\nimport { resolveUniqueHandle } from './utils';\n\nexport async function handleSignupWithPassword(\n props: Args,\n { user, session, connectionInfo }: Context\n) {\n const authConfig = getAuthConfig();\n try {\n // Narrow once at the boundary\n const signupProps = props as SignupProps;\n const { firstName, lastName, avatarUrl, handle } = signupProps;\n\n const email = validateEmail(signupProps.email);\n const password = validatePassword(signupProps.password);\n\n const ip = connectionInfo?.ip;\n if (ip) {\n await consumeRateLimit({\n bucket: 'signupAttempt',\n type: 'ip',\n value: ip,\n });\n }\n\n if (await isDisposableEmail(email)) {\n throw new Error('Please use a permanent email address');\n }\n\n // TODO: captcha check\n\n if (user) {\n // TODO: handle cases where a user is already logged in\n }\n\n const existingUser = await usersCollection.findOne(\n { 'emails.address': email },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (existingUser) {\n const existingEmail = existingUser.emails?.find((e) => e.address.toLowerCase() === email);\n if (existingUser.status === 'disabled') {\n throw new Error(\n `User is marked for deletion, please contact support if you want to restore the account.`\n );\n }\n throw new Error(`User with email already exists: ${existingEmail?.address}`);\n }\n\n if (ip) {\n await consumeRateLimit({\n bucket: 'signup',\n type: 'ip',\n value: ip,\n });\n }\n\n // Validate optional profile fields (firstName, lastName, avatarUrl, handle)\n const profileFields = validateProfileFields({\n firstName,\n lastName,\n avatarUrl,\n handle,\n });\n\n await authConfig.validateSignup?.({\n email,\n password,\n ...profileFields,\n });\n\n // Resolve unique handle\n let resolvedHandle: string;\n\n if (profileFields.handle) {\n resolvedHandle = await resolveUniqueHandle(profileFields.handle, email);\n } else if (authConfig.generateHandle) {\n const generated = await authConfig.generateHandle({\n email,\n firstName: profileFields.firstName,\n lastName: profileFields.lastName,\n });\n\n resolvedHandle = await resolveUniqueHandle(generated, email, {\n throwOnConflict: false,\n });\n } else {\n resolvedHandle = await resolveUniqueHandle(undefined, email);\n }\n\n // Hash password with bcrypt (salt is automatically generated)\n const hash = await bcrypt.hash(password, 10);\n\n const result = await usersCollection.insertOne({\n handle: resolvedHandle,\n status: 'active',\n emails: [\n {\n address: email,\n verified: false,\n },\n ],\n createdAt: new Date(),\n authMethods: {\n password: {\n hash,\n },\n },\n ...(profileFields.firstName !== undefined && { firstName: profileFields.firstName }),\n ...(profileFields.lastName !== undefined && { lastName: profileFields.lastName }),\n ...(profileFields.avatarUrl !== undefined && { avatarUrl: profileFields.avatarUrl }),\n });\n\n const userDocument = await usersCollection.findOne(\n { _id: result.insertedId },\n { readPreference: 'primary' }\n );\n\n if (!userDocument) {\n throw new Error('User not found');\n }\n\n await sendVerificationEmail({\n userId: result?.insertedId,\n email,\n baseUrl: connectionInfo?.baseUrl,\n });\n\n authConfig.onAfterSignup?.({\n provider: 'email',\n user: userDocument,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onSuccess?.(userDocument);\n\n return result.insertedId;\n } catch (error) {\n if (error instanceof Error) {\n authConfig.onSignupError?.({\n provider: 'email',\n error,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onError?.(error);\n }\n throw error;\n }\n}\n","import { z } from 'zod';\nimport bcrypt from 'bcrypt';\nimport { randomBytes } from 'crypto';\n\nimport { Args, Context } from '@/methods/types';\nimport { usersCollection, resetPasswordTokensCollection } from './db';\nimport { getEmailConfig } from '@/app/emailConfig';\nimport { time } from '@/time';\nimport { htmlToText } from '@/utils';\nimport { validateEmail, validatePassword } from './validators';\nimport { consumeRateLimit } from '@/server';\nimport { getConfig } from '@/config/server';\n\nfunction resolveUrl(baseUrl: string, configuredUrl?: string): string {\n if (!configuredUrl) {\n return baseUrl;\n }\n\n if (configuredUrl.startsWith('http://') || configuredUrl.startsWith('https://')) {\n return configuredUrl;\n }\n\n // Handle relative URL\n return `${baseUrl}${configuredUrl.startsWith('/') ? '' : '/'}${configuredUrl}`;\n}\n\nfunction defaultPasswordResetTemplate({ email, resetUrl }: { email: string; resetUrl: string }) {\n return `\n <p>Hi,</p>\n <p>We received a request to reset your password for ${email}.</p>\n <p>Click the link below to reset your password:</p>\n <p><a href=\"${resetUrl}\">${resetUrl}</a></p>\n <p>This link will expire in 1 hour.</p>\n <p>If you did not request this password reset, please ignore this email.</p>\n `;\n}\n\nconst passwordResetSent = {\n success: true,\n message: 'If an account with that email exists, a password reset link has been sent',\n};\n\nexport async function handleSendResetPasswordToken(args: Args, { connectionInfo }: Context) {\n const email = validateEmail(args.email as string);\n const ip = connectionInfo?.ip;\n\n if (ip) {\n await consumeRateLimit({\n bucket: 'passwordReset',\n type: 'ip',\n value: ip,\n });\n }\n\n await consumeRateLimit({\n bucket: 'passwordReset',\n type: 'email',\n value: email,\n });\n\n // Find user by email\n const userDoc = await usersCollection.findOne(\n { 'emails.address': email, status: { $nin: ['deleted', 'disabled'] } },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (!userDoc) {\n // For security, don't reveal if email exists or not\n return passwordResetSent;\n }\n\n // Check if user has password auth method\n if (!userDoc.authMethods?.password) {\n return passwordResetSent;\n }\n\n const emailProvider = getEmailConfig().provider;\n if (!emailProvider) {\n throw new Error('Email provider is not configured');\n }\n\n // Generate reset token\n const resetToken = randomBytes(32).toString('hex');\n const now = Date.now();\n const createdAt = new Date(now);\n const expiresAt = new Date(now + time.hours(1)); // 1 hour expiry\n\n // Store reset token\n await resetPasswordTokensCollection.insertOne({\n userId: userDoc._id,\n email,\n token: resetToken,\n createdAt,\n expiresAt,\n });\n\n // Build reset URL\n const baseUrl = (getConfig('_system.site.url') as string | undefined) || connectionInfo?.baseUrl;\n const resetPasswordUrl = resolveUrl(baseUrl!, getEmailConfig().passwordReset?.redirectUrl);\n const resetUrl = `${resetPasswordUrl}?token=${resetToken}`;\n\n // Send email\n const template = getEmailConfig()?.passwordReset?.template || defaultPasswordResetTemplate;\n const htmlTemplate = template({ email, resetUrl, name: '' });\n const textContent = htmlToText(htmlTemplate);\n\n await emailProvider.sendEmail({\n to: email,\n from: getEmailConfig()?.from || 'noreply@modelence.com',\n subject: getEmailConfig()?.passwordReset?.subject || 'Reset your password',\n text: textContent,\n html: htmlTemplate,\n });\n\n return passwordResetSent;\n}\n\nexport async function handleResetPassword(args: Args, {}: Context) {\n const token = z.string().parse(args.token);\n const password = validatePassword(args.password as string);\n\n // Find the reset token\n const resetTokenDoc = await resetPasswordTokensCollection.findOne({ token });\n if (!resetTokenDoc) {\n throw new Error('Invalid or expired reset token');\n }\n\n // Check if token is expired\n if (resetTokenDoc.expiresAt < new Date()) {\n await resetPasswordTokensCollection.deleteOne({ token });\n throw new Error('Reset token has expired');\n }\n\n // Find the user\n const userDoc = await usersCollection.findOne({ _id: resetTokenDoc.userId });\n if (!userDoc) {\n throw new Error('User not found');\n }\n\n // Hash the new password\n const hash = await bcrypt.hash(password, 10);\n\n // Update user's password\n await usersCollection.updateOne(\n { _id: userDoc._id },\n { $set: { 'authMethods.password.hash': hash } }\n );\n\n // Mark the email as verified since the user proved ownership via the reset token\n if (resetTokenDoc.email) {\n await usersCollection.updateOne(\n { _id: userDoc._id, 'emails.address': resetTokenDoc.email },\n { $set: { 'emails.$.verified': true } }\n );\n }\n\n // Delete the used reset token\n await resetPasswordTokensCollection.deleteOne({ token });\n\n return { success: true, message: 'Password has been reset successfully' };\n}\n","import { randomBytes } from 'crypto';\n\nimport { Module } from '../app/module';\nimport { time } from '../time';\nimport {\n dbDisposableEmailDomains,\n emailVerificationTokensCollection,\n resetPasswordTokensCollection,\n usersCollection,\n} from './db';\nimport { updateDisposableEmailListCron } from './disposableEmails';\nimport { handleLoginWithPassword, handleLogout } from './login';\nimport { getOwnProfile, handleUpdateProfile } from './profile';\nimport { handleUnlinkOAuthProvider } from './unlinkOAuthProvider';\nimport { handleSignupWithPassword } from './signup';\nimport { handleVerifyEmail, handleResendEmailVerification } from './verification';\nimport { handleResetPassword, handleSendResetPasswordToken } from './resetPassword';\n\nexport async function createGuestUser() {\n // TODO: add rate-limiting and captcha handling\n\n const guestId = randomBytes(9)\n .toString('base64')\n .replace(/[+/]/g, (c) => (c === '+' ? 'a' : 'b'));\n\n const handle = `guest_${guestId}`;\n // TODO: re-try on handle collision\n\n const result = await usersCollection.insertOne({\n handle,\n status: 'active',\n createdAt: new Date(),\n authMethods: {},\n });\n\n return result.insertedId;\n}\n\nexport default new Module('_system.user', {\n stores: [\n usersCollection,\n dbDisposableEmailDomains,\n emailVerificationTokensCollection,\n resetPasswordTokensCollection,\n ],\n queries: {\n getOwnProfile,\n },\n mutations: {\n signupWithPassword: handleSignupWithPassword,\n loginWithPassword: handleLoginWithPassword,\n logout: handleLogout,\n resendEmailVerification: handleResendEmailVerification,\n sendResetPasswordToken: handleSendResetPasswordToken,\n resetPassword: handleResetPassword,\n updateProfile: handleUpdateProfile,\n unlinkOAuthProvider: handleUnlinkOAuthProvider,\n },\n cronJobs: {\n updateDisposableEmailList: updateDisposableEmailListCron,\n },\n rateLimits: [\n {\n bucket: 'signup',\n type: 'ip',\n window: time.minutes(15),\n limit: 20,\n },\n {\n bucket: 'signup',\n type: 'ip',\n window: time.days(1),\n limit: 200,\n },\n {\n bucket: 'signupAttempt',\n type: 'ip',\n window: time.minutes(15),\n limit: 50,\n },\n {\n bucket: 'signupAttempt',\n type: 'ip',\n window: time.days(1),\n limit: 500,\n },\n {\n bucket: 'signin',\n type: 'ip',\n window: time.minutes(15),\n limit: 50,\n },\n {\n bucket: 'signin',\n type: 'ip',\n window: time.days(1),\n limit: 500,\n },\n {\n bucket: 'verification',\n type: 'user',\n window: time.seconds(60),\n limit: 1,\n },\n {\n bucket: 'verification',\n type: 'user',\n window: time.days(1),\n limit: 10,\n },\n {\n bucket: 'passwordReset',\n type: 'ip',\n window: time.minutes(15),\n limit: 10,\n },\n {\n bucket: 'passwordReset',\n type: 'ip',\n window: time.days(1),\n limit: 100,\n },\n {\n bucket: 'passwordReset',\n type: 'email',\n window: time.hours(1),\n limit: 5,\n },\n {\n bucket: 'passwordReset',\n type: 'email',\n window: time.days(1),\n limit: 10,\n },\n ],\n configSchema: {\n 'auth.email.enabled': {\n type: 'boolean',\n isPublic: true,\n default: true,\n },\n 'auth.email.from': {\n type: 'string',\n isPublic: false,\n default: '',\n },\n 'auth.email.verification': {\n type: 'boolean',\n isPublic: true,\n default: false,\n },\n 'auth.google.enabled': {\n type: 'boolean',\n isPublic: true,\n default: false,\n },\n 'auth.google.clientId': {\n type: 'string',\n isPublic: false,\n default: '',\n },\n 'auth.google.clientSecret': {\n type: 'secret',\n isPublic: false,\n default: '',\n },\n 'auth.github.enabled': {\n type: 'boolean',\n isPublic: true,\n default: false,\n },\n 'auth.github.clientId': {\n type: 'string',\n isPublic: false,\n default: '',\n },\n 'auth.github.clientSecret': {\n type: 'secret',\n isPublic: false,\n default: '',\n },\n },\n routes: [\n {\n path: '/api/_internal/auth/verify-email',\n handlers: {\n get: handleVerifyEmail,\n },\n },\n ],\n});\n","import { AppConfig, ConfigSchema, ConfigType } from './types';\n\ntype LocalConfigVariant = 'withRemoteServer' | 'withoutRemoteServer';\n\nconst localConfigMap = {\n withoutRemoteServer: {\n MONGODB_URI: '_system.mongodbUri',\n MONGODB_POOL_SIZE: '_system.mongodbPoolSize',\n MODELENCE_AUTH_GOOGLE_ENABLED: '_system.user.auth.google.enabled',\n MODELENCE_AUTH_GOOGLE_CLIENT_ID: '_system.user.auth.google.clientId',\n MODELENCE_AUTH_GOOGLE_CLIENT_SECRET: '_system.user.auth.google.clientSecret',\n MODELENCE_AUTH_GITHUB_ENABLED: '_system.user.auth.github.enabled',\n MODELENCE_AUTH_GITHUB_CLIENT_ID: '_system.user.auth.github.clientId',\n MODELENCE_AUTH_GITHUB_CLIENT_SECRET: '_system.user.auth.github.clientSecret',\n MODELENCE_AUTH_GITHUB_CLIENT_SCOPES: '_system.user.auth.github.scopes',\n MODELENCE_EMAIL_RESEND_API_KEY: '_system.email.resend.apiKey',\n MODELENCE_EMAIL_AWS_SES_REGION: '_system.email.awsSes.region',\n MODELENCE_EMAIL_AWS_SES_ACCESS_KEY_ID: '_system.email.awsSes.accessKeyId',\n MODELENCE_EMAIL_AWS_SES_SECRET_ACCESS_KEY: '_system.email.awsSes.secretAccessKey',\n MODELENCE_EMAIL_SMTP_HOST: '_system.email.smtp.host',\n MODELENCE_EMAIL_SMTP_PORT: '_system.email.smtp.port',\n MODELENCE_EMAIL_SMTP_USER: '_system.email.smtp.user',\n MODELENCE_EMAIL_SMTP_PASS: '_system.email.smtp.pass',\n MODELENCE_SITE_URL: '_system.site.url',\n MODELENCE_ENV_TYPE: '_system.env.type',\n // deprecated\n MODELENCE_ENV: '_system.env',\n GOOGLE_AUTH_ENABLED: '_system.user.auth.google.enabled',\n GOOGLE_AUTH_CLIENT_ID: '_system.user.auth.google.clientId',\n GOOGLE_AUTH_CLIENT_SECRET: '_system.user.auth.google.clientSecret',\n },\n withRemoteServer: {\n MODELENCE_SITE_URL: '_system.site.url',\n },\n} as const;\n\nfunction formatLocalConfigValue(value: string, type: ConfigType): string | number | boolean {\n if (type === 'number') {\n const numValue = Number(value);\n if (isNaN(numValue)) {\n throw new Error(`Invalid number value for config: ${value}`);\n }\n return numValue;\n }\n if (type === 'boolean') {\n if (value.toLowerCase() === 'true') {\n return true;\n }\n if (value.toLowerCase() === 'false') {\n return false;\n }\n throw new Error(`Invalid boolean value for config: ${value}`);\n }\n return value;\n}\n\nfunction getConfigsFromEnvMap(\n configMap: Record<string, string>,\n configSchema: ConfigSchema\n): AppConfig[] {\n const configs: AppConfig[] = [];\n\n for (const [envVar, configKey] of Object.entries(configMap)) {\n const value = process.env[envVar];\n const configSchemaEntry = configSchema[configKey];\n if (value) {\n const type = configSchemaEntry?.type ?? 'string';\n configs.push({\n key: configKey,\n type: type,\n value: formatLocalConfigValue(value, type),\n });\n }\n }\n\n return configs;\n}\n\nexport function getLocalConfigs(\n configSchema: ConfigSchema,\n variant: LocalConfigVariant = 'withoutRemoteServer'\n): AppConfig[] {\n const configMap = localConfigMap[variant];\n return getConfigsFromEnvMap(configMap, configSchema);\n}\n","import os from 'os';\nimport { ConfigSchema } from '../config/types';\nimport { CronJobMetadata } from '../cron/types';\nimport { RoleDefinition } from '../auth/types';\nimport { Store } from '../data/store';\nimport { AppConfig } from '../config/types';\n\ntype CloudBackendConnectOkResponse = {\n status: 'ok';\n configs: AppConfig[];\n environmentId: string;\n appAlias: string;\n environmentAlias: string;\n telemetry: {\n isEnabled: boolean;\n serviceName: string;\n };\n};\n\ntype CloudBackendConnectErrorResponse = {\n status: 'error';\n error: string;\n};\n\nexport type CloudBackendConnectResponse =\n | CloudBackendConnectOkResponse\n | CloudBackendConnectErrorResponse;\n\nexport async function connectCloudBackend({\n configSchema,\n cronJobsMetadata,\n stores,\n roles,\n}: {\n configSchema?: ConfigSchema;\n cronJobsMetadata?: CronJobMetadata[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stores: Store<any, any>[];\n roles?: Record<string, RoleDefinition>;\n}): Promise<CloudBackendConnectOkResponse> {\n const containerId = process.env.MODELENCE_CONTAINER_ID;\n if (!containerId) {\n throw new Error('Unable to connect to Modelence Cloud: MODELENCE_CONTAINER_ID is not set');\n }\n\n try {\n const dataModels = Object.values(stores).map((store) => {\n return {\n name: store.getName(),\n schema: store.getSerializedSchema(),\n collections: [store.getName()],\n version: 2,\n };\n });\n\n const data = await callApi<CloudBackendConnectResponse>('/api/connect', 'POST', {\n hostname: os.hostname(),\n containerId,\n dataModels,\n configSchema,\n cronJobsMetadata,\n roles,\n });\n\n if (data.status === 'error') {\n throw new Error(data.error);\n }\n\n console.log('Successfully connected to Modelence Cloud');\n\n return data;\n } catch (error) {\n console.error('Unable to connect to Modelence Cloud:', error);\n throw error;\n }\n}\n\nexport async function fetchConfigs() {\n return callApi<{ configs: AppConfig[] }>('/api/configs', 'GET');\n}\n\nexport async function syncStatus() {\n const data = await callApi('/api/sync', 'POST', {\n containerId: process.env.MODELENCE_CONTAINER_ID,\n });\n return data;\n}\n\nasync function callApi<T = unknown>(endpoint: string, method: string, payload?: object) {\n return callCloudApi<T>(\n endpoint,\n method,\n payload ? JSON.stringify(payload) : undefined,\n payload ? { 'Content-Type': 'application/json' } : {}\n );\n}\n\nexport async function callCloudApi<T>(\n endpoint: string,\n method: string,\n body?: BodyInit,\n extraHeaders?: Record<string, string>\n): Promise<T> {\n const { MODELENCE_SERVICE_ENDPOINT, MODELENCE_SERVICE_TOKEN } = process.env;\n\n if (!MODELENCE_SERVICE_ENDPOINT) {\n throw new Error('Unable to connect to Modelence Cloud: MODELENCE_SERVICE_ENDPOINT is not set');\n }\n\n const response = await fetch(`${MODELENCE_SERVICE_ENDPOINT}${endpoint}`, {\n method,\n headers: {\n Authorization: `Bearer ${MODELENCE_SERVICE_TOKEN}`,\n ...extraHeaders,\n },\n body,\n });\n\n if (!response.ok) {\n const data = await response.text();\n try {\n const json = JSON.parse(data);\n throw new Error(\n `Unable to connect to Modelence Cloud: HTTP status: ${response.status}, ${json?.error}`\n );\n } catch {\n throw new Error(\n `Unable to connect to Modelence Cloud: HTTP status: ${response.status}, ${data}`\n );\n }\n }\n\n if (response.status === 204 || response.headers?.get('content-length') === '0') {\n return undefined as T;\n }\n\n return (await response.json()) as T;\n}\n","import { time } from '../time';\nimport { fetchConfigs, syncStatus } from '../app/backendApi';\nimport { getLocalConfigs } from './local';\nimport { loadConfigs, getSchema } from './server';\nimport { AppConfig } from './types';\n\nlet isSyncing = false;\n\nconst SYNC_INTERVAL = time.seconds(10);\n\nexport function startConfigSync() {\n setInterval(async () => {\n if (isSyncing) {\n return;\n }\n\n isSyncing = true;\n\n // TODO: move this sync outside of config\n try {\n await syncStatus();\n } catch (error) {\n console.error('Error syncing status', error);\n }\n\n try {\n await syncConfig();\n } catch (error) {\n console.error('Error syncing config', error);\n }\n\n isSyncing = false;\n }, SYNC_INTERVAL);\n}\n\nexport function loadRemoteConfigs(configs: AppConfig[]) {\n loadConfigs(configs);\n loadConfigs(getLocalConfigs(getSchema(), 'withRemoteServer'));\n}\n\nasync function syncConfig() {\n const { configs } = await fetchConfigs();\n loadRemoteConfigs(configs);\n}\n","import { schema } from '../data/types';\nimport { Store } from '../data/store';\n\n/**\n * Database collection for storing distributed locks.\n *\n * Locks are used to ensure that only one instance of the application can perform\n * a specific action at a time, such as running cron jobs or migrations\n */\nexport const locksCollection = new Store('_modelenceLocks', {\n schema: {\n _id: schema.string(), // unique identifier for the lock, used as the primary key\n instanceId: schema.string(),\n acquiredAt: schema.date(),\n\n resource: schema.string(), // deprecated, will be dropped in v1.0.0 (use _id instead)\n },\n indexes: [\n {\n // TODO(v1.0.0): remove after dropping legacy `resource` compatibility.\n key: { resource: 1 },\n unique: true,\n },\n {\n // TODO(v1.0.0): remove after dropping legacy `resource` compatibility.\n key: { resource: 1, instanceId: 1 },\n },\n {\n // TODO(v1.0.0): remove after dropping legacy `resource` compatibility.\n key: { resource: 1, acquiredAt: 1 },\n },\n ],\n indexCreationMode: 'blocking',\n});\n","import { randomBytes } from 'crypto';\nimport { MongoError } from 'mongodb';\nimport { locksCollection } from './db';\nimport { logDebug } from '../telemetry';\nimport { time } from '@/time';\n\n/**\n * In-memory cache to avoid frequent lock acquisition attempts\n * for the same resource within a short time frame.\n */\nconst lockCache: Record<\n string,\n {\n value: boolean;\n expiresAt: number;\n }\n> = {};\n\n/**\n * Time duration to consider a cached lock acquisition valid\n */\nconst DEFAULT_CACHE_DURATION = time.seconds(10);\n\n/**\n * Unique identifier for this application instance.\n * Generated once per application instance to track which container owns which locks.\n */\nconst INSTANCE_ID = randomBytes(32).toString('base64url');\n\n/**\n * Time after which a lock is expired\n */\nconst DEFAULT_LOCK_DURATION = time.seconds(30);\n\ntype LockOptions = {\n lockDuration?: number;\n successfulLockCacheDuration?: number;\n failedLockCacheDuration?: number;\n heartbeat?: boolean;\n bypassCache?: boolean;\n instanceId?: string;\n};\n\ntype LockHeartbeat = {\n timer: ReturnType<typeof setTimeout> | null;\n stopRequested: boolean;\n lockDuration: number;\n heartbeatInterval: number;\n};\n\nconst lockHeartbeats = new Map<string, LockHeartbeat>();\n\ntype DuplicateKeyMongoError = MongoError & {\n code?: number;\n keyPattern?: Record<string, unknown>;\n};\n\nconst isDuplicateKeyError = (error: unknown): error is DuplicateKeyMongoError =>\n error instanceof MongoError && error.code === 11000;\n\nconst hasKeyPatternField = (error: DuplicateKeyMongoError, field: string): boolean =>\n typeof error.keyPattern === 'object' &&\n error.keyPattern !== null &&\n Object.prototype.hasOwnProperty.call(error.keyPattern, field);\n\n/**\n * TODO(v1.0.0): Remove legacy `resource` fallback support.\n * This helper only exists for pre-1.0.0 lock documents where `_id !== resource`.\n * Delete this function and its call sites when releasing 1.0.0.\n */\nconst shouldFallbackToLegacyStrategy = async ({\n error,\n resource,\n}: {\n error: DuplicateKeyMongoError;\n resource: string;\n}): Promise<boolean> => {\n if (hasKeyPatternField(error, 'resource')) {\n return true;\n }\n\n if (hasKeyPatternField(error, '_id')) {\n return false;\n }\n\n const existingLock = (await locksCollection.findOne({ resource })) as {\n _id?: unknown;\n } | null;\n\n return !!existingLock && existingLock._id !== resource;\n};\n\nconst tryAcquireLockById = async ({\n resource,\n staleThresholdDate,\n instanceId,\n}: {\n resource: string;\n staleThresholdDate: Date;\n instanceId: string;\n}): Promise<boolean> => {\n const result = await locksCollection.upsertOne(\n {\n _id: resource,\n $or: [{ instanceId }, { acquiredAt: { $lt: staleThresholdDate } }],\n },\n {\n $set: {\n resource,\n instanceId,\n acquiredAt: new Date(),\n },\n $setOnInsert: {\n _id: resource,\n },\n }\n );\n\n return result.upsertedCount > 0 || result.modifiedCount > 0;\n};\n\nconst deleteLegacyLock = async ({\n resource,\n instanceId,\n staleThresholdDate,\n}: {\n resource: string;\n instanceId: string;\n staleThresholdDate?: Date;\n}): Promise<boolean> => {\n const selector = staleThresholdDate\n ? {\n resource,\n _id: { $ne: resource },\n $or: [{ instanceId }, { acquiredAt: { $lt: staleThresholdDate } }],\n }\n : {\n resource,\n instanceId,\n };\n\n const legacyDeleteResult = await locksCollection.deleteOne(selector);\n\n return legacyDeleteResult.deletedCount > 0;\n};\n\nconst stopLockHeartbeat = (resource: string) => {\n const heartbeatKey = resource;\n const heartbeat = lockHeartbeats.get(heartbeatKey);\n if (!heartbeat) {\n return;\n }\n\n heartbeat.stopRequested = true;\n if (heartbeat.timer) {\n clearTimeout(heartbeat.timer);\n heartbeat.timer = null;\n }\n\n lockHeartbeats.delete(heartbeatKey);\n};\n\nconst startLockHeartbeat = ({\n resource,\n lockDuration,\n instanceId,\n}: {\n resource: string;\n lockDuration: number;\n instanceId: string;\n}) => {\n const heartbeatInterval = Math.floor(lockDuration / 3);\n const heartbeatKey = resource;\n const existingHeartbeat = lockHeartbeats.get(heartbeatKey);\n\n if (\n existingHeartbeat &&\n !existingHeartbeat.stopRequested &&\n existingHeartbeat.heartbeatInterval === heartbeatInterval &&\n existingHeartbeat.lockDuration === lockDuration\n ) {\n return;\n }\n\n if (existingHeartbeat) {\n existingHeartbeat.stopRequested = true;\n if (existingHeartbeat.timer) {\n clearTimeout(existingHeartbeat.timer);\n existingHeartbeat.timer = null;\n }\n lockHeartbeats.delete(heartbeatKey);\n }\n\n const heartbeat: LockHeartbeat = {\n timer: null,\n stopRequested: false,\n lockDuration,\n heartbeatInterval,\n };\n\n const scheduleRefresh = () => {\n heartbeat.timer = setTimeout(() => {\n acquireLock(resource, {\n lockDuration,\n bypassCache: true,\n instanceId,\n })\n .then((isLockAcquired) => {\n if (!isLockAcquired) {\n heartbeat.stopRequested = true;\n logDebug(`Lost lock while refreshing heartbeat: ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n }\n })\n .finally(() => {\n if (heartbeat.stopRequested) {\n lockHeartbeats.delete(heartbeatKey);\n return;\n }\n scheduleRefresh();\n });\n }, heartbeatInterval);\n };\n\n lockHeartbeats.set(heartbeatKey, heartbeat);\n scheduleRefresh();\n};\n\n/**\n * Acquires a lock of the specified resource.\n * If the lock already exists and is owned by another container, this will fail.\n * If the lock is expired (no recent heartbeat), it will be taken over.\n *\n * @param resource - The type of lock to acquire\n * @param options.lockDuration - Time in ms after which a lock is considered expired (default: 30s)\n * @param options.successfulLockCacheDuration - Time in ms to cache successful lock acquisition\n * @param options.failedLockCacheDuration - Time in ms to cache failed lock acquisition\n * @param options.heartbeat - If true, auto-refreshes lock ownership at lockDuration/3 intervals\n * @param options.bypassCache - If true, skips the in-memory cache and always hits the DB\n * @param options.instanceId - The unique identifier for this application instance\n * @returns true if lock was acquired, false otherwise\n */\nexport async function acquireLock(\n resource: string,\n {\n lockDuration = DEFAULT_LOCK_DURATION,\n successfulLockCacheDuration = DEFAULT_CACHE_DURATION,\n failedLockCacheDuration = DEFAULT_CACHE_DURATION,\n heartbeat,\n bypassCache,\n instanceId = INSTANCE_ID,\n }: LockOptions = {}\n): Promise<boolean> {\n const now = Date.now();\n if (!bypassCache && lockCache[resource] && now < lockCache[resource].expiresAt) {\n if (lockCache[resource].value && heartbeat) {\n startLockHeartbeat({\n resource,\n lockDuration,\n instanceId,\n });\n }\n return lockCache[resource].value;\n }\n\n const staleThresholdDate = new Date(now - lockDuration);\n\n logDebug(`Attempting to acquire lock: ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n\n try {\n const isLockAcquired = await acquireLockById({\n resource,\n staleThresholdDate,\n instanceId,\n });\n\n lockCache[resource] = {\n value: isLockAcquired,\n expiresAt: now + (isLockAcquired ? successfulLockCacheDuration : failedLockCacheDuration),\n };\n\n if (isLockAcquired) {\n if (heartbeat) {\n startLockHeartbeat({\n resource,\n lockDuration,\n instanceId,\n });\n }\n\n logDebug(`Lock acquired: ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n } else {\n logDebug(`Failed to acquire lock (already held): ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n }\n\n return isLockAcquired;\n } catch {\n lockCache[resource] = {\n value: false,\n expiresAt: now + failedLockCacheDuration,\n };\n logDebug(`Failed to acquire lock (already held): ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n return false;\n }\n}\n\nconst acquireLockById = async ({\n resource,\n staleThresholdDate,\n instanceId,\n}: {\n resource: string;\n staleThresholdDate: Date;\n instanceId: string;\n}): Promise<boolean> => {\n try {\n return await tryAcquireLockById({ resource, staleThresholdDate, instanceId });\n } catch (error) {\n // TODO(v1.0.0): Remove the legacy fallback\n // Backward compatibility: if an old lock doc exists with a non-resource _id and\n // a unique `resource` index, upserting the new `_id = resource` shape can fail.\n // Migrate that legacy lock document to `_id = resource` and retry current strategy.\n if (isDuplicateKeyError(error) && (await shouldFallbackToLegacyStrategy({ error, resource }))) {\n const hasDeletedLegacyLock = await deleteLegacyLock({\n resource,\n staleThresholdDate,\n instanceId,\n });\n\n if (!hasDeletedLegacyLock) {\n return false;\n }\n\n try {\n return await tryAcquireLockById({ resource, staleThresholdDate, instanceId });\n } catch (retryError) {\n if (isDuplicateKeyError(retryError)) {\n return false;\n }\n throw retryError;\n }\n }\n\n // Duplicate _id means the lock exists but was not eligible for update (owned + fresh).\n if (isDuplicateKeyError(error)) {\n return false;\n }\n\n throw error;\n }\n};\n\n/**\n * Releases a lock of the specified resource owned by this container.\n *\n * @param resource - The resource to release the lock for\n * @param options.instanceId - The unique identifier for this application instance\n * @returns true if lock was released, false if lock wasn't owned by this container or release failed.\n */\nexport async function releaseLock(\n resource: string,\n {\n instanceId = INSTANCE_ID,\n }: {\n instanceId?: string;\n } = {}\n): Promise<boolean> {\n stopLockHeartbeat(resource);\n\n try {\n const result = await locksCollection.deleteOne({\n _id: resource,\n instanceId,\n });\n\n // TODO(v1.0.0): Remove the legacy fallback\n if (result.deletedCount === 0) {\n const hasDeletedLegacyLock = await deleteLegacyLock({\n resource,\n instanceId,\n });\n\n return hasDeletedLegacyLock;\n }\n\n return result.deletedCount > 0;\n } catch {\n return false;\n } finally {\n delete lockCache[resource];\n }\n}\n","// import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';\n\nimport { time } from '../time';\nimport { CronJob, CronJobInputParams } from './types';\nimport { startTransaction, captureError } from '@/telemetry';\nimport { Module } from '../app/module';\nimport { schema } from '../data/types';\nimport { Store } from '../data/store';\nimport { acquireLock } from '../lock/helpers';\n\nconst cronJobs: Record<string, CronJob> = {};\nlet cronJobsInterval: NodeJS.Timeout | null = null;\n\nconst cronJobsCollection = new Store('_modelenceCronJobs', {\n schema: {\n alias: schema.string(),\n lastStartDate: schema.date().optional(),\n },\n indexes: [{ key: { alias: 1 }, unique: true, background: true }],\n});\n\n// TODO: allow changing interval and timeout with cron jobconfigs\nexport function defineCronJob(\n alias: CronJob['alias'],\n {\n description = '',\n interval,\n timeout = Math.min(Math.max(interval, time.minutes(1)), time.days(1)),\n handler,\n }: CronJobInputParams\n) {\n if (cronJobs[alias]) {\n throw new Error(`Duplicate cron job declaration: '${alias}' already exists`);\n }\n\n if (cronJobsInterval) {\n throw new Error(\n `Unable to add a cron job - cron jobs have already been initialized: [${alias}]`\n );\n }\n\n if (interval < time.seconds(5)) {\n throw new Error(`Cron job interval should not be less than 5 second [${alias}]`);\n }\n\n if (timeout > time.days(1)) {\n throw new Error(`Cron job timeout should not be longer than 1 day [${alias}]`);\n }\n\n cronJobs[alias] = {\n alias,\n params: { description, interval, timeout },\n handler,\n state: {\n isRunning: false,\n },\n };\n}\n\nexport async function startCronJobs() {\n if (cronJobsInterval) {\n throw new Error('Cron jobs already started');\n }\n\n const aliasList = Object.keys(cronJobs);\n if (aliasList.length > 0) {\n const aliasSelector = { alias: { $in: aliasList } };\n\n const cronJobRecords = await cronJobsCollection.fetch(aliasSelector);\n const now = Date.now();\n cronJobRecords.forEach((record) => {\n const job = cronJobs[record.alias];\n if (!job) {\n return;\n }\n job.state.scheduledRunTs = record.lastStartDate\n ? record.lastStartDate.getTime() + job.params.interval\n : now;\n });\n Object.values(cronJobs).forEach((job) => {\n if (!job.state.scheduledRunTs) {\n job.state.scheduledRunTs = now;\n }\n });\n\n cronJobsInterval = setInterval(tickCronJobs, time.seconds(1));\n }\n}\n\nasync function tickCronJobs() {\n const now = Date.now();\n\n const ownsLock = await acquireLock('cron', {\n successfulLockCacheDuration: time.seconds(10),\n failedLockCacheDuration: time.seconds(30),\n });\n\n if (!ownsLock) {\n return;\n }\n\n Object.values(cronJobs).forEach(async (job) => {\n const { params, state } = job;\n if (state.isRunning) {\n if (state.startTs && state.startTs + params.timeout < now) {\n // TODO: log cron trace timeout error\n state.isRunning = false;\n }\n return;\n }\n\n // TODO: limit the number of jobs running concurrently\n\n if (state.scheduledRunTs && state.scheduledRunTs <= now) {\n await runCronJob(job);\n }\n });\n}\n\nasync function runCronJob(job: CronJob) {\n const { alias, params, handler, state } = job;\n state.isRunning = true;\n state.startTs = Date.now();\n\n await cronJobsCollection.updateOne(\n { alias },\n {\n $set: {\n lastStartDate: new Date(state.startTs),\n },\n }\n );\n\n const transaction = startTransaction('cron', `cron:${alias}`);\n // TODO: enforce job timeout\n try {\n await handler();\n handleCronJobCompletion(state, params);\n transaction.end('success');\n } catch (err) {\n handleCronJobCompletion(state, params);\n const error = err instanceof Error ? err : new Error(String(err));\n captureError(error);\n transaction.end('error');\n console.error(`Error in cron job '${alias}':`, err);\n }\n}\n\nfunction handleCronJobCompletion(state: CronJob['state'], params: CronJob['params']) {\n state.scheduledRunTs = state.startTs ? state.startTs + params.interval : Date.now();\n state.startTs = undefined;\n state.isRunning = false;\n}\n\nexport function getCronJobsMetadata() {\n return Object.values(cronJobs).map(({ alias, params }) => ({\n alias,\n description: params.description,\n interval: params.interval,\n timeout: params.timeout,\n }));\n}\n\nexport default new Module('_system.cron', {\n stores: [cronJobsCollection],\n});\n\n// const runCronJob = () => {\n// const worker = new Worker(filePath, {\n// workerData: {},\n// execArgv: ['--loader', 'tsx'],\n// });\n\n// const timeoutId = setTimeout(() => {\n// worker.terminate();\n// console.error(`Cron job '${alias}' timed out after ${timeout}ms`);\n// }, timeout);\n\n// worker.on('message', (message) => {\n// if (message === 'done') {\n// clearTimeout(timeoutId);\n// worker.terminate();\n// }\n// });\n\n// worker.on('error', (err) => {\n// clearTimeout(timeoutId);\n// console.error(`Error in cron job '${alias}':`, err);\n// });\n\n// worker.on('exit', (code) => {\n// console.error(`Cron job '${alias}' exited with code ${code}`);\n// setTimeout(runCronJob, interval);\n// });\n// };\n","import { Module } from '../app/module';\nimport { locksCollection } from './db';\n\n/**\n * Lock module for distributed locking across multiple instances.\n */\nexport default new Module('_system.lock', {\n stores: [locksCollection],\n});\n","import { Store } from '../data/store';\nimport { schema } from '../data/types';\n\nexport const dbMigrations = new Store('_modelenceMigrations', {\n schema: {\n version: schema.number(),\n status: schema.enum(['completed', 'failed']),\n description: schema.string().optional(),\n output: schema.string().optional(),\n appliedAt: schema.date(),\n },\n indexes: [{ key: { version: 1 }, unique: true }, { key: { version: 1, status: 1 } }],\n});\n","import { acquireLock, releaseLock } from '@/lock';\nimport { Module } from '../app/module';\nimport { dbMigrations } from './db';\nimport { logInfo } from '../telemetry';\n\nexport type MigrationScript = {\n version: number;\n description: string;\n handler: () => Promise<string | void>;\n};\n\nexport async function runMigrations(migrations: MigrationScript[]) {\n if (migrations.length === 0) {\n return;\n }\n\n const hasLock = await acquireLock('migrations');\n\n if (!hasLock) {\n logInfo('Another instance is running migrations. Skipping migration run.', {\n source: 'migrations',\n });\n return;\n }\n\n try {\n const versions = migrations.map(({ version }) => version);\n\n const existingVersions = await dbMigrations.fetch({\n version: { $in: versions },\n });\n const existingVersionSet = new Set(existingVersions.map(({ version }) => version));\n const pendingMigrations = migrations.filter(({ version }) => !existingVersionSet.has(version));\n\n if (pendingMigrations.length === 0) {\n return;\n }\n\n logInfo(`Running migrations (${pendingMigrations.length})...`, {\n source: 'migrations',\n });\n for (const { version, description, handler } of pendingMigrations) {\n logInfo(`Running migration v${version}: ${description}`, {\n source: 'migrations',\n });\n try {\n const output = await handler();\n const outputStr = (output || '').toString().trim();\n const maxSize = 15 * 1024 * 1024; // 15MB (leaving 1MB buffer for other fields and MongoDB overhead)\n const truncatedOutput =\n outputStr.length > maxSize\n ? outputStr.slice(0, maxSize) + '\\n[Output truncated - exceeded size limit]'\n : outputStr;\n await dbMigrations.upsertOne(\n {\n version,\n },\n {\n $set: {\n version,\n status: 'completed',\n description,\n output: truncatedOutput,\n appliedAt: new Date(),\n },\n }\n );\n logInfo(`Migration v${version} complete`, {\n source: 'migrations',\n });\n } catch (e) {\n if (e instanceof Error) {\n await dbMigrations.upsertOne(\n {\n version,\n },\n {\n $set: {\n version,\n status: 'failed',\n description,\n output: e.message || '',\n appliedAt: new Date(),\n },\n }\n );\n logInfo(`Migration v${version} is failed: ${e.message}`, {\n source: 'migrations',\n });\n }\n }\n }\n } finally {\n await releaseLock('migrations');\n }\n}\n\nexport function startMigrations(migrations: MigrationScript[]) {\n setTimeout(() => {\n runMigrations(migrations).catch((err) => {\n console.error('Error running migrations:', err);\n });\n }, 0);\n}\n\nexport default new Module('_system.migration', {\n stores: [dbMigrations],\n});\n","import { Module } from '../app/module';\nimport { dbRateLimits } from './db';\n\nexport default new Module('_system.rateLimit', {\n stores: [dbRateLimits],\n});\n","import { Module } from '../app/module';\nimport { callCloudApi } from '../app/backendApi';\nexport type { FileVisibility, GetUploadUrlResult } from './types';\nimport type { FileVisibility, GetUploadUrlResult } from './types';\n\ntype DownloadFileResult = {\n downloadUrl: string;\n};\n\ntype GetFileUrlResult = {\n url: string;\n};\n\nexport async function getUploadUrl({\n filePath,\n contentType,\n visibility,\n}: {\n filePath: string;\n contentType: string;\n visibility: FileVisibility;\n}): Promise<GetUploadUrlResult> {\n return await callCloudApi<GetUploadUrlResult>(\n '/api/files/upload',\n 'POST',\n JSON.stringify({ filePath, contentType, visibility }),\n {\n 'Content-Type': 'application/json',\n }\n );\n}\n\nexport async function deleteFile(filePath: string): Promise<void> {\n await callCloudApi<void>('/api/files/delete', 'POST', JSON.stringify({ filePath }), {\n 'Content-Type': 'application/json',\n });\n}\n\nexport async function downloadFile(filePath: string): Promise<DownloadFileResult> {\n return await callCloudApi<DownloadFileResult>(\n '/api/files/download',\n 'POST',\n JSON.stringify({ filePath }),\n {\n 'Content-Type': 'application/json',\n }\n );\n}\n\nexport async function getFileUrl(filePath: string): Promise<GetFileUrlResult> {\n return await callCloudApi<GetFileUrlResult>(\n '/api/files/url',\n 'POST',\n JSON.stringify({ filePath }),\n {\n 'Content-Type': 'application/json',\n }\n );\n}\n\nexport default new Module('_system.files', {\n queries: {\n async downloadFile({ filePath }) {\n return downloadFile(filePath as string);\n },\n async getFileUrl({ filePath }) {\n return getFileUrl(filePath as string);\n },\n },\n mutations: {\n async getUploadUrl({ filePath, contentType, visibility }) {\n return getUploadUrl({\n filePath: filePath as string,\n contentType: contentType as string,\n visibility: visibility as FileVisibility,\n });\n },\n async deleteFile({ filePath }) {\n return deleteFile(filePath as string);\n },\n },\n});\n","import {\n createServer,\n defineConfig,\n ViteDevServer,\n loadConfigFromFile,\n UserConfig,\n mergeConfig,\n Plugin,\n PluginOption,\n} from 'vite';\nimport reactPlugin from '@vitejs/plugin-react';\nimport path from 'path';\nimport fs from 'fs';\nimport express from 'express';\nimport type { AppServer, AppServerInitOptions, ExpressMiddleware } from './types';\n\nclass ViteServer implements AppServer {\n private viteServer?: ViteDevServer;\n private config?: UserConfig;\n\n async init({ httpServer }: AppServerInitOptions) {\n this.config = await getConfig(this.isDev() ? httpServer : undefined);\n if (this.isDev()) {\n console.log('Starting Vite dev server...');\n this.viteServer = await createServer(this.config);\n }\n }\n\n middlewares(): ExpressMiddleware[] {\n if (this.isDev()) {\n return (this.viteServer?.middlewares ?? []) as ExpressMiddleware[];\n }\n\n const staticFolders = [express.static('./.modelence/build/client'.replace(/\\\\/g, '/'))];\n if (this.config?.publicDir) {\n staticFolders.push(express.static(this.config.publicDir));\n }\n return staticFolders;\n }\n\n handler(req: express.Request, res: express.Response) {\n if (this.isDev()) {\n try {\n // Prevent browser from caching the HTML entrypoint in dev mode.\n // Vite's transformMiddleware uses no-cache + ETag for .ts/.tsx modules,\n // which revalidates correctly. But the HTML served by Express's sendFile\n // can be cached by the browser (e.g. bfcache on back/forward navigation).\n // Without HMR WebSocket, stale HTML leads to dynamic import() URLs that\n // reference modules the current Vite instance doesn't recognize.\n res.setHeader('Cache-Control', 'no-store');\n res.sendFile('index.html', { root: './src/client' });\n } catch (e) {\n console.error('Error serving index.html:', e);\n res.status(500).send('Internal Server Error');\n }\n } else {\n res.sendFile('index.html', { root: './.modelence/build/client'.replace(/\\\\/g, '/') });\n }\n }\n\n private isDev() {\n return process.env.NODE_ENV !== 'production';\n }\n}\n\nasync function loadUserViteConfig() {\n const appDir = process.cwd();\n\n try {\n const result = await loadConfigFromFile(\n { command: 'serve', mode: 'development' },\n undefined,\n appDir\n );\n return result?.config || {};\n } catch (error) {\n console.warn(`Could not load vite config:`, error);\n return {};\n }\n}\n\nfunction safelyMergeConfig(baseConfig: UserConfig, userConfig: UserConfig) {\n const mergedConfig = mergeConfig(baseConfig, userConfig);\n\n // Deduplicate plugins by name, keeping user plugins over framework plugins\n if (mergedConfig.plugins && Array.isArray(mergedConfig.plugins)) {\n const seenPlugins = new Set<string>();\n mergedConfig.plugins = mergedConfig.plugins\n .flat()\n .filter((plugin: PluginOption) => {\n if (!plugin || typeof plugin !== 'object' || Array.isArray(plugin)) {\n return true;\n }\n const pluginName = (plugin as Plugin).name;\n if (!pluginName || seenPlugins.has(pluginName)) {\n return false;\n }\n seenPlugins.add(pluginName);\n return true;\n })\n .reverse(); // Reverse to prioritize user plugins over framework plugins\n mergedConfig.plugins.reverse(); // Reverse back to maintain original order\n }\n\n return mergedConfig;\n}\n\nasync function getConfig(httpServer?: import('http').Server) {\n const appDir = process.cwd();\n const userConfig = await loadUserViteConfig();\n\n const eslintConfigFile = [\n '.eslintrc.js',\n '.eslintrc.json',\n '.eslintrc',\n 'eslint.config.js',\n '.eslintrc.yml',\n '.eslintrc.yaml',\n ].find((file) => fs.existsSync(path.join(appDir, file)));\n\n const plugins = [reactPlugin(), modelenceAssetPlugin()];\n\n if (eslintConfigFile) {\n const eslintPlugin = (await import('vite-plugin-eslint')).default;\n plugins.push(\n eslintPlugin({\n failOnError: false,\n include: ['src/**/*.js', 'src/**/*.jsx', 'src/**/*.ts', 'src/**/*.tsx'],\n cwd: appDir,\n overrideConfigFile: path.resolve(appDir, eslintConfigFile),\n })\n );\n }\n\n const baseConfig = defineConfig({\n plugins,\n build: {\n outDir: '.modelence/build/client'.replace(/\\\\/g, '/'),\n emptyOutDir: true,\n },\n server: {\n middlewareMode: true,\n hmr: httpServer ? { server: httpServer } : undefined,\n },\n root: './src/client',\n resolve: {\n alias: {\n '@': path.resolve(appDir, 'src').replace(/\\\\/g, '/'),\n },\n },\n });\n\n return safelyMergeConfig(baseConfig, userConfig);\n}\n\nfunction modelenceAssetPlugin(): Plugin {\n return {\n name: 'modelence-asset-handler',\n async transform(code: string, id: string) {\n const assetRegex = /\\.(png|jpe?g|gif|svg|mpwebm|ogg|mp3|wav|flac|aac)$/;\n if (assetRegex.test(id)) {\n if (process.env.NODE_ENV === 'development') {\n return code;\n }\n // TODO: Upload to CDN\n // return `export default \"${cdnUrl}\"`;\n return code;\n }\n },\n };\n}\n\nexport const viteServer = new ViteServer();\n","import { type Request, type Response } from 'express';\nimport { MongoServerError, ObjectId } from 'mongodb';\nimport { usersCollection } from '@/auth/db';\nimport { createSession } from '@/auth/session';\nimport { getAuthConfig } from '@/app/authConfig';\nimport { getCallContext } from '@/app/server';\nimport { getConfig } from '@/config/server';\nimport { resolveUniqueHandle } from '../utils';\nimport { User, Session, UserEmail, OAuthProvider } from '@/auth/types';\nimport { ConnectionInfo } from '@/methods/types';\n\nexport interface OAuthUserData {\n id: string;\n email: string;\n emailVerified: boolean;\n providerName: OAuthProvider;\n firstName?: string;\n lastName?: string;\n avatarUrl?: string;\n}\n\nexport async function authenticateUser(res: Response, userId: ObjectId) {\n const { authToken } = await createSession(userId);\n\n res.cookie('authToken', authToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n path: '/',\n });\n res.status(302);\n res.redirect('/');\n}\n\nasync function handleExistingProviderLogin(\n res: Response,\n userData: OAuthUserData,\n existingUser: User,\n session: Session | null,\n connectionInfo: ConnectionInfo\n) {\n const authConfig = getAuthConfig();\n\n try {\n if (existingUser.status === 'disabled' || existingUser.status === 'deleted') {\n res.status(400).json({\n error: 'User account is not active.',\n });\n return;\n }\n\n //Add User FirstName,LastName, AvatarURL if not exists\n const update: Partial<Pick<OAuthUserData, 'firstName' | 'lastName' | 'avatarUrl'>> = {};\n\n if (existingUser.firstName === undefined && userData.firstName) {\n update.firstName = userData.firstName;\n }\n if (existingUser.lastName === undefined && userData.lastName) {\n update.lastName = userData.lastName;\n }\n if (existingUser.avatarUrl === undefined && userData.avatarUrl) {\n update.avatarUrl = userData.avatarUrl;\n }\n\n let user = existingUser;\n\n if (Object.keys(update).length > 0) {\n await usersCollection.updateOne({ _id: existingUser._id }, { $set: update });\n user = { ...existingUser, ...update } as typeof existingUser;\n }\n\n await authenticateUser(res, existingUser._id);\n authConfig.onAfterLogin?.({\n provider: userData.providerName,\n user,\n session,\n connectionInfo,\n });\n authConfig.login?.onSuccess?.(user);\n } catch (error) {\n if (error instanceof Error) {\n authConfig.login?.onError?.(error);\n\n authConfig.onLoginError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n });\n }\n throw error;\n }\n}\n\nasync function handleExistingEmailLogin(\n res: Response,\n userData: OAuthUserData,\n existingUserByEmail: User,\n session: Session | null,\n connectionInfo: ConnectionInfo\n) {\n const authConfig = getAuthConfig();\n const linkingMode = authConfig.oauthAccountLinking ?? 'manual';\n\n if (linkingMode === 'auto' && userData.emailVerified) {\n if (existingUserByEmail.status === 'disabled' || existingUserByEmail.status === 'deleted') {\n res.status(400).json({\n error: 'User account is not active.',\n });\n return;\n }\n\n const matchedEmail = existingUserByEmail.emails?.find(\n (emailDoc: UserEmail) => emailDoc.address.toLowerCase() === userData.email.toLowerCase()\n );\n\n // Prevent pre-registration takeover by requiring local ownership verification too.\n if (!matchedEmail?.verified) {\n res.status(400).json({\n error: 'User with this email already exists. Please log in instead.',\n });\n return;\n }\n\n try {\n // Build profile fields to backfill from provider data if missing\n const profileUpdate: Partial<Pick<OAuthUserData, 'firstName' | 'lastName' | 'avatarUrl'>> = {\n ...(existingUserByEmail.firstName === undefined &&\n userData.firstName && { firstName: userData.firstName }),\n ...(existingUserByEmail.lastName === undefined &&\n userData.lastName && { lastName: userData.lastName }),\n ...(existingUserByEmail.avatarUrl === undefined &&\n userData.avatarUrl && { avatarUrl: userData.avatarUrl }),\n };\n\n // Single atomic update — link provider + backfill profile in one round trip\n const updateResult = await usersCollection.updateOne(\n {\n _id: existingUserByEmail._id,\n status: { $nin: ['deleted', 'disabled'] },\n $or: [\n { [`authMethods.${userData.providerName}.id`]: { $exists: false } },\n { [`authMethods.${userData.providerName}.id`]: userData.id },\n ],\n },\n {\n $set: {\n [`authMethods.${userData.providerName}.id`]: userData.id,\n ...profileUpdate,\n },\n }\n );\n\n const autoLinkSuccessful = updateResult.matchedCount > 0;\n\n if (!autoLinkSuccessful) {\n // User was deleted/disabled between findOne and updateOne, or linked to a *different* ID\n res.status(400).json({\n error: 'User with this email already exists. Please log in instead.',\n });\n return;\n }\n\n await authenticateUser(res, existingUserByEmail._id);\n\n // Construct updated user in-memory to provide fresh data to callbacks\n const updatedUser: User = {\n ...existingUserByEmail,\n ...profileUpdate,\n authMethods: {\n ...existingUserByEmail.authMethods,\n [userData.providerName]: {\n id: userData.id,\n },\n },\n };\n\n authConfig.onAfterLogin?.({\n provider: userData.providerName,\n user: updatedUser,\n session,\n connectionInfo,\n });\n authConfig.login?.onSuccess?.(updatedUser);\n\n return;\n } catch (error) {\n if (error instanceof Error) {\n authConfig.login?.onError?.(error);\n\n authConfig.onLoginError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n });\n }\n throw error;\n }\n }\n\n // Manual mode (default) or unverified email — reject\n // TODO: handle case with an HTML page\n res.status(400).json({\n error: 'User with this email already exists. Please log in instead.',\n });\n return;\n}\n\nasync function handleNewUserSignup(\n res: Response,\n userData: OAuthUserData,\n session: Session | null,\n connectionInfo: ConnectionInfo\n) {\n const authConfig = getAuthConfig();\n\n try {\n let handle: string;\n\n if (authConfig.generateHandle) {\n const generated = await authConfig.generateHandle!({\n email: userData.email,\n firstName: userData.firstName,\n lastName: userData.lastName,\n });\n //Don't throw error if handle is already taken, instead add a suffix '_2', '_3', etc. to the handle\n handle = await resolveUniqueHandle(generated, userData.email, {\n throwOnConflict: false,\n });\n } else {\n handle = await resolveUniqueHandle(undefined, userData.email);\n }\n\n const userDoc = {\n handle: handle,\n status: 'active' as const,\n emails: [\n {\n address: userData.email,\n verified: userData.emailVerified,\n },\n ],\n createdAt: new Date(),\n authMethods: {\n [userData.providerName]: {\n id: userData.id,\n },\n },\n ...(userData.firstName !== undefined && { firstName: userData.firstName }),\n ...(userData.lastName !== undefined && { lastName: userData.lastName }),\n ...(userData.avatarUrl !== undefined && { avatarUrl: userData.avatarUrl }),\n };\n\n const newUser = await usersCollection.insertOne(userDoc);\n\n await authenticateUser(res, newUser.insertedId);\n\n const userDocument = await usersCollection.findOne(\n { _id: newUser.insertedId },\n { readPreference: 'primary' }\n );\n\n if (userDocument) {\n authConfig.onAfterSignup?.({\n provider: userData.providerName,\n user: userDocument,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onSuccess?.(userDocument);\n }\n } catch (error) {\n if (error instanceof Error) {\n authConfig.onSignupError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onError?.(error);\n }\n throw error;\n }\n}\n\nexport function getRedirectUri(provider: string): string {\n return `${getConfig('_system.site.url')}/api/_internal/auth/${provider}/callback`;\n}\n\nexport async function handleOAuthUserAuthentication(\n req: Request,\n res: Response,\n userData: OAuthUserData\n): Promise<void> {\n // 1. Try to fetch existing user by OAuth ID\n const existingUser = await usersCollection.findOne({\n [`authMethods.${userData.providerName}.id`]: userData.id,\n });\n\n const { session, connectionInfo } = await getCallContext(req);\n\n if (existingUser) {\n return handleExistingProviderLogin(res, userData, existingUser, session, connectionInfo);\n }\n\n // 2. Validate Email is provided by Provider\n if (!userData.email) {\n res.status(400).json({\n error: `Email address is required for ${userData.providerName} authentication.`,\n });\n return;\n }\n\n // 3. Try to fetch existing user by Email\n let existingUserByEmail;\n\n try {\n existingUserByEmail = await usersCollection.findOne(\n { 'emails.address': userData.email, status: { $ne: 'deleted' } },\n { collation: { locale: 'en', strength: 2 } }\n );\n } catch (error) {\n if (error instanceof Error) {\n const authConfig = getAuthConfig();\n authConfig.onSignupError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onError?.(error);\n }\n throw error;\n }\n\n //User Already existed via email verification but now trying to login via OAuth Providers from the same email\n if (existingUserByEmail) {\n return handleExistingEmailLogin(res, userData, existingUserByEmail, session, connectionInfo);\n }\n\n //New User\n return handleNewUserSignup(res, userData, session, connectionInfo);\n}\n\nexport function clearOAuthLinkCookie(res: Response) {\n // Important: must clear the httpOnly cookie used during OAuth linking\n res.cookie('oauthLinkToken', '', {\n httpOnly: true,\n maxAge: 0,\n path: '/api/_internal/auth/',\n sameSite: 'lax',\n secure: process.env.NODE_ENV === 'production',\n });\n}\n\nfunction safelyCallHook(hook?: () => void) {\n if (!hook) return;\n\n try {\n hook();\n } catch (err) {\n console.error('Error executing OAuth hook:', err);\n }\n}\n\nexport function validateOAuthStateAndGetMode(\n req: Request,\n res: Response,\n stateCookieName: string\n): string | null {\n const state = req.query.state as string;\n const storedState = req.cookies[stateCookieName];\n\n const [storedStateValue, storedMode] = (storedState || '').split(':');\n\n if (!state || !storedState || state !== storedStateValue) {\n res.status(400).json({ error: 'Invalid OAuth state - possible CSRF attack' });\n return null;\n }\n\n res.clearCookie(stateCookieName);\n return storedMode || 'login';\n}\n\nexport async function handleOAuthProviderLink(\n req: Request,\n res: Response,\n userData: OAuthUserData\n): Promise<void> {\n const authConfig = getAuthConfig();\n const { session, connectionInfo } = await getCallContext(req);\n\n if (!session?.userId) {\n clearOAuthLinkCookie(res);\n res.status(401).json({\n error: 'You must be signed in to link a provider.',\n });\n return;\n }\n\n const userId = session.userId;\n\n try {\n // Atomically attach the provider to the current user while preventing\n // overwriting an existing provider ID on the same user.\n // A unique index on the provider ID ensures it cannot be linked to another user.\n const providerField = `authMethods.${userData.providerName}.id`;\n\n const updateResult = await usersCollection.updateOne(\n {\n _id: userId,\n status: { $nin: ['deleted', 'disabled'] },\n $or: [{ [providerField]: { $exists: false } }, { [providerField]: userData.id }],\n },\n {\n $set: {\n [providerField]: userData.id,\n },\n }\n );\n\n // If no document matched, figure out why\n if (updateResult.matchedCount === 0) {\n const currentUser = await usersCollection.findOne({ _id: userId });\n\n if (!currentUser || currentUser.status === 'deleted' || currentUser.status === 'disabled') {\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error: new Error('User account not found or not active'),\n session,\n connectionInfo,\n })\n );\n\n clearOAuthLinkCookie(res);\n\n res.status(400).json({ error: 'User account is not active.' });\n return;\n }\n\n // Detect if the user already linked a different OAuth account\n const existingProviderId = currentUser?.authMethods?.[userData.providerName]?.id;\n\n if (existingProviderId && existingProviderId !== userData.id) {\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error: new Error(\n `User already has a different ${userData.providerName} account linked`\n ),\n session,\n connectionInfo,\n })\n );\n\n clearOAuthLinkCookie(res);\n\n res.status(400).json({\n error: `You have already linked a different ${userData.providerName} account.`,\n });\n\n return;\n }\n\n // Fallback safety guard in case the DB state does not match any expected branch\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error: new Error(`Unexpected OAuth linking state for ${userData.providerName}`),\n session,\n connectionInfo,\n })\n );\n\n clearOAuthLinkCookie(res);\n\n res.status(400).json({\n error: `Unable to link ${userData.providerName} account.`,\n });\n\n return;\n }\n\n const updatedUser = await usersCollection.findOne(\n { _id: userId },\n { readPreference: 'primary' }\n );\n\n if (updatedUser) {\n safelyCallHook(() =>\n authConfig.onAfterOAuthLink?.({\n provider: userData.providerName,\n user: updatedUser,\n session,\n connectionInfo,\n })\n );\n }\n\n // Redirect back to the app after successful link\n clearOAuthLinkCookie(res);\n\n res.status(302).redirect('/');\n } catch (error) {\n if (error instanceof MongoServerError && error.code === 11000) {\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n })\n );\n\n clearOAuthLinkCookie(res);\n\n res.status(400).json({\n error: `This ${userData.providerName} account is already linked to a different user.`,\n });\n\n return;\n }\n\n if (error instanceof Error) {\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n })\n );\n }\n\n clearOAuthLinkCookie(res);\n if (!res.headersSent) {\n throw error;\n }\n }\n}\n\nexport function validateOAuthCode(code: unknown): string | null {\n if (!code || typeof code !== 'string') {\n return null;\n }\n return code;\n}\n","import { getConfig } from '@/server';\nimport { time } from '@/time';\nimport { randomBytes } from 'crypto';\nimport {\n Router,\n type Request,\n type Response,\n type NextFunction,\n type Router as ExpressRouter,\n} from 'express';\nimport {\n getRedirectUri,\n handleOAuthUserAuthentication,\n handleOAuthProviderLink,\n validateOAuthCode,\n type OAuthUserData,\n clearOAuthLinkCookie,\n validateOAuthStateAndGetMode,\n} from './oauth-common';\n\ninterface GoogleTokenResponse {\n access_token: string;\n expires_in: number;\n scope: string;\n token_type: string;\n id_token: string;\n}\n\ninterface GoogleUserInfo {\n id: string;\n name: string;\n given_name?: string;\n family_name?: string;\n email: string;\n verified_email: boolean;\n picture?: string;\n}\n\nasync function exchangeCodeForToken(\n code: string,\n clientId: string,\n clientSecret: string,\n redirectUri: string\n): Promise<GoogleTokenResponse> {\n const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n code,\n client_id: clientId,\n client_secret: clientSecret,\n redirect_uri: redirectUri,\n grant_type: 'authorization_code',\n }),\n });\n\n if (!tokenResponse.ok) {\n throw new Error(`Failed to exchange code for token: ${tokenResponse.statusText}`);\n }\n\n return tokenResponse.json();\n}\n\nasync function fetchGoogleUserInfo(accessToken: string): Promise<GoogleUserInfo> {\n const userInfoResponse = await fetch('https://www.googleapis.com/oauth2/v2/userinfo', {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!userInfoResponse.ok) {\n throw new Error(`Failed to fetch user info: ${userInfoResponse.statusText}`);\n }\n\n return userInfoResponse.json();\n}\n\nasync function handleGoogleAuthenticationCallback(req: Request, res: Response) {\n const code = validateOAuthCode(req.query.code);\n\n if (!code) {\n res.status(400).json({ error: 'Missing authorization code' });\n return;\n }\n\n const mode = validateOAuthStateAndGetMode(req, res, 'authStateGoogle');\n if (!mode) return;\n\n const googleClientId = String(getConfig('_system.user.auth.google.clientId'));\n const googleClientSecret = String(getConfig('_system.user.auth.google.clientSecret'));\n const redirectUri = getRedirectUri('google');\n\n try {\n // Exchange code for tokens\n const tokenData = await exchangeCodeForToken(\n code,\n googleClientId,\n googleClientSecret,\n redirectUri\n );\n\n // Fetch user info\n const googleUser = await fetchGoogleUserInfo(tokenData.access_token);\n\n const userData: OAuthUserData = {\n id: googleUser.id,\n email: googleUser.email,\n emailVerified: googleUser.verified_email,\n providerName: 'google',\n firstName: googleUser.given_name || undefined,\n lastName: googleUser.family_name || undefined,\n avatarUrl: googleUser.picture || undefined,\n };\n if (mode === 'link') {\n await handleOAuthProviderLink(req, res, userData);\n } else {\n await handleOAuthUserAuthentication(req, res, userData);\n }\n } catch (error) {\n console.error('Google OAuth error:', error);\n if (mode === 'link') {\n clearOAuthLinkCookie(res);\n }\n res.status(500).json({ error: 'Authentication failed' });\n }\n}\n\nfunction getRouter(): ExpressRouter {\n const googleAuthRouter = Router();\n\n // Middleware to check if Google auth is enabled and configured\n const checkGoogleEnabled = (_req: Request, res: Response, next: NextFunction) => {\n const googleEnabled = Boolean(getConfig('_system.user.auth.google.enabled'));\n const googleClientId = String(getConfig('_system.user.auth.google.clientId'));\n const googleClientSecret = String(getConfig('_system.user.auth.google.clientSecret'));\n\n if (!googleEnabled || !googleClientId || !googleClientSecret) {\n res.status(503).json({ error: 'Google authentication is not configured' });\n return;\n }\n\n next();\n };\n\n // Initiate OAuth flow\n googleAuthRouter.get(\n '/api/_internal/auth/google',\n checkGoogleEnabled,\n (req: Request, res: Response) => {\n const googleClientId = String(getConfig('_system.user.auth.google.clientId'));\n const redirectUri = getRedirectUri('google');\n\n const state = randomBytes(32).toString('hex');\n\n const mode = req.query.mode === 'link' ? 'link' : 'login';\n\n res.cookie('authStateGoogle', `${state}:${mode}`, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n maxAge: time.minutes(10), // 10 minutes\n });\n\n const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');\n authUrl.searchParams.append('client_id', googleClientId);\n authUrl.searchParams.append('redirect_uri', redirectUri);\n authUrl.searchParams.append('response_type', 'code');\n authUrl.searchParams.append('scope', 'profile email');\n authUrl.searchParams.append('access_type', 'online');\n authUrl.searchParams.append('state', state);\n\n res.redirect(authUrl.toString());\n }\n );\n\n // Handle OAuth callback\n googleAuthRouter.get(\n '/api/_internal/auth/google/callback',\n checkGoogleEnabled,\n handleGoogleAuthenticationCallback\n );\n\n return googleAuthRouter;\n}\n\nexport default getRouter;\n","import { getConfig } from '@/server';\nimport { time } from '@/time';\nimport { randomBytes } from 'crypto';\nimport {\n Router,\n type Request,\n type Response,\n type NextFunction,\n type Router as ExpressRouter,\n} from 'express';\nimport {\n getRedirectUri,\n handleOAuthUserAuthentication,\n handleOAuthProviderLink,\n validateOAuthCode,\n type OAuthUserData,\n clearOAuthLinkCookie,\n validateOAuthStateAndGetMode,\n} from './oauth-common';\n\ninterface GitHubTokenResponse {\n access_token: string;\n token_type: string;\n scope: string;\n}\n\ninterface GitHubUserInfo {\n id: number;\n login: string;\n name: string;\n email: string | null;\n avatar_url?: string;\n}\n\ninterface GitHubEmail {\n email: string;\n primary: boolean;\n verified: boolean;\n visibility: 'public' | 'private' | null;\n}\n\nasync function exchangeCodeForToken(\n code: string,\n clientId: string,\n clientSecret: string,\n redirectUri: string\n): Promise<GitHubTokenResponse> {\n const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify({\n client_id: clientId,\n client_secret: clientSecret,\n code,\n redirect_uri: redirectUri,\n }),\n });\n\n if (!tokenResponse.ok) {\n throw new Error(`Failed to exchange code for token: ${tokenResponse.statusText}`);\n }\n\n return tokenResponse.json();\n}\n\nasync function fetchGitHubUserInfo(accessToken: string): Promise<GitHubUserInfo> {\n const userInfoResponse = await fetch('https://api.github.com/user', {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!userInfoResponse.ok) {\n throw new Error(`Failed to fetch user info: ${userInfoResponse.statusText}`);\n }\n\n return userInfoResponse.json();\n}\n\nasync function fetchGitHubUserEmails(accessToken: string): Promise<GitHubEmail[]> {\n const response = await fetch('https://api.github.com/user/emails', {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch user emails: ${response.statusText}`);\n }\n\n return response.json();\n}\n\nasync function getGitHubUserEmail(\n githubUser: GitHubUserInfo,\n accessToken: string\n): Promise<string | null> {\n if (githubUser.email) {\n return githubUser.email;\n }\n\n const emails = await fetchGitHubUserEmails(accessToken);\n return emails.find((e) => e.primary && e.verified)?.email ?? null;\n}\n\nasync function handleGitHubAuthenticationCallback(req: Request, res: Response) {\n const code = validateOAuthCode(req.query.code);\n\n if (!code) {\n res.status(400).json({ error: 'Missing authorization code' });\n return;\n }\n\n const mode = validateOAuthStateAndGetMode(req, res, 'authStateGithub');\n if (!mode) return;\n\n const githubClientId = String(getConfig('_system.user.auth.github.clientId'));\n const githubClientSecret = String(getConfig('_system.user.auth.github.clientSecret'));\n const redirectUri = getRedirectUri('github');\n\n try {\n // Exchange code for access token\n const tokenData = await exchangeCodeForToken(\n code,\n githubClientId,\n githubClientSecret,\n redirectUri\n );\n\n // Fetch user info\n const githubUser = await fetchGitHubUserInfo(tokenData.access_token);\n\n // Resolve a usable GitHub email (public email or fallback to primary verified email)\n const githubEmail = await getGitHubUserEmail(githubUser, tokenData.access_token);\n\n if (!githubEmail) {\n if (mode === 'link') {\n clearOAuthLinkCookie(res);\n }\n\n res.status(400).json({\n error:\n 'Unable to retrieve a primary verified email from GitHub. Please ensure your GitHub account has a verified email set as primary.',\n });\n return;\n }\n\n const nameParts = githubUser.name ? githubUser.name.trim().split(/\\s+/) : [];\n const firstName = nameParts[0] || undefined;\n const lastName = nameParts.length > 1 ? nameParts.slice(1).join(' ') : undefined;\n\n const userData: OAuthUserData = {\n id: String(githubUser.id),\n email: githubEmail,\n emailVerified: true, // Assume public email is verified\n providerName: 'github',\n firstName,\n lastName,\n avatarUrl: githubUser.avatar_url || undefined,\n };\n\n if (mode === 'link') {\n await handleOAuthProviderLink(req, res, userData);\n } else {\n await handleOAuthUserAuthentication(req, res, userData);\n }\n } catch (error) {\n console.error('GitHub OAuth error:', error);\n if (mode === 'link') {\n clearOAuthLinkCookie(res);\n }\n res.status(500).json({ error: 'Authentication failed' });\n }\n}\n\nfunction getRouter(): ExpressRouter {\n const githubAuthRouter = Router();\n\n // Middleware to check if GitHub auth is enabled and configured\n const checkGitHubEnabled = (_req: Request, res: Response, next: NextFunction) => {\n const githubEnabled = Boolean(getConfig('_system.user.auth.github.enabled'));\n const githubClientId = String(getConfig('_system.user.auth.github.clientId'));\n const githubClientSecret = String(getConfig('_system.user.auth.github.clientSecret'));\n\n if (!githubEnabled || !githubClientId || !githubClientSecret) {\n res.status(503).json({ error: 'GitHub authentication is not configured' });\n return;\n }\n\n next();\n };\n\n // Initiate OAuth flow\n githubAuthRouter.get(\n '/api/_internal/auth/github',\n checkGitHubEnabled,\n (req: Request, res: Response) => {\n const githubClientId = String(getConfig('_system.user.auth.github.clientId'));\n const redirectUri = getRedirectUri('github');\n const githubScopes = getConfig('_system.user.auth.github.scopes');\n const scopes = githubScopes\n ? String(githubScopes)\n .split(',')\n .map((s) => s.trim())\n .join(' ')\n : 'user:email';\n\n const state = randomBytes(32).toString('hex');\n\n const mode = req.query.mode === 'link' ? 'link' : 'login';\n\n res.cookie('authStateGithub', `${state}:${mode}`, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n maxAge: time.minutes(10), // 10 minutes\n });\n\n const authUrl = new URL('https://github.com/login/oauth/authorize');\n authUrl.searchParams.append('client_id', githubClientId);\n authUrl.searchParams.append('redirect_uri', redirectUri);\n authUrl.searchParams.append('scope', scopes);\n authUrl.searchParams.append('state', state);\n\n res.redirect(authUrl.toString());\n }\n );\n\n // Handle OAuth callback\n githubAuthRouter.get(\n '/api/_internal/auth/github/callback',\n checkGitHubEnabled,\n handleGitHubAuthenticationCallback\n );\n\n return githubAuthRouter;\n}\n\nexport default getRouter;\n","import { Request, Response, NextFunction } from 'express';\nimport { RouteHandler } from './types';\nimport { ModelenceError } from '../error';\nimport { authenticate } from '../auth';\nimport { getMongodbUri } from '../db/client';\nimport type { Context } from '../methods/types';\nimport { startTransaction } from '../telemetry';\n\n// TODO: Use cookies for authentication and automatically add session/user to context if accessing from browser\nexport function createRouteHandler(method: string, path: string, handler: RouteHandler) {\n return async (req: Request, res: Response, next: NextFunction) => {\n const authToken = req.headers['x-modelence-auth-token'];\n let context: Pick<Context, 'session' | 'user'> = { session: null, user: null };\n\n if (typeof authToken === 'string' && getMongodbUri()) {\n try {\n const { session, user } = await authenticate(authToken);\n context = { session, user };\n } catch {\n // If authentication fails, context remains null\n }\n }\n\n const transaction = startTransaction('route', `route:${method.toLowerCase()}:${path}`, {\n method,\n path,\n query: req.query,\n body: req.body,\n params: req.params,\n });\n\n try {\n const response = await handler(\n {\n query: req.query as Record<string, string>,\n body: req.body,\n params: req.params,\n headers: req.headers as Record<string, string>,\n cookies: req.cookies,\n rawBody: Buffer.isBuffer(req.body) ? req.body : undefined,\n req,\n res,\n next,\n },\n context\n );\n\n transaction.end();\n\n // If the handler returns null, we expect it to handle the response itself\n if (response) {\n res.status(response.status || 200);\n\n if (response.redirect) {\n res.redirect(response.redirect);\n }\n\n if (response.headers) {\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n }\n\n res.send(response.data);\n }\n } catch (error) {\n transaction.end('error');\n\n if (error instanceof ModelenceError) {\n res.status(error.status).send(error.message);\n } else {\n console.error(`Error in route handler: ${req.path}`);\n console.error(error);\n res.status(500).send(String(error));\n }\n }\n };\n}\n","/**\n * Security configuration for the application\n *\n * By default, the app is protected against clickjacking by setting\n * `Content-Security-Policy: frame-ancestors 'self'` and `X-Frame-Options: SAMEORIGIN`\n * on all responses, preventing the app from being embedded in iframes on other domains.\n *\n * @example\n * ```typescript\n * import { startApp } from 'modelence/server';\n *\n * // Allow embedding in iframes on specific domains\n * startApp({\n * security: {\n * frameAncestors: ['https://modelence.com', 'https://app.example.com'],\n * },\n * });\n * ```\n */\nexport type SecurityConfig = {\n /**\n * Additional origins allowed to embed this app in an iframe.\n * The app's own origin (`'self'`) is always included automatically.\n *\n * When not set, only same-origin framing is allowed.\n * When set, `X-Frame-Options` is omitted since it cannot express multiple origins.\n */\n frameAncestors?: string[];\n};\n\nlet securityConfig: SecurityConfig = Object.freeze({});\n\nexport function setSecurityConfig(newSecurityConfig: SecurityConfig) {\n securityConfig = Object.freeze(Object.assign({}, securityConfig, newSecurityConfig));\n}\n\nexport function getSecurityConfig() {\n return securityConfig;\n}\n","import { WebsocketServerProvider } from '@/websocket/types';\n\nexport type WebsocketConfig = {\n provider?: WebsocketServerProvider;\n};\n\nlet websocketConfig: WebsocketConfig = Object.freeze({});\n\nexport function setWebsocketConfig(newWebsocketConfig: WebsocketConfig) {\n websocketConfig = Object.freeze(Object.assign({}, websocketConfig, newWebsocketConfig));\n}\n\nexport function getWebsocketConfig() {\n return websocketConfig;\n}\n","import googleAuthRouter from '@/auth/providers/google';\nimport githubAuthRouter from '@/auth/providers/github';\nimport { runMethod } from '@/methods';\nimport { getResponseTypeMap, sanitizeResult } from '@/methods/serialize';\nimport { createRouteHandler } from '@/routes/handler';\nimport { HttpMethod } from '@/server';\nimport { logInfo } from '@/telemetry';\nimport cookieParser from 'cookie-parser';\nimport express, { Request, Response } from 'express';\nimport http from 'http';\nimport z from 'zod';\nimport type { AppServer } from '../types';\nimport { authenticate } from '../auth';\nimport { getUnauthenticatedRoles } from '../auth/role';\nimport { getMongodbUri } from '../db/client';\nimport { ModelenceError } from '../error';\nimport { Module } from './module';\nimport { ConnectionInfo } from '@/methods/types';\nimport { ServerChannel } from '@/websocket/serverChannel';\nimport { getSecurityConfig } from './securityConfig';\nimport { getWebsocketConfig } from './websocketConfig';\nimport { getConfig } from '@/config/server';\n\nfunction getBodyParserMiddleware(config?: {\n json?: boolean | { limit?: string };\n urlencoded?: boolean | { limit?: string; extended?: boolean };\n raw?: boolean | { limit?: string; type?: string | string[] };\n}) {\n const middlewares: express.RequestHandler[] = [];\n\n if (!config) {\n // Default: apply JSON and urlencoded parsing\n middlewares.push(express.json({ limit: '16mb' }));\n middlewares.push(express.urlencoded({ extended: true, limit: '16mb' }));\n return middlewares;\n }\n\n // Handle JSON parsing\n if (config.json !== false) {\n const jsonOptions = typeof config.json === 'object' ? config.json : { limit: '16mb' };\n middlewares.push(express.json(jsonOptions));\n }\n\n // Handle URL-encoded parsing\n if (config.urlencoded !== false) {\n const urlencodedOptions =\n typeof config.urlencoded === 'object' ? config.urlencoded : { extended: true, limit: '16mb' };\n middlewares.push(express.urlencoded(urlencodedOptions));\n }\n\n // Handle raw body parsing\n if (config.raw) {\n const rawOptions = typeof config.raw === 'object' ? config.raw : {};\n const defaultRawOptions = {\n limit: rawOptions.limit || '16mb',\n type: rawOptions.type || '*/*',\n };\n middlewares.push(express.raw(defaultRawOptions));\n }\n\n return middlewares;\n}\n\nfunction registerModuleRoutes(app: express.Application, modules: Module[]) {\n for (const module of modules) {\n for (const route of module.routes) {\n const { path, handlers, body } = route;\n const middlewares = getBodyParserMiddleware(body);\n\n Object.entries(handlers).forEach(([method, handler]) => {\n app[method as HttpMethod](path, ...middlewares, createRouteHandler(method, path, handler));\n });\n }\n }\n}\n\nexport async function startServer(\n server: AppServer,\n {\n combinedModules,\n channels,\n }: {\n combinedModules: Module[];\n channels: ServerChannel[];\n }\n) {\n const app = express();\n\n app.use(cookieParser());\n\n app.use(securityHeadersMiddleware());\n\n // Register module routes first (with per-route body parser config)\n registerModuleRoutes(app, combinedModules);\n\n // Apply global body parsing for remaining routes\n app.use(express.json({ limit: '16mb' }));\n app.use(express.urlencoded({ extended: true, limit: '16mb' }));\n\n app.use(googleAuthRouter());\n app.use(githubAuthRouter());\n\n // Set httpOnly cookie for OAuth linking flow\n app.post('/api/_internal/auth/set-link-cookie', async (req: Request, res: Response) => {\n const { session } = await getCallContext(req);\n\n if (!session?.userId) {\n res.status(401).json({ error: 'Not authenticated' });\n return;\n }\n\n res.cookie('oauthLinkToken', session.authToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n path: '/api/_internal/auth/',\n maxAge: 10 * 60 * 1000, // 10 minutes\n });\n\n res.json({ ok: true });\n });\n\n app.post('/api/_internal/method/:methodName(*)', async (req: Request, res: Response) => {\n const { methodName } = req.params;\n const context = await getCallContext(req);\n\n try {\n const result = sanitizeResult(await runMethod(methodName, req.body.args, context));\n res.json({\n data: result,\n typeMap: getResponseTypeMap(result),\n });\n } catch (error) {\n handleMethodError(res, methodName, error);\n }\n });\n\n const httpServer = http.createServer(app);\n\n await server.init({ httpServer });\n\n if (server.middlewares) {\n app.use(server.middlewares());\n }\n\n app.all('*', (req: Request, res: Response) => {\n return server.handler(req, res);\n });\n\n process.on('unhandledRejection', (reason, promise) => {\n console.error('Unhandled Promise Rejection:');\n console.error(reason instanceof Error ? reason.stack : reason);\n console.error('Promise:', promise);\n });\n\n // Global uncaught exceptions\n process.on('uncaughtException', (error) => {\n console.error('Uncaught Exception:');\n console.error(error.stack); // This gives you the full stack trace\n console.trace('Full application stack:'); // Additional context\n });\n\n const websocketProvider = getWebsocketConfig()?.provider;\n if (websocketProvider) {\n websocketProvider.init({\n httpServer,\n channels,\n });\n }\n\n const port = process.env.MODELENCE_PORT || process.env.PORT || 3000;\n httpServer.listen(port, () => {\n logInfo(`Application started`, { source: 'app' });\n const siteUrl = getConfig('_system.site.url') || `http://localhost:${port}`;\n console.log(`\\nApplication started on ${siteUrl}\\n`);\n });\n}\n\nexport async function getCallContext(req: Request) {\n const path = (req.path ?? req.url ?? '').split('?')[0];\n\n const isOAuthCallback = path.startsWith('/api/_internal/auth/') && path.endsWith('/callback');\n\n const authToken = z\n .string()\n .nullish()\n .transform((val) => val ?? null)\n .parse(\n req.cookies.authToken ||\n (isOAuthCallback ? req.cookies.oauthLinkToken : null) ||\n req.body.authToken\n );\n\n const clientInfo = z\n .object({\n screenWidth: z.number(),\n screenHeight: z.number(),\n windowWidth: z.number(),\n windowHeight: z.number(),\n pixelRatio: z.number(),\n orientation: z.string().nullable(),\n })\n .nullish()\n .parse(req.body.clientInfo) ?? {\n screenWidth: 0,\n screenHeight: 0,\n windowWidth: 0,\n windowHeight: 0,\n pixelRatio: 1,\n orientation: null,\n };\n\n const connectionInfo: ConnectionInfo = {\n ip: getClientIp(req),\n userAgent: req.get('user-agent'),\n acceptLanguage: req.get('accept-language'),\n referrer: req.get('referrer'),\n baseUrl: req.protocol + '://' + req.get('host'),\n };\n\n const hasDatabase = Boolean(getMongodbUri());\n if (hasDatabase) {\n const { session, user, roles } = await authenticate(authToken);\n return {\n clientInfo,\n connectionInfo,\n session,\n user,\n roles,\n };\n }\n\n return {\n clientInfo,\n connectionInfo,\n session: null,\n user: null,\n roles: getUnauthenticatedRoles(),\n };\n}\n\nfunction handleMethodError(res: Response, methodName: string, error: unknown) {\n // TODO: add an option to silence these error console logs, especially when Elastic logs are configured\n\n if (error instanceof ModelenceError) {\n if (error.status >= 500 && error.status < 600) {\n console.error(`Error calling ${methodName}:`, error);\n }\n res.status(error.status).send(error.message);\n return;\n }\n\n if (error instanceof Error && error?.constructor?.name === 'ZodError' && 'errors' in error) {\n let errorMessage = '';\n try {\n errorMessage = parseZodError(error as z.ZodError);\n } catch (parsingError) {\n console.error(`Error parsing Zod error in ${methodName}:`, parsingError);\n errorMessage = 'Validation failed';\n }\n res.status(400).send(errorMessage);\n return;\n }\n\n console.error(`Error calling ${methodName}:`, error);\n res.status(500).send(error instanceof Error ? error.message : String(error));\n}\n\nfunction parseZodError(zodError: z.ZodError): string {\n const flattened = zodError.flatten();\n const fieldMessages = Object.entries(flattened.fieldErrors).map(\n ([key, errors]) => `${key}: ${(errors ?? []).join(', ')}`\n );\n const formMessages = flattened.formErrors;\n const allMessages = [...fieldMessages, ...formMessages].filter(Boolean);\n return allMessages.join('; ');\n}\n\nfunction securityHeadersMiddleware(): express.RequestHandler {\n const { frameAncestors } = getSecurityConfig();\n const hasCustomAncestors = frameAncestors && frameAncestors.length > 0;\n const ancestors = hasCustomAncestors ? [\"'self'\", ...frameAncestors].join(' ') : \"'self'\";\n\n return (_req, res, next) => {\n res.setHeader('Content-Security-Policy', `frame-ancestors ${ancestors}`);\n // X-Frame-Options only supports DENY and SAMEORIGIN (ALLOW-FROM is deprecated).\n // When custom ancestors are configured, only CSP frame-ancestors can express that,\n // so we omit X-Frame-Options to avoid conflicting with the CSP directive.\n if (!hasCustomAncestors) {\n res.setHeader('X-Frame-Options', 'SAMEORIGIN');\n }\n next();\n };\n}\n\nfunction getClientIp(req: Request): string | undefined {\n // On Heroku and other proxies, X-Forwarded-For contains the real client IP\n const forwardedFor = req.headers['x-forwarded-for'];\n if (forwardedFor) {\n const firstIp = Array.isArray(forwardedFor) ? forwardedFor[0] : forwardedFor.split(',')[0];\n return firstIp.trim();\n }\n\n const directIp = req.ip || req.socket?.remoteAddress;\n if (directIp) {\n // Remove IPv6-to-IPv4 mapping prefix\n return directIp.startsWith('::ffff:') ? directIp.substring(7) : directIp;\n }\n\n return undefined;\n}\n","import dotenv from 'dotenv';\nimport fs from 'fs/promises';\nimport os from 'os';\nimport path from 'path';\n\nimport type { AppServer, ModelSchema } from '../types';\nimport socketioServer from '@/websocket/socketio/server';\nimport { initRoles } from '../auth/role';\nimport sessionModule from '../auth/session';\nimport { RoleDefinition } from '../auth/types';\nimport userModule from '../auth/user';\nimport { getLocalConfigs } from '../config/local';\nimport { loadConfigs, setSchema } from '../config/server';\nimport { startConfigSync, loadRemoteConfigs } from '../config/sync';\nimport { ConfigSchema } from '../config/types';\nimport cronModule, { defineCronJob, getCronJobsMetadata, startCronJobs } from '../cron/jobs';\nimport { Store } from '../data/store';\nimport { connect, getClient, getMongodbUri } from '../db/client';\nimport { _createSystemMutation, _createSystemQuery, createMutation, createQuery } from '../methods';\nimport { MigrationScript, default as migrationModule, startMigrations } from '../migration';\nimport rateLimitModule from '../rate-limit';\nimport { initRateLimits } from '../rate-limit/rules';\nimport systemModule from '../system';\nimport lockModule, { acquireLock, releaseLock } from '../lock';\nimport filesModule from '../files';\nimport { viteServer } from '../viteServer';\nimport { connectCloudBackend } from './backendApi';\nimport { initMetrics } from './metrics';\nimport { Module } from './module';\nimport { startServer } from './server';\nimport { markAppStarted, setMetadata } from './state';\nimport { time } from '@/time';\nimport { EmailConfig, setEmailConfig } from './emailConfig';\nimport { AuthConfig, setAuthConfig } from './authConfig';\nimport { SecurityConfig, setSecurityConfig } from './securityConfig';\nimport { WebsocketConfig, setWebsocketConfig } from './websocketConfig';\n\nexport type AppOptions = {\n modules?: Module[];\n server?: AppServer;\n email?: EmailConfig;\n auth?: AuthConfig;\n /** Security settings such as clickjacking protection. See {@link SecurityConfig}. */\n security?: SecurityConfig;\n /**\n * Custom role definitions keyed by role name. Defined roles are synced to the\n * Modelence Cloud dashboard for user management. See {@link RoleDefinition}.\n *\n * @example\n * ```typescript\n * startApp({\n * roles: {\n * admin: { description: 'Full access to all features' },\n * editor: { description: 'Can edit content' },\n * viewer: {},\n * },\n * });\n * ```\n */\n roles?: Record<string, RoleDefinition>;\n /** @internal */\n defaultRoles?: Record<string, string>;\n migrations?: Array<MigrationScript>;\n websocket?: WebsocketConfig;\n};\n\nexport async function startApp({\n modules = [],\n roles = {},\n defaultRoles = {},\n server = viteServer,\n migrations = [],\n email = {},\n auth = {},\n security = {},\n websocket = {},\n}: AppOptions) {\n dotenv.config();\n\n dotenv.config({ path: '.modelence.env' });\n\n const hasRemoteBackend = Boolean(process.env.MODELENCE_SERVICE_ENDPOINT);\n\n trackAppStart()\n .then(() => {\n // Do nothing\n })\n .catch(() => {\n // Silently ignore tracking errors to not disrupt app startup\n });\n\n // TODO: verify that user modules don't start with `_system.` prefix\n const systemModules = [\n userModule,\n sessionModule,\n cronModule,\n migrationModule,\n rateLimitModule,\n systemModule,\n lockModule,\n filesModule,\n ];\n const combinedModules = [...systemModules, ...modules];\n\n markAppStarted();\n\n initSystemMethods(systemModules);\n initCustomMethods(modules);\n\n initRoles(roles, defaultRoles);\n\n const configSchema = getConfigSchema(combinedModules);\n setSchema(configSchema);\n const stores = getStores(combinedModules) as Store<ModelSchema, never>[];\n const channels = getChannels(combinedModules);\n\n defineCronJobs(combinedModules);\n\n const rateLimits = getRateLimits(combinedModules);\n initRateLimits(rateLimits);\n\n if (hasRemoteBackend) {\n const { configs, environmentId, appAlias, environmentAlias, telemetry } =\n await connectCloudBackend({\n configSchema,\n cronJobsMetadata: getCronJobsMetadata(),\n stores,\n roles,\n });\n loadRemoteConfigs(configs);\n setMetadata({ environmentId, appAlias, environmentAlias, telemetry });\n } else {\n loadConfigs(getLocalConfigs(configSchema));\n }\n\n setEmailConfig(email);\n setAuthConfig(auth);\n setSecurityConfig(security);\n setWebsocketConfig({\n ...websocket,\n provider: websocket.provider || socketioServer,\n });\n\n const mongodbUri = getMongodbUri();\n if (mongodbUri) {\n await connect();\n initStores(stores);\n await createIndexesWithLock(stores);\n }\n\n startMigrations(migrations);\n\n if (hasRemoteBackend) {\n await initMetrics();\n startConfigSync();\n }\n\n startCronJobs().catch(console.error);\n\n await startServer(server, { combinedModules, channels });\n}\n\nfunction initCustomMethods(modules: Module[]) {\n for (const module of modules) {\n for (const [key, handler] of Object.entries(module.queries)) {\n createQuery(`${module.name}.${key}`, handler);\n }\n for (const [key, handler] of Object.entries(module.mutations)) {\n createMutation(`${module.name}.${key}`, handler);\n }\n }\n}\n\nfunction initSystemMethods(modules: Module[]) {\n for (const module of modules) {\n for (const [key, handler] of Object.entries(module.queries)) {\n _createSystemQuery(`${module.name}.${key}`, handler);\n }\n for (const [key, handler] of Object.entries(module.mutations)) {\n _createSystemMutation(`${module.name}.${key}`, handler);\n }\n }\n}\n\nfunction getStores(modules: Module[]) {\n return modules.flatMap((module) => module.stores);\n}\n\nfunction getChannels(modules: Module[]) {\n return modules.flatMap((module) => module.channels);\n}\n\nfunction getRateLimits(modules: Module[]) {\n return modules.flatMap((module) => module.rateLimits);\n}\n\nfunction warnIndexCreationFailure(storeName: string, error: unknown) {\n console.warn(`Failed to create indexes for store '${storeName}'. Continuing startup.`, error);\n}\n\nconst INDEXES_LOCK_RESOURCE = 'indexes';\n\nasync function createIndexesWithLock(stores: Store<ModelSchema, never>[]) {\n const hasLock = await acquireLock(INDEXES_LOCK_RESOURCE, {\n lockDuration: time.seconds(30),\n heartbeat: true,\n });\n if (!hasLock) {\n return;\n }\n\n let releaseHandledByBackgroundTask = false;\n\n try {\n const blockingStores = stores.filter((store) => store.getIndexCreationMode() === 'blocking');\n const backgroundStores = stores.filter(\n (store) => store.getIndexCreationMode() === 'background'\n );\n\n for (const store of blockingStores) {\n await createStoreIndexes(store);\n }\n\n if (backgroundStores.length > 0) {\n releaseHandledByBackgroundTask = true;\n void Promise.resolve().then(async () => {\n try {\n for (const store of backgroundStores) {\n await createStoreIndexes(store);\n }\n } finally {\n await releaseLock(INDEXES_LOCK_RESOURCE);\n }\n });\n }\n } finally {\n if (!releaseHandledByBackgroundTask) {\n await releaseLock(INDEXES_LOCK_RESOURCE);\n }\n }\n}\n\nasync function createStoreIndexes(store: Store<ModelSchema, never>) {\n const storeName = store.getName();\n\n try {\n await store.createIndexes();\n } catch (error) {\n warnIndexCreationFailure(storeName, error);\n }\n}\n\nfunction getConfigSchema(modules: Module[]): ConfigSchema {\n const merged: ConfigSchema = {};\n\n for (const module of modules) {\n for (const [key, value] of Object.entries(module.configSchema)) {\n const absoluteKey = `${module.name}.${key}`;\n if (absoluteKey in merged) {\n throw new Error(`Duplicate config schema key: ${absoluteKey} (${module.name})`);\n }\n\n merged[absoluteKey] = value;\n }\n }\n\n return merged;\n}\n\nfunction defineCronJobs(modules: Module[]) {\n for (const module of modules) {\n for (const [cronAlias, cronJobParams] of Object.entries(module.cronJobs)) {\n defineCronJob(`${module.name}.${cronAlias}`, cronJobParams);\n }\n }\n}\n\nfunction initStores(stores: Store<ModelSchema, never>[]) {\n const client = getClient();\n if (!client) {\n throw new Error('Failed to initialize stores: MongoDB client not initialized');\n }\n\n for (const store of stores) {\n store.init(client);\n }\n}\n\nasync function trackAppStart() {\n const isTrackingEnabled = process.env.MODELENCE_TRACKING_ENABLED !== 'false';\n\n if (isTrackingEnabled) {\n const serviceEndpoint = process.env.MODELENCE_SERVICE_ENDPOINT ?? 'https://cloud.modelence.com';\n const environmentId = process.env.MODELENCE_ENVIRONMENT_ID;\n\n const appDetails = await getAppDetails();\n const modelencePackageJson = await import('../../package.json');\n\n await fetch(`${serviceEndpoint}/api/track/app-start`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n projectName: appDetails.name,\n version: modelencePackageJson.default.version,\n localHostname: os.hostname(),\n environmentId,\n }),\n });\n }\n}\n\nasync function getAppDetails() {\n try {\n const packageJsonPath = path.join(process.cwd(), 'package.json');\n const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(packageJsonContent);\n\n return {\n name: packageJson.name || 'unknown',\n };\n } catch {\n return {\n name: 'unknown',\n };\n }\n}\n","import { ObjectId } from 'mongodb';\nimport { randomUUID } from 'crypto';\nimport {\n usersCollection,\n emailVerificationTokensCollection,\n resetPasswordTokensCollection,\n} from './db';\n\nexport async function clearTokens(userId: ObjectId) {\n await emailVerificationTokensCollection.deleteMany({\n userId,\n });\n\n await resetPasswordTokensCollection.deleteMany({\n userId,\n });\n}\n\nexport async function disableUser(userId: ObjectId) {\n await clearTokens(userId);\n\n await usersCollection.updateOne(userId, {\n $set: {\n status: 'disabled',\n disabledAt: new Date(),\n },\n });\n}\n\nexport async function deleteUser(userId: ObjectId) {\n await clearTokens(userId);\n\n await usersCollection.updateOne(\n {\n _id: userId,\n },\n {\n $set: {\n handle: `deleted-${userId}-${randomUUID()}`,\n status: 'deleted',\n deletedAt: new Date(),\n authMethods: {},\n emails: [],\n },\n }\n );\n}\n","import { Session, User } from '@/auth/types';\nimport { getWebsocketConfig } from '@/app/websocketConfig';\nimport { logError } from '../telemetry';\n\ntype canAccessChannel = (props: {\n user: User | null;\n session: Session | null;\n roles: string[];\n}) => Promise<boolean>;\n\nexport class ServerChannel<T = unknown> {\n public readonly category: string;\n public readonly canAccessChannel: canAccessChannel | null;\n\n constructor(category: string, canAccessChannel?: canAccessChannel) {\n this.category = category;\n this.canAccessChannel = canAccessChannel || null;\n }\n\n broadcast(id: string, data: T) {\n const websocketProvider = getWebsocketConfig().provider;\n if (!websocketProvider) {\n logError('Websockets provider should be added to startApp', {});\n return;\n }\n\n websocketProvider.broadcast({\n category: this.category,\n id,\n data,\n });\n }\n}\n","import { getEmailConfig } from '@/app/emailConfig';\nimport { EmailPayload } from '../types';\n\nexport function sendEmail(payload: EmailPayload) {\n if (!getEmailConfig().provider) {\n throw new Error(\n 'Email provider is not configured, see https://docs.modelence.com/email for more details.'\n );\n }\n return getEmailConfig().provider?.sendEmail(payload);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/app/module.ts","../src/data/schemaSerializer.ts","../src/data/store.ts","../src/data/types.ts","../src/auth/session.ts","../src/auth/db.ts","../src/auth/role.ts","../src/auth/index.ts","../src/system/index.ts","../src/db/client.ts","../src/live-query/context.ts","../src/utils/index.ts","../src/methods/index.ts","../src/live-query/handlers.ts","../src/websocket/socketio/server.ts","../src/auth/disposableEmails.ts","../src/auth/validators.ts","../src/auth/utils.ts","../src/app/emailConfig.ts","../src/app/authConfig.ts","../src/auth/login.ts","../src/auth/profile.ts","../src/auth/types.ts","../src/auth/unlinkOAuthProvider.ts","../src/rate-limit/db.ts","../src/rate-limit/rules.ts","../src/auth/templates/emailVerficationTemplate.ts","../src/auth/verification.ts","../src/auth/signup.ts","../src/auth/resetPassword.ts","../src/auth/user.ts","../src/config/local.ts","../src/app/backendApi.ts","../src/config/sync.ts","../src/lock/db.ts","../src/lock/helpers.ts","../src/cron/jobs.ts","../src/data/resolveStores.ts","../src/lock/module.ts","../src/migration/db.ts","../src/migration/index.ts","../src/rate-limit/index.ts","../src/files/index.ts","../src/viteServer.ts","../src/auth/providers/oauth-common.ts","../src/auth/providers/google.ts","../src/auth/providers/github.ts","../src/routes/handler.ts","../src/app/securityConfig.ts","../src/app/websocketConfig.ts","../src/app/server.ts","../src/app/index.ts","../src/auth/deleteUser.ts","../src/websocket/serverChannel.ts","../src/app/email.ts"],"names":["Module","name","stores","queries","mutations","routes","cronJobs","configSchema","rateLimits","channels","key","getConfig","serializeZodSchema","zodType","def","shape","serializedShape","value","effectsDef","serializeModelSchema","schema","serialized","item","COMPARABLE_INDEX_OPTION_FIELDS","isDocumentRecord","hasModelencePrefix","getComparableIndexOptions","index","options","field","isSameIndexKey","left","right","leftEntries","rightEntries","leftField","leftDirection","rightField","rightDirection","isDeepStrictEqual","isSameIndexDefinition","existing","desired","getIndexKeySignature","direction","listIndexes","collection","error","MongoError","generateAutoIndexName","normalizeIndexName","autoName","Store","_Store","current","config","tail","extendedSchema","extendedIndexes","extendedSearchIndexes","combinedMethods","extendedStore","client","mode","shouldDropIndexes","shouldCreateIndexes","existingIndexes","indexByName","indexNamesByKey","droppedIndexNames","addIndexToLookup","existingIndex","keySignature","names","removeIndexFromLookup","indexName","dropIndexIfNeeded","currentIndexNames","idx","orphanedIndexes","existingIdx","orphanedIndex","requiresDropBeforeCreate","existingByName","existingNamesForKey","existingName","alignedIndex","searchIndex","document","selector","ObjectId","query","errorHandler","result","cursor","id","idSelector","documents","update","replacement","filter","f","pipeline","operations","oldName","db","embedding","numCandidates","limit","projection","dimensions","similarity","schemaString","z","schemaNumber","schemaDate","schemaBoolean","schemaArray","schemaObject","schemaEnum","_collection","_schema","sessionsCollection","obtainSession","authToken","existingSession","createSession","setSessionUser","userId","clearSessionUser","invalidateAllUserSessions","randomBytes","now","expiresAt","time","processSessionHeartbeat","session","newExpiresAt","setAuthTokenCookie","res","session_default","args","user","getPublicConfigs","usersCollection","dbDisposableEmailDomains","emailVerificationTokensCollection","resetPasswordTokensCollection","roleMap","defaultRoles","initRoles","roles","_defaultRoles","definition","getUnauthenticatedRoles","getDefaultAuthenticatedRoles","requireAccess","requiredPermissions","missingPermission","permission","hasPermission","role","authenticate","userDoc","system_default","connect","mongodbUri","getMongodbUri","maxPoolSize","MongoClient","package_default","err","getClient","LiveData","isServer","requireServer","htmlToText","html","methods","createQuery","methodDef","validateMethodName","_createMethodInternal","createMutation","_createSystemQuery","validateSystemMethodName","_createSystemMutation","type","handler","permissions","runMethod","context","method","transaction","startTransaction","response","runLiveMethod","socketSubscriptions","getSocketSubs","socket","subs","handleSubscribeLiveQuery","payload","parsed","subscriptionId","clientInfo","existingSub","subscription","liveData","fetchAndEmit","data","sanitizeResult","getResponseTypeMap","isPendingPublish","isFetching","processPendingPublish","cleanup","handleUnsubscribeLiveQuery","sub","handleLiveQueryDisconnect","socketServer","COLLECTION","ADAPTER_TTL_SECONDS","init","httpServer","mongodbClient","isMultiInstance","mongoCollection","retryError","SocketServer","createAdapter","next","token","channelName","category","authorized","channel","broadcast","server_default","isDisposableEmail","email","emailParts","domain","updateDisposableEmailListCron","domains","batchSize","batch","MIN_HANDLE_LENGTH","MAX_HANDLE_LENGTH","trimmedNonEmptyString","opts","trimmedOptionalString","val","profileFieldsSchema","validateProfileFields","fields","issue","path","msg","validatePassword","validateEmail","validateHandle","serializeUserForClient","findAvailableHandle","baseHandle","truncatedBase","MAX_SUFFIX_VALUE","suffix","suffixStr","candidate","MAX_RANDOM_ATTEMPTS","attempt","randomSuffix","resolveUniqueHandle","rawHandle","throwOnConflict","handle","emailConfig","setEmailConfig","newEmailConfig","getEmailConfig","authConfig","setAuthConfig","newAuthConfig","getAuthConfig","handleLoginWithPassword","connectionInfo","ip","consumeRateLimit","password","passwordHash","incorrectCredentialsError","e","bcrypt","handleLogout","getOwnProfile","props","profile","handleUpdateProfile","setFields","unsetFields","mongoUpdate","clearedFields","SUPPORTED_OAUTH_PROVIDERS","handleUnlinkOAuthProvider","provider","otherMethods","otherMethodGuard","dbRateLimits","allRules","initRateLimits","bucket","message","rules","rule","createError","RateLimitError","checkRateLimitRule","createRateLimitError","record","currentWindowStart","count","modifier","getCount","prevWindowStart","currentWindowCount","prevWindowCount","prevWindowWeight","weight","emailVerificationTemplate","verificationUrl","verifyEmailToken","tokenDoc","updatedUserDoc","handleVerifyEmail","params","baseUrl","emailVerifiedRedirectUrl","sendVerificationEmail","emailProvider","verificationToken","htmlTemplate","textContent","resendVerificationResponse","handleResendEmailVerification","emailDoc","handleSignupWithPassword","signupProps","firstName","lastName","avatarUrl","existingUser","existingEmail","profileFields","resolvedHandle","generated","hash","userDocument","resolveUrl","configuredUrl","defaultPasswordResetTemplate","resetUrl","passwordResetSent","handleSendResetPasswordToken","resetToken","createdAt","handleResetPassword","resetTokenDoc","user_default","localConfigMap","formatLocalConfigValue","numValue","getConfigsFromEnvMap","configMap","configs","envVar","configKey","configSchemaEntry","getLocalConfigs","variant","connectCloudBackend","cronJobsMetadata","containerId","dataStores","store","callApi","os","fetchConfigs","syncStatus","endpoint","callCloudApi","body","extraHeaders","MODELENCE_SERVICE_ENDPOINT","MODELENCE_SERVICE_TOKEN","json","isSyncing","SYNC_INTERVAL","startConfigSync","syncConfig","loadRemoteConfigs","loadConfigs","getSchema","locksCollection","lockCache","DEFAULT_CACHE_DURATION","INSTANCE_ID","DEFAULT_LOCK_DURATION","lockHeartbeats","isDuplicateKeyError","hasKeyPatternField","shouldFallbackToLegacyStrategy","resource","existingLock","tryAcquireLockById","staleThresholdDate","instanceId","deleteLegacyLock","stopLockHeartbeat","heartbeatKey","heartbeat","startLockHeartbeat","lockDuration","heartbeatInterval","existingHeartbeat","scheduleRefresh","acquireLock","isLockAcquired","logDebug","successfulLockCacheDuration","failedLockCacheDuration","bypassCache","acquireLockById","releaseLock","cronJobsInterval","cronJobsCollection","defineCronJob","alias","description","interval","timeout","startCronJobs","aliasList","aliasSelector","cronJobRecords","job","tickCronJobs","state","runCronJob","handleCronJobCompletion","captureError","getCronJobsMetadata","jobs_default","resolveStores","uniqueStores","rootToTail","root","effectiveStores","nameToRoot","module_default","dbMigrations","runMigrations","migrations","lockMode","logInfo","versions","version","existingVersions","existingVersionSet","pendingMigrations","outputStr","maxSize","truncatedOutput","startMigrations","migration_default","rate_limit_default","getUploadUrl","filePath","contentType","visibility","deleteFile","downloadFile","getFileUrl","files_default","ViteServer","createServer","staticFolders","express","req","loadUserViteConfig","appDir","loadConfigFromFile","safelyMergeConfig","baseConfig","userConfig","mergedConfig","mergeConfig","seenPlugins","plugin","pluginName","eslintConfigFile","file","fs","plugins","reactPlugin","modelenceAssetPlugin","eslintPlugin","defineConfig","code","viteServer","authenticateUser","handleExistingProviderLogin","userData","handleExistingEmailLogin","existingUserByEmail","profileUpdate","updatedUser","handleNewUserSignup","newUser","getRedirectUri","handleOAuthUserAuthentication","getCallContext","clearOAuthLinkCookie","safelyCallHook","hook","validateOAuthStateAndGetMode","stateCookieName","storedState","storedStateValue","storedMode","handleOAuthProviderLink","providerField","currentUser","existingProviderId","MongoServerError","validateOAuthCode","exchangeCodeForToken","clientId","clientSecret","redirectUri","tokenResponse","fetchGoogleUserInfo","accessToken","userInfoResponse","handleGoogleAuthenticationCallback","googleClientId","googleClientSecret","tokenData","googleUser","getRouter","googleAuthRouter","Router","checkGoogleEnabled","_req","googleEnabled","authUrl","google_default","fetchGitHubUserInfo","fetchGitHubUserEmails","getGitHubUserEmail","githubUser","handleGitHubAuthenticationCallback","githubClientId","githubClientSecret","githubEmail","nameParts","githubAuthRouter","checkGitHubEnabled","githubEnabled","githubScopes","scopes","s","github_default","createRouteHandler","ModelenceError","securityConfig","setSecurityConfig","newSecurityConfig","getSecurityConfig","websocketConfig","setWebsocketConfig","newWebsocketConfig","getWebsocketConfig","getBodyParserMiddleware","middlewares","jsonOptions","urlencodedOptions","rawOptions","defaultRawOptions","registerModuleRoutes","app","modules","module","route","handlers","startServer","server","combinedModules","cookieParser","securityHeadersMiddleware","methodName","handleMethodError","http","reason","promise","websocketProvider","port","siteUrl","isOAuthCallback","getClientIp","errorMessage","parseZodError","parsingError","zodError","flattened","fieldMessages","errors","formMessages","frameAncestors","hasCustomAncestors","ancestors","forwardedFor","directIp","startApp","auth","security","websocket","dotenv","hasRemoteBackend","trackAppStart","systemModules","markAppStarted","initSystemMethods","initCustomMethods","getConfigSchema","setSchema","rawStores","getStores","getChannels","defineCronJobs","getRateLimits","storesToInit","environmentId","appAlias","environmentAlias","telemetry","setMetadata","allStoresToInit","initStores","createIndexesAndMigrationsWithLock","initMetrics","warnIndexCreationFailure","storeName","MIGRATIONS_LOCK_RESOURCE","blockingStores","backgroundStores","createStoreIndexes","backgroundIndexCreationPromise","migrationPromise","backgroundIndexesResult","migrationResult","reconcileMode","merged","absoluteKey","cronAlias","cronJobParams","serviceEndpoint","appDetails","getAppDetails","modelencePackageJson","packageJsonPath","packageJsonContent","clearTokens","disableUser","deleteUser","randomUUID","ServerChannel","canAccessChannel","logError","sendEmail"],"mappings":"k6BA0CO,IAAMA,CAAAA,CAAN,KAKL,CAqCA,WAAA,CACEC,CAAAA,CACA,CACE,MAAA,CAAAC,CAAAA,CAAS,EAAC,CACV,OAAA,CAAAC,CAAAA,CAAU,EAAC,CACX,SAAA,CAAAC,CAAAA,CAAY,EAAC,CACb,MAAA,CAAAC,EAAS,EAAC,CACV,QAAA,CAAAC,CAAAA,CAAW,EAAC,CACZ,YAAA,CAAAC,CAAAA,CAAe,EAAC,CAChB,UAAA,CAAAC,CAAAA,CAAa,EAAC,CACd,QAAA,CAAAC,CAAAA,CAAW,EACb,CAAA,CAUI,EAAC,CACL,CACA,IAAA,CAAK,IAAA,CAAOR,CAAAA,CACZ,IAAA,CAAK,MAAA,CAASC,CAAAA,CACd,IAAA,CAAK,OAAA,CAAUC,CAAAA,CACf,IAAA,CAAK,SAAA,CAAYC,CAAAA,CACjB,KAAK,MAAA,CAASC,CAAAA,CACd,IAAA,CAAK,QAAA,CAAWC,CAAAA,CAChB,IAAA,CAAK,YAAA,CAAeC,CAAAA,CACpB,KAAK,UAAA,CAAaC,CAAAA,CAClB,IAAA,CAAK,QAAA,CAAWC,EAClB,CAsBA,SAAA,CAA4CC,CAAAA,CAAuC,CACjF,OAAOC,GAAAA,CAAW,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,CAAA,EAAID,CAAG,CAAA,CAAE,CACzC,CACF,EC3EA,SAASE,CAAAA,CAAmBC,CAAAA,CAAsC,CAChE,IAAMC,CAAAA,CAAMD,CAAAA,CAAQ,IAAA,CAEpB,GAAIC,CAAAA,CAAI,QAAA,GAAa,WAAA,CACnB,OAAO,CAAE,IAAA,CAAM,QAAS,CAAA,CAE1B,GAAIA,CAAAA,CAAI,QAAA,GAAa,WAAA,CACnB,OAAO,CAAE,IAAA,CAAM,QAAS,CAAA,CAE1B,GAAIA,CAAAA,CAAI,QAAA,GAAa,YAAA,CACnB,OAAO,CAAE,IAAA,CAAM,SAAU,CAAA,CAE3B,GAAIA,CAAAA,CAAI,QAAA,GAAa,SAAA,CACnB,OAAO,CAAE,IAAA,CAAM,MAAO,CAAA,CAExB,GAAIA,CAAAA,CAAI,QAAA,GAAa,UAAA,CAEnB,OAAO,CACL,IAAA,CAAM,OAAA,CACN,KAAA,CAAOF,CAAAA,CAHQE,CAAAA,CAGoB,IAAI,CACzC,CAAA,CAEF,GAAIA,CAAAA,CAAI,QAAA,GAAa,WAAA,CAAa,CAEhC,IAAMC,CAAAA,CADYD,EACM,KAAA,EAAM,CACxBE,CAAAA,CAAoD,EAAC,CAC3D,IAAA,GAAW,CAACN,CAAAA,CAAKO,CAAK,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQF,CAAK,CAAA,CAC7CC,CAAAA,CAAgBN,CAAG,CAAA,CAAIE,EAAmBK,CAAkB,CAAA,CAE9D,OAAO,CACL,IAAA,CAAM,QAAA,CACN,KAAA,CAAOD,CACT,CACF,CACA,GAAIF,CAAAA,CAAI,QAAA,GAAa,aAAA,CAEnB,OAAO,CACL,GAAGF,CAAAA,CAFeE,CAAAA,CAEgB,SAAS,CAAA,CAC3C,QAAA,CAAU,IACZ,CAAA,CAEF,GAAIA,EAAI,QAAA,GAAa,aAAA,CAEnB,OAAO,CACL,GAAGF,CAAAA,CAFeE,CAAAA,CAEgB,SAAS,EAC3C,QAAA,CAAU,IACZ,CAAA,CAEF,GAAIA,CAAAA,CAAI,QAAA,GAAa,SAAA,CAEnB,OAAO,CACL,IAAA,CAAM,MAAA,CACN,KAAA,CAHcA,CAAAA,CAGC,MACjB,CAAA,CAEF,GAAIA,CAAAA,CAAI,WAAa,UAAA,CAEnB,OAAO,CACL,IAAA,CAAM,OAAA,CACN,KAAA,CAHeA,CAAAA,CAGC,OAAA,CAAQ,IAAIF,CAAkB,CAChD,CAAA,CAEF,GAAIE,CAAAA,CAAI,QAAA,GAAa,YAAA,CAAc,CAEjC,IAAMI,CAAAA,CAAaJ,CAAAA,CAGnB,OAAII,CAAAA,CAAW,WAAA,CACN,CAAE,IAAA,CAAM,QAAA,CAAU,QAAA,CAAUA,CAAAA,CAAW,WAAY,CAAA,CAIrDN,CAAAA,CAAmBM,CAAAA,CAAW,MAAM,CAC7C,CAGA,OAAO,CAAE,IAAA,CAAM,QAAA,CAAU,QAAA,CAAUJ,CAAAA,CAAI,QAAS,CAClD,CAKO,SAASK,EAAAA,CAAqBC,CAAAA,CAA4C,CAC/E,IAAMC,CAAAA,CAAoC,EAAC,CAE3C,OAAW,CAACX,CAAAA,CAAKO,CAAK,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQG,CAAM,CAAA,CAC1C,KAAA,CAAM,OAAA,CAAQH,CAAK,CAAA,CAErBI,CAAAA,CAAWX,CAAG,CAAA,CAAIO,CAAAA,CAAM,IAAKK,CAAAA,EACvB,OAAOA,CAAAA,EAAS,QAAA,EAAY,MAAA,GAAUA,CAAAA,CACjCV,CAAAA,CAAmBU,CAAiB,EAEtCH,EAAAA,CAAqBG,CAA4B,CACzD,CAAA,CACQ,OAAOL,CAAAA,EAAU,QAAA,EAAY,MAAA,GAAUA,EAEhDI,CAAAA,CAAWX,CAAG,CAAA,CAAIE,CAAAA,CAAmBK,CAAkB,CAAA,CAGvDI,CAAAA,CAAWX,CAAG,CAAA,CAAIS,EAAAA,CAAqBF,CAA6B,CAAA,CAIxE,OAAOI,CACT,CC5CA,IAAME,GAAiC,CACrC,YAAA,CACA,MAAA,CACA,YAAA,CACA,WAAA,CACA,kBAAA,CACA,oBAAA,CACA,QAAA,CACA,oBACA,KAAA,CACA,KAAA,CACA,yBAAA,CACA,QAAA,CACA,eAAA,CACA,kBAAA,CACA,QAAA,CACA,SAAA,CACA,qBACA,sBACF,CAAA,CAEMC,EAAAA,CAAoBP,CAAAA,EACxB,OAAOA,CAAAA,EAAU,QAAA,EAAYA,CAAAA,GAAU,MAAQ,CAAC,KAAA,CAAM,OAAA,CAAQA,CAAK,CAAA,CAE/DQ,EAAAA,CAAsBxB,CAAAA,EAA0BA,CAAAA,CAAK,WAAW,aAAa,CAAA,CAE7EyB,EAAAA,CAA6BC,CAAAA,EAAsD,CACvF,IAAMC,CAAAA,CAAoB,GAE1B,IAAA,IAAWC,CAAAA,IAASN,EAAAA,CAAgC,CAClD,IAAMN,CAAAA,CAASU,CAAAA,CAAmBE,CAAK,EACnCZ,CAAAA,GAAU,MAAA,GACZW,CAAAA,CAAQC,CAAK,CAAA,CAAIZ,CAAAA,EAErB,CAEA,OAAOW,CACT,CAAA,CAKME,EAAAA,CAAiB,CAACC,CAAAA,CAAeC,CAAAA,GAA4B,CACjE,GAAI,CAACR,EAAAA,CAAiBO,CAAI,CAAA,EAAK,CAACP,EAAAA,CAAiBQ,CAAK,CAAA,CACpD,OAAO,OAGT,IAAMC,CAAAA,CAAc,MAAA,CAAO,OAAA,CAAQF,CAAI,CAAA,CACjCG,CAAAA,CAAe,MAAA,CAAO,QAAQF,CAAK,CAAA,CAEzC,OAAIC,CAAAA,CAAY,MAAA,GAAWC,CAAAA,CAAa,MAAA,CAC/B,KAAA,CAGFD,CAAAA,CAAY,KAAA,CAAM,CAAC,CAACE,CAAAA,CAAWC,CAAa,CAAA,CAAGT,CAAAA,GAAU,CAC9D,GAAM,CAACU,CAAAA,CAAYC,CAAc,CAAA,CAAIJ,CAAAA,CAAaP,CAAK,CAAA,EAAK,EAAC,CAC7D,OAAOQ,CAAAA,GAAcE,CAAAA,EAAcE,iBAAAA,CAAkBH,CAAAA,CAAeE,CAAc,CACpF,CAAC,CACH,CAAA,CAEME,EAAAA,CAAwB,CAACC,CAAAA,CAAyBC,CAAAA,GACjDZ,EAAAA,CAAeW,CAAAA,CAAS,GAAA,CAAKC,CAAAA,CAAQ,GAAG,CAAA,CAItCH,iBAAAA,CAAkBb,EAAAA,CAA0Be,CAAQ,CAAA,CAAGf,GAA0BgB,CAAO,CAAC,CAAA,CAHvF,KAAA,CAMLC,EAAAA,CAAwBjC,CAAAA,EACvBc,EAAAA,CAAiBd,CAAG,EAIlB,MAAA,CAAO,OAAA,CAAQA,CAAG,CAAA,CACtB,GAAA,CAAI,CAAC,CAACmB,CAAAA,CAAOe,CAAS,CAAA,GAAM,CAAA,EAAGf,CAAK,CAAA,CAAA,EAAI,IAAA,CAAK,SAAA,CAAUe,CAAS,CAAC,EAAE,CAAA,CACnE,IAAA,CAAK,GAAG,CAAA,CALF,IAAA,CAYLC,EAAAA,CAAc,MAAOC,CAAAA,EAAqD,CAC9E,GAAI,CACF,OAAO,MAAMA,CAAAA,CAAW,WAAA,EAAY,CAAE,OAAA,EACxC,CAAA,MAASC,CAAAA,CAAO,CAGd,GAAIA,CAAAA,YAAiBC,UAAAA,EAAcD,CAAAA,CAAM,IAAA,GAAS,GAChD,OAAO,EAAC,CAEV,MAAMA,CACR,CACF,CAAA,CAMME,EAAAA,CAAyBvC,CAAAA,EACtB,MAAA,CAAO,OAAA,CAAQA,CAAG,CAAA,CACtB,GAAA,CAAI,CAAC,CAACmB,EAAOe,CAAS,CAAA,GAAM,CAAA,EAAGf,CAAK,CAAA,CAAA,EAAIe,CAAS,CAAA,CAAE,CAAA,CACnD,KAAK,GAAG,CAAA,CAMPM,EAAAA,CAAsBvB,CAAAA,EAA8C,CACxE,GAAIA,CAAAA,CAAM,IAAA,CAAM,CAEd,IAAM1B,CAAAA,CAAO0B,CAAAA,CAAM,IAAA,CAAK,UAAA,CAAW,aAAa,CAAA,CAAIA,CAAAA,CAAM,IAAA,CAAO,CAAA,WAAA,EAAcA,CAAAA,CAAM,IAAI,CAAA,CAAA,CACzF,OAAO,CAAE,GAAGA,EAAO,IAAA,CAAA1B,CAAK,CAC1B,CAGA,IAAMkD,CAAAA,CAAWF,EAAAA,CAAsBtB,CAAAA,CAAM,GAAG,CAAA,CAChD,OAAO,CAAE,GAAGA,CAAAA,CAAO,IAAA,CAAM,CAAA,WAAA,EAAcwB,CAAQ,EAAG,CACpD,CAAA,CA0HaC,CAAAA,CAAN,MAAMC,CAOX,CA6BA,WAAA,CACEpD,CAAAA,CACA2B,CAAAA,CAYA,CAvBF,IAAA,CAAQ,YAAA,CAAgC,IAAA,CACxC,IAAA,CAAQ,WAAA,CAA+B,IAAA,CAuBrC,KAAK,IAAA,CAAO3B,CAAAA,CACZ,IAAA,CAAK,MAAA,CAAS2B,CAAAA,CAAQ,MAAA,CACtB,IAAA,CAAK,OAAA,CAAUA,EAAQ,OAAA,CAEvB,IAAA,CAAK,OAAA,CAAUA,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAIsB,EAAkB,CAAA,CACrD,KAAK,aAAA,CAAgBtB,CAAAA,CAAQ,aAAA,EAAiB,EAAC,CAC/C,IAAA,CAAK,iBAAA,CAAoBA,CAAAA,CAAQ,iBAAA,EAAqB,aACxD,CAEA,OAAA,EAAU,CACR,OAAO,IAAA,CAAK,IACd,CAEA,oBAAA,EAAuB,CACrB,OAAO,IAAA,CAAK,iBACd,CAGA,SAAA,EAAY,CACV,OAAO,IAAA,CAAK,MACd,CAGA,mBAAA,EAAsB,CACpB,OAAOT,EAAAA,CAAqB,IAAA,CAAK,MAAM,CACzC,CAGA,UAAA,EAAiC,CAC/B,OAAO,IAAA,CAAK,OACd,CAGA,gBAAA,EAA6C,CAC3C,OAAO,IAAA,CAAK,aACd,CAGA,YAAA,EAAyB,CACvB,IAAImC,CAAAA,CAAoB,IAAA,CACxB,KAAOA,CAAAA,CAAQ,WAAA,EACbA,CAAAA,CAAUA,CAAAA,CAAQ,WAAA,CAEpB,OAAOA,CACT,CAGA,YAAA,EAAyB,CACvB,IAAIA,CAAAA,CAAoB,IAAA,CACxB,KAAOA,EAAQ,YAAA,EACbA,CAAAA,CAAUA,CAAAA,CAAQ,YAAA,CAEpB,OAAOA,CACT,CAmCA,MAAA,CAGEC,CAAAA,CAcA,CAEA,IAAMC,CAAAA,CAAiB,IAAA,CAAK,YAAA,EAAa,CAEzC,GAAI,KAAK,MAAA,EAAUA,CAAAA,CAAK,MAAA,CACtB,MAAM,IAAI,KAAA,CACR,CAAA,wDAAA,EAA2D,IAAA,CAAK,IAAI,CAAA,sDAAA,CACtE,CAAA,CAGF,IAAMC,CAAAA,CAAiB,CACrB,GAAGD,CAAAA,CAAK,MAAA,CACR,GAAID,CAAAA,CAAO,MAAA,EAAU,EACvB,CAAA,CAEMG,CAAAA,CAAkB,CAAC,GAAGF,CAAAA,CAAK,OAAA,CAAS,GAAID,CAAAA,CAAO,OAAA,EAAW,EAAG,CAAA,CAC7DI,EAAwB,CAAC,GAAGH,CAAAA,CAAK,aAAA,CAAe,GAAID,CAAAA,CAAO,aAAA,EAAiB,EAAG,CAAA,CAQ/EK,CAAAA,CAAkB,CACtB,GAAIJ,CAAAA,CAAK,OAAA,EAAW,EAAC,CACrB,GAAID,CAAAA,CAAO,OAAA,EAAW,EACxB,CAAA,CAEMM,CAAAA,CAAgB,IAAIR,CAAAA,CAGxB,KAAK,IAAA,CAAM,CACX,MAAA,CAAQI,CAAAA,CACR,OAAA,CAASG,CAAAA,CACT,OAAA,CAASF,CAAAA,CACT,cAAeC,CAAAA,CACf,iBAAA,CAAmBJ,CAAAA,CAAO,iBAAA,EAAqBC,CAAAA,CAAK,iBACtD,CAAC,CAAA,CAGD,OAAAA,CAAAA,CAAK,WAAA,CAAcK,CAAAA,CACnBA,CAAAA,CAAc,YAAA,CAAeL,CAAAA,CAEtBK,CACT,CAGA,KAAKC,CAAAA,CAAqB,CACxB,GAAI,IAAA,CAAK,UAAA,CACP,MAAM,IAAI,KAAA,CAAM,CAAA,WAAA,EAAc,IAAA,CAAK,IAAI,CAAA,uBAAA,CAAyB,CAAA,CAGlE,IAAA,CAAK,MAAA,CAASA,CAAAA,CACd,KAAK,UAAA,CAAa,IAAA,CAAK,MAAA,CAAO,EAAA,EAAG,CAAE,UAAA,CAA0B,IAAA,CAAK,IAAI,EACxE,CAGA,MAAM,aAAA,CAAcC,CAAAA,CAA2B,MAAA,CAAQ,CACrD,IAAMjB,CAAAA,CAAa,KAAK,iBAAA,EAAkB,CACpCkB,CAAAA,CAAoBD,CAAAA,GAAS,aAAA,CAC7BE,CAAAA,CAAsBF,CAAAA,GAAS,WAAA,CAG/BG,CAAAA,CAAkB,MAAMrB,EAAAA,CAAYC,CAAU,CAAA,CAC9CqB,CAAAA,CAAc,IAAI,GAAA,CAClBC,EAAkB,IAAI,GAAA,CACtBC,CAAAA,CAAoB,IAAI,GAAA,CAExBC,CAAAA,CAAoBC,CAAAA,EAAoD,CAC5EJ,EAAY,GAAA,CAAII,CAAAA,CAAc,IAAA,CAAMA,CAAa,CAAA,CAEjD,IAAMC,CAAAA,CAAe7B,EAAAA,CAAqB4B,EAAc,GAAG,CAAA,CAC3D,GAAI,CAACC,CAAAA,CACH,OAGF,IAAMC,CAAAA,CAAQL,CAAAA,CAAgB,GAAA,CAAII,CAAY,CAAA,CAC1CC,CAAAA,CACFA,CAAAA,CAAM,GAAA,CAAIF,CAAAA,CAAc,IAAI,CAAA,CAE5BH,CAAAA,CAAgB,GAAA,CAAII,CAAAA,CAAc,IAAI,GAAA,CAAI,CAACD,CAAAA,CAAc,IAAI,CAAC,CAAC,EAEnE,CAAA,CAEMG,CAAAA,CAAyBC,CAAAA,EAAsB,CACnD,IAAMJ,EAAgBJ,CAAAA,CAAY,GAAA,CAAIQ,CAAS,CAAA,CAC/C,GAAI,CAACJ,CAAAA,CACH,OAGFJ,EAAY,MAAA,CAAOQ,CAAS,CAAA,CAE5B,IAAMH,CAAAA,CAAe7B,EAAAA,CAAqB4B,CAAAA,CAAc,GAAG,EAC3D,GAAI,CAACC,CAAAA,CACH,OAGF,IAAMC,CAAAA,CAAQL,CAAAA,CAAgB,GAAA,CAAII,CAAY,CAAA,CACzCC,CAAAA,GAILA,CAAAA,CAAM,MAAA,CAAOE,CAAS,CAAA,CAClBF,CAAAA,CAAM,IAAA,GAAS,GACjBL,CAAAA,CAAgB,MAAA,CAAOI,CAAY,CAAA,EAEvC,CAAA,CAEA,IAAA,IAAWD,CAAAA,IAAiBL,CAAAA,CACtB,OAAOK,CAAAA,CAAc,IAAA,EAAS,QAAA,EAChCD,CAAAA,CAAiB,CACf,GAAGC,CAAAA,CACH,KAAMA,CAAAA,CAAc,IACtB,CAAC,CAAA,CAIL,IAAMK,CAAAA,CAAoB,MAAOD,CAAAA,EAAsB,CACrD,GAAI,EAAAA,CAAAA,GAAc,MAAA,EAAUN,CAAAA,CAAkB,GAAA,CAAIM,CAAS,CAAA,CAAA,CAG3D,IAAI,CACF,MAAM7B,CAAAA,CAAW,SAAA,CAAU6B,CAAS,EACtC,CAAA,MAAS5B,CAAAA,CAAO,CAEd,GAAI,EAAEA,CAAAA,YAAiBC,UAAAA,EAAcD,CAAAA,CAAM,IAAA,GAAS,EAAA,CAAA,CAClD,MAAMA,CAEV,CACAsB,CAAAA,CAAkB,GAAA,CAAIM,CAAS,CAAA,CAC/BD,CAAAA,CAAsBC,CAAS,GACjC,CAAA,CAEA,GAAIX,CAAAA,CAAmB,CAErB,IAAMa,CAAAA,CAAoB,IAAI,GAAA,CAC5B,KAAK,OAAA,CACF,GAAA,CAAKC,CAAAA,EAAQA,CAAAA,CAAI,IAAI,CAAA,CACrB,MAAA,CAAQ7E,CAAAA,EAAyB,OAAOA,CAAAA,EAAS,QAAQ,CAC9D,CAAA,CACM8E,CAAAA,CAAkB,CAAC,GAAGZ,EAAY,MAAA,EAAQ,CAAA,CAAE,MAAA,CAC/Ca,CAAAA,EACCvD,EAAAA,CAAmBuD,CAAAA,CAAY,IAAI,GAAK,CAACH,CAAAA,CAAkB,GAAA,CAAIG,CAAAA,CAAY,IAAI,CACnF,CAAA,CAGA,IAAA,IAAWC,KAAiBF,CAAAA,CAC1B,MAAMH,CAAAA,CAAkBK,CAAAA,CAAc,IAAI,EAE9C,CAIA,GAAI,KAAK,OAAA,CAAQ,MAAA,CAAS,CAAA,CACxB,IAAA,IAAWtD,CAAAA,IAAS,IAAA,CAAK,OAAA,CAAS,CAChC,GAAI,CAACA,CAAAA,CAAM,IAAA,CACT,SAGF,IAAIuD,CAAAA,CAA2B,KAAA,CACzBC,CAAAA,CAAiBhB,EAAY,GAAA,CAAIxC,CAAAA,CAAM,IAAI,CAAA,CAC7CwD,CAAAA,EAAkB,CAAC3C,EAAAA,CAAsB2C,CAAAA,CAAgBxD,CAAK,CAAA,GAC5DqC,CAAAA,CACF,MAAMY,CAAAA,CAAkBO,CAAAA,CAAe,IAAI,CAAA,CAE3CD,CAAAA,CAA2B,IAAA,CAAA,CAI/B,IAAMV,CAAAA,CAAe7B,EAAAA,CAAqBhB,CAAAA,CAAM,GAAG,CAAA,CACnD,GAAI6C,EAAc,CAChB,IAAMY,CAAAA,CAAsB,CAAC,GAAIhB,CAAAA,CAAgB,GAAA,CAAII,CAAY,GAAK,EAAG,CAAA,CACzE,IAAA,IAAWa,CAAAA,IAAgBD,CAAAA,CACrBC,CAAAA,GAAiB1D,CAAAA,CAAM,OACrBqC,CAAAA,CACF,MAAMY,CAAAA,CAAkBS,CAAY,CAAA,CAEpCH,CAAAA,CAA2B,IAAA,EAInC,CAEA,IAAMI,CAAAA,CAAenB,CAAAA,CAAY,GAAA,CAAIxC,CAAAA,CAAM,IAAI,CAAA,CAG3C,EAFoB,CAAC,CAAC2D,CAAAA,EAAgB9C,EAAAA,CAAsB8C,CAAAA,CAAc3D,CAAK,CAAA,CAAA,EAE3DsC,CAAAA,EAAuB,CAACiB,IAC9C,MAAMpC,CAAAA,CAAW,aAAA,CAAc,CAACnB,CAAK,CAAC,CAAA,CACtC2C,CAAAA,CAAiB,CACf,IAAA,CAAM3C,CAAAA,CAAM,IAAA,CACZ,GAAA,CAAKA,CAAAA,CAAM,GAAA,CACX,GAAGD,EAAAA,CAA0BC,CAAK,CACpC,CAAC,CAAA,EAEL,CAEF,GAAIsC,CAAAA,EAAuB,IAAA,CAAK,cAAc,MAAA,CAAS,CAAA,CACrD,IAAA,IAAWsB,CAAAA,IAAe,IAAA,CAAK,aAAA,CAC7B,GAAI,CACF,MAAMzC,CAAAA,CAAW,mBAAA,CAAoB,CAACyC,CAAW,CAAC,EACpD,CAAA,MAASxC,CAAAA,CAAO,CACd,GAAIA,CAAAA,YAAiBC,UAAAA,EAAcD,CAAAA,CAAM,IAAA,GAAS,EAAA,EAAMwC,CAAAA,CAAY,IAAA,CAClE,MAAMzC,CAAAA,CAAW,eAAA,CAAgByC,CAAAA,CAAY,IAAI,CAAA,CACjD,MAAMzC,CAAAA,CAAW,oBAAoB,CAACyC,CAAW,CAAC,CAAA,CAAA,KAElD,MAAMxC,CAEV,CAGN,CAEQ,aAAayC,CAAAA,CAAyC,CAC5D,OAAK,IAAA,CAAK,OAAA,CAIK,MAAA,CAAO,MAAA,CACpB,IAAA,CACA,OAAO,yBAAA,CAA0B,CAC/B,GAAGA,CAAAA,CACH,GAAG,IAAA,CAAK,OACV,CAAC,CACH,CAAA,CATSA,CAYX,CAKQ,WAAA,CAAYC,CAAAA,CAA0D,CAC5E,OAAI,OAAOA,CAAAA,EAAa,QAAA,CACf,CAAE,GAAA,CAAK,IAAIC,QAAAA,CAASD,CAAQ,CAAE,EAGnCA,CAAAA,YAAoBC,QAAAA,CACf,CAAE,GAAA,CAAKD,CAAS,CAAA,CAGlBA,CACT,CAGA,mBAAoB,CAClB,GAAI,CAAC,IAAA,CAAK,UAAA,CACR,MAAM,IAAI,KAAA,CAAM,CAAA,WAAA,EAAc,IAAA,CAAK,IAAI,CAAA,mBAAA,CAAqB,CAAA,CAG9D,OAAO,IAAA,CAAK,UACd,CAGA,aAAA,EAAgB,CACd,GAAI,CAAC,IAAA,CAAK,MAAA,CACR,MAAM,IAAI,MAAM,2BAA2B,CAAA,CAG7C,OAAO,IAAA,CAAK,MACd,CAuBA,MAAM,OAAA,CAAQE,EAAmC/D,CAAAA,CAAuB,CACtE,IAAM4D,CAAAA,CAAW,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,OAAA,CAC9CG,CAAAA,CACA/D,CACF,CAAA,CACA,OAAO4D,CAAAA,CAAW,IAAA,CAAK,YAAA,CAAaA,CAAQ,CAAA,CAAI,IAClD,CAEA,MAAM,UAAA,CACJG,CAAAA,CACA/D,CAAAA,CACAgE,CAAAA,CACuB,CACvB,IAAMC,CAAAA,CAAS,MAAM,IAAA,CAAK,OAAA,CAAQF,CAAAA,CAAO/D,CAAO,CAAA,CAChD,GAAI,CAACiE,CAAAA,CACH,MAAMD,CAAAA,CAAeA,CAAAA,EAAa,CAAI,IAAI,KAAA,CAAM,uBAAuB,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA,CAEpF,OAAOC,CACT,CAEQ,IAAA,CAAKF,EAAmC/D,CAAAA,CAAuC,CACrF,IAAMkE,CAAAA,CAAS,IAAA,CAAK,iBAAA,EAAkB,CAAE,IAAA,CACtCH,EACA/D,CAAAA,EAAS,UAAA,CAAa,CAAE,UAAA,CAAYA,CAAAA,CAAQ,UAAW,CAAA,CAAI,MAC7D,EACA,OAAIA,CAAAA,EAAS,IAAA,EACXkE,CAAAA,CAAO,IAAA,CAAKlE,CAAAA,CAAQ,IAAI,CAAA,CAEtBA,CAAAA,EAAS,KAAA,EACXkE,CAAAA,CAAO,KAAA,CAAMlE,CAAAA,CAAQ,KAAK,CAAA,CAExBA,CAAAA,EAAS,MACXkE,CAAAA,CAAO,IAAA,CAAKlE,CAAAA,CAAQ,IAAI,CAAA,CAEnBkE,CACT,CAQA,MAAM,SAASC,CAAAA,CAAqD,CAClE,IAAMC,CAAAA,CAAa,OAAOD,CAAAA,EAAO,QAAA,CAAW,CAAE,IAAK,IAAIL,QAAAA,CAASK,CAAE,CAAE,CAAA,CAAI,CAAE,GAAA,CAAKA,CAAG,CAAA,CAClF,OAAO,MAAM,IAAA,CAAK,OAAA,CAAQC,CAAwC,CACpE,CASA,MAAM,WAAA,CAAYD,CAAAA,CAAuBH,CAAAA,CAAmD,CAC1F,IAAMC,CAAAA,CAAS,MAAM,IAAA,CAAK,SAASE,CAAE,CAAA,CACrC,GAAI,CAACF,CAAAA,CACH,MAAMD,CAAAA,CACFA,CAAAA,GACA,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkBG,CAAE,CAAA,cAAA,EAAiB,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA,CAEhE,OAAOF,CACT,CAQA,cAAA,CAAeF,CAAAA,CAAoD,CACjE,OAAO,KAAK,iBAAA,EAAkB,CAAE,cAAA,CAAeA,CAA8B,CAC/E,CA4BA,MAAM,KAAA,CACJA,EACA/D,CAAAA,CACyB,CAEzB,OAAA,CAAQ,MADO,IAAA,CAAK,IAAA,CAAK+D,CAAAA,CAAO/D,CAAO,EAClB,OAAA,EAAQ,EAAG,GAAA,CAAI,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,IAAI,CAAC,CAClE,CAQA,MAAM,SAAA,CACJ4D,CAAAA,CACA5D,CAAAA,CAC0B,CAC1B,OAAO,MAAM,KAAK,iBAAA,EAAkB,CAAE,SAAA,CAAU4D,CAAAA,CAAU5D,CAAO,CACnE,CAQA,MAAM,WACJqE,CAAAA,CACArE,CAAAA,CAC2B,CAC3B,OAAO,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,WAAWqE,CAAAA,CAAWrE,CAAO,CACrE,CASA,MAAM,SAAA,CACJ6D,CAAAA,CACAS,CAAAA,CACAtE,CAAAA,CACuB,CACvB,OAAO,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,SAAA,CAAU,KAAK,WAAA,CAAY6D,CAAQ,CAAA,CAAGS,CAAAA,CAAQtE,CAAO,CAC7F,CASA,MAAM,UACJ6D,CAAAA,CACAS,CAAAA,CACAtE,CAAAA,CACuB,CACvB,OAAO,MAAM,IAAA,CAAK,iBAAA,GAAoB,SAAA,CAAU,IAAA,CAAK,WAAA,CAAY6D,CAAQ,CAAA,CAAGS,CAAAA,CAAQ,CAClF,MAAA,CAAQ,IAAA,CACR,GAAGtE,CACL,CAAC,CACH,CASA,MAAM,UAAA,CACJ6D,EACAS,CAAAA,CACAtE,CAAAA,CACuB,CACvB,OAAO,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,WACpC6D,CAAAA,CACAS,CAAAA,CACAtE,CACF,CACF,CASA,MAAM,UAAA,CACJ6D,CAAAA,CACAS,EACAtE,CAAAA,CACuB,CACvB,OAAO,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,UAAA,CAAW6D,CAAAA,CAAmCS,CAAAA,CAAQ,CAC1F,MAAA,CAAQ,IAAA,CACR,GAAGtE,CACL,CAAC,CACH,CAQA,MAAM,SAAA,CACJ6D,CAAAA,CACA7D,CAAAA,CACuB,CACvB,OAAO,MAAM,KAAK,iBAAA,EAAkB,CAAE,SAAA,CAAU6D,CAAAA,CAAmC7D,CAAO,CAC5F,CAQA,MAAM,WACJ6D,CAAAA,CACA7D,CAAAA,CACuB,CACvB,OAAO,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,WAAW6D,CAAAA,CAAmC7D,CAAO,CAC7F,CAUA,MAAM,gBAAA,CACJ6D,CAAAA,CACAS,CAAAA,CACAtE,EAC8B,CAC9B,IAAMiE,CAAAA,CAAS,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,gBAAA,CAC5C,KAAK,WAAA,CAAYJ,CAAQ,CAAA,CACzBS,CAAAA,CACAtE,CAAAA,EAAW,EACb,CAAA,CACA,OAAOiE,CAAAA,CAAS,IAAA,CAAK,YAAA,CAAaA,CAAyB,CAAA,CAAI,IACjE,CASA,MAAM,gBAAA,CACJJ,CAAAA,CACA7D,CAAAA,CAC8B,CAC9B,IAAMiE,CAAAA,CAAS,MAAM,IAAA,CAAK,mBAAkB,CAAE,gBAAA,CAC5C,IAAA,CAAK,WAAA,CAAYJ,CAAQ,CAAA,CACzB7D,CAAAA,EAAW,EACb,CAAA,CACA,OAAOiE,CAAAA,CAAS,IAAA,CAAK,YAAA,CAAaA,CAAyB,CAAA,CAAI,IACjE,CAUA,MAAM,iBAAA,CACJJ,CAAAA,CACAU,CAAAA,CACAvE,CAAAA,CAC8B,CAC9B,IAAMiE,CAAAA,CAAS,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,iBAAA,CAC5C,IAAA,CAAK,WAAA,CAAYJ,CAAQ,EACzBU,CAAAA,CACAvE,CAAAA,EAAW,EACb,CAAA,CACA,OAAOiE,CAAAA,CAAS,IAAA,CAAK,aAAaA,CAAyB,CAAA,CAAI,IACjE,CAUA,MAAM,UAAA,CACJJ,CAAAA,CACAU,CAAAA,CACAvE,EACuB,CACvB,OAAO,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,UAAA,CACpC,IAAA,CAAK,WAAA,CAAY6D,CAAQ,CAAA,CACzBU,CAAAA,CACAvE,CACF,CACF,CAWA,MAAM,SACJlB,CAAAA,CACA0F,CAAAA,CACAxE,CAAAA,CAC6C,CAC7C,IAAMyE,CAAAA,CAAKD,CAAAA,EAAU,GACrB,OAAOxE,CAAAA,GAAY,MAAA,CACf,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,QAAA,CAASlB,EAAK2F,CAAAA,CAAGzE,CAAO,CAAA,CACvD,MAAM,IAAA,CAAK,iBAAA,EAAkB,CAAE,QAAA,CAASlB,EAAK2F,CAAC,CACpD,CASA,KAAA,CAAMC,CAAAA,CAAuB1E,CAAAA,CAA6C,CACxE,OAAO,KAAK,iBAAA,EAAkB,CAAE,KAAA,CAAM0E,CAAAA,CAAU1E,CAAO,CACzD,CASA,SAAA,CAAU0E,EAAsB1E,CAAAA,CAAyD,CACvF,OAAO,IAAA,CAAK,iBAAA,EAAkB,CAAE,SAAA,CAAU0E,CAAAA,CAAU1E,CAAO,CAC7D,CAQA,SAAA,CAAU2E,CAAAA,CAA8E,CACtF,OAAO,IAAA,CAAK,iBAAA,EAAkB,CAAE,SAAA,CAAUA,CAAU,CACtD,CAOA,WAAA,EAAc,CACZ,OAAO,KAAK,aAAA,EAAc,CAAE,EAAA,EAC9B,CAOA,aAAA,EAAgB,CACd,OAAO,KAAK,iBAAA,EACd,CAOA,MAAM,UAAA,CAAWC,CAAAA,CAAiB5E,CAAAA,CAAuC,CACvE,IAAM6E,CAAAA,CAAK,IAAA,CAAK,WAAA,EAAY,CAE5B,GAAI,CAAC,IAAA,CAAK,UAAA,EAAc,CAACA,CAAAA,CACvB,MAAM,IAAI,KAAA,CAAM,CAAA,MAAA,EAAS,IAAA,CAAK,IAAI,qBAAqB,CAAA,CAIzD,GAAA,CADuB,MAAMA,CAAAA,CAAG,eAAA,CAAgB,CAAE,IAAA,CAAMD,CAAQ,CAAC,CAAA,CAAE,OAAA,EAAQ,EACxD,MAAA,GAAW,CAAA,CAC5B,MAAM,IAAI,KAAA,CAAM,cAAcA,CAAO,CAAA,UAAA,CAAY,CAAA,CAInD,GAAA,CADuB,MAAMC,CAAAA,CAAG,eAAA,CAAgB,CAAE,IAAA,CAAM,IAAA,CAAK,IAAK,CAAC,CAAA,CAAE,OAAA,EAAQ,EAC1D,MAAA,CAAS,EAC1B,MAAM,IAAI,KAAA,CAAM,CAAA,WAAA,EAAc,IAAA,CAAK,IAAI,CAAA,eAAA,CAAiB,CAAA,CAK1D,MAF2BA,CAAAA,CAAG,UAAA,CAA0BD,CAAO,CAAA,CAEtC,MAAA,CAAO,IAAA,CAAK,IAAA,CAAM5E,CAAO,EACpD,CAyBA,MAAM,YAAA,CAAa,CACjB,KAAA,CAAAC,CAAAA,CACA,SAAA,CAAA6E,CAAAA,CACA,cAAAC,CAAAA,CACA,KAAA,CAAAC,CAAAA,CACA,UAAA,CAAAC,CAAAA,CACA,SAAA,CAAAlC,CACF,CAAA,CAOG,CACD,OAAO,IAAA,CAAK,SAAA,CAAU,CACpB,CACE,aAAA,CAAe,CACb,KAAA,CAAOA,GAAa9C,CAAAA,CAAQ,cAAA,CAC5B,IAAA,CAAMA,CAAAA,CACN,WAAA,CAAa6E,CAAAA,CACb,aAAA,CAAeC,CAAAA,EAAiB,IAChC,KAAA,CAAOC,CAAAA,EAAS,EAClB,CACF,CAAA,CACA,CACE,QAAA,CAAU,CACR,GAAA,CAAK,CAAA,CACL,KAAA,CAAO,CAAE,KAAA,CAAO,mBAAoB,CAAA,CACpC,GAAGC,CACL,CACF,CACF,CAAC,CACH,CA8BA,OAAO,WAAA,CAAY,CACjB,MAAAhF,CAAAA,CACA,UAAA,CAAAiF,CAAAA,CACA,UAAA,CAAAC,CAAAA,CAAa,QAAA,CACb,SAAA,CAAApC,CACF,EAKG,CACD,OAAO,CACL,IAAA,CAAM,cAAA,CACN,IAAA,CAAMA,CAAAA,EAAa9C,CAAAA,CAAQ,cAAA,CAC3B,UAAA,CAAY,CACV,MAAA,CAAQ,CACN,CACE,IAAA,CAAM,QAAA,CACN,KAAMA,CAAAA,CACN,aAAA,CAAeiF,CAAAA,CACf,UAAA,CAAAC,CACF,CACF,CACF,CACF,CACF,CACF,EC7xCA,IAAMC,EAAAA,CAAgCC,CAAAA,CAAE,MAAA,CAAO,IAAA,CAAKA,CAAC,CAAA,CAE/CC,EAAAA,CAAgCD,CAAAA,CAAE,MAAA,CAAO,IAAA,CAAKA,CAAC,CAAA,CAE/CE,EAAAA,CAA4BF,CAAAA,CAAE,KAAK,IAAA,CAAKA,CAAC,CAAA,CAEzCG,EAAAA,CAAkCH,CAAAA,CAAE,OAAA,CAAQ,IAAA,CAAKA,CAAC,EAElDI,EAAAA,CAA8BJ,CAAAA,CAAE,KAAA,CAAM,IAAA,CAAKA,CAAC,CAAA,CAE5CK,EAAAA,CAAgCL,CAAAA,CAAE,OAAO,IAAA,CAAKA,CAAC,CAAA,CAE/CM,EAAAA,CAA4BN,CAAAA,CAAE,IAAA,CAAK,IAAA,CAAKA,CAAC,EAElC7F,CAAAA,CAAS,CACpB,MAAA,CAAQ4F,EAAAA,CACR,MAAA,CAAQE,EAAAA,CACR,IAAA,CAAMC,EAAAA,CACN,QAASC,EAAAA,CACT,KAAA,CAAOC,EAAAA,CACP,MAAA,CAAQC,EAAAA,CACR,IAAA,CAAMC,EAAAA,CACN,SAAA,EAAiC,CAC/B,OAAON,CAAAA,CAAE,KAAA,CAAMA,CAAAA,CAAE,MAAA,EAAQ,CAC3B,CAAA,CACA,UAAgC,CAC9B,OAAOA,CAAAA,CAAE,UAAA,CAAWvB,QAAQ,CAAA,CAAE,QAAA,CAAS,UAAU,CACnD,CAAA,CACA,MAAA,EAA8B,CAC5B,OAAOuB,CAAAA,CAAE,UAAA,CAAWvB,QAAQ,EAAE,QAAA,CAAS,QAAQ,CACjD,CAAA,CACA,GAAA,CACE8B,CAAAA,CACqB,CACrB,OAAOP,EAAE,UAAA,CAAWvB,QAAQ,CAAA,CAAE,QAAA,CAAS,KAAK,CAC9C,CAAA,CACA,KAAA,CAAOuB,EAAE,KAAA,CAAM,IAAA,CAAKA,CAAC,CAAA,CACrB,KAAA,CAAsCQ,CAAAA,CAAkC,CACtE,OAAO,EACT,CACF,EC9CO,IAAMC,CAAAA,CAAqB,IAAItE,CAAAA,CAAM,qBAAsB,CAChE,MAAA,CAAQ,CACN,SAAA,CAAWhC,CAAAA,CAAO,MAAA,EAAO,CACzB,SAAA,CAAWA,EAAO,IAAA,EAAK,CACvB,SAAA,CAAWA,CAAAA,CAAO,IAAA,EAAK,CACvB,MAAA,CAAQA,CAAAA,CAAO,QAAO,CAAE,QAAA,EAC1B,CAAA,CACA,OAAA,CAAS,CACP,CAAE,GAAA,CAAK,CAAE,SAAA,CAAW,CAAE,CAAA,CAAG,MAAA,CAAQ,IAAK,CAAA,CACtC,CAAE,IAAK,CAAE,SAAA,CAAW,CAAE,CAAA,CAAG,kBAAA,CAAoB,CAAE,CAAA,CAC/C,CAAE,IAAK,CAAE,MAAA,CAAQ,CAAE,CAAE,CACvB,CACF,CAAC,CAAA,CAED,eAAsBuG,EAAAA,CAAcC,CAAAA,CAA4C,CAC9E,IAAMC,CAAAA,CAAkBD,CAAAA,CAAY,MAAMF,CAAAA,CAAmB,QAAQ,CAAE,SAAA,CAAAE,CAAU,CAAC,CAAA,CAAI,IAAA,CAEtF,OAAIC,CAAAA,CACK,CACL,SAAA,CAAW,MAAA,CAAOA,CAAAA,CAAgB,SAAS,CAAA,CAC3C,SAAA,CAAW,IAAI,IAAA,CAAKA,EAAgB,SAAS,CAAA,CAC7C,MAAA,CAAQA,CAAAA,CAAgB,MAAA,EAAU,IACpC,CAAA,CAGK,MAAMC,IACf,CAEA,eAAsBC,EAAAA,CAAeH,CAAAA,CAAmBI,CAAAA,CAAkB,CACxE,MAAMN,CAAAA,CAAmB,SAAA,CACvB,CAAE,SAAA,CAAAE,CAAU,CAAA,CACZ,CACE,IAAA,CAAM,CAAE,MAAA,CAAAI,CAAO,CACjB,CACF,EACF,CAEA,eAAsBC,EAAAA,CAAiBL,EAAmB,CACxD,MAAMF,CAAAA,CAAmB,SAAA,CACvB,CAAE,SAAA,CAAAE,CAAU,CAAA,CACZ,CACE,IAAA,CAAM,CAAE,MAAA,CAAQ,IAAK,CACvB,CACF,EACF,CAEA,eAAsBM,EAAAA,CAA0BF,CAAAA,CAAkB,CAChE,MAAMN,CAAAA,CAAmB,UAAA,CAAW,CAAE,OAAAM,CAAO,CAAC,EAChD,CAEA,eAAsBF,EAAAA,CAAcE,CAAAA,CAA0B,IAAA,CAAwB,CAGpF,IAAMJ,CAAAA,CAAYO,WAAAA,CAAY,EAAE,CAAA,CAAE,QAAA,CAAS,WAAW,CAAA,CAChDC,EAAM,IAAA,CAAK,GAAA,EAAI,CACfC,CAAAA,CAAY,IAAI,IAAA,CAAKD,CAAAA,CAAME,CAAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA,CAE7C,OAAA,MAAMZ,CAAAA,CAAmB,SAAA,CAAU,CACjC,UAAAE,CAAAA,CACA,SAAA,CAAW,IAAI,IAAA,CAAKQ,CAAG,CAAA,CACvB,SAAA,CAAAC,CAAAA,CACA,OAAAL,CACF,CAAC,CAAA,CAEM,CACL,SAAA,CAAAJ,CAAAA,CACA,SAAA,CAAAS,CAAAA,CACA,OAAAL,CACF,CACF,CAEA,eAAeO,EAAAA,CAAwBC,CAAAA,CAAkB,CACvD,IAAMJ,CAAAA,CAAM,IAAA,CAAK,GAAA,EAAI,CACfK,CAAAA,CAAe,IAAI,IAAA,CAAKL,CAAAA,CAAME,EAAK,IAAA,CAAK,CAAC,CAAC,CAAA,CAEhD,MAAMZ,CAAAA,CAAmB,SAAA,CACvB,CAAE,UAAWc,CAAAA,CAAQ,SAAU,CAAA,CAC/B,CACE,IAAA,CAAM,CACJ,cAAA,CAAgB,IAAI,KAAKJ,CAAG,CAAA,CAC5B,SAAA,CAAWK,CACb,CACF,CACF,EACF,CAEO,SAASC,EAAAA,CAAmBC,CAAAA,CAAef,CAAAA,CAAmB,CACnEe,CAAAA,CAAI,MAAA,CAAO,WAAA,CAAaf,EAAW,CACjC,QAAA,CAAU,IAAA,CACV,MAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAA,GAAa,YAAA,CACjC,SAAU,QAAA,CACV,IAAA,CAAM,GACR,CAAC,EACH,CAEA,IAAOgB,EAAAA,CAAQ,IAAI5I,CAAAA,CAAO,iBAAA,CAAmB,CAC3C,MAAA,CAAQ,CAAC0H,CAAkB,CAAA,CAC3B,SAAA,CAAW,CACT,IAAA,CAAM,eAAgBmB,CAAAA,CAAM,CAAE,OAAA,CAAAL,CAAAA,CAAS,IAAA,CAAAM,CAAK,CAAA,CAAG,CAG7C,OAAO,CACL,OAAA,CAAAN,CAAAA,CACA,IAAA,CAAAM,CAAAA,CACA,QAASC,CAAAA,EACX,CACF,CAAA,CACA,SAAA,CAAW,eAAgBF,CAAAA,CAAM,CAAE,QAAAL,CAAQ,CAAA,CAAG,CAExCA,CAAAA,EACF,MAAMD,EAAAA,CAAwBC,CAAO,EAEzC,CACF,CACF,CAAC,CAAA,CC3GM,IAAMQ,CAAAA,CAAkB,IAAI5F,CAAAA,CAAM,kBAAmB,CAC1D,MAAA,CAAQ,CACN,MAAA,CAAQhC,CAAAA,CAAO,MAAA,EAAO,CACtB,MAAA,CAAQA,EACL,KAAA,CACCA,CAAAA,CAAO,MAAA,CAAO,CACZ,OAAA,CAASA,CAAAA,CAAO,MAAA,EAAO,CACvB,SAAUA,CAAAA,CAAO,OAAA,EACnB,CAAC,CACH,CAAA,CACC,QAAA,EAAS,CACZ,OAAQA,CAAAA,CAAO,IAAA,CAAK,CAAC,QAAA,CAAU,UAAA,CAAY,SAAS,CAAC,CAAA,CAAE,UAAS,CAChE,SAAA,CAAWA,CAAAA,CAAO,MAAA,EAAO,CAAE,QAAA,EAAS,CACpC,QAAA,CAAUA,EAAO,MAAA,EAAO,CAAE,QAAA,EAAS,CACnC,SAAA,CAAWA,CAAAA,CAAO,MAAA,EAAO,CAAE,UAAS,CACpC,SAAA,CAAWA,CAAAA,CAAO,IAAA,EAAK,CACvB,UAAA,CAAYA,CAAAA,CAAO,IAAA,EAAK,CAAE,QAAA,EAAS,CACnC,SAAA,CAAWA,CAAAA,CAAO,IAAA,EAAK,CAAE,QAAA,GACzB,KAAA,CAAOA,CAAAA,CAAO,KAAA,CAAMA,CAAAA,CAAO,MAAA,EAAQ,CAAA,CAAE,QAAA,GACrC,WAAA,CAAaA,CAAAA,CAAO,MAAA,CAAO,CACzB,QAAA,CAAUA,CAAAA,CACP,MAAA,CAAO,CACN,KAAMA,CAAAA,CAAO,MAAA,EACf,CAAC,CAAA,CACA,QAAA,EAAS,CACZ,MAAA,CAAQA,CAAAA,CACL,MAAA,CAAO,CACN,EAAA,CAAIA,CAAAA,CAAO,MAAA,EACb,CAAC,EACA,QAAA,EAAS,CACZ,MAAA,CAAQA,CAAAA,CACL,MAAA,CAAO,CACN,EAAA,CAAIA,CAAAA,CAAO,QACb,CAAC,CAAA,CACA,QAAA,EACL,CAAC,CACH,CAAA,CACA,QAAS,CACP,CACE,GAAA,CAAK,CAAE,MAAA,CAAQ,CAAE,CAAA,CACjB,MAAA,CAAQ,IAAA,CACR,SAAA,CAAW,CAAE,MAAA,CAAQ,IAAA,CAAM,QAAA,CAAU,CAAE,CACzC,EACA,CACE,GAAA,CAAK,CAAE,gBAAA,CAAkB,CAAA,CAAG,MAAA,CAAQ,CAAE,CACxC,EACA,CACE,GAAA,CAAK,CAAE,uBAAA,CAAyB,CAAE,CAAA,CAClC,MAAA,CAAQ,IAAA,CACR,OAAQ,IACV,CAAA,CACA,CACE,GAAA,CAAK,CAAE,uBAAA,CAAyB,CAAE,CAAA,CAClC,OAAQ,IAAA,CACR,MAAA,CAAQ,IACV,CACF,CACF,CAAC,CAAA,CAEY6H,EAAAA,CAA2B,IAAI7F,CAAAA,CAAM,kCAAA,CAAoC,CACpF,MAAA,CAAQ,CACN,MAAA,CAAQhC,CAAAA,CAAO,MAAA,GACf,OAAA,CAASA,CAAAA,CAAO,IAAA,EAClB,CAAA,CACA,OAAA,CAAS,CACP,CACE,IAAK,CAAE,MAAA,CAAQ,CAAE,CAAA,CACjB,MAAA,CAAQ,IACV,CACF,CACF,CAAC,CAAA,CAEY8H,CAAAA,CAAoC,IAAI9F,CAAAA,CAAM,mCAAA,CAAqC,CAC9F,MAAA,CAAQ,CACN,MAAA,CAAQhC,CAAAA,CAAO,QAAA,EAAS,CACxB,KAAA,CAAOA,CAAAA,CAAO,MAAA,EAAO,CAAE,UAAS,CAChC,KAAA,CAAOA,CAAAA,CAAO,MAAA,EAAO,CACrB,SAAA,CAAWA,CAAAA,CAAO,IAAA,GAClB,SAAA,CAAWA,CAAAA,CAAO,IAAA,EACpB,CAAA,CACA,OAAA,CAAS,CACP,CACE,GAAA,CAAK,CAAE,KAAA,CAAO,CAAE,CAAA,CAChB,MAAA,CAAQ,IACV,CAAA,CACA,CACE,GAAA,CAAK,CAAE,SAAA,CAAW,CAAE,CAAA,CACpB,kBAAA,CAAoB,CACtB,CACF,CACF,CAAC,CAAA,CAEY+H,CAAAA,CAAgC,IAAI/F,CAAAA,CAAM,+BAAA,CAAiC,CACtF,MAAA,CAAQ,CACN,MAAA,CAAQhC,CAAAA,CAAO,QAAA,EAAS,CACxB,KAAA,CAAOA,CAAAA,CAAO,MAAA,EAAO,CAAE,QAAA,EAAS,CAChC,KAAA,CAAOA,CAAAA,CAAO,MAAA,EAAO,CACrB,SAAA,CAAWA,CAAAA,CAAO,MAAK,CACvB,SAAA,CAAWA,CAAAA,CAAO,IAAA,EACpB,CAAA,CACA,OAAA,CAAS,CACP,CACE,GAAA,CAAK,CAAE,KAAA,CAAO,CAAE,CAAA,CAChB,MAAA,CAAQ,IACV,CAAA,CACA,CACE,GAAA,CAAK,CAAE,SAAA,CAAW,CAAE,CAAA,CACpB,kBAAA,CAAoB,CACtB,CACF,CACF,CAAC,EC7HD,IAAMgI,EAAAA,CAAU,IAAI,GAAA,CACdC,EAAAA,CAA6B,CACjC,cAAe,IAAA,CACf,eAAA,CAAiB,IACnB,CAAA,CAEO,SAASC,EAAAA,CACdC,CAAAA,CACAC,CAAAA,CACA,CACAH,EAAAA,CAAa,aAAA,CAAgBG,CAAAA,CAAc,aAAA,CAC3CH,EAAAA,CAAa,eAAA,CAAkBG,CAAAA,CAAc,eAAA,CAE7C,OAAW,CAACvJ,CAAAA,CAAMwJ,CAAU,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQF,CAAK,CAAA,CACnDH,EAAAA,CAAQ,GAAA,CAAInJ,CAAAA,CAAMwJ,CAAU,EAEhC,CAEO,SAASC,EAAAA,EAA0B,CACxC,OAAOL,EAAAA,CAAa,eAAA,CAAkB,CAACA,EAAAA,CAAa,eAAe,CAAA,CAAI,EACzE,CAEO,SAASM,EAAAA,EAA+B,CAC7C,OAAON,EAAAA,CAAa,aAAA,CAAgB,CAACA,GAAa,aAAa,CAAA,CAAI,EACrE,CAMO,SAASO,EAAAA,CAAcL,CAAAA,CAAeM,CAAAA,CAAmC,CAC9E,IAAMC,CAAAA,CAAoBD,CAAAA,CAAoB,IAAA,CAC3CE,CAAAA,EAAe,CAACC,GAAcT,CAAAA,CAAOQ,CAAU,CAClD,CAAA,CAEA,GAAID,CAAAA,CACF,MAAM,IAAI,MAAM,CAAA,qCAAA,EAAwCA,CAAiB,CAAA,CAAA,CAAG,CAEhF,CAEO,SAASE,EAAAA,CAAcT,CAAAA,CAAeQ,EAAwB,CACnE,IAAA,IAAWE,CAAAA,IAAQV,CAAAA,CAGjB,GAFmBH,EAAAA,CAAQ,GAAA,CAAIa,CAAI,CAAA,EAEnB,WAAA,EAAa,QAAA,CAASF,CAAU,CAAA,CAC9C,OAAO,KAAA,CAIX,OAAO,MACT,CC7CA,eAAsBG,CAAAA,CACpBtC,CAAAA,CACqE,CACrE,IAAMY,CAAAA,CAAU,MAAMb,GAAcC,CAAS,CAAA,CAEvCuC,CAAAA,CAAU3B,CAAAA,CAAQ,MAAA,CACpB,MAAMQ,CAAAA,CAAgB,OAAA,CAAQ,CAC5B,GAAA,CAAK,IAAItD,QAAAA,CAAS8C,CAAAA,CAAQ,MAAM,CAAA,CAChC,MAAA,CAAQ,CAAE,KAAM,CAAC,SAAA,CAAW,UAAU,CAAE,CAC1C,CAAC,CAAA,CACD,IAAA,CACEM,EAAOqB,CAAAA,CACT,CACE,EAAA,CAAIA,CAAAA,CAAQ,GAAA,CAAI,QAAA,EAAS,CACzB,MAAA,CAAQA,EAAQ,MAAA,CAChB,KAAA,CAAOA,CAAAA,CAAQ,KAAA,EAAS,EAAC,CACzB,OAAA,CAAUF,CAAAA,EAAAA,CAAkBE,EAAQ,KAAA,EAAS,EAAC,EAAG,QAAA,CAASF,CAAI,CAAA,CAC9D,WAAA,CAAcA,CAAAA,EAAiB,CAC7B,GAAI,CAAA,CAAEE,CAAAA,CAAQ,KAAA,EAAS,EAAC,EAAG,QAAA,CAASF,CAAI,CAAA,CACtC,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyBA,CAAI,CAAA,UAAA,CAAY,CAE7D,EACA,SAAA,CAAWE,CAAAA,CAAQ,SAAA,EAAa,MAAA,CAChC,QAAA,CAAUA,CAAAA,CAAQ,QAAA,EAAY,MAAA,CAC9B,UAAWA,CAAAA,CAAQ,SAAA,EAAa,MAClC,CAAA,CACA,IAAA,CAEEZ,CAAAA,CAAQT,CAAAA,CAAOa,EAAAA,EAA6B,CAAID,EAAAA,EAAwB,CAE9E,OAAO,CACL,IAAA,CAAAZ,CAAAA,CACA,OAAA,CAAAN,EACA,KAAA,CAAAe,CACF,CACF,CCxCA,IAAOa,EAAAA,CAAQ,IAAIpK,CAAAA,CAAO,SAAA,CAAW,CACnC,YAAA,CAAc,CACZ,UAAA,CAAY,CACV,IAAA,CAAM,QAAA,CACN,QAAA,CAAU,KAAA,CACV,OAAA,CAAS,EACX,CAAA,CACA,eAAA,CAAiB,CACf,IAAA,CAAM,QAAA,CACN,QAAA,CAAU,KAAA,CACV,OAAA,CAAS,EACX,CAAA,CACA,WAAY,CACV,IAAA,CAAM,QAAA,CACN,QAAA,CAAU,IAAA,CACV,OAAA,CAAS,EACX,CAAA,CACA,WAAY,CACV,IAAA,CAAM,QAAA,CACN,QAAA,CAAU,IAAA,CACV,OAAA,CAAS,EACX,CAAA,CACA,cAAe,CACb,IAAA,CAAM,SAAA,CACN,QAAA,CAAU,KAAA,CACV,OAAA,CAAS,KACX,CACF,CACF,CAAC,CAAA,CC1BD,IAAI8D,CAAAA,CAA6B,IAAA,CAEjC,eAAsBuG,EAAAA,EAAU,CAC9B,GAAIvG,CAAAA,CAAQ,OAAOA,CAAAA,CAEnB,IAAMwG,CAAAA,CAAaC,CAAAA,EAAc,CACjC,GAAI,CAACD,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,wBAAwB,CAAA,CAG1C,IAAME,CAAAA,CAAcJ,GAAa,SAAA,CAAU,iBAAiB,CAAA,CAE5DtG,CAAAA,CAAS,IAAI2G,WAAAA,CAAYH,CAAAA,CAAY,CACnC,UAAA,CAAY,CACV,IAAA,CAAM,WAAA,CACN,OAAA,CAASI,CAAAA,CAAY,OACvB,CAAA,CACA,gBAAiB,IAAA,CACjB,WAAA,CAAAF,CACF,CAAC,CAAA,CAED,GAAI,CAEF,OAAA,MAAM1G,EAAO,OAAA,EAAQ,CAErB,MAAMA,CAAAA,CAAO,EAAA,CAAG,OAAO,CAAA,CAAE,OAAA,CAAQ,CAAE,IAAA,CAAM,CAAE,CAAC,CAAA,CAC5C,OAAA,CAAQ,GAAA,CAAI,gEAAgE,CAAA,CACrEA,CACT,CAAA,MAAS6G,CAAAA,CAAK,CACZ,MAAA,OAAA,CAAQ,KAAA,CAAMA,CAAG,CAAA,CACjB7G,EAAS,IAAA,CACH6G,CACR,CACF,CAEO,SAASJ,CAAAA,EAAgB,CAC9B,OAAOH,GAAa,SAAA,CAAU,YAAY,CAAA,EAAK,MACjD,CAEO,SAASQ,EAAAA,EAAY,CAC1B,OAAO9G,CACT,CCmBO,IAAM+G,EAAAA,CAAN,KAA4B,CAIjC,WAAA,CAAYtH,CAAAA,CAA2B,CACrC,IAAA,CAAK,KAAA,CAAQA,CAAAA,CAAO,KAAA,CACpB,IAAA,CAAK,KAAA,CAAQA,CAAAA,CAAO,MACtB,CACF,ECxEO,SAASuH,EAAAA,EAAW,CACzB,OAAO,OAAO,MAAA,EAAW,QAC3B,CAEO,SAASC,CAAAA,EAAgB,CAC9B,GAAI,CAACD,EAAAA,EAAS,CACZ,MAAM,IAAI,KAAA,CAAM,gDAAgD,CAEpE,CAEO,SAASE,EAAAA,CAAWC,CAAAA,CAAc,CACvC,OAAOA,CAAAA,CACJ,OAAA,CAAQ,UAAA,CAAY,EAAE,CAAA,CACtB,OAAA,CAAQ,MAAA,CAAQ,GAAG,CAAA,CACnB,IAAA,EACL,CCTA,IAAMC,EAAAA,CAA2C,EAAC,CAE3C,SAASC,EAAAA,CAAiClL,CAAAA,CAAcmL,CAAAA,CAAgC,CAC7F,OAAAL,CAAAA,EAAc,CACdM,EAAAA,CAAmBpL,CAAI,CAAA,CAChBqL,EAAAA,CAAsB,OAAA,CAASrL,CAAAA,CAAMmL,CAAS,CACvD,CAEO,SAASG,EAAAA,CAAoCtL,CAAAA,CAAcmL,CAAAA,CAAgC,CAChG,OAAAL,CAAAA,EAAc,CACdM,EAAAA,CAAmBpL,CAAI,CAAA,CAChBqL,EAAAA,CAAsB,UAAA,CAAYrL,CAAAA,CAAMmL,CAAS,CAC1D,CAEO,SAASI,EAAAA,CACdvL,CAAAA,CACAmL,CAAAA,CACA,CACA,OAAAL,GAAc,CACdU,EAAAA,CAAyBxL,CAAI,CAAA,CACtBqL,EAAAA,CAAsB,OAAA,CAASrL,CAAAA,CAAMmL,CAAS,CACvD,CAEO,SAASM,EAAAA,CACdzL,CAAAA,CACAmL,CAAAA,CACA,CACA,OAAAL,GAAc,CACdU,EAAAA,CAAyBxL,CAAI,CAAA,CACtBqL,EAAAA,CAAsB,UAAA,CAAYrL,CAAAA,CAAMmL,CAAS,CAC1D,CAEA,SAASC,EAAAA,CAAmBpL,CAAAA,CAAc,CACxC,GAAIA,CAAAA,CAAK,WAAA,GAAc,UAAA,CAAW,UAAU,CAAA,CAC1C,MAAM,IAAI,KAAA,CAAM,CAAA,6DAAA,EAAgEA,CAAI,CAAA,CAAA,CAAG,CAE3F,CAEA,SAASwL,EAAAA,CAAyBxL,CAAAA,CAAc,CAC9C,GAAI,CAACA,CAAAA,CAAK,WAAA,EAAY,CAAE,UAAA,CAAW,UAAU,CAAA,CAC3C,MAAM,IAAI,MAAM,CAAA,yDAAA,EAA4DA,CAAI,CAAA,CAAA,CAAG,CAEvF,CAEA,SAASqL,EAAAA,CACPK,CAAAA,CACA1L,EACAmL,CAAAA,CACA,CAGA,GAFAL,CAAAA,EAAc,CAEVG,EAAAA,CAAQjL,CAAI,CAAA,CACd,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqBA,CAAI,CAAA,qBAAA,CAAuB,CAAA,CAGlE,IAAM2L,CAAAA,CAAU,OAAOR,CAAAA,EAAc,UAAA,CAAaA,CAAAA,CAAYA,CAAAA,CAAU,OAAA,CAClES,CAAAA,CAAc,OAAOT,CAAAA,EAAc,WAAa,EAAC,CAAKA,CAAAA,CAAU,WAAA,EAAe,EAAC,CACtFF,EAAAA,CAAQjL,CAAI,EAAI,CAAE,IAAA,CAAA0L,CAAAA,CAAM,IAAA,CAAA1L,CAAAA,CAAM,OAAA,CAAA2L,CAAAA,CAAS,WAAA,CAAAC,CAAY,EACrD,CAEA,eAAsBC,EAAAA,CAAU7L,CAAAA,CAAc4I,CAAAA,CAAYkD,CAAAA,CAAkB,CAC1EhB,CAAAA,EAAc,CAEd,IAAMiB,CAAAA,CAASd,EAAAA,CAAQjL,CAAI,CAAA,CAC3B,GAAI,CAAC+L,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB/L,CAAI,CAAA,iBAAA,CAAmB,CAAA,CAE9D,GAAM,CAAE,IAAA,CAAA0L,CAAAA,CAAM,OAAA,CAAAC,CAAQ,CAAA,CAAII,CAAAA,CAEpBC,CAAAA,CAAcC,CAAAA,CAAiB,QAAA,CAAU,CAAA,OAAA,EAAUjM,CAAI,CAAA,CAAA,CAAI,CAAE,IAAA,CAAA0L,CAAAA,CAAM,KAAA9C,CAAK,CAAC,CAAA,CAE3EsD,CAAAA,CACJ,GAAI,CACFvC,EAAAA,CAAcmC,CAAAA,CAAQ,MAAOC,CAAAA,CAAO,WAAW,CAAA,CAC/CG,CAAAA,CAAW,MAAMP,CAAAA,CAAQ/C,CAAAA,CAAMkD,CAAO,EACxC,CAAA,MAAShJ,CAAAA,CAAO,CAEd,MAAAkJ,CAAAA,CAAY,GAAA,CAAI,OAAO,CAAA,CACjBlJ,CACR,CAEA,OAAAkJ,CAAAA,CAAY,GAAA,EAAI,CAETE,CACT,CAMA,eAAsBC,EAAAA,CAAcnM,CAAAA,CAAc4I,CAAAA,CAAYkD,CAAAA,CAAqC,CACjGhB,CAAAA,EAAc,CAEd,IAAMiB,EAASd,EAAAA,CAAQjL,CAAI,CAAA,CAC3B,GAAI,CAAC+L,CAAAA,CACH,MAAM,IAAI,MAAM,CAAA,kBAAA,EAAqB/L,CAAI,CAAA,iBAAA,CAAmB,CAAA,CAE9D,GAAM,CAAE,IAAA,CAAA0L,CAAAA,CAAM,OAAA,CAAAC,CAAQ,CAAA,CAAII,CAAAA,CAE1B,GAAIL,CAAAA,GAAS,OAAA,CACX,MAAM,IAAI,KAAA,CAAM,6CAA6C,CAAA,CAG/D,IAAMM,CAAAA,CAAcC,CAAAA,CAAiB,QAAA,CAAU,CAAA,OAAA,EAAUjM,CAAI,CAAA,KAAA,CAAA,CAAS,CAAE,IAAA,CAAA0L,CAAAA,CAAM,IAAA,CAAA9C,CAAK,CAAC,CAAA,CAEhFhD,EACJ,GAAI,CAKF,GAJA+D,EAAAA,CAAcmC,CAAAA,CAAQ,KAAA,CAAOC,CAAAA,CAAO,WAAW,CAAA,CAE/CnG,CAAAA,CAAS,MAAM+F,CAAAA,CAAQ/C,CAAAA,CAAMkD,CAAO,CAAA,CAEhC,EAAElG,aAAkBgF,EAAAA,CAAAA,CACtB,MAAM,IAAI,KAAA,CACR,CAAA,wBAAA,EAA2B5K,CAAI,CAAA,2GAAA,CACjC,CAEJ,OAAS8C,CAAAA,CAAO,CACd,MAAAkJ,CAAAA,CAAY,GAAA,CAAI,OAAO,CAAA,CACjBlJ,CACR,CAEA,OAAAkJ,CAAAA,CAAY,GAAA,EAAI,CAETpG,CACT,CCrHA,IAAMwG,EAAAA,CAAsB,IAAI,GAAA,CAEhC,SAASC,EAAAA,CAAcC,CAAAA,CAAiD,CACtE,IAAIC,CAAAA,CAAOH,GAAoB,GAAA,CAAIE,CAAAA,CAAO,EAAE,CAAA,CAC5C,OAAKC,CAAAA,GACHA,CAAAA,CAAO,IAAI,IACXH,EAAAA,CAAoB,GAAA,CAAIE,CAAAA,CAAO,EAAA,CAAIC,CAAI,CAAA,CAAA,CAElCA,CACT,CAEA,eAAsBC,EAAAA,CAAyBF,CAAAA,CAAgBG,CAAAA,CAAkB,CAC/E,IAAMC,CAAAA,CAAS1F,CAAAA,CACZ,MAAA,CAAO,CACN,cAAA,CAAgBA,CAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAChC,OAAQA,CAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CACxB,IAAA,CAAMA,CAAAA,CAAE,OAAOA,CAAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAA,CAAQ,EAAE,CAAA,CACtC,UAAWA,CAAAA,CAAE,MAAA,EAAO,CAAE,OAAA,EAAQ,CAC9B,UAAA,CAAYA,CAAAA,CACT,MAAA,CAAO,CACN,WAAA,CAAaA,CAAAA,CAAE,MAAA,EAAO,CACtB,YAAA,CAAcA,CAAAA,CAAE,MAAA,EAAO,CACvB,YAAaA,CAAAA,CAAE,MAAA,EAAO,CACtB,YAAA,CAAcA,CAAAA,CAAE,MAAA,EAAO,CACvB,UAAA,CAAYA,EAAE,MAAA,EAAO,CACrB,WAAA,CAAaA,CAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAC1B,CAAC,CAAA,CACA,QAAA,EACL,CAAC,CAAA,CACA,SAAA,CAAUyF,CAAO,CAAA,CACpB,GAAI,CAACC,CAAAA,CAAO,OAAA,CAAS,CACnBJ,CAAAA,CAAO,IAAA,CAAK,gBAAA,CAAkB,CAC5B,cAAA,CAAgB,IAAA,CAChB,KAAA,CAAO,CAAA,iBAAA,EAAoBI,CAAAA,CAAO,KAAA,CAAM,OAAO,CAAA,CACjD,CAAC,CAAA,CACD,MACF,CACA,GAAM,CAAE,cAAA,CAAAC,CAAAA,CAAgB,MAAA,CAAAZ,EAAQ,IAAA,CAAAnD,CAAAA,CAAM,SAAA,CAAAjB,CAAAA,CAAW,UAAA,CAAAiF,CAAW,CAAA,CAAIF,CAAAA,CAAO,IAAA,CAEjEH,CAAAA,CAAOF,EAAAA,CAAcC,CAAM,CAAA,CAG3BO,CAAAA,CAAcN,CAAAA,CAAK,GAAA,CAAII,CAAc,CAAA,CAC3C,GAAIE,CAAAA,CACF,GAAIA,CAAAA,CAAY,OAAA,CACd,GAAI,CACFA,EAAY,OAAA,GACd,CAAA,MAASnC,CAAAA,CAAK,CACZ,OAAA,CAAQ,KAAA,CAAM,sDAAA,CAAwDA,CAAG,EAC3E,CAAA,KAGAmC,CAAAA,CAAY,OAAA,CAAU,IAAA,CAK1B,IAAMC,CAAAA,CAAmC,CAAE,OAAA,CAAS,IAAK,CAAA,CACzDP,CAAAA,CAAK,GAAA,CAAII,CAAAA,CAAgBG,CAAY,CAAA,CAErC,GAAI,CACF,GAAM,CAAE,OAAA,CAAAvE,CAAAA,CAAS,IAAA,CAAAM,CAAAA,CAAM,KAAA,CAAAS,CAAM,CAAA,CAAI,MAAMW,CAAAA,CAAatC,CAAAA,EAAa,IAAI,CAAA,CAE/DmE,CAAAA,CAAmB,CACvB,QAAAvD,CAAAA,CACA,IAAA,CAAAM,CAAAA,CACA,KAAA,CAAAS,CAAAA,CACA,UAAA,CAAYsD,CAAAA,EAAc,CACxB,YAAa,CAAA,CACb,YAAA,CAAc,CAAA,CACd,WAAA,CAAa,CAAA,CACb,YAAA,CAAc,CAAA,CACd,UAAA,CAAY,EACZ,WAAA,CAAa,IACf,CAAA,CACA,cAAA,CAAgB,CACd,EAAA,CAAIN,CAAAA,CAAO,SAAA,CAAU,QACrB,SAAA,CAAWA,CAAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,YAAY,CAClD,CACF,CAAA,CAEMS,EAAW,MAAMZ,EAAAA,CAAcJ,CAAAA,CAAQnD,CAAAA,CAAMkD,CAAO,CAAA,CAEpDkB,CAAAA,CAAe,SAAY,CAC/B,IAAMC,CAAAA,CAAOC,GAAAA,CAAe,MAAMH,CAAAA,CAAS,KAAA,EAAO,EAC9CD,CAAAA,CAAa,OAAA,EAGjBR,CAAAA,CAAO,IAAA,CAAK,eAAA,CAAiB,CAC3B,cAAA,CAAAK,CAAAA,CACA,KAAAM,CAAAA,CACA,OAAA,CAASE,GAAAA,CAAmBF,CAAI,CAClC,CAAC,EACH,CAAA,CAGIG,EAAmB,CAAA,CAAA,CACnBC,CAAAA,CAAa,CAAA,CAAA,CAEXC,CAAAA,CAAwB,IAAM,CAC9BR,CAAAA,CAAa,OAAA,EAAW,CAACM,CAAAA,EAAoBC,CAAAA,GAGjDD,CAAAA,CAAmB,CAAA,CAAA,CACnBC,CAAAA,CAAa,CAAA,CAAA,CACbL,CAAAA,GACG,KAAA,CAAOtC,CAAAA,EAAQ,CACVoC,CAAAA,CAAa,OAAA,GAGjB,OAAA,CAAQ,KAAA,CAAM,CAAA,oCAAA,EAAuCf,CAAM,CAAA,CAAA,CAAA,CAAKrB,CAAG,CAAA,CACnE4B,CAAAA,CAAO,IAAA,CAAK,gBAAA,CAAkB,CAC5B,cAAA,CAAAK,EACA,KAAA,CAAOjC,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CACxD,CAAC,CAAA,EACH,CAAC,CAAA,CACA,OAAA,CAAQ,IAAM,CACb2C,CAAAA,CAAa,GAEbC,CAAAA,GACF,CAAC,CAAA,EACL,CAAA,CAEMC,CAAAA,CAAUR,CAAAA,CAAS,KAAA,CAAM,CAC7B,OAAA,CAAS,IAAM,CAMbK,CAAAA,CAAmB,CAAA,CAAA,CACnBE,CAAAA,GACF,CACF,CAAC,CAAA,CAED,GAAIR,CAAAA,CAAa,OAAA,CAAS,CAExB,GAAIS,CAAAA,CACF,GAAI,CACFA,CAAAA,GACF,CAAA,MAAS7C,CAAAA,CAAK,CACZ,OAAA,CAAQ,KAAA,CAAM,8DAAA,CAAgEA,CAAG,EACnF,CAEF,MACF,CAEAoC,CAAAA,CAAa,OAAA,CAAUS,CAAAA,EAAW,IAAA,CAGlCD,IACF,CAAA,MAASxK,CAAAA,CAAO,CACdyJ,CAAAA,CAAK,MAAA,CAAOI,CAAc,CAAA,CAC1B,QAAQ,KAAA,CAAM,CAAA,qBAAA,EAAwBZ,CAAM,CAAA,CAAA,CAAA,CAAKjJ,CAAK,CAAA,CACtDwJ,CAAAA,CAAO,IAAA,CAAK,gBAAA,CAAkB,CAC5B,cAAA,CAAAK,CAAAA,CACA,KAAA,CAAO7J,CAAAA,YAAiB,KAAA,CAAQA,CAAAA,CAAM,QAAU,MAAA,CAAOA,CAAK,CAC9D,CAAC,EACH,CACF,CAEO,SAAS0K,GAA2BlB,CAAAA,CAAgBG,CAAAA,CAAkB,CAC3E,IAAMC,CAAAA,CAAS1F,CAAAA,CACZ,MAAA,CAAO,CACN,eAAgBA,CAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,CAAC,CAClC,CAAC,CAAA,CACA,SAAA,CAAUyF,CAAO,CAAA,CACpB,GAAI,CAACC,CAAAA,CAAO,OAAA,CAAS,CACnB,QAAQ,IAAA,CAAK,CAAA,yCAAA,EAA4CA,CAAAA,CAAO,KAAA,CAAM,OAAO,CAAA,CAAE,CAAA,CAC/E,MACF,CACA,GAAM,CAAE,cAAA,CAAAC,CAAe,CAAA,CAAID,CAAAA,CAAO,IAAA,CAE5BH,CAAAA,CAAOH,GAAoB,GAAA,CAAIE,CAAAA,CAAO,EAAE,CAAA,CAC9C,GAAI,CAACC,CAAAA,CAAM,OAEX,IAAMkB,CAAAA,CAAMlB,CAAAA,CAAK,GAAA,CAAII,CAAc,CAAA,CACnC,GAAIc,CAAAA,CAAK,CACP,GAAIA,CAAAA,CAAI,OAAA,CACN,GAAI,CACFA,CAAAA,CAAI,OAAA,GACN,OAAS/C,CAAAA,CAAK,CACZ,OAAA,CAAQ,KAAA,CAAM,+BAAA,CAAiCA,CAAG,EACpD,CAAA,KAEA+C,EAAI,OAAA,CAAU,IAAA,CAEhBlB,CAAAA,CAAK,MAAA,CAAOI,CAAc,EAC5B,CACF,CAEO,SAASe,EAAAA,CAA0BpB,CAAAA,CAAgB,CACxD,IAAMC,CAAAA,CAAOH,EAAAA,CAAoB,GAAA,CAAIE,CAAAA,CAAO,EAAE,CAAA,CAC9C,GAAIC,CAAAA,CAAM,CAER,IAAA,IAAWkB,CAAAA,IAAOlB,CAAAA,CAAK,MAAA,GACrB,GAAIkB,CAAAA,CAAI,OAAA,CACN,GAAI,CACFA,CAAAA,CAAI,OAAA,GACN,OAAS/C,CAAAA,CAAK,CACZ,OAAA,CAAQ,KAAA,CAAM,6CAAA,CAA+CA,CAAG,EAClE,CAAA,KAEA+C,CAAAA,CAAI,OAAA,CAAU,IAAA,CAGlBrB,EAAAA,CAAoB,MAAA,CAAOE,CAAAA,CAAO,EAAE,EACtC,CACF,CC9MA,IAAIqB,EAAAA,CAAoC,IAAA,CAElCC,EAAAA,CAAa,oBAAA,CACbC,EAAAA,CAAsB,EAAA,CAE5B,eAAsBC,EAAAA,CAAK,CACzB,UAAA,CAAAC,CAAAA,CACA,QAAA,CAAAvN,CACF,CAAA,CAGG,CACD,IAAMwN,CAAAA,CAAgBrD,EAAAA,EAAU,CAC1BsD,CAAAA,CAAkB,CAAA,CAAQvN,GAAAA,CAAU,uBAAuB,CAAA,CAEjE,OAAA,CAAQ,GAAA,CAAI,kCAAkC,CAAA,CAE9C,IAAIwN,CAAAA,CAA+C,IAAA,CAEnD,GAAID,GAAmBD,CAAAA,CAAe,CACpCE,CAAAA,CAAkBF,CAAAA,CAAc,EAAA,EAAG,CAAE,UAAA,CAAWJ,EAAU,EAE1D,GAAI,CACF,MAAMM,CAAAA,CAAgB,WAAA,CACpB,CAAE,SAAA,CAAW,CAAE,EACf,CAAE,kBAAA,CAAoBL,EAAAA,CAAqB,UAAA,CAAY,CAAA,CAAK,CAC9D,EACF,CAAA,MAAS/K,CAAAA,CAAgB,CACvB,GAAIA,CAAAA,YAAiB,KAAA,EAAS,MAAA,GAAUA,CAAAA,EAAUA,CAAAA,CAA2B,OAAS,EAAA,CACpF,GAAI,CACF,MAAMoL,CAAAA,CAAgB,SAAA,CAAU,aAAa,CAAA,CAC7C,MAAMA,CAAAA,CAAgB,WAAA,CACpB,CAAE,SAAA,CAAW,CAAE,CAAA,CACf,CAAE,kBAAA,CAAoBL,GAAqB,UAAA,CAAY,CAAA,CAAK,CAC9D,EACF,CAAA,MAASM,CAAAA,CAAqB,CAC5B,OAAA,CAAQ,MACN,+DAAA,CACAA,CACF,EACF,CAAA,KAEA,OAAA,CAAQ,KAAA,CAAM,6DAAA,CAA+DrL,CAAK,EAEtF,CACF,CAEA6K,EAAAA,CAAe,IAAIS,MAAAA,CAAaL,CAAAA,CAAY,CAC1C,IAAA,CAAM,CACJ,MAAA,CAAQ,GAAA,CACR,OAAA,CAAS,CAAC,KAAA,CAAO,MAAM,CACzB,CAAA,CACA,QAASG,CAAAA,CAAkBG,aAAAA,CAAcH,CAAe,CAAA,CAAI,MAAA,CAC5D,UAAA,CAAY,CAAC,WAAW,CAAA,CACxB,iBAAA,CAAmB,KACrB,CAAC,CAAA,CAEDP,EAAAA,CAAa,EAAA,CAAG,OAAA,CAAU7K,GAAU,CAClC,OAAA,CAAQ,KAAA,CAAM,kBAAA,CAAoBA,CAAK,EACzC,CAAC,CAAA,CAED6K,GAAa,GAAA,CAAI,MAAOrB,CAAAA,CAAQgC,CAAAA,GAAS,CACvC,IAAMC,CAAAA,CAAQjC,CAAAA,CAAO,UAAU,IAAA,CAAK,KAAA,CAEpC,GAAI,CACFA,CAAAA,CAAO,IAAA,CAAO,MAAMrC,CAAAA,CAAasE,CAAK,EACxC,CAAA,OAAE,CACAD,CAAAA,GACF,CACF,CAAC,EAEDX,EAAAA,CAAa,EAAA,CAAG,YAAA,CAAerB,CAAAA,EAAmB,CAChDA,CAAAA,CAAO,EAAA,CAAG,YAAA,CAAc,IAAM,CAC5BoB,EAAAA,CAA0BpB,CAAM,EAClC,CAAC,CAAA,CAEDA,CAAAA,CAAO,EAAA,CAAG,cAAe,MAAOkC,CAAAA,EAAwB,CACtD,GAAM,CAACC,CAAQ,CAAA,CAAID,CAAAA,CAAY,KAAA,CAAM,GAAG,CAAA,CACpCE,CAAAA,CAAa,KAAA,CAEjB,IAAA,IAAWC,CAAAA,IAAWnO,CAAAA,CACpB,GAAImO,CAAAA,CAAQ,QAAA,GAAaF,CAAAA,CAAU,CAAA,CAC7B,CAACE,CAAAA,CAAQ,gBAAA,EAAqB,MAAMA,EAAQ,gBAAA,CAAiBrC,CAAAA,CAAO,IAAI,CAAA,IAC1EA,CAAAA,CAAO,IAAA,CAAKkC,CAAW,CAAA,CACvBE,EAAa,IAAA,CACbpC,CAAAA,CAAO,IAAA,CAAK,eAAA,CAAiBkC,CAAW,CAAA,CAAA,CAE1C,KACF,CAGGE,GACHpC,CAAAA,CAAO,IAAA,CAAK,WAAA,CAAa,CAAE,OAAA,CAASkC,CAAAA,CAAa,KAAA,CAAO,eAAgB,CAAC,EAE7E,CAAC,CAAA,CAEDlC,CAAAA,CAAO,EAAA,CAAG,cAAA,CAAiBkC,CAAAA,EAAwB,CACjDlC,EAAO,KAAA,CAAMkC,CAAW,CAAA,CACxB,OAAA,CAAQ,GAAA,CAAI,CAAA,KAAA,EAAQlC,CAAAA,CAAO,EAAE,iBAAiBkC,CAAW,CAAA,CAAE,CAAA,CAC3DlC,CAAAA,CAAO,IAAA,CAAK,aAAA,CAAekC,CAAW,EACxC,CAAC,CAAA,CAEDlC,CAAAA,CAAO,EAAA,CAAG,oBAAA,CAAuBG,CAAAA,EAAYD,EAAAA,CAAyBF,CAAAA,CAAQG,CAAO,CAAC,CAAA,CACtFH,CAAAA,CAAO,EAAA,CAAG,sBAAA,CAAyBG,CAAAA,EAAYe,EAAAA,CAA2BlB,CAAAA,CAAQG,CAAO,CAAC,EAC5F,CAAC,CAAA,CAED,OAAA,CAAQ,GAAA,CAAI,8BAA8B,EAC5C,CAEA,SAASmC,EAAAA,CAAa,CAAE,QAAA,CAAAH,CAAAA,CAAU,EAAA,CAAA3I,CAAAA,CAAI,IAAA,CAAAmH,CAAK,CAAA,CAA8C,CACvFU,EAAAA,EAAc,EAAA,CAAG,CAAA,EAAGc,CAAQ,CAAA,CAAA,EAAI3I,CAAE,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK2I,CAAAA,CAAUxB,CAAI,EAC3D,CAEA,IAAO4B,GAAQ,CACb,IAAA,CAAAf,EAAAA,CACA,SAAA,CAAAc,EACF,CAAA,CChIA,eAAsBE,EAAAA,CAAkBC,EAAiC,CACvE,IAAMC,CAAAA,CAAaD,CAAAA,CAAM,WAAA,EAAY,CAAE,IAAA,EAAK,CAAE,KAAA,CAAM,GAAG,CAAA,CACvD,GAAIC,CAAAA,CAAW,MAAA,GAAW,CAAA,CACxB,OAAO,OAGT,IAAMC,CAAAA,CAASD,CAAAA,CAAW,CAAC,CAAA,CAE3B,OAAO,CAAA,CADQ,MAAMhG,GAAyB,OAAA,CAAQ,CAAE,MAAA,CAAAiG,CAAO,CAAC,CAElE,CAEO,IAAMC,GAAgC,CAC3C,QAAA,CAAU7G,CAAAA,CAAK,IAAA,CAAK,CAAC,CAAA,CACrB,MAAM,OAAA,EAAU,CACd,IAAM6D,CAAAA,CAAW,MAAM,KAAA,CACrB,mEACF,CAAA,CAEA,GAAI,CAACA,EAAS,EAAA,CACZ,MAAM,IAAI,KAAA,CAAM,CAAA,KAAA,EAAQA,CAAAA,CAAS,MAAM,CAAA,EAAA,EAAKA,EAAS,UAAU,CAAA,CAAE,CAAA,CAKnE,IAAMiD,CAAAA,CAAAA,CAFc,MAAMjD,CAAAA,CAAS,IAAA,IAGhC,KAAA,CAAM;AAAA,CAAI,CAAA,CACV,IAAK+C,CAAAA,EAAWA,CAAAA,CAAO,MAAK,CAAE,WAAA,EAAa,CAAA,CAC3C,MAAA,CAAQA,CAAAA,EAAWA,EAAO,MAAA,CAAS,CAAC,EAEjC9G,CAAAA,CAAM,IAAI,KAGViH,CAAAA,CAAY,GAAA,CAClB,IAAA,IAAS,CAAA,CAAI,CAAA,CAAG,CAAA,CAAID,EAAQ,MAAA,CAAQ,CAAA,EAAKC,EAAW,CAClD,IAAMC,EAAQF,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAG,CAAA,CAAIC,CAAS,CAAA,CAE5C,GAAI,CACF,MAAMpG,GAAyB,UAAA,CAC7BqG,CAAAA,CAAM,IAAKJ,CAAAA,GAAY,CACrB,MAAA,CAAAA,CAAAA,CACA,OAAA,CAAS9G,CACX,EAAE,CACJ,EACF,OAASrF,CAAAA,CAAgB,CAGrBA,GACA,OAAOA,CAAAA,EAAU,QAAA,EACjB,MAAA,GAAUA,CAAAA,EACVA,CAAAA,CAAM,KAIV,CACF,CACF,CACF,CAAA,CCxDO,IAAMwM,EAAAA,CAAoB,CAAA,CACpBC,CAAAA,CAAoB,EAAA,CAG3BC,EAAAA,CAAyBC,GAC7BzI,CAAAA,CACG,MAAA,EAAO,CACP,IAAA,EAAK,CACL,GAAA,CAAIyI,EAAK,GAAA,EAAO,CAAA,CAAG,CAAE,OAAA,CAAS,CAAA,iBAAA,EAAoBA,CAAAA,CAAK,KAAO,CAAC,CAAA,WAAA,CAAc,CAAC,CAAA,CAC9E,GAAA,CAAIA,EAAK,GAAA,CAAK,CAAE,OAAA,CAAS,CAAA,gBAAA,EAAmBA,CAAAA,CAAK,GAAG,aAAc,CAAC,CAAA,CAElEC,GAAyBD,CAAAA,EAC7BzI,CAAAA,CACG,QAAO,CACP,IAAA,EAAK,CACL,GAAA,CAAIyI,CAAAA,CAAK,GAAA,CAAK,CAAE,OAAA,CAAS,CAAA,gBAAA,EAAmBA,EAAK,GAAG,CAAA,WAAA,CAAc,CAAC,CAAA,CACnE,SAAA,CAAWE,CAAAA,EAASA,CAAAA,GAAQ,EAAA,CAAK,MAAA,CAAYA,CAAI,CAAA,CACjD,QAAA,EAAS,CAGRC,EAAAA,CAAsB5I,CAAAA,CACzB,MAAA,CAAO,CACN,SAAA,CAAW0I,EAAAA,CAAsB,CAAE,GAAA,CAAK,EAAG,CAAC,EAC5C,QAAA,CAAUA,EAAAA,CAAsB,CAAE,GAAA,CAAK,EAAG,CAAC,CAAA,CAC3C,SAAA,CAAWA,EAAAA,CAAsB,CAAE,GAAA,CAAK,GAAI,CAAC,CAAA,CAC7C,MAAA,CAAQF,GAAsB,CAAE,GAAA,CAAKF,GAAmB,GAAA,CAAKC,CAAkB,CAAC,CAClF,CAAC,CAAA,CACA,QAAO,CAYH,SAASM,GACdC,CAAAA,CAC6B,CAC7B,IAAMlK,CAAAA,CAASgK,EAAAA,CAAoB,OAAA,EAAQ,CAAE,SAAA,CAAUE,CAAM,EAE7D,GAAI,CAAClK,CAAAA,CAAO,OAAA,CAAS,CACnB,IAAMmK,EAAQnK,CAAAA,CAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,CAC7BoK,CAAAA,CAAOD,EAAM,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA,CAC1BE,CAAAA,CAAMD,EAAO,CAAA,EAAGA,CAAI,CAAA,EAAA,EAAKD,CAAAA,CAAM,OAAO,CAAA,CAAA,CAAKA,EAAM,OAAA,CACvD,MAAM,IAAI,KAAA,CAAME,CAAG,CACrB,CAEA,OAAOrK,CAAAA,CAAO,IAChB,CAEO,SAASsK,GAAiBlP,CAAAA,CAAe,CAC9C,OAAOgG,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAA,CAAG,CAAE,OAAA,CAAS,6CAA8C,CAAC,EAAE,KAAA,CAAMhG,CAAK,CAClG,CAEO,SAASmP,EAAcnP,CAAAA,CAAe,CAC3C,OAAOgG,CAAAA,CAAE,MAAA,EAAO,CAAE,MAAM,CAAE,OAAA,CAAS,uBAAwB,CAAC,CAAA,CAAE,MAAMhG,CAAK,CAAA,CAAE,WAAA,EAC7E,CAEO,SAASoP,GAAepP,CAAAA,CAAe,CAC5C,OAAOwO,EAAAA,CAAsB,CAAE,IAAKF,EAAAA,CAAmB,GAAA,CAAKC,CAAkB,CAAC,CAAA,CAAE,KAAA,CAAMvO,CAAK,CAC9F,CC9DO,SAASqP,EAAAA,CAAuBnG,CAAAA,CAAe,CACpD,OAAO,CACL,EAAA,CAAIA,CAAAA,CAAQ,GAAA,CACZ,MAAA,CAAQA,EAAQ,MAAA,CAChB,KAAA,CAAOA,CAAAA,CAAQ,KAAA,EAAS,EAAC,CACzB,UAAWA,CAAAA,CAAQ,SAAA,EAAa,MAAA,CAChC,QAAA,CAAUA,CAAAA,CAAQ,QAAA,EAAY,OAC9B,SAAA,CAAWA,CAAAA,CAAQ,WAAa,MAClC,CACF,CAOA,eAAeoG,EAAAA,CAAoBC,CAAAA,CAAqC,CAEtE,IAAMC,CAAAA,CAAgBD,EAAW,KAAA,CAAM,CAAA,CAAGhB,CAAiB,CAAA,CAG3D,GAAI,CAMF,GAAI,CALe,MAAMxG,CAAAA,CAAgB,OAAA,CACvC,CAAE,OAAQyH,CAAc,CAAA,CACxB,CAAE,SAAA,CAAW,CAAE,OAAQ,IAAA,CAAM,QAAA,CAAU,CAAE,CAAE,CAC7C,CAAA,CAGE,OAAOA,CAEX,CAAA,MAAS9F,CAAAA,CAAK,CACZ,MAAM,IAAI,MAAM,CAAA,mDAAA,EAAsDA,CAAG,CAAA,CAAE,CAC7E,CAGA,IAAM+F,EAAmB,EAAA,CAEzB,IAAA,IAASC,EAAS,CAAA,CAAGA,CAAAA,EAAUD,EAAkBC,CAAAA,EAAAA,CAAU,CACzD,IAAMC,CAAAA,CAAY,CAAA,CAAA,EAAID,CAAM,GACtBE,CAAAA,CAAY,CAAA,EAAGJ,EAAc,KAAA,CAAM,CAAA,CAAGjB,EAAoBoB,CAAAA,CAAU,MAAM,CAAC,CAAA,EAAGA,CAAS,CAAA,CAAA,CAE7F,GAAI,CAMF,GAAI,CALa,MAAM5H,CAAAA,CAAgB,QACrC,CAAE,MAAA,CAAQ6H,CAAU,CAAA,CACpB,CAAE,SAAA,CAAW,CAAE,MAAA,CAAQ,IAAA,CAAM,QAAA,CAAU,CAAE,CAAE,CAC7C,EAGE,OAAOA,CAEX,CAAA,MAASlG,CAAAA,CAAK,CACZ,MAAM,IAAI,KAAA,CAAM,CAAA,sCAAA,EAAyCkG,CAAS,CAAA,GAAA,EAAMlG,CAAG,EAAE,CAC/E,CACF,CAIA,IAAMmG,CAAAA,CAAsB,EAAA,CAE5B,QAASC,CAAAA,CAAU,CAAA,CAAGA,EAAUD,CAAAA,CAAqBC,CAAAA,EAAAA,CAAW,CAC9D,IAAMC,CAAAA,CAAe,CAAA,CAAA,EAAI7I,WAAAA,CAAY,CAAC,CAAA,CAAE,SAAS,KAAK,CAAC,GACjD0I,CAAAA,CAAY,CAAA,EAAGJ,EAAc,KAAA,CAAM,CAAA,CAAGjB,CAAAA,CAAoBwB,CAAAA,CAAa,MAAM,CAAC,GAAGA,CAAY,CAAA,CAAA,CAEnG,GAAI,CAMF,GAAI,CALa,MAAMhI,CAAAA,CAAgB,OAAA,CACrC,CAAE,MAAA,CAAQ6H,CAAU,EACpB,CAAE,SAAA,CAAW,CAAE,MAAA,CAAQ,IAAA,CAAM,SAAU,CAAE,CAAE,CAC7C,CAAA,CAGE,OAAOA,CAEX,OAASlG,CAAAA,CAAK,CACZ,MAAM,IAAI,KAAA,CAAM,yCAAyCkG,CAAS,CAAA,GAAA,EAAMlG,CAAG,CAAA,CAAE,CAC/E,CACF,CAEA,MAAM,IAAI,MACR,CAAA,6CAAA,EAAgD6F,CAAU,kCAC5D,CACF,CAaA,eAAsBS,CAAAA,CACpBC,CAAAA,CACAlC,CAAAA,CACA,CAAE,eAAA,CAAAmC,CAAAA,CAAkB,IAAK,CAAA,CAAmC,EAAC,CAC5C,CACjB,GAA+BD,CAAAA,EAAc,IAAA,EAAQ,MAAA,CAAOA,CAAS,CAAA,CAAE,MAAK,GAAM,EAAA,CAAI,CAEpF,IAAME,CAAAA,CAASf,GAAe,MAAA,CAAOa,CAAS,CAAA,CAAE,IAAA,EAAM,CAAA,CAEtD,GAAIC,CAAAA,CAAiB,CAMnB,GALiB,MAAMnI,CAAAA,CAAgB,QACrC,CAAE,MAAA,CAAAoI,CAAO,CAAA,CACT,CAAE,SAAA,CAAW,CAAE,MAAA,CAAQ,IAAA,CAAM,SAAU,CAAE,CAAE,CAC7C,CAAA,CAGE,MAAM,IAAI,KAAA,CAAM,uBAAuB,CAAA,CAGzC,OAAOA,CACT,CAGA,OAAOb,EAAAA,CAAoBa,CAAM,CACnC,CAIA,IAAMZ,CAAAA,CAAaxB,CAAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,CAAOO,GAAmB,GAAG,CAAA,CAAE,MAAM,CAAA,CAAGC,CAAiB,CAAA,CAChG,OAAOe,EAAAA,CAAoBC,CAAU,CACvC,CC7GA,IAAIa,GAA2B,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA,CAExC,SAASC,EAAAA,CAAeC,CAAAA,CAA6B,CAC1DF,GAAc,MAAA,CAAO,MAAA,CAAO,OAAO,MAAA,CAAO,GAAIA,EAAAA,CAAaE,CAAc,CAAC,EAC5E,CAEO,SAASC,GAAiB,CAC/B,OAAOH,EACT,CCgEA,IAAII,EAAAA,CAAyB,OAAO,MAAA,CAAO,EAAE,CAAA,CAEtC,SAASC,EAAAA,CAAcC,EAA2B,CACvDF,EAAAA,CAAa,OAAO,MAAA,CAAO,MAAA,CAAO,OAAO,EAAC,CAAGA,EAAAA,CAAYE,CAAa,CAAC,EACzE,CAEO,SAASC,CAAAA,EAAgB,CAC9B,OAAOH,EACT,CCvFA,eAAsBI,EAAAA,CACpBhJ,CAAAA,CACA,CAAE,IAAA,CAAAC,CAAAA,CAAM,QAAAN,CAAAA,CAAS,cAAA,CAAAsJ,CAAe,CAAA,CAChC,CACA,GAAI,CACF,GAAI,CAACtJ,CAAAA,CACH,MAAM,IAAI,MAAM,4BAA4B,CAAA,CAG9C,IAAMuJ,CAAAA,CAAKD,CAAAA,EAAgB,EAAA,CACvBC,GACF,MAAMC,CAAAA,CAAiB,CACrB,MAAA,CAAQ,QAAA,CACR,IAAA,CAAM,KACN,KAAA,CAAOD,CACT,CAAC,CAAA,CAGH,IAAM/C,EAAQoB,CAAAA,CAAcvH,CAAAA,CAAK,KAAe,CAAA,CAE1CoJ,CAAAA,CAAWhL,CAAAA,CAAE,QAAO,CAAE,KAAA,CAAM4B,EAAK,QAAQ,CAAA,CAQzCsB,EAAU,MAAMnB,CAAAA,CAAgB,OAAA,CACpC,CAAE,gBAAA,CAAkBgG,CAAAA,CAAO,OAAQ,CAAE,IAAA,CAAM,CAAC,SAAA,CAAW,UAAU,CAAE,CAAE,CAAA,CACrE,CAAE,SAAA,CAAW,CAAE,MAAA,CAAQ,KAAM,QAAA,CAAU,CAAE,CAAE,CAC7C,CAAA,CAEMkD,CAAAA,CAAe/H,GAAS,WAAA,EAAa,QAAA,EAAU,IAAA,CACrD,GAAI,CAAC+H,CAAAA,CACH,MAAMC,EAAAA,EAA0B,CAKlC,GAAI,CAFahI,CAAAA,CAAQ,QAAQ,IAAA,CAAMiI,CAAAA,EAAMA,CAAAA,CAAE,OAAA,CAAQ,WAAA,EAAY,GAAMpD,CAAK,CAAA,EAE/D,QAAA,EAAYwC,GAAe,EAAG,QAAA,CAC3C,MAAM,IAAI,KAAA,CACR,kGACF,CAAA,CAIF,GAAI,CADoB,MAAMa,EAAAA,CAAO,OAAA,CAAQJ,EAAUC,CAAY,CAAA,CAEjE,MAAMC,EAAAA,EAA0B,CAGlC,OAAA,MAAMpK,EAAAA,CAAeS,CAAAA,CAAQ,SAAA,CAAW2B,EAAQ,GAAG,CAAA,CAEnDyH,CAAAA,EAAc,CAAE,YAAA,GAAe,CAC7B,SAAU,OAAA,CACV,IAAA,CAAMzH,CAAAA,CACN,OAAA,CAAA3B,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CAAA,CACDF,GAAc,CAAE,KAAA,EAAO,YAAYzH,CAAO,CAAA,CAEnC,CACL,IAAA,CAAMmG,EAAAA,CAAuBnG,CAAO,CACtC,CACF,CAAA,MAASpH,EAAO,CACd,MAAIA,aAAiB,KAAA,GACnB6O,CAAAA,EAAc,CAAE,YAAA,GAAe,CAC7B,QAAA,CAAU,QACV,KAAA,CAAA7O,CAAAA,CACA,QAAAyF,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CAAA,CACDF,CAAAA,EAAc,CAAE,KAAA,EAAO,OAAA,GAAU7O,CAAK,CAAA,CAAA,CAElCA,CACR,CACF,CAEA,eAAsBuP,EAAAA,CAAazJ,EAAY,CAAE,OAAA,CAAAL,CAAQ,CAAA,CAAY,CACnE,GAAI,CAACA,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,4BAA4B,EAG9C,MAAMP,EAAAA,CAAiBO,CAAAA,CAAQ,SAAS,EAC1C,CAOA,SAAS2J,EAAAA,EAA4B,CACnC,OAAO,IAAI,KAAA,CAAM,sCAAsC,CACzD,CCnGA,eAAsBI,EAAAA,CAAcC,CAAAA,CAAa,CAAE,KAAA1J,CAAK,CAAA,CAAY,CAClE,GAAI,CAACA,EACH,MAAM,IAAI,KAAA,CAAM,mBAAmB,CAAA,CAGrC,IAAM2J,EAAU,MAAMzJ,CAAAA,CAAgB,YAAYF,CAAAA,CAAK,EAAE,EAEzD,OAAO,CACL,MAAA,CAAQ2J,CAAAA,CAAQ,MAAA,CAChB,MAAA,CAAQA,EAAQ,MAAA,CAChB,WAAA,CAAa,OAAO,IAAA,CAAKA,CAAAA,CAAQ,aAAe,EAAE,CAAA,CAClD,SAAA,CAAWA,CAAAA,CAAQ,SAAA,EAAa,OAChC,QAAA,CAAUA,CAAAA,CAAQ,UAAY,MAAA,CAC9B,SAAA,CAAWA,EAAQ,SAAA,EAAa,MAClC,CACF,CAEA,eAAsBC,EAAAA,CAAoBF,EAAa,CAAE,IAAA,CAAA1J,CAAK,CAAA,CAAY,CACxE,GAAI,CAACA,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,mBAAmB,EAGrC,IAAI2J,CAAAA,CAAU,MAAMzJ,CAAAA,CAAgB,WAAA,CAAYF,CAAAA,CAAK,EAAE,CAAA,CAEjD5C,CAAAA,CAAS4J,EAAAA,CAAsB0C,CAA2B,CAAA,CAKhE,GAHA,MAAMZ,CAAAA,EAAc,CAAE,wBAAwB1L,CAAM,CAAA,CAGhD,WAAYA,CAAAA,EAAUA,CAAAA,CAAO,MAAA,GAAW,MAAA,EACzB,MAAM8C,CAAAA,CAAgB,QACrC,CACE,MAAA,CAAQ9C,EAAO,MAAA,CACf,GAAA,CAAK,CAAE,GAAA,CAAKuM,CAAAA,CAAQ,GAAI,CAC1B,CAAA,CACA,CAAE,UAAW,CAAE,MAAA,CAAQ,KAAM,QAAA,CAAU,CAAE,CAAE,CAC7C,CAAA,CAGE,MAAM,IAAI,KAAA,CAAM,uBAAuB,EAK3C,GAAI,MAAA,CAAO,IAAA,CAAKvM,CAAM,CAAA,CAAE,MAAA,CAAS,EAAG,CAClC,IAAMyM,CAAAA,CAAqC,EAAC,CACtCC,CAAAA,CAAkC,EAAC,CAEzC,IAAA,GAAW,CAAClS,CAAAA,CAAKO,CAAK,IAAK,MAAA,CAAO,OAAA,CAAQiF,CAAM,CAAA,CAC1CjF,CAAAA,GAAU,MAAA,CACZ2R,EAAYlS,CAAG,CAAA,CAAI,GAEnBiS,CAAAA,CAAUjS,CAAG,EAAIO,CAAAA,CAIrB,IAAM4R,CAAAA,CAAuC,EAAC,CAC1C,MAAA,CAAO,KAAKF,CAAS,CAAA,CAAE,OAAS,CAAA,GAAGE,CAAAA,CAAY,KAAOF,CAAAA,CAAAA,CACtD,MAAA,CAAO,IAAA,CAAKC,CAAW,CAAA,CAAE,MAAA,CAAS,IAAGC,CAAAA,CAAY,MAAA,CAASD,CAAAA,CAAAA,CAE9D,GAAI,CACF,MAAM5J,EAAgB,SAAA,CAAU,CAAE,GAAA,CAAKyJ,CAAAA,CAAQ,GAAI,CAAA,CAAGI,CAAW,CAAA,CAGjE,IAAMC,EAAgB,MAAA,CAAO,WAAA,CAC3B,OAAO,IAAA,CAAKF,CAAW,CAAA,CAAE,GAAA,CAAKlS,CAAAA,EAAQ,CAACA,EAAK,KAAA,CAAS,CAAC,CACxD,CAAA,CACA+R,CAAAA,CAAU,CAAE,GAAGA,CAAAA,CAAS,GAAGE,CAAAA,CAAW,GAAGG,CAAc,EACzD,CAAA,MAAS/P,CAAAA,CAAO,CACd,MAAIA,CAAAA,YAAiB,OAAS,MAAA,GAAUA,CAAAA,EAAUA,CAAAA,CAA2B,IAAA,GAAS,IAAA,CAC9E,IAAI,MAAM,uBAAuB,CAAA,CAEnCA,CACR,CACF,CAEA,OAAO,CACL,IAAA,CAAMuN,EAAAA,CAAuBmC,CAAO,CACtC,CACF,CCSO,IAAMM,EAAAA,CAA4B,CAAC,SAAU,QAAQ,CAAA,CC1F5D,eAAsBC,EAAAA,CAA0B,CAAE,QAAA,CAAAC,CAAS,CAAA,CAAS,CAAE,KAAAnK,CAAK,CAAA,CAAY,CACrF,GAAI,CAACA,EACH,MAAM,IAAI,KAAA,CAAM,6CAA6C,CAAA,CAG/D,GACE,OAAOmK,CAAAA,EAAa,QAAA,EACpB,CAACF,EAAAA,CAA0B,QAAA,CAASE,CAAyB,CAAA,CAE7D,MAAM,IAAI,KAAA,CACR,CAAA,2CAAA,EAA8CF,EAAAA,CAA0B,KAAK,IAAI,CAAC,CAAA,CAAA,CACpF,CAAA,CAIF,IAAM5I,CAAAA,CAAU,MAAMnB,CAAAA,CAAgB,WAAA,CAAYF,CAAAA,CAAK,EAAE,CAAA,CAEnDoC,CAAAA,CAAUf,EAAQ,WAAA,EAAe,GAGvC,GAAI,CAACe,EAFe+H,CAEI,CAAA,CACtB,MAAM,IAAI,KAAA,CAAM,CAAA,EAAGA,CAAQ,CAAA,+BAAA,CAAiC,CAAA,CAI9D,GAD2B,MAAA,CAAO,MAAA,CAAO/H,CAAO,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,MAAA,EACxC,CAAA,CACxB,MAAM,IAAI,KAAA,CACR,iFACF,CAAA,CAMF,IAAMgI,EAAe,MAAA,CAAO,IAAA,CAAKhI,CAAO,CAAA,CAAE,MAAA,CACvCxK,CAAAA,EAAQA,IAAQuS,CAAAA,EAAY/H,CAAAA,CAAQxK,CAA2B,CAClE,CAAA,CACMyS,CAAAA,CACJD,EAAa,MAAA,CAAS,CAAA,CAClB,CAAE,GAAA,CAAKA,CAAAA,CAAa,GAAA,CAAKxS,IAAS,CAAE,CAAC,eAAeA,CAAG,CAAA,CAAE,EAAG,CAAE,OAAA,CAAS,IAAK,CAAE,CAAA,CAAE,CAAE,EAClF,EAAC,CAOP,IALe,MAAMsI,CAAAA,CAAgB,UACnC,CAAE,GAAA,CAAKmB,CAAAA,CAAQ,GAAA,CAAK,GAAGgJ,CAAiB,EACxC,CAAE,MAAA,CAAQ,CAAE,CAAC,CAAA,YAAA,EAAeF,CAAQ,CAAA,CAAE,EAAG,EAAG,CAAE,CAChD,CAAA,EAEW,eAAiB,CAAA,CAC1B,MAAM,IAAI,KAAA,CACR,iFACF,CAEJ,CC/CO,IAAMG,EAAAA,CAAe,IAAIhQ,EAAM,sBAAA,CAAwB,CAC5D,OAAQ,CACN,MAAA,CAAQhC,EAAO,MAAA,EAAO,CACtB,IAAA,CAAMA,CAAAA,CAAO,IAAA,CAAK,CAAC,KAAM,MAAA,CAAQ,OAAO,CAAC,CAAA,CACzC,KAAA,CAAOA,EAAO,MAAA,EAAO,CACrB,QAAA,CAAUA,CAAAA,CAAO,MAAA,EAAO,CAExB,YAAaA,CAAAA,CAAO,IAAA,GACpB,WAAA,CAAaA,CAAAA,CAAO,QAAO,CAC3B,eAAA,CAAiBA,CAAAA,CAAO,MAAA,EAAO,CAE/B,SAAA,CAAWA,EAAO,IAAA,EACpB,EACA,OAAA,CAAS,CACP,CAAE,GAAA,CAAK,CAAE,MAAA,CAAQ,CAAA,CAAG,IAAA,CAAM,CAAA,CAAG,MAAO,CAAA,CAAG,QAAA,CAAU,CAAE,CAAA,CAAG,MAAA,CAAQ,IAAK,CAAA,CACnE,CAAE,GAAA,CAAK,CAAE,SAAA,CAAW,CAAE,EAAG,kBAAA,CAAoB,CAAE,CACjD,CACF,CAAC,ECtBD,IAAIiS,EAAAA,CAAiC,EAAC,CAE/B,SAASC,EAAAA,CAAe9S,EAA6B,CAC1D,GAAI6S,GAAS,MAAA,CAAS,CAAA,CACpB,MAAM,IAAI,KAAA,CAAM,wDAAwD,CAAA,CAG1EA,EAAAA,CAAW7S,EACb,CAiBA,eAAsBwR,CAAAA,CAAiBpQ,CAAAA,CAKpC,CACD,GAAM,CAAE,OAAA2R,CAAAA,CAAQ,IAAA,CAAA5H,CAAAA,CAAM,KAAA,CAAA1K,CAAAA,CAAO,OAAA,CAAAuS,CAAQ,CAAA,CAAI5R,CAAAA,CACnC6R,EAAQJ,EAAAA,CAAS,MAAA,CAAQK,GAASA,CAAAA,CAAK,MAAA,GAAWH,CAAAA,EAAUG,CAAAA,CAAK,IAAA,GAAS/H,CAAI,EAC9EgI,CAAAA,CAAcH,CAAAA,CAAU,IAAM,IAAII,GAAAA,CAAeJ,CAAO,CAAA,CAAI,MAAA,CAElE,IAAA,IAAWE,CAAAA,IAAQD,CAAAA,CACjB,MAAMI,GAAmBH,CAAAA,CAAMzS,CAAAA,CAAO0S,CAAW,EAErD,CAGA,eAAeE,EAAAA,CAAmBH,CAAAA,CAAqBzS,CAAAA,CAAe0S,CAAAA,CAA2B,CAC/F,IAAMG,EAAuB,IACpBH,CAAAA,CACHA,CAAAA,EAAY,CACZ,IAAIC,GAAAA,CAAe,2BAA2BF,CAAAA,CAAK,MAAM,CAAA,CAAE,CAAA,CAG3DK,CAAAA,CAAS,MAAMX,GAAa,OAAA,CAAQ,CACxC,OAAQM,CAAAA,CAAK,MAAA,CACb,KAAMA,CAAAA,CAAK,IAAA,CACX,KAAA,CAAAzS,CAAAA,CACA,QAAA,CAAUyS,CAAAA,CAAK,MACjB,CAAC,CAAA,CAEKtL,EAAM,IAAA,CAAK,GAAA,GACX4L,CAAAA,CAAqB,IAAA,CAAK,KAAA,CAAM5L,CAAAA,CAAMsL,CAAAA,CAAK,MAAM,EAAIA,CAAAA,CAAK,MAAA,CAE1D,CAAE,KAAA,CAAAO,CAAAA,CAAO,SAAAC,CAAS,CAAA,CAAIH,CAAAA,CACxBI,EAAAA,CAASJ,CAAAA,CAAQC,CAAAA,CAAoB5L,CAAG,CAAA,CACxC,CACE,KAAA,CAAO,CAAA,CACP,QAAA,CAAU,CACR,aAAc,CACZ,WAAA,CAAa,IAAI,IAAA,CAAK4L,CAAkB,CAAA,CACxC,YAAa,CAAA,CACb,eAAA,CAAiB,EACjB,SAAA,CAAW,IAAI,KAAKA,CAAAA,CAAqBN,CAAAA,CAAK,MAAA,CAASA,CAAAA,CAAK,MAAM,CACpE,CACF,CACF,CAAA,CAEJ,GAAIO,CAAAA,EAASP,CAAAA,CAAK,MAChB,MAAMI,CAAAA,EAAqB,CAO7B,MAAMV,EAAAA,CAAa,SAAA,CACjB,CAAE,MAAA,CAAQM,CAAAA,CAAK,OAAQ,IAAA,CAAMA,CAAAA,CAAK,KAAM,KAAA,CAAAzS,CAAAA,CAAO,QAAA,CAAUyS,CAAAA,CAAK,MAAO,CAAA,CACrEQ,CACF,EACF,CAEA,SAASC,EAAAA,CAASJ,CAAAA,CAAsCC,CAAAA,CAA4B5L,EAAa,CAC/F,IAAMgM,CAAAA,CAAkBJ,CAAAA,CAAqBD,CAAAA,CAAO,QAAA,CAEpD,GAAIA,CAAAA,CAAO,WAAA,CAAY,SAAQ,GAAMC,CAAAA,CAAoB,CACvD,IAAMK,CAAAA,CAAqBN,CAAAA,CAAO,WAAA,CAC5BO,CAAAA,CAAkBP,CAAAA,CAAO,gBACzBQ,CAAAA,CAAmB,CAAA,CAAA,CAAKnM,EAAM4L,CAAAA,EAAsBD,CAAAA,CAAO,SACjE,OAAO,CACL,KAAA,CAAO,IAAA,CAAK,KAAA,CAAMM,CAAAA,CAAqBC,EAAkBC,CAAgB,CAAA,CACzE,SAAU,CACR,IAAA,CAAM,CAAE,WAAA,CAAa,CAAE,CAAA,CACvB,YAAA,CAAc,CACZ,WAAA,CAAa,IAAI,IAAA,CAAKP,CAAkB,CAAA,CACxC,eAAA,CAAiB,CAAA,CACjB,SAAA,CAAW,IAAI,IAAA,CAAKA,CAAAA,CAAqBD,CAAAA,CAAO,QAAA,CAAWA,CAAAA,CAAO,QAAQ,CAC5E,CACF,CACF,CACF,CAEA,GAAIA,EAAO,WAAA,CAAY,OAAA,EAAQ,GAAMK,CAAAA,CAAiB,CACpD,IAAMI,EAAS,CAAA,CAAA,CAAKpM,CAAAA,CAAM4L,GAAsBD,CAAAA,CAAO,QAAA,CACvD,OAAO,CACL,KAAA,CAAO,IAAA,CAAK,KAAA,CAAMA,CAAAA,CAAO,WAAA,CAAcS,CAAM,CAAA,CAC7C,QAAA,CAAU,CACR,IAAA,CAAM,CACJ,YAAa,IAAI,IAAA,CAAKR,CAAkB,CAAA,CACxC,WAAA,CAAa,CAAA,CACb,gBAAiBD,CAAAA,CAAO,WAAA,CACxB,SAAA,CAAW,IAAI,IAAA,CAAKC,CAAAA,CAAqBD,EAAO,QAAA,CAAWA,CAAAA,CAAO,QAAQ,CAC5E,CACF,CACF,CACF,CAEA,OAAO,CACL,KAAA,CAAO,CAAA,CACP,SAAU,CACR,IAAA,CAAM,CACJ,WAAA,CAAa,IAAI,IAAA,CAAKC,CAAkB,CAAA,CACxC,WAAA,CAAa,EACb,eAAA,CAAiB,CAAA,CACjB,UAAW,IAAI,IAAA,CAAKA,CAAAA,CAAqBD,CAAAA,CAAO,QAAA,CAAWA,CAAAA,CAAO,QAAQ,CAC5E,CACF,CACF,CACF,CCxIO,SAASU,EAAAA,CAA0B,CACxC,IAAA,CAAAxU,CAAAA,CACA,KAAA,CAAA+O,EACA,eAAA,CAAA0F,CACF,CAAA,CAIG,CACD,OAAO;AAAA,SAAA,EACEzU,CAAAA,CAAO,CAAA,CAAA,EAAIA,CAAI,CAAA,CAAA,CAAK,EAAE,CAAA;AAAA,wCAAA,EACS+O,CAAK,CAAA;AAAA,gBAAA,EAC7B0F,CAAe,KAAKA,CAAe,CAAA;AAAA;AAAA,EAAA,CAGrD,CCEA,eAAeC,EAAAA,CAAiBnG,CAAAA,CAAe,CAC7C,IAAMoG,CAAAA,CAAW,MAAM1L,CAAAA,CAAkC,OAAA,CAAQ,CAC/D,KAAA,CAAAsF,EACA,SAAA,CAAW,CAAE,GAAA,CAAK,IAAI,IAAO,CAC/B,CAAC,CAAA,CAED,GAAI,CAACoG,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,uCAAuC,CAAA,CAQzD,GAAI,CALY,MAAM5L,CAAAA,CAAgB,OAAA,CAAQ,CAC5C,GAAA,CAAK4L,CAAAA,CAAS,MAAA,CACd,MAAA,CAAQ,CAAE,IAAA,CAAM,CAAC,SAAA,CAAW,UAAU,CAAE,CAC1C,CAAC,CAAA,CAGC,MAAM,IAAI,KAAA,CAAM,gBAAgB,CAAA,CAGlC,IAAM5F,CAAAA,CAAQ4F,CAAAA,CAAS,MAEvB,GAAI,CAAC5F,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,0BAA0B,CAAA,CAI5C,IAAM6F,CAAAA,CAAiB,MAAM7L,CAAAA,CAAgB,gBAAA,CAC3C,CACE,GAAA,CAAK4L,CAAAA,CAAS,MAAA,CACd,MAAA,CAAQ,CAAE,IAAA,CAAM,CAAC,SAAA,CAAW,UAAU,CAAE,CAAA,CACxC,gBAAA,CAAkB5F,CAAAA,CAClB,iBAAA,CAAmB,CAAE,GAAA,CAAK,IAAK,CACjC,CAAA,CACA,CAAE,IAAA,CAAM,CAAE,mBAAA,CAAqB,IAAK,CAAE,CAAA,CACtC,CAAE,cAAA,CAAgB,OAAQ,CAC5B,CAAA,CAEA,GAAI,CAAC6F,CAAAA,CAMH,MALqB,MAAM7L,CAAAA,CAAgB,OAAA,CAAQ,CACjD,GAAA,CAAK4L,CAAAA,CAAS,MAAA,CACd,gBAAA,CAAkB5F,CACpB,CAAC,CAAA,CAGO,IAAI,KAAA,CAAM,2BAA2B,CAAA,CAErC,IAAI,MAAM,uCAAuC,CAAA,CAK3D,OAAA,MAAM9F,CAAAA,CAAkC,SAAA,CAAU,CAAE,IAAK0L,CAAAA,CAAS,GAAI,CAAC,CAAA,CAEhE,CAAE,OAAA,CAASC,CAAAA,CAAgB,KAAA,CAAA7F,CAAM,CAC1C,CAEA,eAAsB8F,EAAAA,CAAkBC,CAAAA,CAA6C,CACnF,IAAMC,CAAAA,CAAUrU,GAAAA,CAAU,kBAAkB,CAAA,CACtCsU,CAAAA,CACJzD,CAAAA,EAAe,CAAE,YAAA,EAAc,WAAA,EAC/BA,CAAAA,EAAe,CAAE,wBAAA,EACjBwD,CAAAA,EACA,IACF,GAAI,CACF,IAAMxG,CAAAA,CAAQvH,CAAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM8N,CAAAA,CAAO,KAAA,CAAM,KAAK,CAAA,CAC3C,CAAE,OAAA,CAAA5K,CAAQ,CAAA,CAAI,MAAMwK,EAAAA,CAAiBnG,CAAK,CAAA,CAE7BoD,CAAAA,GACR,wBAAA,GAA2B,CACpC,QAAA,CAAU,OAAA,CACV,IAAA,CAAMzH,CAAAA,CACN,QAAS,IAAA,CACT,cAAA,CAAgB,CACd,OAAA,CAAA6K,CAAAA,CACA,EAAA,CAAID,CAAAA,CAAO,GAAA,CAAI,EAAA,EAAMA,CAAAA,CAAO,GAAA,CAAI,MAAA,CAAO,aAAA,CACvC,SAAA,CAAWA,EAAO,OAAA,CAAQ,YAAY,CAAA,CACtC,cAAA,CAAgBA,CAAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAA,CAChD,QAAA,CAAUA,CAAAA,CAAO,OAAA,CAAQ,OAC3B,CACF,CAAC,EAED,GAAM,CAAE,SAAA,CAAAnN,CAAU,CAAA,CAAI,MAAME,EAAAA,CAAcqC,CAAAA,CAAQ,GAAG,CAAA,CAErD,OAAAzB,EAAAA,CAAmBqM,CAAAA,CAAO,GAAA,CAAKnN,CAAS,CAAA,CAEjC,CACL,MAAA,CAAQ,GAAA,CACR,QAAA,CAAU,CAAA,EAAGqN,CAAwB,CAAA,gBAAA,CACvC,CACF,CAAA,MAASlS,CAAAA,CAAO,CACd,IAAMyQ,EAAUzQ,CAAAA,YAAiB,KAAA,CAAQA,CAAAA,CAAM,OAAA,CAAU,8BAAA,CACzD,OAAIA,CAAAA,YAAiB,KAAA,GACA6O,CAAAA,EAAc,CACtB,wBAAA,GAA2B,CACpC,QAAA,CAAU,OAAA,CACV,MAAA7O,CAAAA,CACA,OAAA,CAAS,IAAA,CACT,cAAA,CAAgB,CACd,OAAA,CAAAiS,CAAAA,CACA,EAAA,CAAID,CAAAA,CAAO,GAAA,CAAI,EAAA,EAAMA,CAAAA,CAAO,GAAA,CAAI,MAAA,CAAO,cACvC,SAAA,CAAWA,CAAAA,CAAO,OAAA,CAAQ,YAAY,CAAA,CACtC,cAAA,CAAgBA,CAAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAA,CAChD,QAAA,CAAUA,CAAAA,CAAO,OAAA,CAAQ,OAC3B,CACF,CAAC,CAAA,CACD,OAAA,CAAQ,KAAA,CAAM,wBAAA,CAA0BhS,CAAK,GAGxC,CACL,MAAA,CAAQ,GAAA,CACR,QAAA,CAAU,CAAA,EAAGkS,CAAwB,yBAAyB,kBAAA,CAAmBzB,CAAO,CAAC,CAAA,CAC3F,CACF,CACF,CAEA,eAAsB0B,EAAAA,CAAsB,CAC1C,MAAA,CAAAlN,CAAAA,CACA,KAAA,CAAAgH,CAAAA,CACA,QAAAgG,CAAAA,CAAUrU,GAAAA,CAAU,kBAAkB,CACxC,CAAA,CAIG,CACD,GAAI6Q,CAAAA,EAAe,CAAE,QAAA,CAAU,CAC7B,IAAM2D,CAAAA,CAAgB3D,CAAAA,GAAiB,QAAA,CAGjC4D,CAAAA,CAAoBjN,WAAAA,CAAY,EAAE,CAAA,CAAE,QAAA,CAAS,KAAK,CAAA,CAClDE,CAAAA,CAAY,IAAI,IAAA,CAAK,IAAA,CAAK,GAAA,EAAI,CAAIC,EAAK,KAAA,CAAM,EAAE,CAAC,CAAA,CAGtD,MAAMY,CAAAA,CAAkC,UAAU,CAChD,MAAA,CAAAlB,CAAAA,CACA,KAAA,CAAAgH,CAAAA,CACA,KAAA,CAAOoG,EACP,SAAA,CAAW,IAAI,IAAA,CACf,SAAA,CAAA/M,CACF,CAAC,CAAA,CAED,IAAMqM,CAAAA,CAAkB,CAAA,EAAGM,CAAO,CAAA,uCAAA,EAA0CI,CAAiB,CAAA,CAAA,CAIvFC,GAFW7D,CAAAA,EAAe,EAAG,YAAA,EAAc,QAAA,EAAYiD,EAAAA,EAE/B,CAAE,IAAA,CAAM,EAAA,CAAI,KAAA,CAAAzF,CAAAA,CAAO,eAAA,CAAA0F,CAAgB,CAAC,CAAA,CAC5DY,EAActK,EAAAA,CAAWqK,CAAY,CAAA,CAE3C,MAAMF,CAAAA,EAAe,SAAA,CAAU,CAC7B,EAAA,CAAInG,CAAAA,CACJ,IAAA,CAAMwC,CAAAA,EAAe,EAAG,IAAA,EAAQ,uBAAA,CAChC,QAASA,CAAAA,EAAe,EAAG,YAAA,EAAc,OAAA,EAAW,2BAAA,CACpD,IAAA,CAAM8D,EACN,IAAA,CAAMD,CACR,CAAC,EACH,CACF,CAEA,IAAME,EAAAA,CAA6B,CACjC,OAAA,CAAS,IAAA,CACT,OAAA,CAAS,sFACX,CAAA,CAEA,eAAsBC,EAAAA,CAA8B3M,CAAAA,CAAY,CAAE,cAAA,CAAAiJ,CAAe,CAAA,CAAY,CAC3F,IAAM9C,CAAAA,CAAQoB,CAAAA,CAAcvH,CAAAA,CAAK,KAAe,CAAA,CAG1CsB,CAAAA,CAAU,MAAMnB,CAAAA,CAAgB,OAAA,CACpC,CAAE,gBAAA,CAAkBgG,CAAAA,CAAO,MAAA,CAAQ,CAAE,IAAA,CAAM,CAAC,SAAA,CAAW,UAAU,CAAE,CAAE,CAAA,CACrE,CAAE,SAAA,CAAW,CAAE,MAAA,CAAQ,IAAA,CAAM,QAAA,CAAU,CAAE,CAAE,CAC7C,CAAA,CAIA,GAAI,CAAC7E,CAAAA,CACH,OAAOoL,GAGT,IAAME,CAAAA,CAAWtL,CAAAA,CAAQ,MAAA,EAAQ,IAAA,CAAMiI,CAAAA,EAAMA,EAAE,OAAA,CAAQ,WAAA,EAAY,GAAMpD,CAAK,CAAA,CAE9E,GAAI,CAACyG,CAAAA,EAAYA,CAAAA,CAAS,QAAA,CACxB,OAAOF,EAAAA,CAGT,GAAI,CAAC/D,GAAe,CAAE,QAAA,CACpB,MAAM,IAAI,KAAA,CAAM,kCAAkC,EAGpD,OAAA,MAAMQ,CAAAA,CAAiB,CACrB,MAAA,CAAQ,cAAA,CACR,IAAA,CAAM,OACN,KAAA,CAAO7H,CAAAA,CAAQ,GAAA,CAAI,QAAA,EAAS,CAC5B,OAAA,CAAS,8EACX,CAAC,CAAA,CAED,MAAM+K,EAAAA,CAAsB,CAC1B,MAAA,CAAQ/K,CAAAA,CAAQ,IAChB,KAAA,CAAA6E,CAAAA,CACA,OAAA,CAAS8C,CAAAA,EAAgB,OAC3B,CAAC,EAEMyD,EACT,CChNA,eAAsBG,EAAAA,CACpBlD,CAAAA,CACA,CAAE,KAAA1J,CAAAA,CAAM,OAAA,CAAAN,CAAAA,CAAS,cAAA,CAAAsJ,CAAe,CAAA,CAChC,CACA,IAAML,CAAAA,CAAaG,CAAAA,EAAc,CACjC,GAAI,CAEF,IAAM+D,EAAcnD,CAAAA,CACd,CAAE,SAAA,CAAAoD,CAAAA,CAAW,QAAA,CAAAC,CAAAA,CAAU,SAAA,CAAAC,CAAAA,CAAW,MAAA,CAAA1E,CAAO,CAAA,CAAIuE,CAAAA,CAE7C3G,CAAAA,CAAQoB,CAAAA,CAAcuF,EAAY,KAAK,CAAA,CACvC1D,CAAAA,CAAW9B,EAAAA,CAAiBwF,CAAAA,CAAY,QAAQ,CAAA,CAEhD5D,CAAAA,CAAKD,CAAAA,EAAgB,EAAA,CAS3B,GARIC,CAAAA,EACF,MAAMC,CAAAA,CAAiB,CACrB,MAAA,CAAQ,eAAA,CACR,IAAA,CAAM,IAAA,CACN,KAAA,CAAOD,CACT,CAAC,CAAA,CAGC,MAAMhD,EAAAA,CAAkBC,CAAK,CAAA,CAC/B,MAAM,IAAI,KAAA,CAAM,sCAAsC,CAAA,CASxD,IAAM+G,CAAAA,CAAe,MAAM/M,CAAAA,CAAgB,OAAA,CACzC,CAAE,gBAAA,CAAkBgG,CAAM,CAAA,CAC1B,CAAE,SAAA,CAAW,CAAE,MAAA,CAAQ,IAAA,CAAM,QAAA,CAAU,CAAE,CAAE,CAC7C,CAAA,CAEA,GAAI+G,CAAAA,CAAc,CAChB,IAAMC,CAAAA,CAAgBD,CAAAA,CAAa,MAAA,EAAQ,KAAM3D,CAAAA,EAAMA,CAAAA,CAAE,OAAA,CAAQ,WAAA,EAAY,GAAMpD,CAAK,CAAA,CACxF,MAAI+G,CAAAA,CAAa,MAAA,GAAW,UAAA,CACpB,IAAI,KAAA,CACR,yFACF,EAEI,IAAI,KAAA,CAAM,CAAA,gCAAA,EAAmCC,CAAAA,EAAe,OAAO,CAAA,CAAE,CAC7E,CAEIjE,CAAAA,EACF,MAAMC,CAAAA,CAAiB,CACrB,MAAA,CAAQ,SACR,IAAA,CAAM,IAAA,CACN,KAAA,CAAOD,CACT,CAAC,CAAA,CAIH,IAAMkE,CAAAA,CAAgBnG,EAAAA,CAAsB,CAC1C,SAAA,CAAA8F,CAAAA,CACA,QAAA,CAAAC,CAAAA,CACA,UAAAC,CAAAA,CACA,MAAA,CAAA1E,CACF,CAAC,CAAA,CAED,MAAMK,CAAAA,CAAW,cAAA,GAAiB,CAChC,KAAA,CAAAzC,CAAAA,CACA,QAAA,CAAAiD,CAAAA,CACA,GAAGgE,CACL,CAAC,CAAA,CAGD,IAAIC,CAAAA,CAEJ,GAAID,CAAAA,CAAc,MAAA,CAChBC,CAAAA,CAAiB,MAAMjF,CAAAA,CAAoBgF,CAAAA,CAAc,MAAA,CAAQjH,CAAK,CAAA,CAAA,KAAA,GAC7DyC,EAAW,cAAA,CAAgB,CACpC,IAAM0E,CAAAA,CAAY,MAAM1E,CAAAA,CAAW,eAAe,CAChD,KAAA,CAAAzC,CAAAA,CACA,SAAA,CAAWiH,CAAAA,CAAc,SAAA,CACzB,SAAUA,CAAAA,CAAc,QAC1B,CAAC,CAAA,CAEDC,CAAAA,CAAiB,MAAMjF,CAAAA,CAAoBkF,CAAAA,CAAWnH,CAAAA,CAAO,CAC3D,eAAA,CAAiB,CAAA,CACnB,CAAC,EACH,MACEkH,CAAAA,CAAiB,MAAMjF,CAAAA,CAAoB,KAAA,CAAA,CAAWjC,CAAK,CAAA,CAI7D,IAAMoH,CAAAA,CAAO,MAAM/D,EAAAA,CAAO,IAAA,CAAKJ,CAAAA,CAAU,EAAE,CAAA,CAErCpM,EAAS,MAAMmD,CAAAA,CAAgB,SAAA,CAAU,CAC7C,MAAA,CAAQkN,CAAAA,CACR,MAAA,CAAQ,QAAA,CACR,MAAA,CAAQ,CACN,CACE,OAAA,CAASlH,CAAAA,CACT,QAAA,CAAU,EACZ,CACF,CAAA,CACA,SAAA,CAAW,IAAI,IAAA,CACf,WAAA,CAAa,CACX,QAAA,CAAU,CACR,IAAA,CAAAoH,CACF,CACF,CAAA,CACA,GAAIH,CAAAA,CAAc,SAAA,GAAc,KAAA,CAAA,EAAa,CAAE,SAAA,CAAWA,CAAAA,CAAc,SAAU,CAAA,CAClF,GAAIA,CAAAA,CAAc,QAAA,GAAa,KAAA,CAAA,EAAa,CAAE,QAAA,CAAUA,EAAc,QAAS,CAAA,CAC/E,GAAIA,CAAAA,CAAc,SAAA,GAAc,KAAA,CAAA,EAAa,CAAE,SAAA,CAAWA,CAAAA,CAAc,SAAU,CACpF,CAAC,CAAA,CAEKI,CAAAA,CAAe,MAAMrN,CAAAA,CAAgB,OAAA,CACzC,CAAE,GAAA,CAAKnD,CAAAA,CAAO,UAAW,CAAA,CACzB,CAAE,cAAA,CAAgB,SAAU,CAC9B,CAAA,CAEA,GAAI,CAACwQ,EACH,MAAM,IAAI,KAAA,CAAM,gBAAgB,CAAA,CAGlC,OAAA,MAAMnB,GAAsB,CAC1B,MAAA,CAAQrP,CAAAA,EAAQ,UAAA,CAChB,KAAA,CAAAmJ,CAAAA,CACA,QAAS8C,CAAAA,EAAgB,OAC3B,CAAC,CAAA,CAEDL,CAAAA,CAAW,aAAA,GAAgB,CACzB,QAAA,CAAU,OAAA,CACV,IAAA,CAAM4E,CAAAA,CACN,OAAA,CAAA7N,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CAAA,CAEDL,CAAAA,CAAW,MAAA,EAAQ,SAAA,GAAY4E,CAAY,CAAA,CAEpCxQ,CAAAA,CAAO,UAChB,CAAA,MAAS9C,CAAAA,CAAO,CACd,MAAIA,CAAAA,YAAiB,QACnB0O,CAAAA,CAAW,aAAA,GAAgB,CACzB,QAAA,CAAU,OAAA,CACV,KAAA,CAAA1O,CAAAA,CACA,OAAA,CAAAyF,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CAAA,CAEDL,CAAAA,CAAW,QAAQ,OAAA,GAAU1O,CAAK,CAAA,CAAA,CAE9BA,CACR,CACF,CCjJA,SAASuT,EAAAA,CAAWtB,CAAAA,CAAiBuB,CAAAA,CAAgC,CACnE,OAAKA,CAAAA,CAIDA,CAAAA,CAAc,UAAA,CAAW,SAAS,CAAA,EAAKA,EAAc,UAAA,CAAW,UAAU,CAAA,CACrEA,CAAAA,CAIF,CAAA,EAAGvB,CAAO,CAAA,EAAGuB,CAAAA,CAAc,UAAA,CAAW,GAAG,CAAA,CAAI,EAAA,CAAK,GAAG,CAAA,EAAGA,CAAa,CAAA,CAAA,CARnEvB,CASX,CAEA,SAASwB,EAAAA,CAA6B,CAAE,KAAA,CAAAxH,CAAAA,CAAO,QAAA,CAAAyH,CAAS,CAAA,CAAwC,CAC9F,OAAO;AAAA;AAAA,wDAAA,EAEiDzH,CAAK,CAAA;AAAA;AAAA,gBAAA,EAE7CyH,CAAQ,KAAKA,CAAQ,CAAA;AAAA;AAAA;AAAA,EAAA,CAIvC,CAEA,IAAMC,EAAAA,CAAoB,CACxB,OAAA,CAAS,KACT,OAAA,CAAS,2EACX,CAAA,CAEA,eAAsBC,GAA6B9N,CAAAA,CAAY,CAAE,eAAAiJ,CAAe,CAAA,CAAY,CAC1F,IAAM9C,CAAAA,CAAQoB,CAAAA,CAAcvH,CAAAA,CAAK,KAAe,CAAA,CAC1CkJ,CAAAA,CAAKD,CAAAA,EAAgB,EAAA,CAEvBC,GACF,MAAMC,CAAAA,CAAiB,CACrB,MAAA,CAAQ,gBACR,IAAA,CAAM,IAAA,CACN,MAAOD,CACT,CAAC,EAGH,MAAMC,CAAAA,CAAiB,CACrB,MAAA,CAAQ,gBACR,IAAA,CAAM,OAAA,CACN,KAAA,CAAOhD,CACT,CAAC,CAAA,CAGD,IAAM7E,CAAAA,CAAU,MAAMnB,EAAgB,OAAA,CACpC,CAAE,iBAAkBgG,CAAAA,CAAO,MAAA,CAAQ,CAAE,IAAA,CAAM,CAAC,SAAA,CAAW,UAAU,CAAE,CAAE,CAAA,CACrE,CAAE,SAAA,CAAW,CAAE,OAAQ,IAAA,CAAM,QAAA,CAAU,CAAE,CAAE,CAC7C,CAAA,CAQA,GANI,CAAC7E,CAAAA,EAMD,CAACA,EAAQ,WAAA,EAAa,QAAA,CACxB,OAAOuM,EAAAA,CAGT,IAAMvB,CAAAA,CAAgB3D,CAAAA,EAAe,CAAE,QAAA,CACvC,GAAI,CAAC2D,CAAAA,CACH,MAAM,IAAI,MAAM,kCAAkC,CAAA,CAIpD,IAAMyB,CAAAA,CAAazO,WAAAA,CAAY,EAAE,CAAA,CAAE,QAAA,CAAS,KAAK,CAAA,CAC3CC,IAAM,IAAA,CAAK,GAAA,EAAI,CACfyO,CAAAA,CAAY,IAAI,IAAA,CAAKzO,GAAG,CAAA,CACxBC,CAAAA,CAAY,IAAI,IAAA,CAAKD,GAAAA,CAAME,EAAK,KAAA,CAAM,CAAC,CAAC,CAAA,CAG9C,MAAMa,CAAAA,CAA8B,SAAA,CAAU,CAC5C,MAAA,CAAQgB,CAAAA,CAAQ,GAAA,CAChB,KAAA,CAAA6E,EACA,KAAA,CAAO4H,CAAAA,CACP,SAAA,CAAAC,CAAAA,CACA,UAAAxO,CACF,CAAC,EAGD,IAAM2M,CAAAA,CAAWrU,IAAU,kBAAkB,CAAA,EAA4BmR,CAAAA,EAAgB,OAAA,CAEnF2E,EAAW,CAAA,EADQH,EAAAA,CAAWtB,EAAUxD,CAAAA,EAAe,CAAE,eAAe,WAAW,CACrD,CAAA,OAAA,EAAUoF,CAAU,GAIlDvB,CAAAA,CAAAA,CADW7D,CAAAA,IAAkB,aAAA,EAAe,QAAA,EAAYgF,IAChC,CAAE,KAAA,CAAAxH,CAAAA,CAAO,QAAA,CAAAyH,EAAU,IAAA,CAAM,EAAG,CAAC,CAAA,CACrDnB,EAActK,EAAAA,CAAWqK,CAAY,CAAA,CAE3C,OAAA,MAAMF,EAAc,SAAA,CAAU,CAC5B,GAAInG,CAAAA,CACJ,IAAA,CAAMwC,GAAe,EAAG,IAAA,EAAQ,uBAAA,CAChC,OAAA,CAASA,GAAe,EAAG,aAAA,EAAe,OAAA,EAAW,qBAAA,CACrD,KAAM8D,CAAAA,CACN,IAAA,CAAMD,CACR,CAAC,EAEMqB,EACT,CAEA,eAAsBI,EAAAA,CAAoBjO,CAAAA,CAAY,EAAC,CAAY,CACjE,IAAM2F,CAAAA,CAAQvH,EAAE,MAAA,EAAO,CAAE,KAAA,CAAM4B,CAAAA,CAAK,KAAK,CAAA,CACnCoJ,CAAAA,CAAW9B,EAAAA,CAAiBtH,CAAAA,CAAK,QAAkB,CAAA,CAGnDkO,CAAAA,CAAgB,MAAM5N,CAAAA,CAA8B,OAAA,CAAQ,CAAE,KAAA,CAAAqF,CAAM,CAAC,CAAA,CAC3E,GAAI,CAACuI,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,gCAAgC,CAAA,CAIlD,GAAIA,CAAAA,CAAc,SAAA,CAAY,IAAI,IAAA,CAChC,MAAA,MAAM5N,EAA8B,SAAA,CAAU,CAAE,MAAAqF,CAAM,CAAC,CAAA,CACjD,IAAI,MAAM,yBAAyB,CAAA,CAI3C,IAAMrE,CAAAA,CAAU,MAAMnB,CAAAA,CAAgB,OAAA,CAAQ,CAAE,GAAA,CAAK+N,EAAc,MAAO,CAAC,EAC3E,GAAI,CAAC5M,EACH,MAAM,IAAI,KAAA,CAAM,gBAAgB,EAIlC,IAAMiM,CAAAA,CAAO,MAAM/D,EAAAA,CAAO,IAAA,CAAKJ,EAAU,EAAE,CAAA,CAG3C,OAAA,MAAMjJ,CAAAA,CAAgB,UACpB,CAAE,GAAA,CAAKmB,EAAQ,GAAI,CAAA,CACnB,CAAE,IAAA,CAAM,CAAE,2BAAA,CAA6BiM,CAAK,CAAE,CAChD,CAAA,CAGIW,CAAAA,CAAc,KAAA,EAChB,MAAM/N,CAAAA,CAAgB,SAAA,CACpB,CAAE,GAAA,CAAKmB,EAAQ,GAAA,CAAK,gBAAA,CAAkB4M,EAAc,KAAM,CAAA,CAC1D,CAAE,IAAA,CAAM,CAAE,mBAAA,CAAqB,IAAK,CAAE,CACxC,CAAA,CAKF,MAAM7O,EAAAA,CAA0BiC,CAAAA,CAAQ,GAAG,CAAA,CAG3C,MAAMhB,CAAAA,CAA8B,SAAA,CAAU,CAAE,KAAA,CAAAqF,CAAM,CAAC,CAAA,CAEhD,CAAE,QAAS,IAAA,CAAM,OAAA,CAAS,sCAAuC,CAC1E,CC/HA,IAAOwI,EAAAA,CAAQ,IAAIhX,CAAAA,CAAO,eAAgB,CACxC,MAAA,CAAQ,CACNgJ,CAAAA,CACAC,GACAC,CAAAA,CACAC,CACF,EACA,OAAA,CAAS,CACP,cAAAoJ,EACF,CAAA,CACA,SAAA,CAAW,CACT,mBAAoBmD,EAAAA,CACpB,iBAAA,CAAmB7D,EAAAA,CACnB,MAAA,CAAQS,GACR,uBAAA,CAAyBkD,EAAAA,CACzB,sBAAA,CAAwBmB,EAAAA,CACxB,cAAeG,EAAAA,CACf,aAAA,CAAepE,GACf,mBAAA,CAAqBM,EACvB,EACA,QAAA,CAAU,CACR,yBAAA,CAA2B7D,EAC7B,EACA,UAAA,CAAY,CACV,CACE,MAAA,CAAQ,SACR,IAAA,CAAM,IAAA,CACN,MAAA,CAAQ7G,CAAAA,CAAK,QAAQ,EAAE,CAAA,CACvB,MAAO,EACT,CAAA,CACA,CACE,MAAA,CAAQ,QAAA,CACR,IAAA,CAAM,IAAA,CACN,OAAQA,CAAAA,CAAK,IAAA,CAAK,CAAC,CAAA,CACnB,KAAA,CAAO,GACT,CAAA,CACA,CACE,MAAA,CAAQ,eAAA,CACR,KAAM,IAAA,CACN,MAAA,CAAQA,EAAK,OAAA,CAAQ,EAAE,EACvB,KAAA,CAAO,EACT,CAAA,CACA,CACE,OAAQ,eAAA,CACR,IAAA,CAAM,IAAA,CACN,MAAA,CAAQA,EAAK,IAAA,CAAK,CAAC,CAAA,CACnB,KAAA,CAAO,GACT,CAAA,CACA,CACE,OAAQ,QAAA,CACR,IAAA,CAAM,KACN,MAAA,CAAQA,CAAAA,CAAK,OAAA,CAAQ,EAAE,EACvB,KAAA,CAAO,EACT,CAAA,CACA,CACE,OAAQ,QAAA,CACR,IAAA,CAAM,IAAA,CACN,MAAA,CAAQA,EAAK,IAAA,CAAK,CAAC,EACnB,KAAA,CAAO,GACT,EACA,CACE,MAAA,CAAQ,cAAA,CACR,IAAA,CAAM,OACN,MAAA,CAAQA,CAAAA,CAAK,OAAA,CAAQ,EAAE,EACvB,KAAA,CAAO,CACT,CAAA,CACA,CACE,OAAQ,cAAA,CACR,IAAA,CAAM,OACN,MAAA,CAAQA,CAAAA,CAAK,KAAK,CAAC,CAAA,CACnB,KAAA,CAAO,EACT,EACA,CACE,MAAA,CAAQ,gBACR,IAAA,CAAM,IAAA,CACN,OAAQA,CAAAA,CAAK,OAAA,CAAQ,EAAE,CAAA,CACvB,MAAO,EACT,CAAA,CACA,CACE,MAAA,CAAQ,eAAA,CACR,KAAM,IAAA,CACN,MAAA,CAAQA,CAAAA,CAAK,IAAA,CAAK,CAAC,CAAA,CACnB,KAAA,CAAO,GACT,CAAA,CACA,CACE,MAAA,CAAQ,eAAA,CACR,IAAA,CAAM,OAAA,CACN,OAAQA,CAAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CACpB,KAAA,CAAO,CACT,CAAA,CACA,CACE,MAAA,CAAQ,eAAA,CACR,KAAM,OAAA,CACN,MAAA,CAAQA,CAAAA,CAAK,IAAA,CAAK,CAAC,CAAA,CACnB,KAAA,CAAO,EACT,CACF,EACA,YAAA,CAAc,CACZ,qBAAsB,CACpB,IAAA,CAAM,UACN,QAAA,CAAU,IAAA,CACV,OAAA,CAAS,IACX,EACA,iBAAA,CAAmB,CACjB,IAAA,CAAM,QAAA,CACN,SAAU,KAAA,CACV,OAAA,CAAS,EACX,CAAA,CACA,0BAA2B,CACzB,IAAA,CAAM,UACN,QAAA,CAAU,IAAA,CACV,QAAS,KACX,CAAA,CACA,qBAAA,CAAuB,CACrB,KAAM,SAAA,CACN,QAAA,CAAU,KACV,OAAA,CAAS,KACX,EACA,sBAAA,CAAwB,CACtB,IAAA,CAAM,QAAA,CACN,SAAU,KAAA,CACV,OAAA,CAAS,EACX,CAAA,CACA,0BAAA,CAA4B,CAC1B,IAAA,CAAM,QAAA,CACN,QAAA,CAAU,KAAA,CACV,QAAS,EACX,CAAA,CACA,qBAAA,CAAuB,CACrB,KAAM,SAAA,CACN,QAAA,CAAU,IAAA,CACV,OAAA,CAAS,KACX,CAAA,CACA,sBAAA,CAAwB,CACtB,IAAA,CAAM,QAAA,CACN,SAAU,KAAA,CACV,OAAA,CAAS,EACX,CAAA,CACA,2BAA4B,CAC1B,IAAA,CAAM,SACN,QAAA,CAAU,KAAA,CACV,QAAS,EACX,CACF,CAAA,CACA,MAAA,CAAQ,CACN,CACE,IAAA,CAAM,mCACN,QAAA,CAAU,CACR,IAAKwM,EACP,CACF,CACF,CACF,CAAC,CAAA,CC1LD,IAAMmC,EAAAA,CAAiB,CACrB,oBAAqB,CACnB,WAAA,CAAa,oBAAA,CACb,iBAAA,CAAmB,0BACnB,6BAAA,CAA+B,kCAAA,CAC/B,gCAAiC,mCAAA,CACjC,mCAAA,CAAqC,wCACrC,6BAAA,CAA+B,kCAAA,CAC/B,+BAAA,CAAiC,mCAAA,CACjC,oCAAqC,uCAAA,CACrC,mCAAA,CAAqC,kCACrC,8BAAA,CAAgC,6BAAA,CAChC,+BAAgC,6BAAA,CAChC,qCAAA,CAAuC,kCAAA,CACvC,yCAAA,CAA2C,uCAC3C,yBAAA,CAA2B,yBAAA,CAC3B,0BAA2B,yBAAA,CAC3B,yBAAA,CAA2B,0BAC3B,yBAAA,CAA2B,yBAAA,CAC3B,kBAAA,CAAoB,kBAAA,CACpB,mBAAoB,kBAAA,CACpB,wBAAA,CAA0B,uBAAA,CAE1B,aAAA,CAAe,cACf,mBAAA,CAAqB,kCAAA,CACrB,qBAAA,CAAuB,mCAAA,CACvB,0BAA2B,uCAC7B,CAAA,CACA,iBAAkB,CAChB,kBAAA,CAAoB,kBACtB,CACF,CAAA,CAEA,SAASC,EAAAA,CAAuBjW,EAAe0K,CAAAA,CAA6C,CAC1F,GAAIA,CAAAA,GAAS,SAAU,CACrB,IAAMwL,CAAAA,CAAW,MAAA,CAAOlW,CAAK,CAAA,CAC7B,GAAI,MAAMkW,CAAQ,CAAA,CAChB,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoClW,CAAK,EAAE,CAAA,CAE7D,OAAOkW,CACT,CACA,GAAIxL,CAAAA,GAAS,SAAA,CAAW,CACtB,GAAI1K,EAAM,WAAA,EAAY,GAAM,OAC1B,OAAO,KAAA,CAET,GAAIA,CAAAA,CAAM,WAAA,EAAY,GAAM,OAAA,CAC1B,OAAO,MAAA,CAET,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqCA,CAAK,CAAA,CAAE,CAC9D,CACA,OAAOA,CACT,CAEA,SAASmW,GACPC,CAAAA,CACA9W,CAAAA,CACa,CACb,IAAM+W,CAAAA,CAAuB,EAAC,CAE9B,OAAW,CAACC,CAAAA,CAAQC,CAAS,CAAA,GAAK,OAAO,OAAA,CAAQH,CAAS,CAAA,CAAG,CAC3D,IAAMpW,CAAAA,CAAQ,OAAA,CAAQ,IAAIsW,CAAM,CAAA,CAC1BE,EAAoBlX,CAAAA,CAAaiX,CAAS,CAAA,CAChD,GAAIvW,EAAO,CACT,IAAM0K,CAAAA,CAAO8L,CAAAA,EAAmB,MAAQ,QAAA,CACxCH,CAAAA,CAAQ,IAAA,CAAK,CACX,IAAKE,CAAAA,CACL,IAAA,CAAM7L,EACN,KAAA,CAAOuL,EAAAA,CAAuBjW,EAAO0K,CAAI,CAC3C,CAAC,EACH,CACF,CAEA,OAAO2L,CACT,CAEO,SAASI,EAAAA,CACdnX,CAAAA,CACAoX,CAAAA,CAA8B,qBAAA,CACjB,CACb,IAAMN,CAAAA,CAAYJ,GAAeU,CAAO,CAAA,CACxC,OAAOP,EAAAA,CAAqBC,CAAAA,CAAW9W,CAAY,CACrD,CCxDA,eAAsBqX,EAAAA,CAAoB,CACxC,YAAA,CAAArX,CAAAA,CACA,gBAAA,CAAAsX,CAAAA,CACA,OAAA3X,CAAAA,CACA,KAAA,CAAAqJ,CACF,CAAA,CAK2C,CACzC,IAAMuO,CAAAA,CAAc,OAAA,CAAQ,GAAA,CAAI,sBAAA,CAChC,GAAI,CAACA,CAAAA,CACH,MAAM,IAAI,MAAM,yEAAyE,CAAA,CAG3F,GAAI,CACF,IAAMC,CAAAA,CAAAA,CAAc7X,CAAAA,EAAU,EAAC,EAAG,GAAA,CAAK8X,IAAW,CAChD,IAAA,CAAMA,CAAAA,CAAM,OAAA,GACZ,MAAA,CAAQA,CAAAA,CAAM,mBAAA,EAAoB,CAClC,YAAa,CAACA,CAAAA,CAAM,OAAA,EAAS,EAC7B,OAAA,CAAS,CAAA,CACT,QAASA,CAAAA,CAAM,UAAA,GACf,aAAA,CAAeA,CAAAA,CAAM,gBAAA,EAAiB,CACtC,kBAAmBA,CAAAA,CAAM,oBAAA,EAC3B,CAAA,CAAE,EAEI9K,CAAAA,CAAO,MAAM+K,EAAAA,CAAqC,cAAA,CAAgB,OAAQ,CAC9E,QAAA,CAAUC,GAAG,QAAA,EAAS,CACtB,YAAAJ,CAAAA,CACA,UAAA,CAAYC,CAAAA,CACZ,YAAA,CAAAxX,EACA,gBAAA,CAAAsX,CAAAA,CACA,MAAAtO,CACF,CAAC,EAED,GAAI2D,CAAAA,CAAK,MAAA,GAAW,OAAA,CAClB,MAAM,IAAI,KAAA,CAAMA,EAAK,KAAK,CAAA,CAG5B,eAAQ,GAAA,CAAI,2CAA2C,CAAA,CAEhDA,CACT,OAASnK,CAAAA,CAAO,CACd,MAAA,OAAA,CAAQ,KAAA,CAAM,wCAAyCA,CAAK,CAAA,CACtDA,CACR,CACF,CAEA,eAAsBoV,EAAAA,EAAe,CACnC,OAAOF,EAAAA,CAAkC,eAAgB,KAAK,CAChE,CAEA,eAAsBG,IAAa,CAIjC,OAHa,MAAMH,EAAAA,CAAQ,WAAA,CAAa,OAAQ,CAC9C,WAAA,CAAa,OAAA,CAAQ,GAAA,CAAI,sBAC3B,CAAC,CAEH,CAEA,eAAeA,EAAAA,CAAqBI,EAAkBrM,CAAAA,CAAgBU,CAAAA,CAAkB,CACtF,OAAO4L,GACLD,CAAAA,CACArM,CAAAA,CACAU,CAAAA,CAAU,IAAA,CAAK,UAAUA,CAAO,CAAA,CAAI,MAAA,CACpCA,CAAAA,CAAU,CAAE,cAAA,CAAgB,kBAAmB,EAAI,EACrD,CACF,CAEA,eAAsB4L,EAAAA,CACpBD,CAAAA,CACArM,EACAuM,CAAAA,CACAC,CAAAA,CACY,CACZ,GAAM,CAAE,2BAAAC,CAAAA,CAA4B,uBAAA,CAAAC,CAAwB,CAAA,CAAI,QAAQ,GAAA,CAExE,GAAI,CAACD,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,6EAA6E,CAAA,CAG/F,IAAMtM,EAAW,MAAM,KAAA,CAAM,CAAA,EAAGsM,CAA0B,GAAGJ,CAAQ,CAAA,CAAA,CAAI,CACvE,MAAA,CAAArM,EACA,OAAA,CAAS,CACP,cAAe,CAAA,OAAA,EAAU0M,CAAuB,GAChD,GAAGF,CACL,CAAA,CACA,IAAA,CAAAD,CACF,CAAC,CAAA,CAED,GAAI,CAACpM,EAAS,EAAA,CAAI,CAChB,IAAMe,CAAAA,CAAO,MAAMf,CAAAA,CAAS,IAAA,GAC5B,GAAI,CACF,IAAMwM,CAAAA,CAAO,IAAA,CAAK,KAAA,CAAMzL,CAAI,EAC5B,MAAM,IAAI,KAAA,CACR,CAAA,mDAAA,EAAsDf,EAAS,MAAM,CAAA,EAAA,EAAKwM,CAAAA,EAAM,KAAK,EACvF,CACF,CAAA,KAAQ,CACN,MAAM,IAAI,MACR,CAAA,mDAAA,EAAsDxM,CAAAA,CAAS,MAAM,CAAA,EAAA,EAAKe,CAAI,CAAA,CAChF,CACF,CACF,CAEA,GAAI,EAAAf,CAAAA,CAAS,MAAA,GAAW,GAAA,EAAOA,CAAAA,CAAS,SAAS,GAAA,CAAI,gBAAgB,IAAM,GAAA,CAAA,CAI3E,OAAQ,MAAMA,CAAAA,CAAS,IAAA,EACzB,CCpIA,IAAIyM,EAAAA,CAAY,KAAA,CAEVC,EAAAA,CAAgBvQ,CAAAA,CAAK,QAAQ,EAAE,CAAA,CAE9B,SAASwQ,EAAAA,EAAkB,CAChC,WAAA,CAAY,SAAY,CACtB,GAAI,CAAAF,GAIJ,CAAAA,EAAAA,CAAY,IAAA,CAGZ,GAAI,CACF,MAAMR,EAAAA,GACR,CAAA,MAASrV,CAAAA,CAAO,CACd,OAAA,CAAQ,KAAA,CAAM,sBAAA,CAAwBA,CAAK,EAC7C,CAEA,GAAI,CACF,MAAMgW,EAAAA,GACR,CAAA,MAAShW,CAAAA,CAAO,CACd,OAAA,CAAQ,MAAM,sBAAA,CAAwBA,CAAK,EAC7C,CAEA6V,GAAY,MAAA,CACd,CAAA,CAAGC,EAAa,EAClB,CAEO,SAASG,EAAAA,CAAkB1B,EAAsB,CACtD2B,CAAAA,CAAY3B,CAAO,CAAA,CACnB2B,CAAAA,CAAYvB,EAAAA,CAAgBwB,GAAAA,GAAa,kBAAkB,CAAC,EAC9D,CAEA,eAAeH,IAAa,CAC1B,GAAM,CAAE,OAAA,CAAAzB,CAAQ,CAAA,CAAI,MAAMa,IAAa,CACvCa,EAAAA,CAAkB1B,CAAO,EAC3B,CClCO,IAAM6B,CAAAA,CAAkB,IAAI/V,CAAAA,CAAM,kBAAmB,CAC1D,MAAA,CAAQ,CACN,GAAA,CAAKhC,CAAAA,CAAO,QAAO,CACnB,UAAA,CAAYA,CAAAA,CAAO,MAAA,GACnB,UAAA,CAAYA,CAAAA,CAAO,IAAA,EAAK,CAExB,SAAUA,CAAAA,CAAO,MAAA,EACnB,CAAA,CACA,QAAS,CACP,CAEE,IAAK,CAAE,QAAA,CAAU,CAAE,CAAA,CACnB,MAAA,CAAQ,IACV,CAAA,CACA,CAEE,GAAA,CAAK,CAAE,QAAA,CAAU,CAAA,CAAG,WAAY,CAAE,CACpC,CAAA,CACA,CAEE,IAAK,CAAE,QAAA,CAAU,EAAG,UAAA,CAAY,CAAE,CACpC,CACF,CAAA,CACA,iBAAA,CAAmB,UACrB,CAAC,CAAA,CCvBD,IAAMgY,EAMF,EAAC,CAKCC,GAAyB/Q,CAAAA,CAAK,OAAA,CAAQ,EAAE,CAAA,CAMxCgR,GAAcnR,WAAAA,CAAY,EAAE,EAAE,QAAA,CAAS,WAAW,EAKlDoR,EAAAA,CAAwBjR,CAAAA,CAAK,OAAA,CAAQ,EAAE,EAkBvCkR,EAAAA,CAAiB,IAAI,GAAA,CAOrBC,EAAAA,CAAuB1W,GAC3BA,CAAAA,YAAiBC,UAAAA,EAAcD,CAAAA,CAAM,IAAA,GAAS,KAE1C2W,EAAAA,CAAqB,CAAC3W,EAA+BlB,CAAAA,GACzD,OAAOkB,EAAM,UAAA,EAAe,QAAA,EAC5BA,CAAAA,CAAM,UAAA,GAAe,MACrB,MAAA,CAAO,SAAA,CAAU,eAAe,IAAA,CAAKA,CAAAA,CAAM,WAAYlB,CAAK,CAAA,CAOxD8X,EAAAA,CAAiC,MAAO,CAC5C,KAAA,CAAA5W,CAAAA,CACA,SAAA6W,CACF,CAAA,GAGwB,CACtB,GAAIF,EAAAA,CAAmB3W,CAAAA,CAAO,UAAU,EACtC,OAAO,KAAA,CAGT,GAAI2W,EAAAA,CAAmB3W,EAAO,KAAK,CAAA,CACjC,OAAO,MAAA,CAGT,IAAM8W,CAAAA,CAAgB,MAAMV,EAAgB,OAAA,CAAQ,CAAE,SAAAS,CAAS,CAAC,CAAA,CAIhE,OAAO,CAAC,CAACC,CAAAA,EAAgBA,EAAa,GAAA,GAAQD,CAChD,EAEME,EAAAA,CAAqB,MAAO,CAChC,QAAA,CAAAF,EACA,kBAAA,CAAAG,CAAAA,CACA,WAAAC,CACF,CAAA,GAIwB,CACtB,IAAMnU,CAAAA,CAAS,MAAMsT,CAAAA,CAAgB,UACnC,CACE,GAAA,CAAKS,CAAAA,CACL,GAAA,CAAK,CAAC,CAAE,UAAA,CAAAI,CAAW,CAAA,CAAG,CAAE,UAAA,CAAY,CAAE,IAAKD,CAAmB,CAAE,CAAC,CACnE,CAAA,CACA,CACE,IAAA,CAAM,CACJ,QAAA,CAAAH,CAAAA,CACA,UAAA,CAAAI,CAAAA,CACA,WAAY,IAAI,IAClB,CAAA,CACA,YAAA,CAAc,CACZ,GAAA,CAAKJ,CACP,CACF,CACF,CAAA,CAEA,OAAO/T,CAAAA,CAAO,aAAA,CAAgB,CAAA,EAAKA,CAAAA,CAAO,cAAgB,CAC5D,CAAA,CAEMoU,EAAAA,CAAmB,MAAO,CAC9B,QAAA,CAAAL,CAAAA,CACA,UAAA,CAAAI,CAAAA,CACA,mBAAAD,CACF,CAAA,GAIwB,CACtB,IAAMtU,CAAAA,CAAWsU,EACb,CACE,QAAA,CAAAH,CAAAA,CACA,GAAA,CAAK,CAAE,GAAA,CAAKA,CAAS,EACrB,GAAA,CAAK,CAAC,CAAE,UAAA,CAAAI,CAAW,CAAA,CAAG,CAAE,WAAY,CAAE,GAAA,CAAKD,CAAmB,CAAE,CAAC,CACnE,CAAA,CACA,CACE,QAAA,CAAAH,CAAAA,CACA,WAAAI,CACF,CAAA,CAIJ,OAAA,CAF2B,MAAMb,EAAgB,SAAA,CAAU1T,CAAQ,CAAA,EAEzC,YAAA,CAAe,CAC3C,CAAA,CAEMyU,EAAAA,CAAqBN,GAAqB,CAC9C,IAAMO,EAAeP,CAAAA,CACfQ,CAAAA,CAAYZ,EAAAA,CAAe,GAAA,CAAIW,CAAY,CAAA,CAC5CC,CAAAA,GAILA,CAAAA,CAAU,aAAA,CAAgB,KACtBA,CAAAA,CAAU,KAAA,GACZ,YAAA,CAAaA,CAAAA,CAAU,KAAK,CAAA,CAC5BA,CAAAA,CAAU,MAAQ,IAAA,CAAA,CAGpBZ,EAAAA,CAAe,OAAOW,CAAY,CAAA,EACpC,CAAA,CAEME,EAAAA,CAAqB,CAAC,CAC1B,QAAA,CAAAT,CAAAA,CACA,YAAA,CAAAU,EACA,UAAA,CAAAN,CACF,CAAA,GAIM,CACJ,IAAMO,CAAAA,CAAoB,IAAA,CAAK,MAAMD,CAAAA,CAAe,CAAC,EAC/CH,CAAAA,CAAeP,CAAAA,CACfY,GAAAA,CAAoBhB,EAAAA,CAAe,IAAIW,CAAY,CAAA,CAEzD,GACEK,GAAAA,EACA,CAACA,IAAkB,aAAA,EACnBA,GAAAA,CAAkB,iBAAA,GAAsBD,CAAAA,EACxCC,IAAkB,YAAA,GAAiBF,CAAAA,CAEnC,OAGEE,GAAAA,GACFA,GAAAA,CAAkB,cAAgB,IAAA,CAC9BA,GAAAA,CAAkB,KAAA,GACpB,YAAA,CAAaA,IAAkB,KAAK,CAAA,CACpCA,GAAAA,CAAkB,KAAA,CAAQ,MAE5BhB,EAAAA,CAAe,MAAA,CAAOW,CAAY,CAAA,CAAA,CAGpC,IAAMC,CAAAA,CAA2B,CAC/B,MAAO,IAAA,CACP,aAAA,CAAe,MACf,YAAA,CAAAE,CAAAA,CACA,iBAAA,CAAAC,CACF,EAEME,CAAAA,CAAkB,IAAM,CAC5BL,CAAAA,CAAU,MAAQ,UAAA,CAAW,IAAM,CACjCM,CAAAA,CAAYd,EAAU,CACpB,YAAA,CAAAU,EACA,WAAA,CAAa,IAAA,CACb,WAAAN,CACF,CAAC,CAAA,CACE,IAAA,CAAMW,GAAmB,CACnBA,CAAAA,GACHP,CAAAA,CAAU,aAAA,CAAgB,KAC1BQ,CAAAA,CAAS,CAAA,sCAAA,EAAyChB,CAAQ,CAAA,CAAA,CAAI,CAC5D,MAAA,CAAQ,MAAA,CACR,SAAAA,CAAAA,CACA,UAAA,CAAAI,CACF,CAAC,CAAA,EAEL,CAAC,CAAA,CACA,QAAQ,IAAM,CACb,GAAII,CAAAA,CAAU,aAAA,CAAe,CAC3BZ,EAAAA,CAAe,MAAA,CAAOW,CAAY,CAAA,CAClC,MACF,CACAM,CAAAA,GACF,CAAC,EACL,EAAGF,CAAiB,EACtB,CAAA,CAEAf,EAAAA,CAAe,IAAIW,CAAAA,CAAcC,CAAS,CAAA,CAC1CK,CAAAA,GACF,CAAA,CAgBA,eAAsBC,CAAAA,CACpBd,CAAAA,CACA,CACE,YAAA,CAAAU,CAAAA,CAAef,GACf,2BAAA,CAAAsB,CAAAA,CAA8BxB,GAC9B,uBAAA,CAAAyB,CAAAA,CAA0BzB,EAAAA,CAC1B,SAAA,CAAAe,EACA,WAAA,CAAAW,GAAAA,CACA,WAAAf,CAAAA,CAAaV,EACf,EAAiB,EAAC,CACA,CAClB,IAAMlR,EAAM,IAAA,CAAK,GAAA,GACjB,GAAI,CAAC2S,KAAe3B,CAAAA,CAAUQ,CAAQ,CAAA,EAAKxR,CAAAA,CAAMgR,EAAUQ,CAAQ,CAAA,CAAE,SAAA,CACnE,OAAIR,EAAUQ,CAAQ,CAAA,CAAE,KAAA,EAASQ,CAAAA,EAC/BC,GAAmB,CACjB,QAAA,CAAAT,EACA,YAAA,CAAAU,CAAAA,CACA,WAAAN,CACF,CAAC,CAAA,CAEIZ,CAAAA,CAAUQ,CAAQ,CAAA,CAAE,KAAA,CAG7B,IAAMG,CAAAA,CAAqB,IAAI,KAAK3R,CAAAA,CAAMkS,CAAY,CAAA,CAEtDM,CAAAA,CAAS,+BAA+BhB,CAAQ,CAAA,CAAA,CAAI,CAClD,MAAA,CAAQ,MAAA,CACR,SAAAA,CAAAA,CACA,UAAA,CAAAI,CACF,CAAC,EAED,GAAI,CACF,IAAMW,CAAAA,CAAiB,MAAMK,EAAAA,CAAgB,CAC3C,QAAA,CAAApB,CAAAA,CACA,mBAAAG,CAAAA,CACA,UAAA,CAAAC,CACF,CAAC,CAAA,CAED,OAAAZ,CAAAA,CAAUQ,CAAQ,CAAA,CAAI,CACpB,MAAOe,CAAAA,CACP,SAAA,CAAWvS,CAAAA,EAAOuS,CAAAA,CAAiBE,EAA8BC,CAAAA,CACnE,CAAA,CAEIH,CAAAA,EACEP,CAAAA,EACFC,GAAmB,CACjB,QAAA,CAAAT,EACA,YAAA,CAAAU,CAAAA,CACA,WAAAN,CACF,CAAC,CAAA,CAGHY,CAAAA,CAAS,kBAAkBhB,CAAQ,CAAA,CAAA,CAAI,CACrC,MAAA,CAAQ,OACR,QAAA,CAAAA,CAAAA,CACA,UAAA,CAAAI,CACF,CAAC,CAAA,EAEDY,CAAAA,CAAS,0CAA0ChB,CAAQ,CAAA,CAAA,CAAI,CAC7D,MAAA,CAAQ,MAAA,CACR,QAAA,CAAAA,CAAAA,CACA,WAAAI,CACF,CAAC,EAGIW,CACT,CAAA,KAAQ,CACN,OAAAvB,CAAAA,CAAUQ,CAAQ,CAAA,CAAI,CACpB,KAAA,CAAO,KAAA,CACP,UAAWxR,CAAAA,CAAM0S,CACnB,EACAF,CAAAA,CAAS,CAAA,uCAAA,EAA0ChB,CAAQ,CAAA,CAAA,CAAI,CAC7D,MAAA,CAAQ,MAAA,CACR,QAAA,CAAAA,CAAAA,CACA,WAAAI,CACF,CAAC,CAAA,CACM,KACT,CACF,CAEA,IAAMgB,GAAkB,MAAO,CAC7B,SAAApB,CAAAA,CACA,kBAAA,CAAAG,CAAAA,CACA,UAAA,CAAAC,CACF,CAAA,GAIwB,CACtB,GAAI,CACF,OAAO,MAAMF,EAAAA,CAAmB,CAAE,QAAA,CAAAF,EAAU,kBAAA,CAAAG,CAAAA,CAAoB,WAAAC,CAAW,CAAC,CAC9E,CAAA,MAASjX,CAAAA,CAAO,CAKd,GAAI0W,GAAoB1W,CAAK,CAAA,EAAM,MAAM4W,EAAAA,CAA+B,CAAE,KAAA,CAAA5W,CAAAA,CAAO,QAAA,CAAA6W,CAAS,CAAC,CAAA,CAAI,CAO7F,GAAI,CANyB,MAAMK,GAAiB,CAClD,QAAA,CAAAL,CAAAA,CACA,kBAAA,CAAAG,EACA,UAAA,CAAAC,CACF,CAAC,CAAA,CAGC,OAAO,OAGT,GAAI,CACF,OAAO,MAAMF,GAAmB,CAAE,QAAA,CAAAF,EAAU,kBAAA,CAAAG,CAAAA,CAAoB,WAAAC,CAAW,CAAC,CAC9E,CAAA,MAAS5L,EAAY,CACnB,GAAIqL,EAAAA,CAAoBrL,CAAU,EAChC,OAAO,MAAA,CAET,MAAMA,CACR,CACF,CAGA,GAAIqL,GAAoB1W,CAAK,CAAA,CAC3B,OAAO,MAAA,CAGT,MAAMA,CACR,CACF,EASA,eAAsBkY,EAAAA,CACpBrB,CAAAA,CACA,CACE,WAAAI,CAAAA,CAAaV,EACf,CAAA,CAEI,GACc,CAClBY,EAAAA,CAAkBN,CAAQ,CAAA,CAE1B,GAAI,CACF,IAAM/T,CAAAA,CAAS,MAAMsT,CAAAA,CAAgB,UAAU,CAC7C,GAAA,CAAKS,CAAAA,CACL,UAAA,CAAAI,CACF,CAAC,CAAA,CAGD,OAAInU,CAAAA,CAAO,eAAiB,CAAA,CACG,MAAMoU,GAAiB,CAClD,QAAA,CAAAL,EACA,UAAA,CAAAI,CACF,CAAC,CAAA,CAKInU,EAAO,YAAA,CAAe,CAC/B,MAAQ,CACN,OAAO,MACT,CAAA,OAAE,CACA,OAAOuT,CAAAA,CAAUQ,CAAQ,EAC3B,CACF,CChZA,IAAMtZ,CAAAA,CAAoC,EAAC,CACvC4a,EAAAA,CAA0C,IAAA,CAExCC,EAAAA,CAAqB,IAAI/X,CAAAA,CAAM,oBAAA,CAAsB,CACzD,MAAA,CAAQ,CACN,KAAA,CAAOhC,CAAAA,CAAO,MAAA,EAAO,CACrB,cAAeA,CAAAA,CAAO,IAAA,GAAO,QAAA,EAC/B,EACA,OAAA,CAAS,CAAC,CAAE,GAAA,CAAK,CAAE,KAAA,CAAO,CAAE,EAAG,MAAA,CAAQ,IAAA,CAAM,WAAY,IAAK,CAAC,CACjE,CAAC,EAGM,SAASga,EAAAA,CACdC,EACA,CACE,WAAA,CAAAC,EAAc,EAAA,CACd,QAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,EAAU,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAID,EAAUjT,CAAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,EAAGA,CAAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA,CACpE,QAAAsD,CACF,CAAA,CACA,CACA,GAAItL,EAAS+a,CAAK,CAAA,CAChB,MAAM,IAAI,KAAA,CAAM,oCAAoCA,CAAK,CAAA,gBAAA,CAAkB,CAAA,CAG7E,GAAIH,GACF,MAAM,IAAI,MACR,CAAA,qEAAA,EAAwEG,CAAK,GAC/E,CAAA,CAGF,GAAIE,CAAAA,CAAWjT,CAAAA,CAAK,QAAQ,CAAC,CAAA,CAC3B,MAAM,IAAI,MAAM,CAAA,oDAAA,EAAuD+S,CAAK,CAAA,CAAA,CAAG,CAAA,CAGjF,GAAIG,CAAAA,CAAUlT,CAAAA,CAAK,KAAK,CAAC,CAAA,CACvB,MAAM,IAAI,KAAA,CAAM,CAAA,kDAAA,EAAqD+S,CAAK,GAAG,CAAA,CAG/E/a,CAAAA,CAAS+a,CAAK,CAAA,CAAI,CAChB,KAAA,CAAAA,CAAAA,CACA,MAAA,CAAQ,CAAE,YAAAC,CAAAA,CAAa,QAAA,CAAAC,EAAU,OAAA,CAAAC,CAAQ,EACzC,OAAA,CAAA5P,CAAAA,CACA,KAAA,CAAO,CACL,UAAW,KACb,CACF,EACF,CAEA,eAAsB6P,EAAAA,EAAgB,CACpC,GAAIP,EAAAA,CACF,MAAM,IAAI,KAAA,CAAM,2BAA2B,CAAA,CAG7C,IAAMQ,EAAY,MAAA,CAAO,IAAA,CAAKpb,CAAQ,CAAA,CACtC,GAAIob,CAAAA,CAAU,MAAA,CAAS,EAAG,CACxB,IAAMC,EAAgB,CAAE,KAAA,CAAO,CAAE,GAAA,CAAKD,CAAU,CAAE,CAAA,CAE5CE,EAAiB,MAAMT,EAAAA,CAAmB,MAAMQ,CAAa,CAAA,CAC7DvT,CAAAA,CAAM,IAAA,CAAK,KAAI,CACrBwT,CAAAA,CAAe,OAAA,CAAS7H,CAAAA,EAAW,CACjC,IAAM8H,CAAAA,CAAMvb,CAAAA,CAASyT,CAAAA,CAAO,KAAK,CAAA,CAC5B8H,CAAAA,GAGLA,EAAI,KAAA,CAAM,cAAA,CAAiB9H,EAAO,aAAA,CAC9BA,CAAAA,CAAO,aAAA,CAAc,OAAA,GAAY8H,CAAAA,CAAI,MAAA,CAAO,QAAA,CAC5CzT,CAAAA,EACN,CAAC,CAAA,CACD,MAAA,CAAO,MAAA,CAAO9H,CAAQ,EAAE,OAAA,CAASub,CAAAA,EAAQ,CAClCA,CAAAA,CAAI,KAAA,CAAM,iBACbA,CAAAA,CAAI,KAAA,CAAM,cAAA,CAAiBzT,CAAAA,EAE/B,CAAC,CAAA,CAED8S,EAAAA,CAAmB,WAAA,CAAYY,EAAAA,CAAcxT,EAAK,OAAA,CAAQ,CAAC,CAAC,EAC9D,CACF,CAEA,eAAewT,IAAe,CAC5B,IAAM1T,EAAM,IAAA,CAAK,GAAA,EAAI,CAEJ,MAAMsS,EAAY,MAAA,CAAQ,CACzC,4BAA6BpS,CAAAA,CAAK,OAAA,CAAQ,EAAE,CAAA,CAC5C,uBAAA,CAAyBA,CAAAA,CAAK,OAAA,CAAQ,EAAE,CAC1C,CAAC,GAMD,MAAA,CAAO,MAAA,CAAOhI,CAAQ,CAAA,CAAE,OAAA,CAAQ,MAAOub,CAAAA,EAAQ,CAC7C,GAAM,CAAE,MAAA,CAAA9G,CAAAA,CAAQ,MAAAgH,CAAM,CAAA,CAAIF,CAAAA,CAC1B,GAAIE,EAAM,SAAA,CAAW,CACfA,EAAM,OAAA,EAAWA,CAAAA,CAAM,QAAUhH,CAAAA,CAAO,OAAA,CAAU3M,CAAAA,GAEpD2T,CAAAA,CAAM,UAAY,KAAA,CAAA,CAEpB,MACF,CAIIA,CAAAA,CAAM,gBAAkBA,CAAAA,CAAM,cAAA,EAAkB3T,CAAAA,EAClD,MAAM4T,GAAWH,CAAG,EAExB,CAAC,EACH,CAEA,eAAeG,EAAAA,CAAWH,CAAAA,CAAc,CACtC,GAAM,CAAE,KAAA,CAAAR,CAAAA,CAAO,MAAA,CAAAtG,CAAAA,CAAQ,QAAAnJ,CAAAA,CAAS,KAAA,CAAAmQ,CAAM,CAAA,CAAIF,EAC1CE,CAAAA,CAAM,SAAA,CAAY,KAClBA,CAAAA,CAAM,OAAA,CAAU,KAAK,GAAA,EAAI,CAEzB,MAAMZ,EAAAA,CAAmB,UACvB,CAAE,KAAA,CAAAE,CAAM,CAAA,CACR,CACE,KAAM,CACJ,aAAA,CAAe,IAAI,IAAA,CAAKU,EAAM,OAAO,CACvC,CACF,CACF,CAAA,CAEA,IAAM9P,CAAAA,CAAcC,CAAAA,CAAiB,MAAA,CAAQ,CAAA,KAAA,EAAQmP,CAAK,CAAA,CAAE,CAAA,CAE5D,GAAI,CACF,MAAMzP,CAAAA,EAAQ,CACdqQ,EAAAA,CAAwBF,CAAAA,CAAOhH,CAAM,CAAA,CACrC9I,CAAAA,CAAY,IAAI,SAAS,EAC3B,OAAStB,CAAAA,CAAK,CACZsR,EAAAA,CAAwBF,CAAAA,CAAOhH,CAAM,CAAA,CACrC,IAAMhS,EAAQ4H,CAAAA,YAAe,KAAA,CAAQA,EAAM,IAAI,KAAA,CAAM,MAAA,CAAOA,CAAG,CAAC,CAAA,CAChEuR,GAAAA,CAAanZ,CAAK,CAAA,CAClBkJ,CAAAA,CAAY,IAAI,OAAO,CAAA,CACvB,OAAA,CAAQ,KAAA,CAAM,sBAAsBoP,CAAK,CAAA,EAAA,CAAA,CAAM1Q,CAAG,EACpD,CACF,CAEA,SAASsR,EAAAA,CAAwBF,CAAAA,CAAyBhH,EAA2B,CACnFgH,CAAAA,CAAM,eAAiBA,CAAAA,CAAM,OAAA,CAAUA,EAAM,OAAA,CAAUhH,CAAAA,CAAO,QAAA,CAAW,IAAA,CAAK,KAAI,CAClFgH,CAAAA,CAAM,QAAU,MAAA,CAChBA,CAAAA,CAAM,UAAY,MACpB,CAEO,SAASI,EAAAA,EAAsB,CACpC,OAAO,MAAA,CAAO,OAAO7b,CAAQ,CAAA,CAAE,IAAI,CAAC,CAAE,KAAA,CAAA+a,CAAAA,CAAO,OAAAtG,CAAO,CAAA,IAAO,CACzD,KAAA,CAAAsG,EACA,WAAA,CAAatG,CAAAA,CAAO,WAAA,CACpB,QAAA,CAAUA,EAAO,QAAA,CACjB,OAAA,CAASA,EAAO,OAClB,CAAA,CAAE,CACJ,CAEA,IAAOqH,EAAAA,CAAQ,IAAIpc,EAAO,cAAA,CAAgB,CACxC,MAAA,CAAQ,CAACmb,EAAkB,CAC7B,CAAC,CAAA,CChJM,SAASkB,GAAcnc,CAAAA,CAA2C,CACvE,IAAMoc,CAAAA,CAAe,CAAC,GAAG,IAAI,GAAA,CAAIpc,CAAM,CAAC,EAGlCqc,CAAAA,CAAa,IAAI,GAAA,CACvB,IAAA,IAAWvE,KAASsE,CAAAA,CAAc,CAChC,IAAME,CAAAA,CAAOxE,EAAM,YAAA,EAAa,CAChCuE,EAAW,GAAA,CAAIC,CAAAA,CAAMA,EAAK,YAAA,EAAc,EAC1C,CAEA,IAAMC,CAAAA,CAAkB,CAAC,GAAG,IAAI,GAAA,CAAIF,EAAW,MAAA,EAAQ,CAAC,CAAA,CAGlDG,EAAa,IAAI,GAAA,CACvB,OAAW,CAACF,CAAAA,CAAMhZ,CAAI,CAAA,GAAK+Y,CAAAA,CAAY,CACrC,IAAMtc,EAAOuD,CAAAA,CAAK,OAAA,EAAQ,CACpBf,CAAAA,CAAWia,EAAW,GAAA,CAAIzc,CAAI,CAAA,CACpC,GAAIwC,IAAa,MAAA,EAAaA,CAAAA,GAAa+Z,EACzC,MAAM,IAAI,MACR,CAAA,gEAAA,EAAmEvc,CAAI,CAAA,kFAAA,CAEzE,CAAA,CAEFyc,EAAW,GAAA,CAAIzc,CAAAA,CAAMuc,CAAI,EAC3B,CAEA,OAAO,CAAE,YAAA,CAAcF,CAAAA,CAAc,eAAA,CAAAG,CAAgB,CACvD,CC1CA,IAAOE,EAAAA,CAAQ,IAAI3c,EAAO,cAAA,CAAgB,CACxC,MAAA,CAAQ,CAACmZ,CAAe,CAC1B,CAAC,CAAA,CCLM,IAAMyD,GAAe,IAAIxZ,CAAAA,CAAM,sBAAA,CAAwB,CAC5D,OAAQ,CACN,OAAA,CAAShC,EAAO,MAAA,EAAO,CACvB,OAAQA,CAAAA,CAAO,IAAA,CAAK,CAAC,WAAA,CAAa,QAAQ,CAAC,CAAA,CAC3C,YAAaA,CAAAA,CAAO,MAAA,GAAS,QAAA,EAAS,CACtC,MAAA,CAAQA,CAAAA,CAAO,QAAO,CAAE,QAAA,GACxB,SAAA,CAAWA,CAAAA,CAAO,MACpB,CAAA,CACA,OAAA,CAAS,CAAC,CAAE,GAAA,CAAK,CAAE,OAAA,CAAS,CAAE,EAAG,MAAA,CAAQ,IAAK,CAAA,CAAG,CAAE,IAAK,CAAE,OAAA,CAAS,EAAG,MAAA,CAAQ,CAAE,CAAE,CAAC,CACrF,CAAC,CAAA,CCGD,eAAsByb,EAAAA,CACpBC,CAAAA,CACA,CAAE,QAAA,CAAAC,EAAW,SAAU,CAAA,CAAyB,EAAC,CACjD,CACA,GAAID,CAAAA,CAAW,SAAW,CAAA,CAI1B,CAAA,GAAIC,IAAa,SAAA,EAGX,CAFY,MAAMrC,CAAAA,CAAY,YAAY,CAAA,CAEhC,CACZsC,GAAAA,CAAQ,iEAAA,CAAmE,CACzE,MAAA,CAAQ,YACV,CAAC,CAAA,CACD,MACF,CAGF,GAAI,CACF,IAAMC,CAAAA,CAAWH,EAAW,GAAA,CAAI,CAAC,CAAE,OAAA,CAAAI,CAAQ,CAAA,GAAMA,CAAO,EAElDC,CAAAA,CAAmB,MAAMP,GAAa,KAAA,CAAM,CAChD,OAAA,CAAS,CAAE,IAAKK,CAAS,CAC3B,CAAC,CAAA,CACKG,CAAAA,CAAqB,IAAI,GAAA,CAAID,CAAAA,CAAiB,GAAA,CAAI,CAAC,CAAE,OAAA,CAAAD,CAAQ,CAAA,GAAMA,CAAO,CAAC,CAAA,CAC3EG,CAAAA,CAAoBP,CAAAA,CAAW,MAAA,CAAO,CAAC,CAAE,OAAA,CAAAI,CAAQ,CAAA,GAAM,CAACE,EAAmB,GAAA,CAAIF,CAAO,CAAC,CAAA,CAE7F,GAAIG,CAAAA,CAAkB,MAAA,GAAW,EAC/B,OAGFL,GAAAA,CAAQ,uBAAuBK,CAAAA,CAAkB,MAAM,CAAA,IAAA,CAAA,CAAQ,CAC7D,OAAQ,YACV,CAAC,EACD,IAAA,GAAW,CAAE,QAAAH,CAAAA,CAAS,WAAA,CAAA5B,CAAAA,CAAa,OAAA,CAAA1P,CAAQ,CAAA,GAAKyR,CAAAA,CAAmB,CACjEL,GAAAA,CAAQ,sBAAsBE,CAAO,CAAA,EAAA,EAAK5B,CAAW,CAAA,CAAA,CAAI,CACvD,MAAA,CAAQ,YACV,CAAC,CAAA,CACD,GAAI,CAEF,IAAMgC,CAAAA,CAAAA,CADS,MAAM1R,CAAAA,IACQ,EAAA,EAAI,QAAA,GAAW,IAAA,EAAK,CAC3C2R,EAAU,EAAA,CAAK,IAAA,CAAO,IAAA,CACtBC,CAAAA,CACJF,EAAU,MAAA,CAASC,CAAAA,CACfD,EAAU,KAAA,CAAM,CAAA,CAAGC,CAAO,CAAA,CAAI;AAAA,wCAAA,CAAA,CAC9BD,CAAAA,CACN,MAAMV,EAAAA,CAAa,SAAA,CACjB,CACE,QAAAM,CACF,CAAA,CACA,CACE,IAAA,CAAM,CACJ,OAAA,CAAAA,EACA,MAAA,CAAQ,WAAA,CACR,WAAA,CAAA5B,CAAAA,CACA,MAAA,CAAQkC,CAAAA,CACR,SAAA,CAAW,IAAI,IACjB,CACF,CACF,CAAA,CACAR,GAAAA,CAAQ,CAAA,WAAA,EAAcE,CAAO,CAAA,SAAA,CAAA,CAAa,CACxC,MAAA,CAAQ,YACV,CAAC,EACH,OAAS9K,CAAAA,CAAG,CACNA,CAAAA,YAAa,KAAA,GACf,MAAMwK,EAAAA,CAAa,UACjB,CACE,OAAA,CAAAM,CACF,CAAA,CACA,CACE,IAAA,CAAM,CACJ,OAAA,CAAAA,CAAAA,CACA,MAAA,CAAQ,QAAA,CACR,WAAA,CAAA5B,CAAAA,CACA,MAAA,CAAQlJ,EAAE,OAAA,EAAW,EAAA,CACrB,SAAA,CAAW,IAAI,IACjB,CACF,CACF,CAAA,CACA4K,GAAAA,CAAQ,CAAA,WAAA,EAAcE,CAAO,CAAA,YAAA,EAAe9K,CAAAA,CAAE,OAAO,CAAA,CAAA,CAAI,CACvD,MAAA,CAAQ,YACV,CAAC,CAAA,EAEL,CACF,CACF,CAAA,OAAE,CACI2K,CAAAA,GAAa,SAAA,EACf,MAAM9B,EAAAA,CAAY,YAAY,EAElC,CAAA,CACF,CAEO,SAASwC,EAAAA,CAAgBX,CAAAA,CAA+B,CAC7D,UAAA,CAAW,IAAM,CACfD,EAAAA,CAAcC,CAAU,CAAA,CAAE,MAAOnS,CAAAA,EAAQ,CACvC,OAAA,CAAQ,KAAA,CAAM,2BAAA,CAA6BA,CAAG,EAChD,CAAC,EACH,CAAA,CAAG,CAAC,EACN,CAEA,IAAO+S,GAAQ,IAAI1d,CAAAA,CAAO,mBAAA,CAAqB,CAC7C,MAAA,CAAQ,CAAC4c,EAAY,CACvB,CAAC,CAAA,CCnHD,IAAOe,EAAAA,CAAQ,IAAI3d,EAAO,mBAAA,CAAqB,CAC7C,MAAA,CAAQ,CAACoT,EAAY,CACvB,CAAC,CAAA,CCQD,eAAsBwK,EAAAA,CAAa,CACjC,QAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,EACA,UAAA,CAAAC,CACF,CAAA,CAIgC,CAC9B,OAAO,MAAMzF,GACX,mBAAA,CACA,MAAA,CACA,IAAA,CAAK,SAAA,CAAU,CAAE,QAAA,CAAAuF,EAAU,WAAA,CAAAC,CAAAA,CAAa,UAAA,CAAAC,CAAW,CAAC,CAAA,CACpD,CACE,cAAA,CAAgB,kBAClB,CACF,CACF,CAEA,eAAsBC,EAAAA,CAAWH,EAAiC,CAChE,MAAMvF,EAAAA,CAAmB,mBAAA,CAAqB,MAAA,CAAQ,IAAA,CAAK,UAAU,CAAE,QAAA,CAAAuF,CAAS,CAAC,CAAA,CAAG,CAClF,eAAgB,kBAClB,CAAC,EACH,CAEA,eAAsBI,EAAAA,CAAaJ,CAAAA,CAA+C,CAChF,OAAO,MAAMvF,EAAAA,CACX,qBAAA,CACA,MAAA,CACA,IAAA,CAAK,UAAU,CAAE,QAAA,CAAAuF,CAAS,CAAC,CAAA,CAC3B,CACE,eAAgB,kBAClB,CACF,CACF,CAEA,eAAsBK,EAAAA,CAAWL,EAA6C,CAC5E,OAAO,MAAMvF,EAAAA,CACX,gBAAA,CACA,MAAA,CACA,IAAA,CAAK,SAAA,CAAU,CAAE,QAAA,CAAAuF,CAAS,CAAC,CAAA,CAC3B,CACE,eAAgB,kBAClB,CACF,CACF,CAEA,IAAOM,EAAAA,CAAQ,IAAIne,CAAAA,CAAO,eAAA,CAAiB,CACzC,OAAA,CAAS,CACP,MAAM,aAAa,CAAE,QAAA,CAAA6d,CAAS,CAAA,CAAG,CAC/B,OAAOI,EAAAA,CAAaJ,CAAkB,CACxC,CAAA,CACA,MAAM,UAAA,CAAW,CAAE,QAAA,CAAAA,CAAS,CAAA,CAAG,CAC7B,OAAOK,EAAAA,CAAWL,CAAkB,CACtC,CACF,CAAA,CACA,SAAA,CAAW,CACT,MAAM,YAAA,CAAa,CAAE,SAAAA,CAAAA,CAAU,WAAA,CAAAC,CAAAA,CAAa,UAAA,CAAAC,CAAW,CAAA,CAAG,CACxD,OAAOH,EAAAA,CAAa,CAClB,QAAA,CAAUC,CAAAA,CACV,WAAA,CAAaC,CAAAA,CACb,WAAYC,CACd,CAAC,CACH,CAAA,CACA,MAAM,UAAA,CAAW,CAAE,QAAA,CAAAF,CAAS,CAAA,CAAG,CAC7B,OAAOG,EAAAA,CAAWH,CAAkB,CACtC,CACF,CACF,CAAC,CAAA,CCjED,IAAMO,GAAN,KAAsC,CAIpC,MAAM,IAAA,CAAK,CAAE,UAAA,CAAApQ,CAAW,CAAA,CAAyB,CAC/C,IAAA,CAAK,MAAA,CAAS,MAAMrN,EAAAA,CAAU,IAAA,CAAK,OAAM,CAAIqN,CAAAA,CAAa,MAAS,CAAA,CAC/D,IAAA,CAAK,KAAA,KACP,OAAA,CAAQ,GAAA,CAAI,6BAA6B,CAAA,CACzC,IAAA,CAAK,UAAA,CAAa,MAAMqQ,YAAAA,CAAa,IAAA,CAAK,MAAM,CAAA,EAEpD,CAEA,WAAA,EAAmC,CACjC,GAAI,IAAA,CAAK,KAAA,EAAM,CACb,OAAQ,IAAA,CAAK,UAAA,EAAY,aAAe,EAAC,CAG3C,IAAMC,CAAAA,CAAgB,CAACC,CAAAA,CAAQ,OAAO,2BAAA,CAA4B,OAAA,CAAQ,KAAA,CAAO,GAAG,CAAC,CAAC,EACtF,OAAI,IAAA,CAAK,MAAA,EAAQ,SAAA,EACfD,CAAAA,CAAc,IAAA,CAAKC,CAAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,SAAS,CAAC,CAAA,CAEnDD,CACT,CAEA,OAAA,CAAQE,CAAAA,CAAsB7V,CAAAA,CAAuB,CACnD,GAAI,IAAA,CAAK,OAAM,CACb,GAAI,CAOFA,CAAAA,CAAI,SAAA,CAAU,eAAA,CAAiB,UAAU,CAAA,CACzCA,CAAAA,CAAI,QAAA,CAAS,YAAA,CAAc,CAAE,IAAA,CAAM,cAAe,CAAC,EACrD,CAAA,MAASyJ,CAAAA,CAAG,CACV,OAAA,CAAQ,KAAA,CAAM,4BAA6BA,CAAC,CAAA,CAC5CzJ,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,uBAAuB,EAC9C,CAAA,KAEAA,CAAAA,CAAI,QAAA,CAAS,YAAA,CAAc,CAAE,IAAA,CAAM,2BAAA,CAA4B,OAAA,CAAQ,KAAA,CAAO,GAAG,CAAE,CAAC,EAExF,CAEQ,KAAA,EAAQ,CACd,OAAO,OAAA,CAAQ,GAAA,CAAI,WAAa,YAClC,CACF,CAAA,CAEA,eAAe8V,EAAAA,EAAqB,CAClC,IAAMC,CAAAA,CAAS,OAAA,CAAQ,GAAA,EAAI,CAE3B,GAAI,CAMF,QALe,MAAMC,kBAAAA,CACnB,CAAE,OAAA,CAAS,OAAA,CAAS,IAAA,CAAM,aAAc,CAAA,CACxC,KAAA,CAAA,CACAD,CACF,CAAA,GACe,MAAA,EAAU,EAC3B,OAAS3b,CAAAA,CAAO,CACd,OAAA,OAAA,CAAQ,IAAA,CAAK,6BAAA,CAA+BA,CAAK,EAC1C,EACT,CACF,CAEA,SAAS6b,EAAAA,CAAkBC,EAAwBC,CAAAA,CAAwB,CACzE,IAAMC,CAAAA,CAAeC,WAAAA,CAAYH,CAAAA,CAAYC,CAAU,CAAA,CAGvD,GAAIC,CAAAA,CAAa,OAAA,EAAW,KAAA,CAAM,OAAA,CAAQA,CAAAA,CAAa,OAAO,CAAA,CAAG,CAC/D,IAAME,CAAAA,CAAc,IAAI,GAAA,CACxBF,EAAa,OAAA,CAAUA,CAAAA,CAAa,OAAA,CACjC,IAAA,EAAK,CACL,MAAA,CAAQG,GAAyB,CAChC,GAAI,CAACA,CAAAA,EAAU,OAAOA,CAAAA,EAAW,QAAA,EAAY,KAAA,CAAM,OAAA,CAAQA,CAAM,CAAA,CAC/D,OAAO,KAAA,CAET,IAAMC,EAAcD,CAAAA,CAAkB,IAAA,CACtC,OAAI,CAACC,CAAAA,EAAcF,CAAAA,CAAY,IAAIE,CAAU,CAAA,CACpC,KAAA,EAETF,CAAAA,CAAY,GAAA,CAAIE,CAAU,EACnB,IAAA,CACT,CAAC,CAAA,CACA,OAAA,EAAQ,CACXJ,CAAAA,CAAa,OAAA,CAAQ,OAAA,GACvB,CAEA,OAAOA,CACT,CAEA,eAAepe,GAAUqN,CAAAA,CAAoC,CAC3D,IAAM0Q,CAAAA,CAAS,OAAA,CAAQ,GAAA,GACjBI,CAAAA,CAAa,MAAML,EAAAA,EAAmB,CAEtCW,CAAAA,CAAmB,CACvB,eACA,gBAAA,CACA,WAAA,CACA,kBAAA,CACA,eAAA,CACA,gBACF,CAAA,CAAE,IAAA,CAAMC,CAAAA,EAASC,EAAAA,CAAG,UAAA,CAAWrP,EAAAA,CAAK,IAAA,CAAKyO,CAAAA,CAAQW,CAAI,CAAC,CAAC,CAAA,CAEjDE,CAAAA,CAAU,CAACC,EAAAA,EAAY,CAAGC,IAAsB,CAAA,CAEtD,GAAIL,CAAAA,CAAkB,CACpB,IAAMM,GAAgB,MAAM,OAAO,oBAAoB,CAAA,EAAG,OAAA,CAC1DH,CAAAA,CAAQ,IAAA,CACNG,CAAAA,CAAa,CACX,WAAA,CAAa,KAAA,CACb,OAAA,CAAS,CAAC,aAAA,CAAe,eAAgB,aAAA,CAAe,cAAc,CAAA,CACtE,GAAA,CAAKhB,CAAAA,CACL,kBAAA,CAAoBzO,GAAK,OAAA,CAAQyO,CAAAA,CAAQU,CAAgB,CAC3D,CAAC,CACH,EACF,CAEA,IAAMP,CAAAA,CAAac,YAAAA,CAAa,CAC9B,OAAA,CAAAJ,CAAAA,CACA,KAAA,CAAO,CACL,MAAA,CAAQ,yBAAA,CAA0B,OAAA,CAAQ,KAAA,CAAO,GAAG,EACpD,WAAA,CAAa,IACf,CAAA,CACA,MAAA,CAAQ,CACN,cAAA,CAAgB,KAChB,GAAA,CAAKvR,CAAAA,CAAa,CAAE,MAAA,CAAQA,CAAW,CAAA,CAAI,MAC7C,CAAA,CACA,IAAA,CAAM,cAAA,CACN,OAAA,CAAS,CACP,KAAA,CAAO,CACL,GAAA,CAAKiC,EAAAA,CAAK,OAAA,CAAQyO,CAAAA,CAAQ,KAAK,CAAA,CAAE,OAAA,CAAQ,MAAO,GAAG,CACrD,CACF,CACF,CAAC,CAAA,CAED,OAAOE,EAAAA,CAAkBC,CAAAA,CAAYC,CAAU,CACjD,CAEA,SAASW,IAA+B,CACtC,OAAO,CACL,IAAA,CAAM,yBAAA,CACN,MAAM,SAAA,CAAUG,CAAAA,CAAc7Z,CAAAA,CAAY,CAExC,GADmB,oDAAA,CACJ,IAAA,CAAKA,CAAE,EACpB,OAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,GAAa,aAAA,CACpB6Z,CAMb,CACF,CACF,CAEO,IAAMC,EAAAA,CAAa,IAAIzB,EAAAA,CCvJ9B,eAAsB0B,EAAAA,CAAiBnX,CAAAA,CAAeX,EAAkB,CACtE,GAAM,CAAE,SAAA,CAAAJ,CAAU,CAAA,CAAI,MAAME,EAAAA,CAAcE,CAAM,CAAA,CAEhDU,EAAAA,CAAmBC,CAAAA,CAAKf,CAAS,EACjCe,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CACdA,CAAAA,CAAI,QAAA,CAAS,GAAG,EAClB,CAEA,eAAeoX,EAAAA,CACbpX,CAAAA,CACAqX,CAAAA,CACAjK,CAAAA,CACAvN,EACAsJ,CAAAA,CACA,CACA,IAAML,CAAAA,CAAaG,CAAAA,EAAc,CAEjC,GAAI,CACF,GAAImE,CAAAA,CAAa,MAAA,GAAW,UAAA,EAAcA,CAAAA,CAAa,SAAW,SAAA,CAAW,CAC3EpN,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,KAAA,CAAO,6BACT,CAAC,CAAA,CACD,MACF,CAGA,IAAMzC,CAAAA,CAA+E,EAAC,CAElF6P,CAAAA,CAAa,SAAA,GAAc,KAAA,CAAA,EAAaiK,EAAS,SAAA,GACnD9Z,CAAAA,CAAO,SAAA,CAAY8Z,CAAAA,CAAS,SAAA,CAAA,CAE1BjK,CAAAA,CAAa,WAAa,KAAA,CAAA,EAAaiK,CAAAA,CAAS,QAAA,GAClD9Z,CAAAA,CAAO,QAAA,CAAW8Z,CAAAA,CAAS,QAAA,CAAA,CAEzBjK,CAAAA,CAAa,SAAA,GAAc,KAAA,CAAA,EAAaiK,CAAAA,CAAS,SAAA,GACnD9Z,CAAAA,CAAO,SAAA,CAAY8Z,EAAS,SAAA,CAAA,CAG9B,IAAIlX,CAAAA,CAAOiN,CAAAA,CAEP,MAAA,CAAO,IAAA,CAAK7P,CAAM,CAAA,CAAE,MAAA,CAAS,CAAA,GAC/B,MAAM8C,CAAAA,CAAgB,SAAA,CAAU,CAAE,GAAA,CAAK+M,CAAAA,CAAa,GAAI,CAAA,CAAG,CAAE,IAAA,CAAM7P,CAAO,CAAC,CAAA,CAC3E4C,CAAAA,CAAO,CAAE,GAAGiN,CAAAA,CAAc,GAAG7P,CAAO,CAAA,CAAA,CAGtC,MAAM4Z,EAAAA,CAAiBnX,CAAAA,CAAKoN,CAAAA,CAAa,GAAG,EAC5CtE,CAAAA,CAAW,YAAA,GAAe,CACxB,QAAA,CAAUuO,CAAAA,CAAS,YAAA,CACnB,KAAAlX,CAAAA,CACA,OAAA,CAAAN,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CAAA,CACDL,CAAAA,CAAW,KAAA,EAAO,SAAA,GAAY3I,CAAI,EACpC,CAAA,MAAS/F,CAAAA,CAAO,CACd,MAAIA,CAAAA,YAAiB,KAAA,GACnB0O,CAAAA,CAAW,KAAA,EAAO,OAAA,GAAU1O,CAAK,CAAA,CAEjC0O,CAAAA,CAAW,YAAA,GAAe,CACxB,QAAA,CAAUuO,CAAAA,CAAS,YAAA,CACnB,MAAAjd,CAAAA,CACA,OAAA,CAAAyF,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CAAA,CAAA,CAEG/O,CACR,CACF,CAEA,eAAekd,EAAAA,CACbtX,CAAAA,CACAqX,CAAAA,CACAE,EACA1X,CAAAA,CACAsJ,CAAAA,CACA,CACA,IAAML,CAAAA,CAAaG,CAAAA,GAGnB,GAAA,CAFoBH,CAAAA,CAAW,mBAAA,EAAuB,QAAA,IAElC,MAAA,EAAUuO,CAAAA,CAAS,cAAe,CACpD,GAAIE,CAAAA,CAAoB,MAAA,GAAW,UAAA,EAAcA,CAAAA,CAAoB,MAAA,GAAW,SAAA,CAAW,CACzFvX,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,KAAA,CAAO,6BACT,CAAC,CAAA,CACD,MACF,CAOA,GAAI,CALiBuX,CAAAA,CAAoB,MAAA,EAAQ,IAAA,CAC9CzK,CAAAA,EAAwBA,CAAAA,CAAS,QAAQ,WAAA,EAAY,GAAMuK,CAAAA,CAAS,KAAA,CAAM,WAAA,EAC7E,CAAA,EAGmB,QAAA,CAAU,CAC3BrX,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,KAAA,CAAO,6DACT,CAAC,CAAA,CACD,MACF,CAEA,GAAI,CAEF,IAAMwX,CAAAA,CAAsF,CAC1F,GAAID,CAAAA,CAAoB,YAAc,KAAA,CAAA,EACpCF,CAAAA,CAAS,SAAA,EAAa,CAAE,SAAA,CAAWA,CAAAA,CAAS,SAAU,CAAA,CACxD,GAAIE,CAAAA,CAAoB,QAAA,GAAa,KAAA,CAAA,EACnCF,CAAAA,CAAS,QAAA,EAAY,CAAE,QAAA,CAAUA,CAAAA,CAAS,QAAS,CAAA,CACrD,GAAIE,CAAAA,CAAoB,YAAc,KAAA,CAAA,EACpCF,CAAAA,CAAS,SAAA,EAAa,CAAE,SAAA,CAAWA,CAAAA,CAAS,SAAU,CAC1D,CAAA,CAsBA,GAAI,EAAA,CAnBiB,MAAMhX,CAAAA,CAAgB,SAAA,CACzC,CACE,GAAA,CAAKkX,CAAAA,CAAoB,GAAA,CACzB,MAAA,CAAQ,CAAE,IAAA,CAAM,CAAC,SAAA,CAAW,UAAU,CAAE,CAAA,CACxC,GAAA,CAAK,CACH,CAAE,CAAC,CAAA,YAAA,EAAeF,CAAAA,CAAS,YAAY,CAAA,GAAA,CAAK,EAAG,CAAE,OAAA,CAAS,CAAA,CAAM,CAAE,CAAA,CAClE,CAAE,CAAC,CAAA,YAAA,EAAeA,CAAAA,CAAS,YAAY,CAAA,GAAA,CAAK,EAAGA,CAAAA,CAAS,EAAG,CAC7D,CACF,CAAA,CACA,CACE,IAAA,CAAM,CACJ,CAAC,CAAA,YAAA,EAAeA,EAAS,YAAY,CAAA,GAAA,CAAK,EAAGA,CAAAA,CAAS,EAAA,CACtD,GAAGG,CACL,CACF,CACF,CAAA,EAEwC,YAAA,CAAe,CAAA,CAAA,CAE9B,CAEvBxX,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,KAAA,CAAO,6DACT,CAAC,CAAA,CACD,MACF,CAEA,MAAMmX,EAAAA,CAAiBnX,CAAAA,CAAKuX,EAAoB,GAAG,CAAA,CAGnD,IAAME,CAAAA,CAAoB,CACxB,GAAGF,EACH,GAAGC,CAAAA,CACH,WAAA,CAAa,CACX,GAAGD,CAAAA,CAAoB,WAAA,CACvB,CAACF,CAAAA,CAAS,YAAY,EAAG,CACvB,EAAA,CAAIA,CAAAA,CAAS,EACf,CACF,CACF,CAAA,CAEAvO,CAAAA,CAAW,YAAA,GAAe,CACxB,SAAUuO,CAAAA,CAAS,YAAA,CACnB,IAAA,CAAMI,CAAAA,CACN,OAAA,CAAA5X,CAAAA,CACA,eAAAsJ,CACF,CAAC,CAAA,CACDL,CAAAA,CAAW,KAAA,EAAO,SAAA,GAAY2O,CAAW,CAAA,CAEzC,MACF,CAAA,MAASrd,CAAAA,CAAO,CACd,MAAIA,CAAAA,YAAiB,QACnB0O,CAAAA,CAAW,KAAA,EAAO,OAAA,GAAU1O,CAAK,CAAA,CAEjC0O,CAAAA,CAAW,eAAe,CACxB,QAAA,CAAUuO,CAAAA,CAAS,YAAA,CACnB,KAAA,CAAAjd,CAAAA,CACA,QAAAyF,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CAAA,CAAA,CAEG/O,CACR,CACF,CAIA4F,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,MAAO,6DACT,CAAC,EAEH,CAEA,eAAe0X,EAAAA,CACb1X,EACAqX,CAAAA,CACAxX,CAAAA,CACAsJ,CAAAA,CACA,CACA,IAAML,CAAAA,CAAaG,GAAc,CAEjC,GAAI,CACF,IAAIR,CAAAA,CAEJ,GAAIK,CAAAA,CAAW,cAAA,CAAgB,CAC7B,IAAM0E,CAAAA,CAAY,MAAM1E,CAAAA,CAAW,cAAA,CAAgB,CACjD,KAAA,CAAOuO,CAAAA,CAAS,KAAA,CAChB,SAAA,CAAWA,CAAAA,CAAS,SAAA,CACpB,SAAUA,CAAAA,CAAS,QACrB,CAAC,CAAA,CAED5O,CAAAA,CAAS,MAAMH,EAAoBkF,CAAAA,CAAW6J,CAAAA,CAAS,KAAA,CAAO,CAC5D,eAAA,CAAiB,CAAA,CACnB,CAAC,EACH,CAAA,KACE5O,CAAAA,CAAS,MAAMH,CAAAA,CAAoB,KAAA,CAAA,CAAW+O,CAAAA,CAAS,KAAK,CAAA,CAG9D,IAAM7V,CAAAA,CAAU,CACd,MAAA,CAAQiH,CAAAA,CACR,OAAQ,QAAA,CACR,MAAA,CAAQ,CACN,CACE,OAAA,CAAS4O,CAAAA,CAAS,MAClB,QAAA,CAAUA,CAAAA,CAAS,aACrB,CACF,CAAA,CACA,SAAA,CAAW,IAAI,IAAA,CACf,WAAA,CAAa,CACX,CAACA,CAAAA,CAAS,YAAY,EAAG,CACvB,EAAA,CAAIA,CAAAA,CAAS,EACf,CACF,CAAA,CACA,GAAIA,EAAS,SAAA,GAAc,KAAA,CAAA,EAAa,CAAE,SAAA,CAAWA,CAAAA,CAAS,SAAU,EACxE,GAAIA,CAAAA,CAAS,QAAA,GAAa,KAAA,CAAA,EAAa,CAAE,QAAA,CAAUA,CAAAA,CAAS,QAAS,CAAA,CACrE,GAAIA,CAAAA,CAAS,SAAA,GAAc,KAAA,CAAA,EAAa,CAAE,UAAWA,CAAAA,CAAS,SAAU,CAC1E,CAAA,CAEMM,CAAAA,CAAU,MAAMtX,EAAgB,SAAA,CAAUmB,CAAO,CAAA,CAEvD,MAAM2V,EAAAA,CAAiBnX,CAAAA,CAAK2X,EAAQ,UAAU,CAAA,CAE9C,IAAMjK,CAAAA,CAAe,MAAMrN,CAAAA,CAAgB,OAAA,CACzC,CAAE,GAAA,CAAKsX,CAAAA,CAAQ,UAAW,CAAA,CAC1B,CAAE,cAAA,CAAgB,SAAU,CAC9B,CAAA,CAEIjK,CAAAA,GACF5E,CAAAA,CAAW,aAAA,GAAgB,CACzB,SAAUuO,CAAAA,CAAS,YAAA,CACnB,IAAA,CAAM3J,CAAAA,CACN,OAAA,CAAA7N,CAAAA,CACA,eAAAsJ,CACF,CAAC,CAAA,CAEDL,CAAAA,CAAW,MAAA,EAAQ,SAAA,GAAY4E,CAAY,CAAA,EAE/C,CAAA,MAAStT,CAAAA,CAAO,CACd,MAAIA,CAAAA,YAAiB,KAAA,GACnB0O,EAAW,aAAA,GAAgB,CACzB,QAAA,CAAUuO,CAAAA,CAAS,YAAA,CACnB,KAAA,CAAAjd,EACA,OAAA,CAAAyF,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CAAA,CAEDL,EAAW,MAAA,EAAQ,OAAA,GAAU1O,CAAK,CAAA,CAAA,CAE9BA,CACR,CACF,CAEO,SAASwd,EAAAA,CAAetN,CAAAA,CAA0B,CACvD,OAAO,CAAA,EAAGtS,GAAAA,CAAU,kBAAkB,CAAC,CAAA,oBAAA,EAAuBsS,CAAQ,CAAA,SAAA,CACxE,CAEA,eAAsBuN,GACpBhC,CAAAA,CACA7V,CAAAA,CACAqX,CAAAA,CACe,CAEf,IAAMjK,CAAAA,CAAe,MAAM/M,CAAAA,CAAgB,OAAA,CAAQ,CACjD,CAAC,CAAA,YAAA,EAAegX,CAAAA,CAAS,YAAY,CAAA,GAAA,CAAK,EAAGA,CAAAA,CAAS,EACxD,CAAC,CAAA,CAEK,CAAE,QAAAxX,CAAAA,CAAS,cAAA,CAAAsJ,CAAe,CAAA,CAAI,MAAM2O,EAAAA,CAAejC,CAAG,CAAA,CAE5D,GAAIzI,CAAAA,CACF,OAAOgK,EAAAA,CAA4BpX,CAAAA,CAAKqX,EAAUjK,CAAAA,CAAcvN,CAAAA,CAASsJ,CAAc,CAAA,CAIzF,GAAI,CAACkO,CAAAA,CAAS,KAAA,CAAO,CACnBrX,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,KAAA,CAAO,CAAA,8BAAA,EAAiCqX,CAAAA,CAAS,YAAY,CAAA,gBAAA,CAC/D,CAAC,EACD,MACF,CAGA,IAAIE,CAAAA,CAEJ,GAAI,CACFA,EAAsB,MAAMlX,CAAAA,CAAgB,OAAA,CAC1C,CAAE,gBAAA,CAAkBgX,CAAAA,CAAS,KAAA,CAAO,MAAA,CAAQ,CAAE,GAAA,CAAK,SAAU,CAAE,CAAA,CAC/D,CAAE,UAAW,CAAE,MAAA,CAAQ,IAAA,CAAM,QAAA,CAAU,CAAE,CAAE,CAC7C,EACF,CAAA,MAASjd,CAAAA,CAAO,CACd,GAAIA,CAAAA,YAAiB,MAAO,CAC1B,IAAM0O,CAAAA,CAAaG,CAAAA,EAAc,CACjCH,CAAAA,CAAW,aAAA,GAAgB,CACzB,QAAA,CAAUuO,CAAAA,CAAS,YAAA,CACnB,KAAA,CAAAjd,CAAAA,CACA,OAAA,CAAAyF,EACA,cAAA,CAAAsJ,CACF,CAAC,CAAA,CAEDL,CAAAA,CAAW,MAAA,EAAQ,UAAU1O,CAAK,EACpC,CACA,MAAMA,CACR,CAGA,OAAImd,CAAAA,CACKD,EAAAA,CAAyBtX,CAAAA,CAAKqX,CAAAA,CAAUE,CAAAA,CAAqB1X,CAAAA,CAASsJ,CAAc,CAAA,CAItFuO,EAAAA,CAAoB1X,CAAAA,CAAKqX,CAAAA,CAAUxX,CAAAA,CAASsJ,CAAc,CACnE,CAEO,SAAS4O,CAAAA,CAAqB/X,CAAAA,CAAe,CAElDA,CAAAA,CAAI,MAAA,CAAO,iBAAkB,EAAA,CAAI,CAC/B,QAAA,CAAU,IAAA,CACV,MAAA,CAAQ,CAAA,CACR,KAAM,sBAAA,CACN,QAAA,CAAU,KAAA,CACV,MAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAA,GAAa,YACnC,CAAC,EACH,CAEA,SAASgY,EAAAA,CAAeC,CAAAA,CAAmB,CACzC,GAAKA,CAAAA,CAEL,GAAI,CACFA,CAAAA,GACF,OAASjW,CAAAA,CAAK,CACZ,OAAA,CAAQ,KAAA,CAAM,6BAAA,CAA+BA,CAAG,EAClD,CACF,CAEO,SAASkW,EAAAA,CACdrC,CAAAA,CACA7V,CAAAA,CACAmY,CAAAA,CACe,CACf,IAAM/E,CAAAA,CAAQyC,CAAAA,CAAI,KAAA,CAAM,KAAA,CAClBuC,CAAAA,CAAcvC,EAAI,OAAA,CAAQsC,CAAe,CAAA,CAEzC,CAACE,CAAAA,CAAkBC,CAAU,GAAKF,CAAAA,EAAe,EAAA,EAAI,KAAA,CAAM,GAAG,CAAA,CAEpE,OAAI,CAAChF,CAAAA,EAAS,CAACgF,CAAAA,EAAehF,CAAAA,GAAUiF,CAAAA,EACtCrY,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CAAE,KAAA,CAAO,4CAA6C,CAAC,EACrE,IAAA,GAGTA,CAAAA,CAAI,WAAA,CAAYmY,CAAe,CAAA,CACxBG,CAAAA,EAAc,QACvB,CAEA,eAAsBC,EAAAA,CACpB1C,CAAAA,CACA7V,CAAAA,CACAqX,CAAAA,CACe,CACf,IAAMvO,CAAAA,CAAaG,CAAAA,EAAc,CAC3B,CAAE,OAAA,CAAApJ,CAAAA,CAAS,cAAA,CAAAsJ,CAAe,CAAA,CAAI,MAAM2O,EAAAA,CAAejC,CAAG,CAAA,CAE5D,GAAI,CAAChW,CAAAA,EAAS,MAAA,CAAQ,CACpBkY,CAAAA,CAAqB/X,CAAG,EACxBA,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,MAAO,2CACT,CAAC,CAAA,CACD,MACF,CAEA,IAAMX,CAAAA,CAASQ,CAAAA,CAAQ,MAAA,CAEvB,GAAI,CAIF,IAAM2Y,CAAAA,CAAgB,CAAA,YAAA,EAAenB,EAAS,YAAY,CAAA,GAAA,CAAA,CAgB1D,GAAA,CAdqB,MAAMhX,CAAAA,CAAgB,SAAA,CACzC,CACE,GAAA,CAAKhB,CAAAA,CACL,MAAA,CAAQ,CAAE,IAAA,CAAM,CAAC,UAAW,UAAU,CAAE,CAAA,CACxC,GAAA,CAAK,CAAC,CAAE,CAACmZ,CAAa,EAAG,CAAE,OAAA,CAAS,CAAA,CAAM,CAAE,CAAA,CAAG,CAAE,CAACA,CAAa,EAAGnB,CAAAA,CAAS,EAAG,CAAC,CACjF,CAAA,CACA,CACE,IAAA,CAAM,CACJ,CAACmB,CAAa,EAAGnB,CAAAA,CAAS,EAC5B,CACF,CACF,CAAA,EAGiB,YAAA,GAAiB,CAAA,CAAG,CACnC,IAAMoB,CAAAA,CAAc,MAAMpY,CAAAA,CAAgB,OAAA,CAAQ,CAAE,IAAKhB,CAAO,CAAC,CAAA,CAEjE,GAAI,CAACoZ,CAAAA,EAAeA,EAAY,MAAA,GAAW,SAAA,EAAaA,CAAAA,CAAY,MAAA,GAAW,UAAA,CAAY,CACzFT,GAAe,IACblP,CAAAA,CAAW,gBAAA,GAAmB,CAC5B,QAAA,CAAUuO,CAAAA,CAAS,YAAA,CACnB,KAAA,CAAO,IAAI,KAAA,CAAM,sCAAsC,CAAA,CACvD,OAAA,CAAAxX,CAAAA,CACA,eAAAsJ,CACF,CAAC,CACH,CAAA,CAEA4O,CAAAA,CAAqB/X,CAAG,EAExBA,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CAAE,MAAO,6BAA8B,CAAC,CAAA,CAC7D,MACF,CAGA,IAAM0Y,CAAAA,CAAqBD,CAAAA,EAAa,WAAA,GAAcpB,CAAAA,CAAS,YAAY,CAAA,EAAG,EAAA,CAE9E,GAAIqB,GAAsBA,CAAAA,GAAuBrB,CAAAA,CAAS,EAAA,CAAI,CAC5DW,EAAAA,CAAe,IACblP,EAAW,gBAAA,GAAmB,CAC5B,QAAA,CAAUuO,CAAAA,CAAS,YAAA,CACnB,KAAA,CAAO,IAAI,KAAA,CACT,CAAA,6BAAA,EAAgCA,CAAAA,CAAS,YAAY,CAAA,eAAA,CACvD,CAAA,CACA,OAAA,CAAAxX,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CACH,CAAA,CAEA4O,CAAAA,CAAqB/X,CAAG,CAAA,CAExBA,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,KAAA,CAAO,CAAA,oCAAA,EAAuCqX,CAAAA,CAAS,YAAY,CAAA,SAAA,CACrE,CAAC,CAAA,CAED,MACF,CAGAW,EAAAA,CAAe,IACblP,CAAAA,CAAW,gBAAA,GAAmB,CAC5B,QAAA,CAAUuO,CAAAA,CAAS,YAAA,CACnB,KAAA,CAAO,IAAI,KAAA,CAAM,CAAA,mCAAA,EAAsCA,CAAAA,CAAS,YAAY,CAAA,CAAE,CAAA,CAC9E,OAAA,CAAAxX,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CACH,CAAA,CAEA4O,CAAAA,CAAqB/X,CAAG,CAAA,CAExBA,CAAAA,CAAI,OAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,KAAA,CAAO,CAAA,eAAA,EAAkBqX,CAAAA,CAAS,YAAY,CAAA,SAAA,CAChD,CAAC,CAAA,CAED,MACF,CAEA,IAAMI,EAAc,MAAMpX,CAAAA,CAAgB,OAAA,CACxC,CAAE,GAAA,CAAKhB,CAAO,EACd,CAAE,cAAA,CAAgB,SAAU,CAC9B,CAAA,CAEIoY,CAAAA,EACFO,GAAe,IACblP,CAAAA,CAAW,gBAAA,GAAmB,CAC5B,QAAA,CAAUuO,CAAAA,CAAS,YAAA,CACnB,IAAA,CAAMI,CAAAA,CACN,OAAA,CAAA5X,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CACH,CAAA,CAIF4O,CAAAA,CAAqB/X,CAAG,CAAA,CAExBA,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,QAAA,CAAS,GAAG,EAC9B,CAAA,MAAS5F,CAAAA,CAAO,CACd,GAAIA,CAAAA,YAAiBue,gBAAAA,EAAoBve,CAAAA,CAAM,IAAA,GAAS,IAAA,CAAO,CAC7D4d,EAAAA,CAAe,IACblP,CAAAA,CAAW,gBAAA,GAAmB,CAC5B,QAAA,CAAUuO,CAAAA,CAAS,aACnB,KAAA,CAAAjd,CAAAA,CACA,OAAA,CAAAyF,CAAAA,CACA,cAAA,CAAAsJ,CACF,CAAC,CACH,CAAA,CAEA4O,CAAAA,CAAqB/X,CAAG,CAAA,CAExBA,CAAAA,CAAI,OAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,KAAA,CAAO,CAAA,KAAA,EAAQqX,CAAAA,CAAS,YAAY,CAAA,+CAAA,CACtC,CAAC,CAAA,CAED,MACF,CAcA,GAZIjd,aAAiB,KAAA,EACnB4d,EAAAA,CAAe,IACblP,CAAAA,CAAW,gBAAA,GAAmB,CAC5B,SAAUuO,CAAAA,CAAS,YAAA,CACnB,KAAA,CAAAjd,CAAAA,CACA,OAAA,CAAAyF,CAAAA,CACA,eAAAsJ,CACF,CAAC,CACH,CAAA,CAGF4O,CAAAA,CAAqB/X,CAAG,CAAA,CACpB,CAACA,CAAAA,CAAI,WAAA,CACP,MAAM5F,CAEV,CACF,CAEO,SAASwe,EAAAA,CAAkB3B,CAAAA,CAA8B,CAC9D,OAAI,CAACA,CAAAA,EAAQ,OAAOA,CAAAA,EAAS,QAAA,CACpB,IAAA,CAEFA,CACT,CC5fA,eAAe4B,GACb5B,CAAAA,CACA6B,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CAC8B,CAC9B,IAAMC,CAAAA,CAAgB,MAAM,KAAA,CAAM,qCAAA,CAAuC,CACvE,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,CACP,cAAA,CAAgB,mCAClB,CAAA,CACA,IAAA,CAAM,IAAI,eAAA,CAAgB,CACxB,IAAA,CAAAhC,CAAAA,CACA,SAAA,CAAW6B,CAAAA,CACX,aAAA,CAAeC,CAAAA,CACf,aAAcC,CAAAA,CACd,UAAA,CAAY,oBACd,CAAC,CACH,CAAC,CAAA,CAED,GAAI,CAACC,CAAAA,CAAc,EAAA,CACjB,MAAM,IAAI,KAAA,CAAM,sCAAsCA,CAAAA,CAAc,UAAU,CAAA,CAAE,CAAA,CAGlF,OAAOA,CAAAA,CAAc,MACvB,CAEA,eAAeC,EAAAA,CAAoBC,CAAAA,CAA8C,CAC/E,IAAMC,CAAAA,CAAmB,MAAM,KAAA,CAAM,+CAAA,CAAiD,CACpF,OAAA,CAAS,CACP,aAAA,CAAe,CAAA,OAAA,EAAUD,CAAW,CAAA,CACtC,CACF,CAAC,CAAA,CAED,GAAI,CAACC,CAAAA,CAAiB,EAAA,CACpB,MAAM,IAAI,KAAA,CAAM,8BAA8BA,CAAAA,CAAiB,UAAU,CAAA,CAAE,CAAA,CAG7E,OAAOA,CAAAA,CAAiB,MAC1B,CAEA,eAAeC,EAAAA,CAAmCxD,CAAAA,CAAc7V,CAAAA,CAAe,CAC7E,IAAMiX,CAAAA,CAAO2B,EAAAA,CAAkB/C,CAAAA,CAAI,KAAA,CAAM,IAAI,CAAA,CAE7C,GAAI,CAACoB,CAAAA,CAAM,CACTjX,CAAAA,CAAI,MAAA,CAAO,GAAG,EAAE,IAAA,CAAK,CAAE,KAAA,CAAO,4BAA6B,CAAC,CAAA,CAC5D,MACF,CAEA,IAAM5E,CAAAA,CAAO8c,EAAAA,CAA6BrC,CAAAA,CAAK7V,CAAAA,CAAK,iBAAiB,CAAA,CACrE,GAAI,CAAC5E,CAAAA,CAAM,OAEX,IAAMke,CAAAA,CAAiB,OAAOthB,GAAAA,CAAU,mCAAmC,CAAC,CAAA,CACtEuhB,CAAAA,CAAqB,MAAA,CAAOvhB,IAAU,uCAAuC,CAAC,CAAA,CAC9EghB,CAAAA,CAAcpB,EAAAA,CAAe,QAAQ,EAE3C,GAAI,CAEF,IAAM4B,CAAAA,CAAY,MAAMX,EAAAA,CACtB5B,CAAAA,CACAqC,CAAAA,CACAC,CAAAA,CACAP,CACF,CAAA,CAGMS,CAAAA,CAAa,MAAMP,EAAAA,CAAoBM,EAAU,YAAY,CAAA,CAE7DnC,CAAAA,CAA0B,CAC9B,EAAA,CAAIoC,CAAAA,CAAW,GACf,KAAA,CAAOA,CAAAA,CAAW,KAAA,CAClB,aAAA,CAAeA,CAAAA,CAAW,cAAA,CAC1B,aAAc,QAAA,CACd,SAAA,CAAWA,CAAAA,CAAW,UAAA,EAAc,KAAA,CAAA,CACpC,QAAA,CAAUA,CAAAA,CAAW,WAAA,EAAe,KAAA,CAAA,CACpC,SAAA,CAAWA,CAAAA,CAAW,OAAA,EAAW,KAAA,CACnC,CAAA,CACIre,IAAS,MAAA,CACX,MAAMmd,EAAAA,CAAwB1C,CAAAA,CAAK7V,CAAAA,CAAKqX,CAAQ,EAEhD,MAAMQ,EAAAA,CAA8BhC,CAAAA,CAAK7V,CAAAA,CAAKqX,CAAQ,EAE1D,OAASjd,CAAAA,CAAO,CACd,OAAA,CAAQ,KAAA,CAAM,qBAAA,CAAuBA,CAAK,CAAA,CACtCgB,CAAAA,GAAS,MAAA,EACX2c,CAAAA,CAAqB/X,CAAG,CAAA,CAE1BA,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CAAE,KAAA,CAAO,uBAAwB,CAAC,EACzD,CACF,CAEA,SAAS0Z,EAAAA,EAA2B,CAClC,IAAMC,EAAmBC,MAAAA,EAAO,CAG1BC,CAAAA,CAAqB,CAACC,CAAAA,CAAe9Z,CAAAA,CAAe4F,CAAAA,GAAuB,CAC/E,IAAMmU,CAAAA,CAAgB,CAAA,CAAQ/hB,GAAAA,CAAU,kCAAkC,CAAA,CACpEshB,EAAiB,MAAA,CAAOthB,GAAAA,CAAU,mCAAmC,CAAC,CAAA,CACtEuhB,CAAAA,CAAqB,OAAOvhB,GAAAA,CAAU,uCAAuC,CAAC,CAAA,CAEpF,GAAI,CAAC+hB,GAAiB,CAACT,CAAAA,EAAkB,CAACC,CAAAA,CAAoB,CAC5DvZ,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CAAE,KAAA,CAAO,yCAA0C,CAAC,EACzE,MACF,CAEA4F,CAAAA,GACF,CAAA,CAGA,OAAA+T,EAAiB,GAAA,CACf,4BAAA,CACAE,CAAAA,CACA,CAAChE,CAAAA,CAAc7V,CAAAA,GAAkB,CAC/B,IAAMsZ,CAAAA,CAAiB,MAAA,CAAOthB,GAAAA,CAAU,mCAAmC,CAAC,CAAA,CACtEghB,CAAAA,CAAcpB,EAAAA,CAAe,QAAQ,CAAA,CAErCxE,CAAAA,CAAQ5T,WAAAA,CAAY,EAAE,EAAE,QAAA,CAAS,KAAK,CAAA,CAEtCpE,GAAAA,CAAOya,CAAAA,CAAI,KAAA,CAAM,OAAS,MAAA,CAAS,MAAA,CAAS,OAAA,CAElD7V,CAAAA,CAAI,MAAA,CAAO,iBAAA,CAAmB,GAAGoT,CAAK,CAAA,CAAA,EAAIhY,GAAI,CAAA,CAAA,CAAI,CAChD,QAAA,CAAU,IAAA,CACV,MAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAA,GAAa,YAAA,CACjC,QAAA,CAAU,KAAA,CACV,OAAQuE,CAAAA,CAAK,OAAA,CAAQ,EAAE,CACzB,CAAC,CAAA,CAED,IAAMqa,CAAAA,CAAU,IAAI,GAAA,CAAI,8CAA8C,CAAA,CACtEA,CAAAA,CAAQ,aAAa,MAAA,CAAO,WAAA,CAAaV,CAAc,CAAA,CACvDU,CAAAA,CAAQ,YAAA,CAAa,MAAA,CAAO,cAAA,CAAgBhB,CAAW,CAAA,CACvDgB,CAAAA,CAAQ,YAAA,CAAa,MAAA,CAAO,eAAA,CAAiB,MAAM,CAAA,CACnDA,CAAAA,CAAQ,YAAA,CAAa,MAAA,CAAO,OAAA,CAAS,eAAe,EACpDA,CAAAA,CAAQ,YAAA,CAAa,MAAA,CAAO,aAAA,CAAe,QAAQ,CAAA,CACnDA,EAAQ,YAAA,CAAa,MAAA,CAAO,OAAA,CAAS5G,CAAK,CAAA,CAE1CpT,CAAAA,CAAI,QAAA,CAASga,CAAAA,CAAQ,QAAA,EAAU,EACjC,CACF,CAAA,CAGAL,CAAAA,CAAiB,IACf,qCAAA,CACAE,CAAAA,CACAR,EACF,CAAA,CAEOM,CACT,CAEA,IAAOM,EAAAA,CAAQP,EAAAA,CClJf,eAAeb,EAAAA,CACb5B,CAAAA,CACA6B,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CAC8B,CAC9B,IAAMC,CAAAA,CAAgB,MAAM,KAAA,CAAM,8CAA+C,CAC/E,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,CACP,cAAA,CAAgB,mBAChB,MAAA,CAAQ,kBACV,CAAA,CACA,IAAA,CAAM,IAAA,CAAK,SAAA,CAAU,CACnB,SAAA,CAAWH,CAAAA,CACX,aAAA,CAAeC,CAAAA,CACf,IAAA,CAAA9B,CAAAA,CACA,YAAA,CAAc+B,CAChB,CAAC,CACH,CAAC,CAAA,CAED,GAAI,CAACC,EAAc,EAAA,CACjB,MAAM,IAAI,KAAA,CAAM,CAAA,mCAAA,EAAsCA,CAAAA,CAAc,UAAU,CAAA,CAAE,CAAA,CAGlF,OAAOA,CAAAA,CAAc,IAAA,EACvB,CAEA,eAAeiB,EAAAA,CAAoBf,CAAAA,CAA8C,CAC/E,IAAMC,CAAAA,CAAmB,MAAM,KAAA,CAAM,6BAAA,CAA+B,CAClE,OAAA,CAAS,CACP,aAAA,CAAe,CAAA,OAAA,EAAUD,CAAW,CAAA,CAAA,CACpC,MAAA,CAAQ,gCACV,CACF,CAAC,CAAA,CAED,GAAI,CAACC,CAAAA,CAAiB,EAAA,CACpB,MAAM,IAAI,KAAA,CAAM,8BAA8BA,CAAAA,CAAiB,UAAU,CAAA,CAAE,CAAA,CAG7E,OAAOA,CAAAA,CAAiB,IAAA,EAC1B,CAEA,eAAee,EAAAA,CAAsBhB,CAAAA,CAA6C,CAChF,IAAM3V,EAAW,MAAM,KAAA,CAAM,oCAAA,CAAsC,CACjE,OAAA,CAAS,CACP,cAAe,CAAA,OAAA,EAAU2V,CAAW,CAAA,CAAA,CACpC,MAAA,CAAQ,gCACV,CACF,CAAC,CAAA,CAED,GAAI,CAAC3V,CAAAA,CAAS,EAAA,CACZ,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgCA,CAAAA,CAAS,UAAU,CAAA,CAAE,CAAA,CAGvE,OAAOA,EAAS,IAAA,EAClB,CAEA,eAAe4W,EAAAA,CACbC,CAAAA,CACAlB,EACwB,CACxB,OAAIkB,CAAAA,CAAW,KAAA,CACNA,CAAAA,CAAW,KAAA,CAAA,CAGL,MAAMF,EAAAA,CAAsBhB,CAAW,CAAA,EACxC,IAAA,CAAM1P,CAAAA,EAAMA,CAAAA,CAAE,OAAA,EAAWA,CAAAA,CAAE,QAAQ,CAAA,EAAG,KAAA,EAAS,IAC/D,CAEA,eAAe6Q,GAAmCzE,CAAAA,CAAc7V,CAAAA,CAAe,CAC7E,IAAMiX,CAAAA,CAAO2B,EAAAA,CAAkB/C,EAAI,KAAA,CAAM,IAAI,CAAA,CAE7C,GAAI,CAACoB,CAAAA,CAAM,CACTjX,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CAAE,KAAA,CAAO,4BAA6B,CAAC,CAAA,CAC5D,MACF,CAEA,IAAM5E,CAAAA,CAAO8c,GAA6BrC,CAAAA,CAAK7V,CAAAA,CAAK,iBAAiB,CAAA,CACrE,GAAI,CAAC5E,EAAM,OAEX,IAAMmf,CAAAA,CAAiB,MAAA,CAAOviB,GAAAA,CAAU,mCAAmC,CAAC,CAAA,CACtEwiB,CAAAA,CAAqB,MAAA,CAAOxiB,GAAAA,CAAU,uCAAuC,CAAC,CAAA,CAC9EghB,CAAAA,CAAcpB,EAAAA,CAAe,QAAQ,CAAA,CAE3C,GAAI,CAEF,IAAM4B,EAAY,MAAMX,EAAAA,CACtB5B,CAAAA,CACAsD,CAAAA,CACAC,CAAAA,CACAxB,CACF,EAGMqB,CAAAA,CAAa,MAAMH,EAAAA,CAAoBV,CAAAA,CAAU,YAAY,CAAA,CAG7DiB,EAAc,MAAML,EAAAA,CAAmBC,CAAAA,CAAYb,CAAAA,CAAU,YAAY,CAAA,CAE/E,GAAI,CAACiB,CAAAA,CAAa,CACZrf,CAAAA,GAAS,MAAA,EACX2c,CAAAA,CAAqB/X,CAAG,EAG1BA,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CACnB,MACE,iIACJ,CAAC,CAAA,CACD,MACF,CAEA,IAAM0a,EAAYL,CAAAA,CAAW,IAAA,CAAOA,CAAAA,CAAW,IAAA,CAAK,IAAA,EAAK,CAAE,KAAA,CAAM,KAAK,CAAA,CAAI,EAAC,CACrEpN,CAAAA,CAAYyN,CAAAA,CAAU,CAAC,GAAK,KAAA,CAAA,CAC5BxN,CAAAA,CAAWwN,CAAAA,CAAU,MAAA,CAAS,CAAA,CAAIA,CAAAA,CAAU,MAAM,CAAC,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAAI,KAAA,CAAA,CAEjErD,EAA0B,CAC9B,EAAA,CAAI,MAAA,CAAOgD,CAAAA,CAAW,EAAE,CAAA,CACxB,KAAA,CAAOI,CAAAA,CACP,aAAA,CAAe,CAAA,CAAA,CACf,YAAA,CAAc,QAAA,CACd,SAAA,CAAAxN,CAAAA,CACA,SAAAC,CAAAA,CACA,SAAA,CAAWmN,CAAAA,CAAW,UAAA,EAAc,KAAA,CACtC,CAAA,CAEIjf,IAAS,MAAA,CACX,MAAMmd,EAAAA,CAAwB1C,CAAAA,CAAK7V,CAAAA,CAAKqX,CAAQ,EAEhD,MAAMQ,EAAAA,CAA8BhC,CAAAA,CAAK7V,CAAAA,CAAKqX,CAAQ,EAE1D,CAAA,MAASjd,CAAAA,CAAO,CACd,OAAA,CAAQ,KAAA,CAAM,qBAAA,CAAuBA,CAAK,CAAA,CACtCgB,IAAS,MAAA,EACX2c,CAAAA,CAAqB/X,CAAG,CAAA,CAE1BA,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CAAE,KAAA,CAAO,uBAAwB,CAAC,EACzD,CACF,CAEA,SAAS0Z,EAAAA,EAA2B,CAClC,IAAMiB,CAAAA,CAAmBf,MAAAA,EAAO,CAG1BgB,CAAAA,CAAqB,CAACd,CAAAA,CAAe9Z,CAAAA,CAAe4F,CAAAA,GAAuB,CAC/E,IAAMiV,CAAAA,CAAgB,CAAA,CAAQ7iB,GAAAA,CAAU,kCAAkC,CAAA,CACpEuiB,CAAAA,CAAiB,OAAOviB,GAAAA,CAAU,mCAAmC,CAAC,CAAA,CACtEwiB,CAAAA,CAAqB,MAAA,CAAOxiB,IAAU,uCAAuC,CAAC,CAAA,CAEpF,GAAI,CAAC6iB,CAAAA,EAAiB,CAACN,CAAAA,EAAkB,CAACC,CAAAA,CAAoB,CAC5Dxa,CAAAA,CAAI,MAAA,CAAO,GAAG,EAAE,IAAA,CAAK,CAAE,KAAA,CAAO,yCAA0C,CAAC,CAAA,CACzE,MACF,CAEA4F,CAAAA,GACF,CAAA,CAGA,OAAA+U,CAAAA,CAAiB,IACf,4BAAA,CACAC,CAAAA,CACA,CAAC/E,CAAAA,CAAc7V,CAAAA,GAAkB,CAC/B,IAAMua,CAAAA,CAAiB,MAAA,CAAOviB,GAAAA,CAAU,mCAAmC,CAAC,CAAA,CACtEghB,CAAAA,CAAcpB,GAAe,QAAQ,CAAA,CACrCkD,CAAAA,CAAe9iB,GAAAA,CAAU,iCAAiC,CAAA,CAC1D+iB,IAASD,CAAAA,CACX,MAAA,CAAOA,CAAY,CAAA,CAChB,KAAA,CAAM,GAAG,EACT,GAAA,CAAKE,CAAAA,EAAMA,CAAAA,CAAE,IAAA,EAAM,CAAA,CACnB,IAAA,CAAK,GAAG,CAAA,CACX,YAAA,CAEE5H,CAAAA,CAAQ5T,WAAAA,CAAY,EAAE,CAAA,CAAE,SAAS,KAAK,CAAA,CAEtCpE,CAAAA,CAAOya,CAAAA,CAAI,KAAA,CAAM,IAAA,GAAS,OAAS,MAAA,CAAS,OAAA,CAElD7V,CAAAA,CAAI,MAAA,CAAO,iBAAA,CAAmB,CAAA,EAAGoT,CAAK,CAAA,CAAA,EAAIhY,CAAI,CAAA,CAAA,CAAI,CAChD,QAAA,CAAU,IAAA,CACV,MAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAA,GAAa,YAAA,CACjC,QAAA,CAAU,KAAA,CACV,MAAA,CAAQuE,EAAK,OAAA,CAAQ,EAAE,CACzB,CAAC,CAAA,CAED,IAAMqa,EAAU,IAAI,GAAA,CAAI,0CAA0C,CAAA,CAClEA,CAAAA,CAAQ,YAAA,CAAa,OAAO,WAAA,CAAaO,CAAc,CAAA,CACvDP,CAAAA,CAAQ,YAAA,CAAa,MAAA,CAAO,cAAA,CAAgBhB,CAAW,CAAA,CACvDgB,CAAAA,CAAQ,YAAA,CAAa,MAAA,CAAO,OAAA,CAASe,GAAM,EAC3Cf,CAAAA,CAAQ,YAAA,CAAa,MAAA,CAAO,OAAA,CAAS5G,CAAK,CAAA,CAE1CpT,EAAI,QAAA,CAASga,CAAAA,CAAQ,QAAA,EAAU,EACjC,CACF,EAGAW,CAAAA,CAAiB,GAAA,CACf,qCAAA,CACAC,CAAAA,CACAN,EACF,CAAA,CAEOK,CACT,CAEA,IAAOM,EAAAA,CAAQvB,EAAAA,CC1OR,SAASwB,EAAAA,CAAmB7X,CAAAA,CAAgBiE,EAAcrE,CAAAA,CAAuB,CACtF,OAAO,MAAO4S,CAAAA,CAAc7V,CAAAA,CAAe4F,IAAuB,CAChE,IAAM3G,CAAAA,CAAY4W,CAAAA,CAAI,OAAA,CAAQ,wBAAwB,EAClDzS,CAAAA,CAA6C,CAAE,OAAA,CAAS,IAAA,CAAM,IAAA,CAAM,IAAK,CAAA,CAE7E,GAAI,OAAOnE,CAAAA,EAAc,QAAA,EAAY2C,CAAAA,EAAc,CACjD,GAAI,CACF,GAAM,CAAE,OAAA,CAAA/B,CAAAA,CAAS,IAAA,CAAAM,CAAK,EAAI,MAAMoB,CAAAA,CAAatC,CAAS,CAAA,CACtDmE,CAAAA,CAAU,CAAE,QAAAvD,CAAAA,CAAS,IAAA,CAAAM,CAAK,EAC5B,CAAA,KAAQ,EAKV,IAAMmD,CAAAA,CAAcC,CAAAA,CAAiB,OAAA,CAAS,CAAA,MAAA,EAASF,CAAAA,CAAO,WAAA,EAAa,CAAA,CAAA,EAAIiE,CAAI,CAAA,CAAA,CAAI,CACrF,MAAA,CAAAjE,CAAAA,CACA,KAAAiE,CAAAA,CACA,KAAA,CAAOuO,CAAAA,CAAI,KAAA,CACX,IAAA,CAAMA,CAAAA,CAAI,KACV,MAAA,CAAQA,CAAAA,CAAI,MACd,CAAC,CAAA,CAED,GAAI,CACF,IAAMrS,CAAAA,CAAW,MAAMP,CAAAA,CACrB,CACE,KAAA,CAAO4S,CAAAA,CAAI,MACX,IAAA,CAAMA,CAAAA,CAAI,IAAA,CACV,MAAA,CAAQA,CAAAA,CAAI,MAAA,CACZ,QAASA,CAAAA,CAAI,OAAA,CACb,OAAA,CAASA,CAAAA,CAAI,OAAA,CACb,OAAA,CAAS,OAAO,QAAA,CAASA,CAAAA,CAAI,IAAI,CAAA,CAAIA,CAAAA,CAAI,IAAA,CAAO,KAAA,CAAA,CAChD,GAAA,CAAAA,CAAAA,CACA,GAAA,CAAA7V,CAAAA,CACA,IAAA,CAAA4F,CACF,CAAA,CACAxC,CACF,CAAA,CAEAE,CAAAA,CAAY,GAAA,EAAI,CAGZE,CAAAA,GACFxD,CAAAA,CAAI,OAAOwD,CAAAA,CAAS,MAAA,EAAU,GAAG,CAAA,CAE7BA,CAAAA,CAAS,QAAA,EACXxD,EAAI,QAAA,CAASwD,CAAAA,CAAS,QAAQ,CAAA,CAG5BA,CAAAA,CAAS,OAAA,EACX,MAAA,CAAO,OAAA,CAAQA,CAAAA,CAAS,OAAO,CAAA,CAAE,OAAA,CAAQ,CAAC,CAACzL,EAAKO,CAAK,CAAA,GAAM,CACzD0H,CAAAA,CAAI,SAAA,CAAUjI,CAAAA,CAAKO,CAAK,EAC1B,CAAC,CAAA,CAGH0H,CAAAA,CAAI,IAAA,CAAKwD,CAAAA,CAAS,IAAI,CAAA,EAE1B,CAAA,MAASpJ,CAAAA,CAAO,CACdkJ,CAAAA,CAAY,GAAA,CAAI,OAAO,CAAA,CAEnBlJ,CAAAA,YAAiB+gB,GAAAA,CACnBnb,CAAAA,CAAI,MAAA,CAAO5F,CAAAA,CAAM,MAAM,EAAE,IAAA,CAAKA,CAAAA,CAAM,OAAO,CAAA,EAE3C,OAAA,CAAQ,KAAA,CAAM,2BAA2Byb,CAAAA,CAAI,IAAI,CAAA,CAAE,CAAA,CACnD,OAAA,CAAQ,KAAA,CAAMzb,CAAK,CAAA,CACnB4F,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,MAAA,CAAO5F,CAAK,CAAC,CAAA,EAEtC,CACF,CACF,CC/CA,IAAIghB,EAAAA,CAAiC,MAAA,CAAO,OAAO,EAAE,CAAA,CAE9C,SAASC,EAAAA,CAAkBC,CAAAA,CAAmC,CACnEF,EAAAA,CAAiB,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,EAAC,CAAGA,GAAgBE,CAAiB,CAAC,EACrF,CAEO,SAASC,EAAAA,EAAoB,CAClC,OAAOH,EACT,CChCA,IAAII,EAAAA,CAAmC,MAAA,CAAO,OAAO,EAAE,CAAA,CAEhD,SAASC,EAAAA,CAAmBC,CAAAA,CAAqC,CACtEF,EAAAA,CAAkB,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,EAAC,CAAGA,GAAiBE,CAAkB,CAAC,EACxF,CAEO,SAASC,EAAAA,EAAqB,CACnC,OAAOH,EACT,CCSA,SAASI,EAAAA,CAAwBhhB,CAAAA,CAI9B,CACD,IAAMihB,CAAAA,CAAwC,EAAC,CAE/C,GAAI,CAACjhB,CAAAA,CAEH,OAAAihB,CAAAA,CAAY,IAAA,CAAKjG,CAAAA,CAAQ,IAAA,CAAK,CAAE,KAAA,CAAO,MAAO,CAAC,CAAC,CAAA,CAChDiG,CAAAA,CAAY,IAAA,CAAKjG,CAAAA,CAAQ,UAAA,CAAW,CAAE,QAAA,CAAU,IAAA,CAAM,KAAA,CAAO,MAAO,CAAC,CAAC,EAC/DiG,CAAAA,CAIT,GAAIjhB,CAAAA,CAAO,IAAA,GAAS,KAAA,CAAO,CACzB,IAAMkhB,CAAAA,CAAc,OAAOlhB,CAAAA,CAAO,IAAA,EAAS,QAAA,CAAWA,CAAAA,CAAO,IAAA,CAAO,CAAE,KAAA,CAAO,MAAO,CAAA,CACpFihB,CAAAA,CAAY,IAAA,CAAKjG,CAAAA,CAAQ,KAAKkG,CAAW,CAAC,EAC5C,CAGA,GAAIlhB,CAAAA,CAAO,aAAe,KAAA,CAAO,CAC/B,IAAMmhB,CAAAA,CACJ,OAAOnhB,CAAAA,CAAO,UAAA,EAAe,QAAA,CAAWA,CAAAA,CAAO,UAAA,CAAa,CAAE,QAAA,CAAU,IAAA,CAAM,KAAA,CAAO,MAAO,CAAA,CAC9FihB,CAAAA,CAAY,IAAA,CAAKjG,CAAAA,CAAQ,UAAA,CAAWmG,CAAiB,CAAC,EACxD,CAGA,GAAInhB,CAAAA,CAAO,GAAA,CAAK,CACd,IAAMohB,CAAAA,CAAa,OAAOphB,CAAAA,CAAO,GAAA,EAAQ,QAAA,CAAWA,CAAAA,CAAO,GAAA,CAAM,EAAC,CAC5DqhB,CAAAA,CAAoB,CACxB,KAAA,CAAOD,CAAAA,CAAW,KAAA,EAAS,OAC3B,IAAA,CAAMA,CAAAA,CAAW,IAAA,EAAQ,KAC3B,CAAA,CACAH,CAAAA,CAAY,KAAKjG,CAAAA,CAAQ,GAAA,CAAIqG,CAAiB,CAAC,EACjD,CAEA,OAAOJ,CACT,CAEA,SAASK,EAAAA,CAAqBC,CAAAA,CAA0BC,CAAAA,CAAmB,CACzE,IAAA,IAAWC,CAAAA,IAAUD,CAAAA,CACnB,IAAA,IAAWE,CAAAA,IAASD,CAAAA,CAAO,MAAA,CAAQ,CACjC,GAAM,CAAE,IAAA,CAAA/U,CAAAA,CAAM,QAAA,CAAAiV,CAAAA,CAAU,KAAA3M,CAAK,CAAA,CAAI0M,CAAAA,CAC3BT,CAAAA,CAAcD,EAAAA,CAAwBhM,CAAI,EAEhD,MAAA,CAAO,OAAA,CAAQ2M,CAAQ,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAClZ,CAAAA,CAAQJ,CAAO,CAAA,GAAM,CACtDkZ,CAAAA,CAAI9Y,CAAoB,CAAA,CAAEiE,EAAM,GAAGuU,CAAAA,CAAaX,EAAAA,CAAmB7X,CAAAA,CAAQiE,CAAAA,CAAMrE,CAAO,CAAC,EAC3F,CAAC,EACH,CAEJ,CAEA,eAAsBuZ,GACpBC,CAAAA,CACA,CACE,eAAA,CAAAC,CAAAA,CACA,QAAA,CAAA5kB,CACF,CAAA,CAIA,CACA,IAAMqkB,CAAAA,CAAMvG,CAAAA,EAAQ,CAEpBuG,CAAAA,CAAI,GAAA,CAAIQ,IAAc,CAAA,CAEtBR,CAAAA,CAAI,GAAA,CAAIS,EAAAA,EAA2B,EAGnCV,EAAAA,CAAqBC,CAAAA,CAAKO,CAAe,CAAA,CAGzCP,CAAAA,CAAI,GAAA,CAAIvG,EAAQ,IAAA,CAAK,CAAE,KAAA,CAAO,MAAO,CAAC,CAAC,CAAA,CACvCuG,CAAAA,CAAI,GAAA,CAAIvG,CAAAA,CAAQ,UAAA,CAAW,CAAE,QAAA,CAAU,IAAA,CAAM,MAAO,MAAO,CAAC,CAAC,CAAA,CAE7DuG,CAAAA,CAAI,GAAA,CAAIlC,IAAkB,CAAA,CAC1BkC,CAAAA,CAAI,GAAA,CAAIlB,EAAAA,EAAkB,EAG1BkB,CAAAA,CAAI,IAAA,CAAK,qCAAA,CAAuC,MAAOtG,CAAAA,CAAc7V,CAAAA,GAAkB,CACrF,GAAM,CAAE,OAAA,CAAAH,CAAQ,CAAA,CAAI,MAAMiY,EAAAA,CAAejC,CAAG,CAAA,CAE5C,GAAI,CAAChW,CAAAA,EAAS,MAAA,CAAQ,CACpBG,EAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CAAE,KAAA,CAAO,mBAAoB,CAAC,CAAA,CACnD,MACF,CAEAA,CAAAA,CAAI,MAAA,CAAO,gBAAA,CAAkBH,CAAAA,CAAQ,SAAA,CAAW,CAC9C,QAAA,CAAU,IAAA,CACV,MAAA,CAAQ,OAAA,CAAQ,IAAI,QAAA,GAAa,YAAA,CACjC,QAAA,CAAU,KAAA,CACV,IAAA,CAAM,sBAAA,CACN,OAAQ,EAAA,CAAK,EAAA,CAAK,GACpB,CAAC,CAAA,CAEDG,CAAAA,CAAI,KAAK,CAAE,EAAA,CAAI,IAAK,CAAC,EACvB,CAAC,CAAA,CAEDmc,CAAAA,CAAI,IAAA,CAAK,sCAAA,CAAwC,MAAOtG,CAAAA,CAAc7V,CAAAA,GAAkB,CACtF,GAAM,CAAE,UAAA,CAAA6c,CAAW,CAAA,CAAIhH,CAAAA,CAAI,MAAA,CACrBzS,EAAU,MAAM0U,EAAAA,CAAejC,CAAG,CAAA,CAExC,GAAI,CACF,IAAM3Y,CAAAA,CAASsH,GAAAA,CAAe,MAAMrB,EAAAA,CAAU0Z,CAAAA,CAAYhH,CAAAA,CAAI,IAAA,CAAK,IAAA,CAAMzS,CAAO,CAAC,CAAA,CACjFpD,CAAAA,CAAI,IAAA,CAAK,CACP,KAAM9C,CAAAA,CACN,OAAA,CAASuH,GAAAA,CAAmBvH,CAAM,CACpC,CAAC,EACH,CAAA,MAAS9C,CAAAA,CAAO,CACd0iB,EAAAA,CAAkB9c,CAAAA,CAAK6c,CAAAA,CAAYziB,CAAK,EAC1C,CACF,CAAC,CAAA,CAED,IAAMiL,CAAAA,CAAa0X,EAAAA,CAAK,YAAA,CAAaZ,CAAG,CAAA,CAExC,MAAMM,CAAAA,CAAO,IAAA,CAAK,CAAE,WAAApX,CAAW,CAAC,CAAA,CAE5BoX,CAAAA,CAAO,WAAA,EACTN,CAAAA,CAAI,IAAIM,CAAAA,CAAO,WAAA,EAAa,CAAA,CAG9BN,CAAAA,CAAI,GAAA,CAAI,IAAK,CAACtG,CAAAA,CAAc7V,CAAAA,GACnByc,CAAAA,CAAO,OAAA,CAAQ5G,CAAAA,CAAK7V,CAAG,CAC/B,CAAA,CAED,OAAA,CAAQ,EAAA,CAAG,oBAAA,CAAsB,CAACgd,CAAAA,CAAQC,IAAY,CACpD,OAAA,CAAQ,KAAA,CAAM,8BAA8B,CAAA,CAC5C,OAAA,CAAQ,MAAMD,CAAAA,YAAkB,KAAA,CAAQA,CAAAA,CAAO,KAAA,CAAQA,CAAM,CAAA,CAC7D,QAAQ,KAAA,CAAM,UAAA,CAAYC,CAAO,EACnC,CAAC,CAAA,CAGD,OAAA,CAAQ,EAAA,CAAG,mBAAA,CAAsB7iB,CAAAA,EAAU,CACzC,OAAA,CAAQ,KAAA,CAAM,qBAAqB,EACnC,OAAA,CAAQ,KAAA,CAAMA,CAAAA,CAAM,KAAK,CAAA,CACzB,OAAA,CAAQ,MAAM,yBAAyB,EACzC,CAAC,CAAA,CAED,IAAM8iB,CAAAA,CAAoBvB,IAAmB,EAAG,QAAA,CAC5CuB,CAAAA,EACFA,CAAAA,CAAkB,IAAA,CAAK,CACrB,UAAA,CAAA7X,CAAAA,CACA,QAAA,CAAAvN,CACF,CAAC,CAAA,CAGH,IAAMqlB,CAAAA,CAAO,QAAQ,GAAA,CAAI,cAAA,EAAkB,OAAA,CAAQ,GAAA,CAAI,IAAA,EAAQ,GAAA,CAC/D9X,CAAAA,CAAW,MAAA,CAAO8X,CAAAA,CAAM,IAAM,CAC5B9I,GAAAA,CAAQ,qBAAA,CAAuB,CAAE,OAAQ,KAAM,CAAC,CAAA,CAChD,IAAM+I,CAAAA,CAAUplB,GAAAA,CAAU,kBAAkB,CAAA,EAAK,CAAA,iBAAA,EAAoBmlB,CAAI,CAAA,CAAA,CACzE,OAAA,CAAQ,GAAA,CAAI;AAAA,uBAAA,EAA4BC,CAAO;AAAA,CAAI,EACrD,CAAC,EACH,CAEA,eAAsBtF,GAAejC,CAAAA,CAAc,CACjD,IAAMvO,CAAAA,CAAAA,CAAQuO,EAAI,IAAA,EAAQA,CAAAA,CAAI,KAAO,EAAA,EAAI,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,CAE/CwH,CAAAA,CAAkB/V,EAAK,UAAA,CAAW,sBAAsB,CAAA,EAAKA,CAAAA,CAAK,SAAS,WAAW,CAAA,CAEtFrI,CAAAA,CAAYX,GAAA,CACf,QAAO,CACP,OAAA,GACA,SAAA,CAAW2I,CAAAA,EAAQA,GAAO,IAAI,CAAA,CAC9B,KAAA,CACC4O,CAAAA,CAAI,QAAQ,SAAA,GACTwH,CAAAA,CAAkBxH,CAAAA,CAAI,OAAA,CAAQ,eAAiB,IAAA,CAAA,EAChDA,CAAAA,CAAI,IAAA,CAAK,SACb,EAEI3R,CAAAA,CAAa5F,GAAA,CAChB,OAAO,CACN,WAAA,CAAaA,IAAE,MAAA,EAAO,CACtB,YAAA,CAAcA,GAAA,CAAE,QAAO,CACvB,WAAA,CAAaA,IAAE,MAAA,EAAO,CACtB,aAAcA,GAAA,CAAE,MAAA,EAAO,CACvB,UAAA,CAAYA,IAAE,MAAA,EAAO,CACrB,YAAaA,GAAA,CAAE,MAAA,GAAS,QAAA,EAC1B,CAAC,CAAA,CACA,SAAQ,CACR,KAAA,CAAMuX,CAAAA,CAAI,IAAA,CAAK,UAAU,CAAA,EAAK,CAC/B,WAAA,CAAa,CAAA,CACb,aAAc,CAAA,CACd,WAAA,CAAa,EACb,YAAA,CAAc,CAAA,CACd,WAAY,CAAA,CACZ,WAAA,CAAa,IACf,CAAA,CAEM1M,EAAiC,CACrC,EAAA,CAAImU,GAAYzH,CAAG,CAAA,CACnB,UAAWA,CAAAA,CAAI,GAAA,CAAI,YAAY,CAAA,CAC/B,eAAgBA,CAAAA,CAAI,GAAA,CAAI,iBAAiB,CAAA,CACzC,QAAA,CAAUA,EAAI,GAAA,CAAI,UAAU,CAAA,CAC5B,OAAA,CAASA,EAAI,QAAA,CAAW,KAAA,CAAQA,CAAAA,CAAI,GAAA,CAAI,MAAM,CAChD,CAAA,CAGA,GADoB,CAAA,CAAQjU,GAAc,CACzB,CACf,GAAM,CAAE,OAAA,CAAA/B,EAAS,IAAA,CAAAM,CAAAA,CAAM,KAAA,CAAAS,CAAM,EAAI,MAAMW,CAAAA,CAAatC,CAAS,CAAA,CAC7D,OAAO,CACL,UAAA,CAAAiF,CAAAA,CACA,cAAA,CAAAiF,CAAAA,CACA,QAAAtJ,CAAAA,CACA,IAAA,CAAAM,EACA,KAAA,CAAAS,CACF,CACF,CAEA,OAAO,CACL,UAAA,CAAAsD,EACA,cAAA,CAAAiF,CAAAA,CACA,OAAA,CAAS,IAAA,CACT,KAAM,IAAA,CACN,KAAA,CAAOpI,EAAAA,EACT,CACF,CAEA,SAAS+b,GAAkB9c,CAAAA,CAAe6c,CAAAA,CAAoBziB,EAAgB,CAG5E,GAAIA,CAAAA,YAAiB+gB,GAAAA,CAAgB,CAC/B/gB,CAAAA,CAAM,MAAA,EAAU,GAAA,EAAOA,CAAAA,CAAM,OAAS,GAAA,EACxC,OAAA,CAAQ,KAAA,CAAM,CAAA,cAAA,EAAiByiB,CAAU,CAAA,CAAA,CAAA,CAAKziB,CAAK,EAErD4F,CAAAA,CAAI,MAAA,CAAO5F,EAAM,MAAM,CAAA,CAAE,IAAA,CAAKA,CAAAA,CAAM,OAAO,CAAA,CAC3C,MACF,CAEA,GAAIA,aAAiB,KAAA,EAASA,CAAAA,EAAO,WAAA,EAAa,IAAA,GAAS,YAAc,QAAA,GAAYA,CAAAA,CAAO,CAC1F,IAAImjB,CAAAA,CAAe,GACnB,GAAI,CACFA,CAAAA,CAAeC,EAAAA,CAAcpjB,CAAmB,EAClD,CAAA,MAASqjB,EAAc,CACrB,OAAA,CAAQ,MAAM,CAAA,2BAAA,EAA8BZ,CAAU,CAAA,CAAA,CAAA,CAAKY,CAAY,EACvEF,CAAAA,CAAe,oBACjB,CACAvd,CAAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAKud,CAAY,CAAA,CACjC,MACF,CAEA,OAAA,CAAQ,KAAA,CAAM,CAAA,cAAA,EAAiBV,CAAU,CAAA,CAAA,CAAA,CAAKziB,CAAK,CAAA,CACnD4F,CAAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK5F,CAAAA,YAAiB,KAAA,CAAQA,EAAM,OAAA,CAAU,MAAA,CAAOA,CAAK,CAAC,EAC7E,CAEA,SAASojB,GAAcE,CAAAA,CAA8B,CACnD,IAAMC,CAAAA,CAAYD,CAAAA,CAAS,OAAA,EAAQ,CAC7BE,EAAgB,MAAA,CAAO,OAAA,CAAQD,EAAU,WAAW,CAAA,CAAE,IAC1D,CAAC,CAAC5lB,CAAAA,CAAK8lB,CAAM,IAAM,CAAA,EAAG9lB,CAAG,CAAA,EAAA,EAAA,CAAM8lB,CAAAA,EAAU,EAAC,EAAG,IAAA,CAAK,IAAI,CAAC,EACzD,CAAA,CACMC,CAAAA,CAAeH,EAAU,UAAA,CAE/B,OADoB,CAAC,GAAGC,CAAAA,CAAe,GAAGE,CAAY,EAAE,MAAA,CAAO,OAAO,EACnD,IAAA,CAAK,IAAI,CAC9B,CAEA,SAASlB,EAAAA,EAAoD,CAC3D,GAAM,CAAE,cAAA,CAAAmB,CAAe,CAAA,CAAIxC,EAAAA,GACrByC,CAAAA,CAAqBD,CAAAA,EAAkBA,CAAAA,CAAe,MAAA,CAAS,EAC/DE,CAAAA,CAAYD,CAAAA,CAAqB,CAAC,QAAA,CAAU,GAAGD,CAAc,CAAA,CAAE,IAAA,CAAK,GAAG,EAAI,QAAA,CAEjF,OAAO,CAACjE,CAAAA,CAAM9Z,CAAAA,CAAK4F,IAAS,CAC1B5F,CAAAA,CAAI,SAAA,CAAU,yBAAA,CAA2B,mBAAmBie,CAAS,CAAA,CAAE,CAAA,CAIlED,CAAAA,EACHhe,EAAI,SAAA,CAAU,iBAAA,CAAmB,YAAY,CAAA,CAE/C4F,IACF,CACF,CAEA,SAAS0X,EAAAA,CAAYzH,EAAkC,CAErD,IAAMqI,CAAAA,CAAerI,CAAAA,CAAI,QAAQ,iBAAiB,CAAA,CAClD,GAAIqI,CAAAA,CAEF,QADgB,KAAA,CAAM,OAAA,CAAQA,CAAY,CAAA,CAAIA,EAAa,CAAC,CAAA,CAAIA,EAAa,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA,EAC1E,IAAA,EAAK,CAGtB,IAAMC,CAAAA,CAAWtI,CAAAA,CAAI,IAAMA,CAAAA,CAAI,MAAA,EAAQ,cACvC,GAAIsI,CAAAA,CAEF,OAAOA,CAAAA,CAAS,WAAW,SAAS,CAAA,CAAIA,EAAS,SAAA,CAAU,CAAC,EAAIA,CAIpE,CC9OA,eAAsBC,EAAAA,CAAS,CAC7B,OAAA,CAAAhC,CAAAA,CAAU,EAAC,CACX,MAAAxb,GAAAA,CAAQ,EAAC,CACT,YAAA,CAAAF,EAAe,EAAC,CAChB,OAAA+b,CAAAA,CAASvF,EAAAA,CACT,WAAA/C,CAAAA,CAAa,EAAC,CACd,KAAA,CAAA9N,EAAQ,EAAC,CACT,KAAAgY,CAAAA,CAAO,GACP,QAAA,CAAAC,CAAAA,CAAW,EAAC,CACZ,UAAAC,GAAAA,CAAY,EACd,CAAA,CAAe,CACbC,GAAO,MAAA,EAAO,CAEdA,EAAAA,CAAO,MAAA,CAAO,CAAE,IAAA,CAAM,gBAAiB,CAAC,CAAA,CAExC,IAAMC,CAAAA,CAAmB,CAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,2BAE7CC,EAAAA,EAAc,CACX,KAAK,IAAM,EAEX,CAAA,CACA,KAAA,CAAM,IAAM,EAEZ,CAAA,CAGH,IAAMC,EAAgB,CACpBtQ,EAAAA,CACApO,GACAwT,EAAAA,CACAsB,EAAAA,CACAC,EAAAA,CACAvT,EAAAA,CACAuS,GACAwB,EACF,CAAA,CACMkH,IAAkB,CAAC,GAAGiC,EAAe,GAAGvC,CAAO,CAAA,CAErDwC,CAAAA,GAEAC,EAAAA,CAAkBF,CAAa,CAAA,CAC/BG,EAAAA,CAAkB1C,CAAO,CAAA,CAEzBzb,EAAAA,CAAUC,GAAAA,CAAOF,CAAY,EAE7B,IAAM9I,CAAAA,CAAemnB,GAAgBrC,GAAe,CAAA,CACpDsC,EAAUpnB,CAAY,CAAA,CACtB,IAAMqnB,CAAAA,CAAYC,GAAUxC,GAAe,CAAA,CACrC5kB,IAAWqnB,EAAAA,CAAYzC,GAAe,EAE5C0C,EAAAA,CAAe1C,GAAe,CAAA,CAE9B,IAAM7kB,EAAawnB,EAAAA,CAAc3C,GAAe,EAChD/R,EAAAA,CAAe9S,CAAU,EAEzB,GAAM,CAAE,YAAA,CAAAynB,CAAAA,CAAc,gBAAAxL,CAAgB,CAAA,CAAIJ,EAAAA,CAAcuL,CAAS,EAKjE,GAAIR,CAAAA,CAAkB,CACpB,GAAM,CAAE,OAAA,CAAA9P,CAAAA,CAAS,cAAA4Q,CAAAA,CAAe,QAAA,CAAAC,EAAU,gBAAA,CAAAC,EAAAA,CAAkB,SAAA,CAAAC,EAAU,EACpE,MAAMzQ,EAAAA,CAAoB,CACxB,YAAA,CAAArX,CAAAA,CACA,iBAAkB4b,EAAAA,EAAoB,CACtC,MAAA,CAAQM,CAAAA,CACR,MAAAlT,GACF,CAAC,EACHyP,EAAAA,CAAkB1B,CAAO,EACzBgR,CAAAA,CAAY,CAAE,aAAA,CAAAJ,CAAAA,CAAe,SAAAC,CAAAA,CAAU,gBAAA,CAAAC,EAAAA,CAAkB,SAAA,CAAAC,EAAU,CAAC,EACtE,CAAA,KACEpP,CAAAA,CAAYvB,GAAgBnX,CAAY,CAAC,EAY3C,GATA+Q,EAAAA,CAAetC,CAAK,CAAA,CACpB0C,EAAAA,CAAcsV,CAAI,CAAA,CAClBhD,GAAkBiD,CAAQ,CAAA,CAC1B7C,GAAmB,CACjB,GAAG8C,IACH,QAAA,CAAUA,GAAAA,CAAU,QAAA,EAAYpY,EAClC,CAAC,CAAA,CAEkBvE,CAAAA,GACH,CACd,MAAMF,IAAQ,CACd,IAAMke,CAAAA,CAAkB,CAAC,GAAG,IAAI,GAAA,CAAI,CAAC,GAAGN,EAAc,GAAGxL,CAAe,CAAC,CAAC,EAC1E+L,EAAAA,CAAWD,CAAe,EAC1B,MAAME,EAAAA,CAAmChM,EAAiBK,CAAU,EACtE,CAAA,KACEW,EAAAA,CAAgBX,CAAU,CAAA,CAGxBsK,CAAAA,GACF,MAAMsB,CAAAA,EAAY,CAClB5P,IAAgB,CAAA,CAGlB2C,EAAAA,EAAc,CAAE,KAAA,CAAM,QAAQ,KAAK,CAAA,CAEnC,MAAM0J,EAAAA,CAAYC,CAAAA,CAAQ,CAAE,eAAA,CAAAC,GAAAA,CAAiB,QAAA,CAAA5kB,GAAS,CAAC,EACzD,CAEA,SAASgnB,EAAAA,CAAkB1C,EAAmB,CAC5C,IAAA,IAAWC,CAAAA,IAAUD,CAAAA,CAAS,CAC5B,IAAA,GAAW,CAACrkB,EAAKkL,CAAO,CAAA,GAAK,OAAO,OAAA,CAAQoZ,CAAAA,CAAO,OAAO,CAAA,CACxD7Z,GAAY,CAAA,EAAG6Z,CAAAA,CAAO,IAAI,CAAA,CAAA,EAAItkB,CAAG,CAAA,CAAA,CAAIkL,CAAO,CAAA,CAE9C,IAAA,GAAW,CAAClL,CAAAA,CAAKkL,CAAO,IAAK,MAAA,CAAO,OAAA,CAAQoZ,EAAO,SAAS,CAAA,CAC1DzZ,EAAAA,CAAe,CAAA,EAAGyZ,EAAO,IAAI,CAAA,CAAA,EAAItkB,CAAG,CAAA,CAAA,CAAIkL,CAAO,EAEnD,CACF,CAEA,SAAS4b,GAAkBzC,CAAAA,CAAmB,CAC5C,QAAWC,CAAAA,IAAUD,CAAAA,CAAS,CAC5B,IAAA,GAAW,CAACrkB,CAAAA,CAAKkL,CAAO,IAAK,MAAA,CAAO,OAAA,CAAQoZ,EAAO,OAAO,CAAA,CACxDxZ,GAAmB,CAAA,EAAGwZ,CAAAA,CAAO,IAAI,CAAA,CAAA,EAAItkB,CAAG,CAAA,CAAA,CAAIkL,CAAO,EAErD,IAAA,GAAW,CAAClL,EAAKkL,CAAO,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQoZ,EAAO,SAAS,CAAA,CAC1DtZ,EAAAA,CAAsB,CAAA,EAAGsZ,EAAO,IAAI,CAAA,CAAA,EAAItkB,CAAG,CAAA,CAAA,CAAIkL,CAAO,EAE1D,CACF,CAEA,SAASic,EAAAA,CAAU9C,EAAmB,CACpC,OAAOA,CAAAA,CAAQ,OAAA,CAASC,GAAWA,CAAAA,CAAO,MAAM,CAClD,CAEA,SAAS8C,GAAY/C,CAAAA,CAAmB,CACtC,OAAOA,CAAAA,CAAQ,QAASC,CAAAA,EAAWA,CAAAA,CAAO,QAAQ,CACpD,CAEA,SAASgD,EAAAA,CAAcjD,CAAAA,CAAmB,CACxC,OAAOA,EAAQ,OAAA,CAASC,CAAAA,EAAWA,CAAAA,CAAO,UAAU,CACtD,CAEA,SAAS2D,EAAAA,CAAyBC,CAAAA,CAAmB7lB,EAAgB,CACnE,OAAA,CAAQ,KAAK,CAAA,oCAAA,EAAuC6lB,CAAS,yBAA0B7lB,CAAK,EAC9F,CAEA,IAAM8lB,GAA2B,YAAA,CAEjC,eAAeJ,GACbhM,CAAAA,CACAK,CAAAA,CACA,CAKA,GAAI,CAJY,MAAMpC,CAAAA,CAAYmO,GAA0B,CAC1D,YAAA,CAAcvgB,EAAK,OAAA,CAAQ,EAAE,EAC7B,SAAA,CAAW,IACb,CAAC,CAAA,CAEC,OAGF,IAAIwgB,CAAAA,CACAC,CAAAA,CAEJ,GAAI,CACFD,CAAAA,CAAiBrM,CAAAA,CAAgB,MAAA,CAAQzE,CAAAA,EAAUA,EAAM,oBAAA,EAAqB,GAAM,UAAU,CAAA,CAC9F+Q,CAAAA,CAAmBtM,EAAgB,MAAA,CAChCzE,CAAAA,EAAUA,CAAAA,CAAM,oBAAA,KAA2B,YAC9C,CAAA,CAEA,QAAWA,CAAAA,IAAS8Q,CAAAA,CAClB,MAAME,EAAAA,CAAmBhR,CAAAA,CAAO,MAAM,CAAA,CAExC,QAAWA,CAAAA,IAAS+Q,CAAAA,CAClB,MAAMC,EAAAA,CAAmBhR,CAAAA,CAAO,WAAW,EAE/C,CAAA,MAASjV,CAAAA,CAAO,CACd,YAAMkY,EAAAA,CAAY4N,EAAwB,CAAA,CACpC9lB,CACR,CAEA,IAAMkmB,CAAAA,CAAAA,CAAkC,SAAY,CAClD,QAAWjR,CAAAA,IAAS+Q,CAAAA,CAClB,MAAMC,EAAAA,CAAmBhR,CAAAA,CAAO,aAAa,EAEjD,CAAA,GAAG,CACGkR,CAAAA,CAAmBrM,GAAcC,CAAAA,CAAY,CAAE,SAAU,MAAO,CAAC,EAElE,OAAA,CAAQ,UAAA,CAAW,CAACmM,CAAAA,CAAgCC,CAAgB,CAAC,CAAA,CACvE,KAAK,CAAC,CAACC,EAAyBC,CAAe,CAAA,GAAM,CAChDD,CAAAA,CAAwB,SAAW,UAAA,EACrC,OAAA,CAAQ,KAAA,CAAM,oCAAA,CAAsCA,EAAwB,MAAM,CAAA,CAGhFC,CAAAA,CAAgB,MAAA,GAAW,YAC7B,OAAA,CAAQ,KAAA,CAAM,4BAA6BA,CAAAA,CAAgB,MAAM,EAErE,CAAC,CAAA,CACA,OAAA,CAAQ,SAAY,CACnB,MAAMnO,EAAAA,CAAY4N,EAAwB,EAC5C,CAAC,EACL,CAEA,eAAeG,EAAAA,CACbhR,CAAAA,CACAqR,EAAoC,MAAA,CACpC,CACA,IAAMT,CAAAA,CAAY5Q,CAAAA,CAAM,SAAQ,CAEhC,GAAI,CACF,MAAMA,EAAM,aAAA,CAAcqR,CAAa,EACzC,CAAA,MAAStmB,EAAO,CACd4lB,EAAAA,CAAyBC,CAAAA,CAAW7lB,CAAK,EAC3C,CACF,CAEA,SAAS2kB,EAAAA,CAAgB3C,CAAAA,CAAiC,CACxD,IAAMuE,CAAAA,CAAuB,EAAC,CAE9B,QAAWtE,CAAAA,IAAUD,CAAAA,CACnB,OAAW,CAACrkB,CAAAA,CAAKO,CAAK,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQ+jB,CAAAA,CAAO,YAAY,CAAA,CAAG,CAC9D,IAAMuE,CAAAA,CAAc,CAAA,EAAGvE,EAAO,IAAI,CAAA,CAAA,EAAItkB,CAAG,CAAA,CAAA,CACzC,GAAI6oB,CAAAA,IAAeD,CAAAA,CACjB,MAAM,IAAI,MAAM,CAAA,6BAAA,EAAgCC,CAAW,CAAA,EAAA,EAAKvE,CAAAA,CAAO,IAAI,CAAA,CAAA,CAAG,CAAA,CAGhFsE,EAAOC,CAAW,CAAA,CAAItoB,EACxB,CAGF,OAAOqoB,CACT,CAEA,SAASvB,EAAAA,CAAehD,CAAAA,CAAmB,CACzC,IAAA,IAAWC,KAAUD,CAAAA,CACnB,IAAA,GAAW,CAACyE,CAAAA,CAAWC,CAAa,CAAA,GAAK,MAAA,CAAO,QAAQzE,CAAAA,CAAO,QAAQ,EACrE5J,EAAAA,CAAc,CAAA,EAAG4J,CAAAA,CAAO,IAAI,IAAIwE,CAAS,CAAA,CAAA,CAAIC,CAAa,EAGhE,CAEA,SAASjB,EAAAA,CAAWtoB,CAAAA,CAAqC,CACvD,IAAM4D,CAAAA,CAAS8G,EAAAA,GACf,GAAI,CAAC9G,EACH,MAAM,IAAI,KAAA,CAAM,6DAA6D,EAG/E,IAAA,IAAWkU,CAAAA,IAAS9X,EAClB8X,CAAAA,CAAM,IAAA,CAAKlU,CAAM,EAErB,CAEA,eAAeujB,EAAAA,EAAgB,CAG7B,GAF0B,OAAA,CAAQ,IAAI,0BAAA,GAA+B,OAAA,CAE9C,CACrB,IAAMqC,CAAAA,CAAkB,OAAA,CAAQ,GAAA,CAAI,4BAA8B,6BAAA,CAC5DxB,CAAAA,CAAgB,OAAA,CAAQ,GAAA,CAAI,yBAE5ByB,CAAAA,CAAa,MAAMC,EAAAA,EAAc,CACjCC,EAAuB,MAAM,OAAO,uBAAoB,CAAA,CAE9D,MAAM,MAAM,CAAA,EAAGH,CAAe,CAAA,oBAAA,CAAA,CAAwB,CACpD,OAAQ,MAAA,CACR,OAAA,CAAS,CACP,cAAA,CAAgB,kBAClB,EACA,IAAA,CAAM,IAAA,CAAK,SAAA,CAAU,CACnB,YAAaC,CAAAA,CAAW,IAAA,CACxB,QAASE,CAAAA,CAAqB,OAAA,CAAQ,QACtC,aAAA,CAAe3R,EAAAA,CAAG,QAAA,EAAS,CAC3B,cAAAgQ,CACF,CAAC,CACH,CAAC,EACH,CACF,CAEA,eAAe0B,EAAAA,EAAgB,CAC7B,GAAI,CACF,IAAME,CAAAA,CAAkB7Z,EAAAA,CAAK,KAAK,OAAA,CAAQ,GAAA,EAAI,CAAG,cAAc,EACzD8Z,CAAAA,CAAqB,MAAMzK,GAAG,QAAA,CAASwK,CAAAA,CAAiB,OAAO,CAAA,CAGrE,OAAO,CACL,IAAA,CAHkB,KAAK,KAAA,CAAMC,CAAkB,EAG7B,IAAA,EAAQ,SAC5B,CACF,CAAA,KAAQ,CACN,OAAO,CACL,KAAM,SACR,CACF,CACF,CC5VA,eAAsBC,EAAAA,CAAYhiB,CAAAA,CAAkB,CAClD,MAAMkB,CAAAA,CAAkC,UAAA,CAAW,CACjD,OAAAlB,CACF,CAAC,EAED,MAAMmB,CAAAA,CAA8B,WAAW,CAC7C,MAAA,CAAAnB,CACF,CAAC,EACH,CAEA,eAAsBiiB,GAAYjiB,CAAAA,CAAkB,CAClD,MAAMgiB,EAAAA,CAAYhiB,CAAM,CAAA,CAExB,MAAMgB,EAAgB,SAAA,CAAUhB,CAAAA,CAAQ,CACtC,IAAA,CAAM,CACJ,MAAA,CAAQ,UAAA,CACR,UAAA,CAAY,IAAI,IAClB,CACF,CAAC,EACH,CAEA,eAAsBkiB,GAAWliB,CAAAA,CAAkB,CACjD,MAAMgiB,EAAAA,CAAYhiB,CAAM,CAAA,CAExB,MAAMgB,EAAgB,SAAA,CACpB,CACE,IAAKhB,CACP,CAAA,CACA,CACE,IAAA,CAAM,CACJ,MAAA,CAAQ,CAAA,QAAA,EAAWA,CAAM,CAAA,CAAA,EAAImiB,UAAAA,EAAY,CAAA,CAAA,CACzC,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,IAAI,IAAA,CACf,WAAA,CAAa,EAAC,CACd,OAAQ,EACV,CACF,CACF,EACF,CCpCO,IAAMC,GAAN,KAAiC,CAItC,YAAY1b,CAAAA,CAAkB2b,CAAAA,CAAqC,CACjE,IAAA,CAAK,SAAW3b,CAAAA,CAChB,IAAA,CAAK,iBAAmB2b,CAAAA,EAAoB,KAC9C,CAEA,SAAA,CAAUtkB,CAAAA,CAAYmH,CAAAA,CAAS,CAC7B,IAAM2Y,CAAAA,CAAoBvB,EAAAA,GAAqB,QAAA,CAC/C,GAAI,CAACuB,CAAAA,CAAmB,CACtByE,CAAAA,CAAS,iDAAA,CAAmD,EAAE,CAAA,CAC9D,MACF,CAEAzE,EAAkB,SAAA,CAAU,CAC1B,QAAA,CAAU,IAAA,CAAK,SACf,EAAA,CAAA9f,CAAAA,CACA,KAAAmH,CACF,CAAC,EACH,CACF,EC7BO,SAASqd,EAAAA,CAAU7d,EAAuB,CAC/C,GAAI,CAAC8E,CAAAA,EAAe,CAAE,SACpB,MAAM,IAAI,KAAA,CACR,0FACF,EAEF,OAAOA,CAAAA,GAAiB,QAAA,EAAU,SAAA,CAAU9E,CAAO,CACrD","file":"server.js","sourcesContent":["import { ConfigSchema, ConfigParams, ValueType } from '../config/types';\nimport { getConfig as _getConfig } from '../config/server';\nimport { CronJobInputParams } from '../cron/types';\nimport { Store } from '../data/store';\nimport { AnyMethodShape } from '../methods/types';\nimport { RouteDefinition } from '../routes/types';\nimport { RateLimitRule } from '../rate-limit/types';\nimport { ServerChannel } from '@/websocket/serverChannel';\n\n/** Array of Store instances that will be provisioned when the module is loaded */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Stores = Store<any, any>[];\n\n/** Record of query methods that can be called from the client */\ntype Queries = Record<string, AnyMethodShape>;\n\n/** Record of mutation methods that can be called from the client */\ntype Mutations = Record<string, AnyMethodShape>;\n\n/**\n * The Module class is a core building block of a Modelence application that encapsulates related functionality.\n * Modules can contain stores, queries, mutations, routes, cron jobs and configurations.\n *\n * @category Module\n *\n * @example\n * ```ts\n * const todoModule = new Module('todo', {\n * stores: [dbTodos],\n * queries: {\n * async getAll() {\n * // Fetch and return all Todo items\n * }\n * },\n * mutations: {\n * async create({ title }, { user }) {\n * // Create a new Todo item\n * }\n * }\n * });\n * ```\n */\nexport class Module<\n TName extends string = string,\n TSchema extends Record<string, ConfigParams> = ConfigSchema,\n TQueries extends Queries = Queries,\n TMutations extends Mutations = Mutations,\n> {\n /** @internal */\n public readonly name: TName;\n\n /** @internal */\n public readonly stores: Stores;\n\n /** @internal */\n public readonly queries: TQueries;\n\n /** @internal */\n public readonly mutations: TMutations;\n\n /** @internal */\n public readonly routes: RouteDefinition[];\n\n /** @internal */\n public readonly cronJobs: Record<string, CronJobInputParams>;\n\n /** @internal */\n public readonly configSchema: TSchema;\n\n /** @internal */\n public readonly rateLimits: RateLimitRule[];\n\n /** @internal */\n public readonly channels: ServerChannel[];\n\n /**\n * Creates a new Module instance\n *\n * @param name - The unique name of the module.\n * This name is used to namespace queries, mutations,\n * cron jobs and configuration values with a prefix (e.g. \"todo.create\")\n *\n * @param options - Module configuration options\n */\n constructor(\n name: TName,\n {\n stores = [],\n queries = {} as TQueries,\n mutations = {} as TMutations,\n routes = [],\n cronJobs = {},\n configSchema = {} as TSchema,\n rateLimits = [],\n channels = [],\n }: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stores?: Store<any, any>[];\n queries?: TQueries;\n mutations?: TMutations;\n routes?: RouteDefinition[];\n cronJobs?: Record<string, CronJobInputParams>;\n configSchema?: TSchema;\n rateLimits?: RateLimitRule[];\n channels?: ServerChannel[];\n } = {}\n ) {\n this.name = name;\n this.stores = stores;\n this.queries = queries;\n this.mutations = mutations;\n this.routes = routes;\n this.cronJobs = cronJobs;\n this.configSchema = configSchema;\n this.rateLimits = rateLimits;\n this.channels = channels;\n }\n\n /**\n * Retrieves a typed configuration value for this module.\n * The return type is inferred from the schema — no casts needed.\n *\n * @example\n * ```ts\n * const myModule = new Module('payments', {\n * configSchema: {\n * apiKey: { type: 'secret', default: '', isPublic: false },\n * maxRetries: { type: 'number', default: 3, isPublic: false },\n * },\n * mutations: {\n * async charge({ amount }) {\n * const apiKey = myModule.getConfig('apiKey'); // string\n * const maxRetries = myModule.getConfig('maxRetries'); // number\n * },\n * },\n * });\n * ```\n */\n getConfig<K extends keyof TSchema & string>(key: K): ValueType<TSchema[K]['type']> {\n return _getConfig(`${this.name}.${key}`) as ValueType<TSchema[K]['type']>;\n }\n}\n","import { z } from 'zod';\nimport { ModelSchema } from './types';\n\ntype ObjectTypeDefinition = {\n [key: string]: z.ZodType | ObjectTypeDefinition | Array<z.ZodType | ObjectTypeDefinition>;\n};\n\nexport interface SerializedModelSchema {\n [key: string]:\n | SerializedSchema\n | (SerializedSchema | SerializedModelSchema)[]\n | SerializedModelSchema\n | 'v2';\n}\n\n// Type guards for Zod schema types\ntype ZodDefWithTypeName = {\n typeName: z.ZodFirstPartyTypeKind;\n};\n\ntype ZodArrayDef = ZodDefWithTypeName & {\n type: z.ZodType;\n};\n\ntype ZodObjectDef = ZodDefWithTypeName & {\n shape: () => Record<string, z.ZodType>;\n};\n\ntype ZodOptionalDef = ZodDefWithTypeName & {\n innerType: z.ZodType;\n};\n\ntype ZodNullableDef = ZodDefWithTypeName & {\n innerType: z.ZodType;\n};\n\ntype ZodEnumDef = ZodDefWithTypeName & {\n values: readonly [string, ...string[]];\n};\n\ntype ZodUnionDef = ZodDefWithTypeName & {\n options: readonly [z.ZodType, z.ZodType, ...z.ZodType[]];\n};\n\ntype ZodEffectsDef = ZodDefWithTypeName & {\n schema: z.ZodType;\n effect: { type: 'refinement' | 'transform' | 'preprocess' };\n description?: string;\n};\n\ntype BaseSerializedSchema =\n | { type: 'string' }\n | { type: 'number' }\n | { type: 'boolean' }\n | { type: 'date' }\n | { type: 'array'; items: SerializedSchema }\n | { type: 'object'; items: Record<string, SerializedSchema> }\n | { type: 'enum'; items: readonly string[] }\n | { type: 'union'; items: SerializedSchema[] }\n | { type: 'custom'; typeName: string };\n\ntype SerializedSchema = BaseSerializedSchema | (BaseSerializedSchema & { optional: true });\n\n/**\n * Serializes a Zod schema to a JSON-serializable format\n */\nfunction serializeZodSchema(zodType: z.ZodType): SerializedSchema {\n const def = zodType._def as ZodDefWithTypeName;\n\n if (def.typeName === 'ZodString') {\n return { type: 'string' };\n }\n if (def.typeName === 'ZodNumber') {\n return { type: 'number' };\n }\n if (def.typeName === 'ZodBoolean') {\n return { type: 'boolean' };\n }\n if (def.typeName === 'ZodDate') {\n return { type: 'date' };\n }\n if (def.typeName === 'ZodArray') {\n const arrayDef = def as ZodArrayDef;\n return {\n type: 'array',\n items: serializeZodSchema(arrayDef.type),\n };\n }\n if (def.typeName === 'ZodObject') {\n const objectDef = def as ZodObjectDef;\n const shape = objectDef.shape();\n const serializedShape: Record<string, SerializedSchema> = {};\n for (const [key, value] of Object.entries(shape)) {\n serializedShape[key] = serializeZodSchema(value as z.ZodType);\n }\n return {\n type: 'object',\n items: serializedShape,\n };\n }\n if (def.typeName === 'ZodOptional') {\n const optionalDef = def as ZodOptionalDef;\n return {\n ...serializeZodSchema(optionalDef.innerType),\n optional: true,\n };\n }\n if (def.typeName === 'ZodNullable') {\n const nullableDef = def as ZodNullableDef;\n return {\n ...serializeZodSchema(nullableDef.innerType),\n optional: true,\n };\n }\n if (def.typeName === 'ZodEnum') {\n const enumDef = def as ZodEnumDef;\n return {\n type: 'enum',\n items: enumDef.values,\n };\n }\n if (def.typeName === 'ZodUnion') {\n const unionDef = def as ZodUnionDef;\n return {\n type: 'union',\n items: unionDef.options.map(serializeZodSchema),\n };\n }\n if (def.typeName === 'ZodEffects') {\n // ZodEffects is used for z.instanceof(ObjectId), z.refine(), etc.\n const effectsDef = def as ZodEffectsDef;\n\n // Check description for custom types\n if (effectsDef.description) {\n return { type: 'custom', typeName: effectsDef.description } as SerializedSchema;\n }\n\n // For other effects, try to serialize the underlying schema\n return serializeZodSchema(effectsDef.schema);\n }\n\n // For custom types like ObjectId, ref, etc.\n return { type: 'custom', typeName: def.typeName };\n}\n\n/**\n * Serializes a model schema to a JSON-serializable format\n */\nexport function serializeModelSchema(schema: ModelSchema): SerializedModelSchema {\n const serialized: SerializedModelSchema = {};\n\n for (const [key, value] of Object.entries(schema)) {\n if (Array.isArray(value)) {\n // Handle array of schema definitions\n serialized[key] = value.map((item) => {\n if (typeof item === 'object' && '_def' in item) {\n return serializeZodSchema(item as z.ZodType);\n }\n return serializeModelSchema(item as ObjectTypeDefinition);\n });\n } else if (typeof value === 'object' && '_def' in value) {\n // It's a Zod type\n serialized[key] = serializeZodSchema(value as z.ZodType);\n } else {\n // It's a nested object definition\n serialized[key] = serializeModelSchema(value as ObjectTypeDefinition);\n }\n }\n\n return serialized;\n}\n","import { isDeepStrictEqual } from 'node:util';\n\nimport {\n AggregateOptions,\n AggregationCursor,\n Collection,\n DeleteResult,\n Document,\n IndexDescription,\n InsertOneResult,\n MongoClient,\n UpdateResult,\n Filter,\n WithId,\n WithoutId,\n OptionalUnlessRequiredId,\n FindOptions,\n UpdateFilter,\n ObjectId,\n BulkWriteResult,\n AnyBulkWriteOperation,\n InsertManyResult,\n ClientSession,\n SearchIndexDescription,\n MongoError,\n FilterOperators,\n SortDirection,\n FindOneAndUpdateOptions,\n FindOneAndDeleteOptions,\n FindOneAndReplaceOptions,\n ReplaceOptions,\n ChangeStream,\n ChangeStreamOptions,\n DistinctOptions,\n} from 'mongodb';\n\nimport { ModelSchema, InferDocumentType } from './types';\nimport { serializeModelSchema } from './schemaSerializer';\n\n/**\n * Top-level query operators (logical and evaluation) - custom version without Document index signature\n * Based on MongoDB's RootFilterOperators but without the [key: string]: any from Document\n * @internal\n */\ntype StrictRootFilterOperators<TSchema> = {\n $and?: TypedFilter<TSchema>[];\n $or?: TypedFilter<TSchema>[];\n $nor?: TypedFilter<TSchema>[];\n $not?: TypedFilter<TSchema>;\n $text?: {\n $search: string;\n $language?: string;\n $caseSensitive?: boolean;\n $diacriticSensitive?: boolean;\n };\n\n $where?: string | ((this: TSchema) => boolean);\n $comment?: string | Document;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n $expr?: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n $jsonSchema?: any;\n};\n\n/**\n * Helper type to extract array element type\n * @internal\n */\ntype ArrayElement<T> = T extends (infer E)[] ? E : never;\ntype Flatten<T> = T extends ReadonlyArray<infer E> ? E : T;\n\n/**\n * Helper type for $in/$nin that accepts any array/tuple where elements are assignable to T\n * This solves the issue where TypeScript infers ['a', 'b'] as a tuple instead of ('a' | 'b')[]\n * and where Array<Union> gets distributed into Union1[] | Union2[] | ...\n * We wrap the Exclude in a tuple check to prevent distribution\n * @internal\n */\ntype NonUndefined<T> = T extends undefined ? never : T;\ntype ArrayLikeOfUnion<T> = [NonUndefined<T>] extends [never]\n ? never\n : ReadonlyArray<NonUndefined<T>> | Array<NonUndefined<T>>;\n\n/**\n * Enhanced FilterOperators that fixes $in and $nin to properly accept arrays of union types\n * MongoDB's native FilterOperators has issues with union types in $in/$nin arrays\n * because TypeScript distributes Array<Union> into Array1 | Array2 | ...\n * @internal\n */\ntype EnhancedFilterOperators<T> = Omit<FilterOperators<T>, '$in' | '$nin'> & {\n $in?: ArrayLikeOfUnion<T>;\n $nin?: ArrayLikeOfUnion<T>;\n};\n\ntype ExistingIndex = Document & {\n key?: Document;\n name?: string;\n};\n\ntype TypedFieldSelection<T, TValue> = {\n [K in keyof WithId<T> & string]?: TValue;\n} & {\n [key: `${string}.${string}`]: TValue;\n};\n\ntype ProjectionValue =\n | 0\n | 1\n | boolean\n | { $meta: string }\n | { $slice: number | [number, number] }\n | { $elemMatch: Document };\n\ntype TypedSort<T> = TypedFieldSelection<T, SortDirection>;\ntype TypedProjection<T> = TypedFieldSelection<T, ProjectionValue>;\n\ntype FetchOptions<T> = {\n sort?: TypedSort<T>;\n limit?: number;\n skip?: number;\n projection?: TypedProjection<T>;\n};\n\nexport type IndexCreationMode = 'blocking' | 'background';\nexport type IndexReconcileMode = 'full' | 'drop-only' | 'create-only';\n\nconst COMPARABLE_INDEX_OPTION_FIELDS = [\n 'background',\n 'bits',\n 'bucketSize',\n 'collation',\n 'default_language',\n 'expireAfterSeconds',\n 'hidden',\n 'language_override',\n 'max',\n 'min',\n 'partialFilterExpression',\n 'sparse',\n 'storageEngine',\n 'textIndexVersion',\n 'unique',\n 'weights',\n 'wildcardProjection',\n '2dsphereIndexVersion',\n] as const;\n\nconst isDocumentRecord = (value: unknown): value is Document =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst hasModelencePrefix = (name: string): boolean => name.startsWith('_modelence_');\n\nconst getComparableIndexOptions = (index: ExistingIndex | IndexDescription): Document => {\n const options: Document = {};\n\n for (const field of COMPARABLE_INDEX_OPTION_FIELDS) {\n const value = (index as Document)[field];\n if (value !== undefined) {\n options[field] = value;\n }\n }\n\n return options;\n};\n\n/**\n * MongoDB index key order is significant (e.g. { a: 1, b: 1 } !== { b: 1, a: 1 }).\n */\nconst isSameIndexKey = (left: unknown, right: unknown): boolean => {\n if (!isDocumentRecord(left) || !isDocumentRecord(right)) {\n return false;\n }\n\n const leftEntries = Object.entries(left);\n const rightEntries = Object.entries(right);\n\n if (leftEntries.length !== rightEntries.length) {\n return false;\n }\n\n return leftEntries.every(([leftField, leftDirection], index) => {\n const [rightField, rightDirection] = rightEntries[index] || [];\n return leftField === rightField && isDeepStrictEqual(leftDirection, rightDirection);\n });\n};\n\nconst isSameIndexDefinition = (existing: ExistingIndex, desired: IndexDescription): boolean => {\n if (!isSameIndexKey(existing.key, desired.key)) {\n return false;\n }\n\n return isDeepStrictEqual(getComparableIndexOptions(existing), getComparableIndexOptions(desired));\n};\n\nconst getIndexKeySignature = (key: unknown): string | null => {\n if (!isDocumentRecord(key)) {\n return null;\n }\n\n return Object.entries(key)\n .map(([field, direction]) => `${field}:${JSON.stringify(direction)}`)\n .join('|');\n};\n\n/**\n * Lists all indexes in a collection, returning an empty array if collection doesn't exist\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst listIndexes = async (collection: Collection<any>): Promise<Document[]> => {\n try {\n return await collection.listIndexes().toArray();\n } catch (error) {\n // If collection doesn't exist yet, return empty array\n // It will be created when we insert data or create indexes\n if (error instanceof MongoError && error.code === 26) {\n return [];\n }\n throw error;\n }\n};\n\n/**\n * Generates an auto-generated index name from the index keys\n * Mimics MongoDB's default naming: field1_direction1_field2_direction2\n */\nconst generateAutoIndexName = (key: Document): string => {\n return Object.entries(key)\n .map(([field, direction]) => `${field}_${direction}`)\n .join('_');\n};\n\n/**\n * Normalizes an index by ensuring it has a name with _modelence_ prefix\n */\nconst normalizeIndexName = (index: IndexDescription): IndexDescription => {\n if (index.name) {\n // If name is provided, add _modelence_ prefix if not already present\n const name = index.name.startsWith('_modelence_') ? index.name : `_modelence_${index.name}`;\n return { ...index, name };\n }\n\n // Auto-generate name with _modelence_ prefix\n const autoName = generateAutoIndexName(index.key);\n return { ...index, name: `_modelence_${autoName}` };\n};\n\n/**\n * Custom filter value type that handles array fields specially:\n * - For array fields: allows element type, full array type, or FilterOperators\n * - For non-array fields: allows exact type or FilterOperators\n * We use [T] to prevent distribution when T is a union type\n * @internal\n */\ntype FilterValue<T> = [T] extends [unknown[]]\n ? ArrayElement<T> | T | EnhancedFilterOperators<T>\n : [T] extends [never]\n ? never\n : T | EnhancedFilterOperators<[T] extends [never] ? never : T>;\n\n/**\n * Type-safe MongoDB filter that ensures only schema fields can be queried\n * while supporting all MongoDB query operators and dot notation for nested fields.\n *\n * This type combines:\n * - MongoDB's native `FilterOperators<T>` for field-level operators (comprehensive operator support)\n * - Custom `StrictRootFilterOperators<T>` for top-level operators without index signature\n * - Custom array field handling: allows passing single element when field is an array\n * - Custom restriction: only strings containing dots are allowed for nested field queries\n *\n * @example\n * ```ts\n * const dbUsers = new Store('users', {\n * schema: {\n * name: schema.string(),\n * age: schema.number(),\n * tags: schema.array(schema.string()),\n * collections: schema.array(schema.string()),\n * address: schema.object({\n * street: schema.string(),\n * city: schema.string(),\n * }),\n * },\n * indexes: []\n * });\n *\n * // ✅ Valid - field exists in schema\n * await dbUsers.findOne({ name: 'John' });\n *\n * // ✅ Valid - using MongoDB operators (from FilterOperators)\n * await dbUsers.findOne({ age: { $gt: 18 } });\n * await dbUsers.findOne({ tags: { $in: ['typescript', 'mongodb'] } });\n * await dbUsers.findOne({ $or: [{ name: 'John' }, { name: 'Jane' }] });\n *\n * // ✅ Valid - array field with single element (checks if array contains the element)\n * await dbUsers.findOne({ collections: 'users' });\n *\n * // ✅ Valid - dot notation for nested fields (must contain a dot)\n * await dbUsers.findOne({ 'address.city': 'New York' });\n * await dbUsers.findOne({ 'emails.0.address': 'test@example.com' });\n *\n * // ❌ TypeScript error - 'id' is not in schema and doesn't contain a dot\n * await dbUsers.findOne({ id: '123' });\n * ```\n */\nexport type TypedFilter<T> = {\n [K in keyof WithId<T>]?: FilterValue<WithId<T>[K]>;\n} & StrictRootFilterOperators<T> & {\n // Support for MongoDB dot notation (e.g., 'emails.address', 'profile.settings.theme')\n // Only strings containing dots are allowed, which provides better type safety\n // while still enabling MongoDB's nested field query syntax\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K: `${string}.${string}`]: any;\n };\n\n/**\n * Helper type to preserve method types when extending a store.\n * Maps each method to work with the extended schema while preserving signatures.\n * @internal\n */\ntype PreserveMethodsForExtendedSchema<\n TBaseMethods extends Record<string, (...args: never[]) => unknown>,\n TExtendedSchema extends ModelSchema,\n> = {\n [K in keyof TBaseMethods]: TBaseMethods[K] extends (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this: any,\n ...args: infer Args\n ) => infer Return\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this: WithId<InferDocumentType<TExtendedSchema>> & any, ...args: Args) => Return\n : never;\n};\n\n/**\n * Type-erased Store reference for chain traversal.\n * Chain members carry different TSchema/TMethods, so the generic\n * parameters must be erased. This alias contains the `any` in one place.\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStore = Store<any, any>;\n\n/**\n * The Store class provides a type-safe interface for MongoDB collections with built-in schema validation and helper methods.\n *\n * @category Store\n * @typeParam TSchema - The document schema type\n * @typeParam TMethods - Custom methods that will be added to documents\n *\n * @example\n * ```ts\n * const dbTodos = new Store('todos', {\n * schema: {\n * title: schema.string(),\n * completed: schema.boolean(),\n * dueDate: schema.date().optional(),\n * userId: schema.userId(),\n * },\n * methods: {\n * isOverdue() {\n * return this.dueDate < new Date();\n * }\n * }\n * });\n * ```\n */\nexport class Store<\n TSchema extends ModelSchema,\n TMethods extends Record<\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this: WithId<InferDocumentType<TSchema>> & TMethods, ...args: any[]) => any\n >,\n> {\n /** @internal */\n readonly _type!: InferDocumentType<TSchema>;\n /** @internal */\n readonly _rawDoc!: WithId<this['_type']>;\n /** @internal */\n readonly _doc!: this['_rawDoc'] & TMethods;\n\n readonly Doc!: this['_doc'];\n\n private name: string;\n private readonly schema: TSchema;\n private readonly methods?: TMethods;\n private readonly indexes: IndexDescription[];\n private readonly searchIndexes: SearchIndexDescription[];\n private readonly indexCreationMode: IndexCreationMode;\n private collection?: Collection<this['_type']>;\n private client?: MongoClient;\n\n // Chain tracking for linear extension model\n private _chainParent: AnyStore | null = null;\n private _chainChild: AnyStore | null = null;\n\n /**\n * Creates a new Store instance\n *\n * @param name - The collection name in MongoDB\n * @param options - Store configuration (schema, indexes, methods, search indexes, and optional index creation mode)\n */\n constructor(\n name: string,\n options: {\n /** Document schema using Modelence schema types */\n schema: TSchema;\n /** Custom methods to add to documents */\n methods?: TMethods;\n /** MongoDB indexes to create */\n indexes: IndexDescription[];\n /** MongoDB Atlas Search */\n searchIndexes?: SearchIndexDescription[];\n /** Whether index creation should block startup or run in background (default: 'background') */\n indexCreationMode?: IndexCreationMode;\n }\n ) {\n this.name = name;\n this.schema = options.schema;\n this.methods = options.methods;\n // Normalize all indexes to have _modelence_ prefix\n this.indexes = options.indexes.map(normalizeIndexName);\n this.searchIndexes = options.searchIndexes || [];\n this.indexCreationMode = options.indexCreationMode ?? 'background';\n }\n\n getName() {\n return this.name;\n }\n\n getIndexCreationMode() {\n return this.indexCreationMode;\n }\n\n /** @internal */\n getSchema() {\n return this.schema;\n }\n\n /** @internal */\n getSerializedSchema() {\n return serializeModelSchema(this.schema);\n }\n\n /** @internal – normalized indexes (already have _modelence_ prefix) */\n getIndexes(): IndexDescription[] {\n return this.indexes;\n }\n\n /** @internal */\n getSearchIndexes(): SearchIndexDescription[] {\n return this.searchIndexes;\n }\n\n /** @internal – follows the chain to the latest extension */\n getChainTail(): AnyStore {\n let current: AnyStore = this;\n while (current._chainChild) {\n current = current._chainChild;\n }\n return current;\n }\n\n /** @internal – follows the chain back to the original store */\n getChainRoot(): AnyStore {\n let current: AnyStore = this;\n while (current._chainParent) {\n current = current._chainParent;\n }\n return current;\n }\n\n /**\n * Extends the store with additional schema fields, indexes, methods, and search indexes.\n * Returns a new Store instance with the extended schema and updated types.\n * Methods from the original store are preserved with updated type signatures.\n *\n * @param config - Additional schema fields, indexes, methods, search indexes, and optional index creation mode to add\n * @returns A new Store instance with the extended schema\n *\n * @example\n * ```ts\n * // Extend the users collection\n * export const dbUsers = baseUsersCollection.extend({\n * schema: {\n * firstName: schema.string(),\n * lastName: schema.string(),\n * companyId: schema.objectId().optional(),\n * },\n * indexes: [\n * { key: { companyId: 1 } },\n * { key: { lastName: 1, firstName: 1 } },\n * ],\n * methods: {\n * getFullName() {\n * return `${this.firstName} ${this.lastName}`;\n * }\n * }\n * });\n *\n * // Now fully typed with new fields\n * const user = await dbUsers.findOne({ firstName: 'John' });\n * console.log(user?.getFullName());\n * ```\n */\n extend<\n TExtendedSchema extends ModelSchema,\n TExtendedMethods extends Record<string, Function> = Record<string, never>,\n >(config: {\n schema?: TExtendedSchema;\n indexes?: IndexDescription[];\n methods?: TExtendedMethods;\n searchIndexes?: SearchIndexDescription[];\n /** Whether index creation should block startup or run in background */\n indexCreationMode?: IndexCreationMode;\n }): Store<\n TSchema & TExtendedSchema & Record<string, unknown>,\n PreserveMethodsForExtendedSchema<\n TMethods,\n TSchema & TExtendedSchema & Record<string, unknown>\n > &\n TExtendedMethods\n > {\n // Follow chain to the tail – extending always appends to the end\n const tail: AnyStore = this.getChainTail();\n\n if (this.client || tail.client) {\n throw new Error(\n `Store.extend() must be called before startApp(). Store '${this.name}' has already been initialized and cannot be extended.`\n );\n }\n\n const extendedSchema = {\n ...tail.schema,\n ...(config.schema || {}),\n } as TSchema & TExtendedSchema & Record<string, unknown>;\n\n const extendedIndexes = [...tail.indexes, ...(config.indexes || [])];\n const extendedSearchIndexes = [...tail.searchIndexes, ...(config.searchIndexes || [])];\n\n type CombinedMethods = PreserveMethodsForExtendedSchema<\n TMethods,\n TSchema & TExtendedSchema & Record<string, unknown>\n > &\n TExtendedMethods;\n\n const combinedMethods = {\n ...(tail.methods || {}),\n ...(config.methods || {}),\n } as CombinedMethods | undefined;\n\n const extendedStore = new Store<\n TSchema & TExtendedSchema & Record<string, unknown>,\n CombinedMethods\n >(this.name, {\n schema: extendedSchema,\n methods: combinedMethods as unknown as CombinedMethods | undefined,\n indexes: extendedIndexes,\n searchIndexes: extendedSearchIndexes,\n indexCreationMode: config.indexCreationMode ?? tail.indexCreationMode,\n });\n\n // Link into the chain\n tail._chainChild = extendedStore;\n extendedStore._chainParent = tail;\n\n return extendedStore;\n }\n\n /** @internal */\n init(client: MongoClient) {\n if (this.collection) {\n throw new Error(`Collection ${this.name} is already initialized`);\n }\n\n this.client = client;\n this.collection = this.client.db().collection<this['_type']>(this.name);\n }\n\n /** @internal */\n async createIndexes(mode: IndexReconcileMode = 'full') {\n const collection = this.requireCollection();\n const shouldDropIndexes = mode !== 'create-only';\n const shouldCreateIndexes = mode !== 'drop-only';\n\n // Get all existing indexes in the collection (returns [] if collection doesn't exist)\n const existingIndexes = await listIndexes(collection);\n const indexByName = new Map<string, ExistingIndex & { name: string }>();\n const indexNamesByKey = new Map<string, Set<string>>();\n const droppedIndexNames = new Set<string>();\n\n const addIndexToLookup = (existingIndex: ExistingIndex & { name: string }) => {\n indexByName.set(existingIndex.name, existingIndex);\n\n const keySignature = getIndexKeySignature(existingIndex.key);\n if (!keySignature) {\n return;\n }\n\n const names = indexNamesByKey.get(keySignature);\n if (names) {\n names.add(existingIndex.name);\n } else {\n indexNamesByKey.set(keySignature, new Set([existingIndex.name]));\n }\n };\n\n const removeIndexFromLookup = (indexName: string) => {\n const existingIndex = indexByName.get(indexName);\n if (!existingIndex) {\n return;\n }\n\n indexByName.delete(indexName);\n\n const keySignature = getIndexKeySignature(existingIndex.key);\n if (!keySignature) {\n return;\n }\n\n const names = indexNamesByKey.get(keySignature);\n if (!names) {\n return;\n }\n\n names.delete(indexName);\n if (names.size === 0) {\n indexNamesByKey.delete(keySignature);\n }\n };\n\n for (const existingIndex of existingIndexes) {\n if (typeof existingIndex.name === 'string') {\n addIndexToLookup({\n ...existingIndex,\n name: existingIndex.name,\n });\n }\n }\n\n const dropIndexIfNeeded = async (indexName: string) => {\n if (indexName === '_id_' || droppedIndexNames.has(indexName)) {\n return;\n }\n try {\n await collection.dropIndex(indexName);\n } catch (error) {\n // Another concurrent reconciler may have already dropped it.\n if (!(error instanceof MongoError && error.code === 27)) {\n throw error;\n }\n }\n droppedIndexNames.add(indexName);\n removeIndexFromLookup(indexName);\n };\n\n if (shouldDropIndexes) {\n // Find all _modelence_ prefixed indexes that are not in the current schema\n const currentIndexNames = new Set(\n this.indexes\n .map((idx) => idx.name)\n .filter((name): name is string => typeof name === 'string')\n );\n const orphanedIndexes = [...indexByName.values()].filter(\n (existingIdx) =>\n hasModelencePrefix(existingIdx.name) && !currentIndexNames.has(existingIdx.name)\n );\n\n // Drop orphaned indexes\n for (const orphanedIndex of orphanedIndexes) {\n await dropIndexIfNeeded(orphanedIndex.name);\n }\n }\n\n // Reconcile code-defined indexes against the current DB metadata.\n // Code wins on conflicts; non-conflicting manual indexes are preserved.\n if (this.indexes.length > 0) {\n for (const index of this.indexes) {\n if (!index.name) {\n continue;\n }\n\n let requiresDropBeforeCreate = false;\n const existingByName = indexByName.get(index.name);\n if (existingByName && !isSameIndexDefinition(existingByName, index)) {\n if (shouldDropIndexes) {\n await dropIndexIfNeeded(existingByName.name);\n } else {\n requiresDropBeforeCreate = true;\n }\n }\n\n const keySignature = getIndexKeySignature(index.key);\n if (keySignature) {\n const existingNamesForKey = [...(indexNamesByKey.get(keySignature) || [])];\n for (const existingName of existingNamesForKey) {\n if (existingName !== index.name) {\n if (shouldDropIndexes) {\n await dropIndexIfNeeded(existingName);\n } else {\n requiresDropBeforeCreate = true;\n }\n }\n }\n }\n\n const alignedIndex = indexByName.get(index.name);\n const hasAlignedIndex = !!alignedIndex && isSameIndexDefinition(alignedIndex, index);\n\n if (!hasAlignedIndex && shouldCreateIndexes && !requiresDropBeforeCreate) {\n await collection.createIndexes([index]);\n addIndexToLookup({\n name: index.name,\n key: index.key,\n ...getComparableIndexOptions(index),\n });\n }\n }\n }\n if (shouldCreateIndexes && this.searchIndexes.length > 0) {\n for (const searchIndex of this.searchIndexes) {\n try {\n await collection.createSearchIndexes([searchIndex]);\n } catch (error) {\n if (error instanceof MongoError && error.code === 68 && searchIndex.name) {\n await collection.dropSearchIndex(searchIndex.name);\n await collection.createSearchIndexes([searchIndex]);\n } else {\n throw error;\n }\n }\n }\n }\n }\n\n private wrapDocument(document: this['_rawDoc']): this['_doc'] {\n if (!this.methods) {\n return document as unknown as this['_doc'];\n }\n\n const result = Object.create(\n null,\n Object.getOwnPropertyDescriptors({\n ...document,\n ...this.methods,\n })\n );\n\n return result as this['_doc'];\n }\n\n /**\n * For convenience, to also allow directy passing a string or ObjectId as the selector\n */\n private getSelector(selector: TypedFilter<this['_type']> | string | ObjectId) {\n if (typeof selector === 'string') {\n return { _id: new ObjectId(selector) } as Filter<this['_type']>;\n }\n\n if (selector instanceof ObjectId) {\n return { _id: selector } as Filter<this['_type']>;\n }\n\n return selector as Filter<this['_type']>;\n }\n\n /** @internal */\n requireCollection() {\n if (!this.collection) {\n throw new Error(`Collection ${this.name} is not provisioned`);\n }\n\n return this.collection;\n }\n\n /** @internal */\n requireClient() {\n if (!this.client) {\n throw new Error(`Database is not connected`);\n }\n\n return this.client;\n }\n\n /**\n * Finds a single document matching the query\n *\n * @param query - Type-safe query filter. Only schema fields, MongoDB operators, and dot notation are allowed.\n * @param options - Find options\n * @returns The document, or null if not found\n *\n * @example\n * ```ts\n * // ✅ Valid queries:\n * await store.findOne({ name: 'John' })\n * await store.findOne({ age: { $gt: 18 } })\n * await store.findOne({ _id: new ObjectId('...') })\n * await store.findOne({ tags: { $in: ['typescript', 'mongodb'] } })\n * await store.findOne({ $or: [{ name: 'John' }, { name: 'Jane' }] })\n * await store.findOne({ 'emails.address': 'test@example.com' }) // dot notation\n *\n * // ❌ TypeScript error - 'id' is not in schema:\n * await store.findOne({ id: '123' })\n * ```\n */\n async findOne(query: TypedFilter<this['_type']>, options?: FindOptions) {\n const document = await this.requireCollection().findOne<this['_rawDoc']>(\n query as Filter<this['_type']>,\n options\n );\n return document ? this.wrapDocument(document) : null;\n }\n\n async requireOne(\n query: TypedFilter<this['_type']>,\n options?: FindOptions,\n errorHandler?: () => Error\n ): Promise<this['_doc']> {\n const result = await this.findOne(query, options);\n if (!result) {\n throw errorHandler ? errorHandler() : new Error(`Record not found in ${this.name}`);\n }\n return result;\n }\n\n private find(query: TypedFilter<this['_type']>, options?: FetchOptions<this['_type']>) {\n const cursor = this.requireCollection().find(\n query as Filter<this['_type']>,\n options?.projection ? { projection: options.projection } : undefined\n );\n if (options?.sort) {\n cursor.sort(options.sort);\n }\n if (options?.limit) {\n cursor.limit(options.limit);\n }\n if (options?.skip) {\n cursor.skip(options.skip);\n }\n return cursor;\n }\n\n /**\n * Fetches a single document by its ID\n *\n * @param id - The ID of the document to find\n * @returns The document, or null if not found\n */\n async findById(id: string | ObjectId): Promise<this['_doc'] | null> {\n const idSelector = typeof id === 'string' ? { _id: new ObjectId(id) } : { _id: id };\n return await this.findOne(idSelector as TypedFilter<this['_type']>);\n }\n\n /**\n * Fetches a single document by its ID, or throws an error if not found\n *\n * @param id - The ID of the document to find\n * @param errorHandler - Optional error handler to return a custom error if the document is not found\n * @returns The document\n */\n async requireById(id: string | ObjectId, errorHandler?: () => Error): Promise<this['_doc']> {\n const result = await this.findById(id);\n if (!result) {\n throw errorHandler\n ? errorHandler()\n : new Error(`Record with id ${id} not found in ${this.name}`);\n }\n return result;\n }\n\n /**\n * Counts the number of documents that match a query\n *\n * @param query - The query to filter documents\n * @returns The number of documents that match the query\n */\n countDocuments(query: TypedFilter<this['_type']>): Promise<number> {\n return this.requireCollection().countDocuments(query as Filter<this['_type']>);\n }\n\n /**\n * Fetches multiple documents, equivalent to Node.js MongoDB driver's `find` and `toArray` methods combined.\n *\n * @param query - The query to filter documents\n * @param options - Optional fetch options\n * @param options.projection - Fields to include or exclude in the result documents\n * @param options.sort - Sort order for matching documents\n * @param options.limit - Maximum number of documents to return\n * @param options.skip - Number of matching documents to skip\n * @returns The documents\n *\n * @example\n * ```ts\n * // Include only selected fields\n * const docs = await store.fetch(\n * { userId: user.id },\n * { projection: { framework: 1, title: 1 }, sort: { createdAt: -1 }, limit: 50 }\n * );\n *\n * // Exclude large fields when not needed\n * const chunks = await store.fetch(\n * { documentId },\n * { projection: { embedding: 0 } }\n * );\n * ```\n */\n async fetch(\n query: TypedFilter<this['_type']>,\n options?: FetchOptions<this['_type']>\n ): Promise<this['_doc'][]> {\n const cursor = this.find(query, options);\n return (await cursor.toArray()).map(this.wrapDocument.bind(this));\n }\n\n /**\n * Inserts a single document\n *\n * @param document - The document to insert\n * @returns The result of the insert operation\n */\n async insertOne(\n document: OptionalUnlessRequiredId<InferDocumentType<TSchema>>,\n options?: { session?: ClientSession }\n ): Promise<InsertOneResult> {\n return await this.requireCollection().insertOne(document, options);\n }\n\n /**\n * Inserts multiple documents\n *\n * @param documents - The documents to insert\n * @returns The result of the insert operation\n */\n async insertMany(\n documents: OptionalUnlessRequiredId<InferDocumentType<TSchema>>[],\n options?: { session?: ClientSession }\n ): Promise<InsertManyResult> {\n return await this.requireCollection().insertMany(documents, options);\n }\n\n /**\n * Updates a single document\n *\n * @param selector - The selector to find the document to update\n * @param update - The update to apply to the document\n * @returns The result of the update operation\n */\n async updateOne(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n update: UpdateFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<UpdateResult> {\n return await this.requireCollection().updateOne(this.getSelector(selector), update, options);\n }\n\n /**\n * Updates a single document, or inserts it if it doesn't exist\n *\n * @param selector - The selector to find the document to update\n * @param update - The MongoDB modifier to apply to the document\n * @returns The result of the update operation\n */\n async upsertOne(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n update: UpdateFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<UpdateResult> {\n return await this.requireCollection().updateOne(this.getSelector(selector), update, {\n upsert: true,\n ...options,\n });\n }\n\n /**\n * Updates multiple documents\n *\n * @param selector - The selector to find the documents to update\n * @param update - The MongoDB modifier to apply to the documents\n * @returns The result of the update operation\n */\n async updateMany(\n selector: TypedFilter<this['_type']>,\n update: UpdateFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<UpdateResult> {\n return await this.requireCollection().updateMany(\n selector as Filter<this['_type']>,\n update,\n options\n );\n }\n\n /**\n * Updates multiple documents, or inserts them if they don't exist\n *\n * @param selector - The selector to find the documents to update\n * @param update - The MongoDB modifier to apply to the documents\n * @returns The result of the update operation\n */\n async upsertMany(\n selector: TypedFilter<this['_type']>,\n update: UpdateFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<UpdateResult> {\n return await this.requireCollection().updateMany(selector as Filter<this['_type']>, update, {\n upsert: true,\n ...options,\n });\n }\n\n /**\n * Deletes a single document\n *\n * @param selector - The selector to find the document to delete\n * @returns The result of the delete operation\n */\n async deleteOne(\n selector: TypedFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<DeleteResult> {\n return await this.requireCollection().deleteOne(selector as Filter<this['_type']>, options);\n }\n\n /**\n * Deletes multiple documents\n *\n * @param selector - The selector to find the documents to delete\n * @returns The result of the delete operation\n */\n async deleteMany(\n selector: TypedFilter<this['_type']>,\n options?: { session?: ClientSession }\n ): Promise<DeleteResult> {\n return await this.requireCollection().deleteMany(selector as Filter<this['_type']>, options);\n }\n\n /**\n * Atomically finds a document and updates it, returning the document\n *\n * @param selector - The selector to find the document\n * @param update - The update to apply\n * @param options - Options including `returnDocument` ('before' or 'after'), `upsert`, `session`, etc.\n * @returns The document (before or after update, depending on options), or null if not found\n */\n async findOneAndUpdate(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n update: UpdateFilter<this['_type']>,\n options?: Omit<FindOneAndUpdateOptions, 'includeResultMetadata'>\n ): Promise<this['_doc'] | null> {\n const result = await this.requireCollection().findOneAndUpdate(\n this.getSelector(selector),\n update,\n options ?? {}\n );\n return result ? this.wrapDocument(result as this['_rawDoc']) : null;\n }\n\n /**\n * Atomically finds a document and deletes it, returning the deleted document\n *\n * @param selector - The selector to find the document\n * @param options - Options including `session`, `projection`, etc.\n * @returns The deleted document, or null if not found\n */\n async findOneAndDelete(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n options?: Omit<FindOneAndDeleteOptions, 'includeResultMetadata'>\n ): Promise<this['_doc'] | null> {\n const result = await this.requireCollection().findOneAndDelete(\n this.getSelector(selector),\n options ?? {}\n );\n return result ? this.wrapDocument(result as this['_rawDoc']) : null;\n }\n\n /**\n * Atomically finds a document and replaces it, returning the document\n *\n * @param selector - The selector to find the document\n * @param replacement - The replacement document\n * @param options - Options including `returnDocument` ('before' or 'after'), `upsert`, `session`, etc.\n * @returns The document (before or after replacement, depending on options), or null if not found\n */\n async findOneAndReplace(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n replacement: WithoutId<this['_type']>,\n options?: Omit<FindOneAndReplaceOptions, 'includeResultMetadata'>\n ): Promise<this['_doc'] | null> {\n const result = await this.requireCollection().findOneAndReplace(\n this.getSelector(selector),\n replacement,\n options ?? {}\n );\n return result ? this.wrapDocument(result as this['_rawDoc']) : null;\n }\n\n /**\n * Replaces a single document\n *\n * @param selector - The selector to find the document to replace\n * @param replacement - The replacement document (must not contain update operators)\n * @param options - Options including `upsert`, `session`, etc.\n * @returns The result of the replace operation\n */\n async replaceOne(\n selector: TypedFilter<this['_type']> | string | ObjectId,\n replacement: WithoutId<this['_type']>,\n options?: ReplaceOptions\n ): Promise<UpdateResult> {\n return await this.requireCollection().replaceOne(\n this.getSelector(selector),\n replacement,\n options\n );\n }\n\n /**\n * Returns an array of distinct values for a field across the collection\n *\n * @param key - The field name (supports dot notation for nested fields)\n * @param filter - Optional filter to narrow the documents\n * @param options - Optional distinct options\n * @returns An array of distinct values\n */\n\n async distinct<K extends keyof this['_rawDoc'] & string>(\n key: K,\n filter?: TypedFilter<this['_type']>,\n options?: DistinctOptions\n ): Promise<Array<Flatten<this['_rawDoc'][K]>>> {\n const f = (filter ?? {}) as Filter<this['_type']>;\n return options !== undefined\n ? await this.requireCollection().distinct(key, f, options)\n : await this.requireCollection().distinct(key, f);\n }\n\n /**\n * Opens a change stream on the collection to watch for real-time changes\n *\n * @param pipeline - Optional aggregation pipeline to filter/transform change events\n * @param options - Optional change stream options\n * @returns A ChangeStream instance\n */\n watch(pipeline?: Document[], options?: ChangeStreamOptions): ChangeStream {\n return this.requireCollection().watch(pipeline, options);\n }\n\n /**\n * Aggregates documents using MongoDB's aggregation framework\n *\n * @param pipeline - The aggregation pipeline\n * @param options - Optional options\n * @returns The aggregation cursor\n */\n aggregate(pipeline: Document[], options?: AggregateOptions): AggregationCursor<Document> {\n return this.requireCollection().aggregate(pipeline, options);\n }\n\n /**\n * Performs a bulk write operation on the collection\n *\n * @param operations - The operations to perform\n * @returns The result of the bulk write operation\n */\n bulkWrite(operations: AnyBulkWriteOperation<this['_type']>[]): Promise<BulkWriteResult> {\n return this.requireCollection().bulkWrite(operations);\n }\n\n /**\n * Returns the raw MongoDB database instance for advanced operations\n * @returns The MongoDB database instance\n * @throws Error if the store is not provisioned\n */\n getDatabase() {\n return this.requireClient().db();\n }\n\n /**\n * Returns the raw MongoDB collection instance for advanced operations\n * @returns The MongoDB collection instance\n * @throws Error if the store is not provisioned\n */\n rawCollection() {\n return this.requireCollection();\n }\n\n /**\n * Renames an existing collection to this store's name, used for migrations\n * @param oldName - The previous name of the collection\n * @throws Error if the old collection doesn't exist or if this store's collection already exists\n */\n async renameFrom(oldName: string, options?: { session?: ClientSession }) {\n const db = this.getDatabase();\n\n if (!this.collection || !db) {\n throw new Error(`Store ${this.name} is not provisioned`);\n }\n\n const oldCollections = await db.listCollections({ name: oldName }).toArray();\n if (oldCollections.length === 0) {\n throw new Error(`Collection ${oldName} not found`);\n }\n\n const newCollections = await db.listCollections({ name: this.name }).toArray();\n if (newCollections.length > 0) {\n throw new Error(`Collection ${this.name} already exists`);\n }\n\n const existingCollection = db.collection<this['_type']>(oldName);\n\n await existingCollection.rename(this.name, options);\n }\n\n /**\n * Performs a vector similarity search using MongoDB Atlas Vector Search\n *\n * @param params - Vector search parameters\n * @param params.field - The field name containing the vector embeddings\n * @param params.embedding - The query vector to search for\n * @param params.numCandidates - Number of nearest neighbors to consider (default: 100)\n * @param params.limit - Maximum number of results to return (default: 10)\n * @param params.projection - Additional fields to include in the results\n * @param params.indexName - Name of index (default: field + VectorSearch)\n * @returns An aggregation cursor with search results and scores\n *\n * @example\n * ```ts\n * const results = await store.vectorSearch({\n * field: 'embedding',\n * embedding: [0.1, 0.2, 0.3, ...],\n * numCandidates: 100,\n * limit: 10,\n * projection: { title: 1, description: 1 }\n * });\n * ```\n */\n async vectorSearch({\n field,\n embedding,\n numCandidates,\n limit,\n projection,\n indexName,\n }: {\n field: string;\n embedding: number[];\n numCandidates?: number;\n limit?: number;\n projection?: Document;\n indexName?: string;\n }) {\n return this.aggregate([\n {\n $vectorSearch: {\n index: indexName || field + 'VectorSearch',\n path: field,\n queryVector: embedding,\n numCandidates: numCandidates || 100,\n limit: limit || 10,\n },\n },\n {\n $project: {\n _id: 1,\n score: { $meta: 'vectorSearchScore' },\n ...projection,\n },\n },\n ]);\n }\n\n /**\n * Creates a MongoDB Atlas Vector Search index definition\n *\n * @param params - Vector index parameters\n * @param params.field - The field name to create the vector index on\n * @param params.dimensions - The number of dimensions in the vector embeddings\n * @param params.similarity - The similarity metric to use (default: 'cosine')\n * @param params.indexName - Name of index (default: field + VectorSearch)\n * @returns A search index description object\n *\n * @example\n * ```ts\n * const store = new Store('documents', {\n * schema: {\n * title: schema.string(),\n * embedding: schema.array(schema.number()),\n * },\n * indexes: [],\n * searchIndexes: [\n * Store.vectorIndex({\n * field: 'embedding',\n * dimensions: 1536,\n * similarity: 'cosine'\n * })\n * ]\n * });\n * ```\n */\n static vectorIndex({\n field,\n dimensions,\n similarity = 'cosine',\n indexName,\n }: {\n field: string;\n dimensions: number;\n similarity?: 'cosine' | 'euclidean' | 'dotProduct';\n indexName?: string;\n }) {\n return {\n type: 'vectorSearch',\n name: indexName || field + 'VectorSearch',\n definition: {\n fields: [\n {\n type: 'vector',\n path: field,\n numDimensions: dimensions,\n similarity,\n },\n ],\n },\n };\n }\n}\n","import { ObjectId } from 'mongodb';\nimport { z, ZodArray, ZodNumber } from 'zod';\nimport { Store } from './store';\n\ntype ObjectTypeDefinition = {\n [key: string]: SchemaTypeDefinition;\n};\n\ntype SingularSchemaTypeDefinition = z.ZodType | ObjectTypeDefinition; // ReturnType<typeof schema[keyof typeof schema]>;\n\ntype SchemaTypeDefinition = SingularSchemaTypeDefinition | Array<SingularSchemaTypeDefinition>;\n\nexport type ModelSchema = {\n [key: string]: SchemaTypeDefinition;\n};\n\nconst schemaString: typeof z.string = z.string.bind(z);\n\nconst schemaNumber: typeof z.number = z.number.bind(z);\n\nconst schemaDate: typeof z.date = z.date.bind(z);\n\nconst schemaBoolean: typeof z.boolean = z.boolean.bind(z);\n\nconst schemaArray: typeof z.array = z.array.bind(z);\n\nconst schemaObject: typeof z.object = z.object.bind(z);\n\nconst schemaEnum: typeof z.enum = z.enum.bind(z);\n\nexport const schema = {\n string: schemaString,\n number: schemaNumber,\n date: schemaDate,\n boolean: schemaBoolean,\n array: schemaArray,\n object: schemaObject,\n enum: schemaEnum,\n embedding(): ZodArray<ZodNumber> {\n return z.array(z.number());\n },\n objectId(): z.ZodType<ObjectId> {\n return z.instanceof(ObjectId).describe('ObjectId');\n },\n userId(): z.ZodType<ObjectId> {\n return z.instanceof(ObjectId).describe('UserId');\n },\n ref<T extends ModelSchema>(\n _collection: string | Store<T, InferDocumentType<T>>\n ): z.ZodType<ObjectId> {\n return z.instanceof(ObjectId).describe('Ref');\n },\n union: z.union.bind(z),\n infer<T extends SchemaTypeDefinition>(_schema: T): InferDocumentType<T> {\n return {} as InferDocumentType<T>;\n },\n} as const;\n\nexport type InferDocumentType<T extends SchemaTypeDefinition> = {\n [K in keyof T as T[K] extends z.ZodOptional<z.ZodTypeAny> ? K : never]?: T[K] extends z.ZodType\n ? z.infer<T[K]>\n : never;\n} & {\n [K in keyof T as T[K] extends z.ZodOptional<z.ZodTypeAny> ? never : K]: T[K] extends z.ZodType\n ? z.infer<T[K]>\n : T[K] extends Array<infer ElementType extends SchemaTypeDefinition>\n ? Array<InferDocumentType<ElementType>>\n : T[K] extends ObjectTypeDefinition\n ? InferDocumentType<T[K]>\n : never;\n};\n\nexport namespace schema {\n export type infer<T extends SchemaTypeDefinition> = InferDocumentType<T>;\n}\n","import { randomBytes } from 'crypto';\nimport { type Response } from 'express';\nimport { ObjectId } from 'mongodb';\nimport { Module } from '../app/module';\nimport { getPublicConfigs } from '../config/server';\nimport { Store } from '../data/store';\nimport { schema } from '../data/types';\nimport { time } from '../time';\nimport { Session } from './types';\n\nexport const sessionsCollection = new Store('_modelenceSessions', {\n schema: {\n authToken: schema.string(),\n createdAt: schema.date(),\n expiresAt: schema.date(),\n userId: schema.userId().nullable(),\n },\n indexes: [\n { key: { authToken: 1 }, unique: true },\n { key: { expiresAt: 1 }, expireAfterSeconds: 0 },\n { key: { userId: 1 } },\n ],\n});\n\nexport async function obtainSession(authToken: string | null): Promise<Session> {\n const existingSession = authToken ? await sessionsCollection.findOne({ authToken }) : null;\n\n if (existingSession) {\n return {\n authToken: String(existingSession.authToken),\n expiresAt: new Date(existingSession.expiresAt),\n userId: existingSession.userId ?? null,\n };\n }\n\n return await createSession();\n}\n\nexport async function setSessionUser(authToken: string, userId: ObjectId) {\n await sessionsCollection.updateOne(\n { authToken },\n {\n $set: { userId },\n }\n );\n}\n\nexport async function clearSessionUser(authToken: string) {\n await sessionsCollection.updateOne(\n { authToken },\n {\n $set: { userId: null },\n }\n );\n}\n\nexport async function invalidateAllUserSessions(userId: ObjectId) {\n await sessionsCollection.deleteMany({ userId });\n}\n\nexport async function createSession(userId: ObjectId | null = null): Promise<Session> {\n // TODO: add rate-limiting and captcha handling\n\n const authToken = randomBytes(32).toString('base64url');\n const now = Date.now();\n const expiresAt = new Date(now + time.days(7));\n\n await sessionsCollection.insertOne({\n authToken,\n createdAt: new Date(now),\n expiresAt,\n userId,\n });\n\n return {\n authToken,\n expiresAt,\n userId,\n };\n}\n\nasync function processSessionHeartbeat(session: Session) {\n const now = Date.now();\n const newExpiresAt = new Date(now + time.days(7));\n\n await sessionsCollection.updateOne(\n { authToken: session.authToken },\n {\n $set: {\n lastActiveDate: new Date(now),\n expiresAt: newExpiresAt,\n },\n }\n );\n}\n\nexport function setAuthTokenCookie(res: Response, authToken: string) {\n res.cookie('authToken', authToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n path: '/',\n });\n}\n\nexport default new Module('_system.session', {\n stores: [sessionsCollection],\n mutations: {\n init: async function (args, { session, user }) {\n // TODO: mark or track app load somewhere\n\n return {\n session,\n user,\n configs: getPublicConfigs(),\n };\n },\n heartbeat: async function (args, { session }) {\n // Session might not exist if there is no database/authentication setup\n if (session) {\n await processSessionHeartbeat(session);\n }\n },\n },\n});\n","import { schema } from '../data/types';\nimport { Store } from '../data/store';\n\n/**\n * Database collection for storing user accounts with authentication methods and profile information.\n *\n * This is where **signupWithPassword** automatically creates new users.\n *\n * @example\n * ```typescript\n * // Find user by email\n * const user = await dbUsers.findOne(\n * { 'emails.address': 'john@example.com' }\n * );\n * ```\n *\n */\nexport const usersCollection = new Store('_modelenceUsers', {\n schema: {\n handle: schema.string(),\n emails: schema\n .array(\n schema.object({\n address: schema.string(),\n verified: schema.boolean(),\n })\n )\n .optional(),\n status: schema.enum(['active', 'disabled', 'deleted']).optional(),\n firstName: schema.string().optional(),\n lastName: schema.string().optional(),\n avatarUrl: schema.string().optional(),\n createdAt: schema.date(),\n disabledAt: schema.date().optional(),\n deletedAt: schema.date().optional(),\n roles: schema.array(schema.string()).optional(),\n authMethods: schema.object({\n password: schema\n .object({\n hash: schema.string(),\n })\n .optional(),\n google: schema\n .object({\n id: schema.string(),\n })\n .optional(),\n github: schema\n .object({\n id: schema.string(),\n })\n .optional(),\n }),\n },\n indexes: [\n {\n key: { handle: 1 },\n unique: true,\n collation: { locale: 'en', strength: 2 }, // Case-insensitive\n },\n {\n key: { 'emails.address': 1, status: 1 },\n },\n {\n key: { 'authMethods.google.id': 1 },\n sparse: true,\n unique: true,\n },\n {\n key: { 'authMethods.github.id': 1 },\n sparse: true,\n unique: true,\n },\n ],\n});\n\nexport const dbDisposableEmailDomains = new Store('_modelenceDisposableEmailDomains', {\n schema: {\n domain: schema.string(),\n addedAt: schema.date(),\n },\n indexes: [\n {\n key: { domain: 1 },\n unique: true,\n },\n ],\n});\n\nexport const emailVerificationTokensCollection = new Store('_modelenceEmailVerificationTokens', {\n schema: {\n userId: schema.objectId(),\n email: schema.string().optional(),\n token: schema.string(),\n createdAt: schema.date(),\n expiresAt: schema.date(),\n },\n indexes: [\n {\n key: { token: 1 },\n unique: true,\n },\n {\n key: { expiresAt: 1 },\n expireAfterSeconds: 0,\n },\n ],\n});\n\nexport const resetPasswordTokensCollection = new Store('_modelenceResetPasswordTokens', {\n schema: {\n userId: schema.objectId(),\n email: schema.string().optional(),\n token: schema.string(),\n createdAt: schema.date(),\n expiresAt: schema.date(),\n },\n indexes: [\n {\n key: { token: 1 },\n unique: true,\n },\n {\n key: { expiresAt: 1 },\n expireAfterSeconds: 0,\n },\n ],\n});\n","import { RoleDefinition, Role, DefaultRoles, Permission } from './types';\n\nconst roleMap = new Map<Role, RoleDefinition>();\nconst defaultRoles: DefaultRoles = {\n authenticated: null,\n unauthenticated: null,\n};\n\nexport function initRoles(\n roles: Record<Role, RoleDefinition>,\n _defaultRoles: Record<string, Role>\n) {\n defaultRoles.authenticated = _defaultRoles.authenticated;\n defaultRoles.unauthenticated = _defaultRoles.unauthenticated;\n\n for (const [name, definition] of Object.entries(roles)) {\n roleMap.set(name, definition);\n }\n}\n\nexport function getUnauthenticatedRoles() {\n return defaultRoles.unauthenticated ? [defaultRoles.unauthenticated] : [];\n}\n\nexport function getDefaultAuthenticatedRoles() {\n return defaultRoles.authenticated ? [defaultRoles.authenticated] : [];\n}\n\nexport function hasAccess(roles: Role[], requiredPermissions: Permission[]) {\n return requiredPermissions.every((permission) => hasPermission(roles, permission));\n}\n\nexport function requireAccess(roles: Role[], requiredPermissions: Permission[]) {\n const missingPermission = requiredPermissions.find(\n (permission) => !hasPermission(roles, permission)\n );\n\n if (missingPermission) {\n throw new Error(`Access denied - missing permission: '${missingPermission}'`);\n }\n}\n\nexport function hasPermission(roles: Role[], permission: Permission) {\n for (const role of roles) {\n const definition = roleMap.get(role);\n\n if (definition?.permissions?.includes(permission)) {\n return true;\n }\n }\n\n return false;\n}\n","import { ObjectId } from 'mongodb';\n\nimport { obtainSession } from './session';\nimport { usersCollection } from './db';\nimport { getDefaultAuthenticatedRoles, getUnauthenticatedRoles } from './role';\nimport { Role, Session, UserInfo } from './types';\n\nexport async function authenticate(\n authToken: string | null\n): Promise<{ session: Session; user: UserInfo | null; roles: Role[] }> {\n const session = await obtainSession(authToken);\n\n const userDoc = session.userId\n ? await usersCollection.findOne({\n _id: new ObjectId(session.userId),\n status: { $nin: ['deleted', 'disabled'] },\n })\n : null;\n const user = userDoc\n ? {\n id: userDoc._id.toString(),\n handle: userDoc.handle,\n roles: userDoc.roles || [],\n hasRole: (role: string) => (userDoc.roles || []).includes(role),\n requireRole: (role: string) => {\n if (!(userDoc.roles || []).includes(role)) {\n throw new Error(`Access denied - role '${role}' required`);\n }\n },\n firstName: userDoc.firstName ?? undefined,\n lastName: userDoc.lastName ?? undefined,\n avatarUrl: userDoc.avatarUrl ?? undefined,\n }\n : null;\n\n const roles = user ? getDefaultAuthenticatedRoles() : getUnauthenticatedRoles();\n\n return {\n user,\n session,\n roles,\n };\n}\n","import { Module } from '../app/module';\n\nexport default new Module('_system', {\n configSchema: {\n mongodbUri: {\n type: 'secret',\n isPublic: false,\n default: '',\n },\n mongodbPoolSize: {\n type: 'number',\n isPublic: false,\n default: 10,\n },\n 'env.type': {\n type: 'string',\n isPublic: true,\n default: '',\n },\n 'site.url': {\n type: 'string',\n isPublic: true,\n default: '',\n },\n multiInstance: {\n type: 'boolean',\n isPublic: false,\n default: false,\n },\n },\n});\n","import { MongoClient } from 'mongodb';\nimport systemModule from '../system';\nimport packageJson from '../../package.json';\n\nlet client: MongoClient | null = null;\n\nexport async function connect() {\n if (client) return client;\n\n const mongodbUri = getMongodbUri();\n if (!mongodbUri) {\n throw new Error('MongoDB URI is not set');\n }\n\n const maxPoolSize = systemModule.getConfig('mongodbPoolSize');\n\n client = new MongoClient(mongodbUri, {\n driverInfo: {\n name: 'Modelence',\n version: packageJson.version,\n },\n ignoreUndefined: true,\n maxPoolSize,\n });\n\n try {\n // Connect the client to the server\n await client.connect();\n // Send a ping to confirm a successful connection\n await client.db('admin').command({ ping: 1 });\n console.log('Pinged your deployment. You successfully connected to MongoDB!');\n return client;\n } catch (err) {\n console.error(err);\n client = null;\n throw err;\n }\n}\n\nexport function getMongodbUri() {\n return systemModule.getConfig('mongodbUri') || undefined;\n}\n\nexport function getClient() {\n return client;\n}\n\n// export async function closeConnection() {\n// if (client) {\n// await client.close();\n// client = null;\n// }\n// }\n","/**\n * Publish function provided to watch handlers.\n * Call this to trigger a re-fetch and send updated data to the client.\n */\nexport type LiveQueryPublish = () => void;\n\n/**\n * Cleanup function returned by watch handlers.\n * Called when the client unsubscribes.\n */\nexport type LiveQueryCleanup = () => void;\n\n/**\n * Context passed to watch handlers.\n */\nexport interface WatchContext {\n publish: LiveQueryPublish;\n}\n\n/**\n * Watch function that sets up real-time monitoring.\n * Receives a context with publish callback to trigger re-fetches.\n * Returns a cleanup function.\n */\nexport type LiveQueryWatch = (context: WatchContext) => LiveQueryCleanup | void;\n\n/**\n * Configuration for creating LiveData.\n */\nexport interface LiveDataConfig<T = unknown> {\n /**\n * Fetches the current data. Called initially and whenever watch triggers publish.\n */\n fetch: () => Promise<T> | T;\n /**\n * Sets up watching for changes. Receives publish callback and returns cleanup.\n */\n watch: LiveQueryWatch;\n}\n\n/**\n * LiveData object returned by live query handlers.\n *\n * @example\n * ```typescript\n * import { LiveData } from 'modelence/server';\n *\n * ...\n *\n * getTodos({ userId }, context) {\n * return new LiveData({\n * fetch: async () => await dbTodos.fetch({ userId }),\n * watch: ({ publish }) => {\n * // Subscribe to changes and call publish when data changes\n * listener.onChange(publish);\n *\n * return () => {\n * // Cleanup function to unsubscribe from changes\n * };\n * }\n * });\n * }\n * ```\n */\nexport class LiveData<T = unknown> {\n readonly fetch: () => Promise<T> | T;\n readonly watch: LiveQueryWatch;\n\n constructor(config: LiveDataConfig<T>) {\n this.fetch = config.fetch;\n this.watch = config.watch;\n }\n}\n","export function isServer() {\n return typeof window !== 'object';\n}\n\nexport function requireServer() {\n if (!isServer()) {\n throw new Error('This function can only be called on the server');\n }\n}\n\nexport function htmlToText(html: string) {\n return html\n .replace(/<[^>]*>/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n","import { requireServer } from '../utils';\nimport { startTransaction } from '@/telemetry';\nimport { requireAccess } from '../auth/role';\nimport { Method, MethodDefinition, MethodType, Args, Context } from './types';\nimport { LiveData } from '../live-query';\n\nconst methods: Record<string, Method<unknown>> = {};\n\nexport function createQuery<T extends unknown[]>(name: string, methodDef: MethodDefinition<T>) {\n requireServer();\n validateMethodName(name);\n return _createMethodInternal('query', name, methodDef);\n}\n\nexport function createMutation<T extends unknown[]>(name: string, methodDef: MethodDefinition<T>) {\n requireServer();\n validateMethodName(name);\n return _createMethodInternal('mutation', name, methodDef);\n}\n\nexport function _createSystemQuery<T extends unknown[]>(\n name: string,\n methodDef: MethodDefinition<T>\n) {\n requireServer();\n validateSystemMethodName(name);\n return _createMethodInternal('query', name, methodDef);\n}\n\nexport function _createSystemMutation<T extends unknown[]>(\n name: string,\n methodDef: MethodDefinition<T>\n) {\n requireServer();\n validateSystemMethodName(name);\n return _createMethodInternal('mutation', name, methodDef);\n}\n\nfunction validateMethodName(name: string) {\n if (name.toLowerCase().startsWith('_system.')) {\n throw new Error(`Method name cannot start with a reserved prefix: '_system.' (${name})`);\n }\n}\n\nfunction validateSystemMethodName(name: string) {\n if (!name.toLowerCase().startsWith('_system.')) {\n throw new Error(`System method name must start with a prefix: '_system.' (${name})`);\n }\n}\n\nfunction _createMethodInternal<T = unknown>(\n type: MethodType,\n name: string,\n methodDef: MethodDefinition<T>\n) {\n requireServer();\n\n if (methods[name]) {\n throw new Error(`Method with name '${name}' is already defined.`);\n }\n\n const handler = typeof methodDef === 'function' ? methodDef : methodDef.handler;\n const permissions = typeof methodDef === 'function' ? [] : (methodDef.permissions ?? []);\n methods[name] = { type, name, handler, permissions };\n}\n\nexport async function runMethod(name: string, args: Args, context: Context) {\n requireServer();\n\n const method = methods[name];\n if (!method) {\n throw new Error(`Method with name '${name}' is not defined.`);\n }\n const { type, handler } = method;\n\n const transaction = startTransaction('method', `method:${name}`, { type, args });\n\n let response;\n try {\n requireAccess(context.roles, method.permissions);\n response = await handler(args, context);\n } catch (error) {\n // TODO: log error and associate it with the transaction\n transaction.end('error');\n throw error;\n }\n\n transaction.end();\n\n return response;\n}\n\n/**\n * Run a method as a live query.\n * The handler should return a LiveData object with fetch and watch functions.\n */\nexport async function runLiveMethod(name: string, args: Args, context: Context): Promise<LiveData> {\n requireServer();\n\n const method = methods[name];\n if (!method) {\n throw new Error(`Method with name '${name}' is not defined.`);\n }\n const { type, handler } = method;\n\n if (type !== 'query') {\n throw new Error(`Live methods are only supported for queries`);\n }\n\n const transaction = startTransaction('method', `method:${name}:live`, { type, args });\n\n let result;\n try {\n requireAccess(context.roles, method.permissions);\n\n result = await handler(args, context);\n\n if (!(result instanceof LiveData)) {\n throw new Error(\n `Live query handler for '${name}' must return a LiveData object with fetch and watch functions. See https://docs.modelence.com/live-queries`\n );\n }\n } catch (error) {\n transaction.end('error');\n throw error;\n }\n\n transaction.end();\n\n return result;\n}\n","import { Socket } from 'socket.io';\nimport { z } from 'zod';\nimport { authenticate } from '../auth';\nimport { runLiveMethod } from '../methods';\nimport { getResponseTypeMap, sanitizeResult } from '../methods/serialize';\nimport { LiveQueryCleanup } from './context';\nimport { Context } from '@/methods/types';\n\ninterface ActiveSubscription {\n cleanup: LiveQueryCleanup | null;\n aborted?: boolean;\n}\n\nconst socketSubscriptions = new Map<string, Map<string, ActiveSubscription>>();\n\nfunction getSocketSubs(socket: Socket): Map<string, ActiveSubscription> {\n let subs = socketSubscriptions.get(socket.id);\n if (!subs) {\n subs = new Map();\n socketSubscriptions.set(socket.id, subs);\n }\n return subs;\n}\n\nexport async function handleSubscribeLiveQuery(socket: Socket, payload: unknown) {\n const parsed = z\n .object({\n subscriptionId: z.string().min(1),\n method: z.string().min(1),\n args: z.record(z.unknown()).default({}),\n authToken: z.string().nullish(),\n clientInfo: z\n .object({\n screenWidth: z.number(),\n screenHeight: z.number(),\n windowWidth: z.number(),\n windowHeight: z.number(),\n pixelRatio: z.number(),\n orientation: z.string().nullable(),\n })\n .optional(),\n })\n .safeParse(payload);\n if (!parsed.success) {\n socket.emit('liveQueryError', {\n subscriptionId: null,\n error: `Invalid payload: ${parsed.error.message}`,\n });\n return;\n }\n const { subscriptionId, method, args, authToken, clientInfo } = parsed.data;\n\n const subs = getSocketSubs(socket);\n\n // Clean up any existing subscription with the same ID (handles reconnect race conditions)\n const existingSub = subs.get(subscriptionId);\n if (existingSub) {\n if (existingSub.cleanup) {\n try {\n existingSub.cleanup();\n } catch (err) {\n console.error('[LiveQuery] Error cleaning up existing subscription:', err);\n }\n } else {\n // Subscription is still initializing - mark it for abort so it cleans up when ready\n existingSub.aborted = true;\n }\n }\n\n // Create placeholder entry BEFORE the async call so disconnect handler can find it\n const subscription: ActiveSubscription = { cleanup: null };\n subs.set(subscriptionId, subscription);\n\n try {\n const { session, user, roles } = await authenticate(authToken ?? null);\n\n const context: Context = {\n session,\n user,\n roles,\n clientInfo: clientInfo ?? {\n screenWidth: 0,\n screenHeight: 0,\n windowWidth: 0,\n windowHeight: 0,\n pixelRatio: 1,\n orientation: null,\n },\n connectionInfo: {\n ip: socket.handshake.address,\n userAgent: socket.handshake.headers['user-agent'],\n },\n };\n\n const liveData = await runLiveMethod(method, args, context);\n\n const fetchAndEmit = async () => {\n const data = sanitizeResult(await liveData.fetch());\n if (subscription.aborted) {\n return;\n }\n socket.emit('liveQueryData', {\n subscriptionId,\n data,\n typeMap: getResponseTypeMap(data),\n });\n };\n\n // Set to true to perform initial fetch at the beginning\n let isPendingPublish = true;\n let isFetching = false;\n\n const processPendingPublish = () => {\n if (subscription.aborted || !isPendingPublish || isFetching) {\n return;\n }\n isPendingPublish = false;\n isFetching = true;\n fetchAndEmit()\n .catch((err) => {\n if (subscription.aborted) {\n return;\n }\n console.error(`[LiveQuery] Error fetching data for ${method}:`, err);\n socket.emit('liveQueryError', {\n subscriptionId,\n error: err instanceof Error ? err.message : String(err),\n });\n })\n .finally(() => {\n isFetching = false;\n // Process the next pending publish if another publish was triggered while fetching\n processPendingPublish();\n });\n };\n\n const cleanup = liveData.watch({\n publish: () => {\n /*\n Use a pending flag to ensure concurrent publishes are processed sequentially\n (and run only once if there have been multiple publishes while the previous one was processing)\n Without sequential processing, we could end up sending an older fetch after a newer one\n */\n isPendingPublish = true;\n processPendingPublish();\n },\n });\n\n if (subscription.aborted) {\n // Unsubscribe/disconnect happened during watch setup - clean up immediately\n if (cleanup) {\n try {\n cleanup();\n } catch (err) {\n console.error('[LiveQuery] Error cleaning up after disconnect during setup:', err);\n }\n }\n return;\n }\n\n subscription.cleanup = cleanup || null;\n\n // Process initial fetch\n processPendingPublish();\n } catch (error) {\n subs.delete(subscriptionId);\n console.error(`[LiveQuery] Error in ${method}:`, error);\n socket.emit('liveQueryError', {\n subscriptionId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n}\n\nexport function handleUnsubscribeLiveQuery(socket: Socket, payload: unknown) {\n const parsed = z\n .object({\n subscriptionId: z.string().min(1),\n })\n .safeParse(payload);\n if (!parsed.success) {\n console.warn(`[LiveQuery] Invalid unsubscribe payload: ${parsed.error.message}`);\n return;\n }\n const { subscriptionId } = parsed.data;\n\n const subs = socketSubscriptions.get(socket.id);\n if (!subs) return;\n\n const sub = subs.get(subscriptionId);\n if (sub) {\n if (sub.cleanup) {\n try {\n sub.cleanup();\n } catch (err) {\n console.error('[LiveQuery] Error in cleanup:', err);\n }\n } else {\n sub.aborted = true;\n }\n subs.delete(subscriptionId);\n }\n}\n\nexport function handleLiveQueryDisconnect(socket: Socket) {\n const subs = socketSubscriptions.get(socket.id);\n if (subs) {\n // Clean up all subscriptions for this socket\n for (const sub of subs.values()) {\n if (sub.cleanup) {\n try {\n sub.cleanup();\n } catch (err) {\n console.error('[LiveQuery] Error in cleanup on disconnect:', err);\n }\n } else {\n sub.aborted = true;\n }\n }\n socketSubscriptions.delete(socket.id);\n }\n}\n","import { Server } from 'http';\nimport { Server as SocketServer, Socket } from 'socket.io';\nimport { createAdapter } from '@socket.io/mongo-adapter';\nimport { authenticate } from '@/auth';\nimport { getConfig } from '@/config/server';\nimport { getClient } from '@/db/client';\nimport { WebsocketServerProvider } from '../types';\nimport { ServerChannel } from '../serverChannel';\nimport {\n handleSubscribeLiveQuery,\n handleUnsubscribeLiveQuery,\n handleLiveQueryDisconnect,\n} from '@/live-query';\nimport type { Collection, Document } from 'mongodb';\n\nlet socketServer: SocketServer | null = null;\n\nconst COLLECTION = '_modelenceSocketio';\nconst ADAPTER_TTL_SECONDS = 60;\n\nexport async function init({\n httpServer,\n channels,\n}: {\n httpServer: Server;\n channels: ServerChannel[];\n}) {\n const mongodbClient = getClient();\n const isMultiInstance = Boolean(getConfig('_system.multiInstance'));\n\n console.log('Initializing Socket.IO server...');\n\n let mongoCollection: Collection<Document> | null = null;\n\n if (isMultiInstance && mongodbClient) {\n mongoCollection = mongodbClient.db().collection(COLLECTION);\n\n try {\n await mongoCollection.createIndex(\n { createdAt: 1 },\n { expireAfterSeconds: ADAPTER_TTL_SECONDS, background: true }\n );\n } catch (error: unknown) {\n if (error instanceof Error && 'code' in error && (error as { code: number }).code === 85) {\n try {\n await mongoCollection.dropIndex('createdAt_1');\n await mongoCollection.createIndex(\n { createdAt: 1 },\n { expireAfterSeconds: ADAPTER_TTL_SECONDS, background: true }\n );\n } catch (retryError: unknown) {\n console.error(\n 'Failed to recreate index on MongoDB collection for Socket.IO:',\n retryError\n );\n }\n } else {\n console.error('Failed to create index on MongoDB collection for Socket.IO:', error);\n }\n }\n }\n\n socketServer = new SocketServer(httpServer, {\n cors: {\n origin: '*',\n methods: ['GET', 'POST'],\n },\n adapter: mongoCollection ? createAdapter(mongoCollection) : undefined,\n transports: ['websocket'],\n perMessageDeflate: false,\n });\n\n socketServer.on('error', (error) => {\n console.error('Socket.IO error:', error);\n });\n\n socketServer.use(async (socket, next) => {\n const token = socket.handshake.auth.token;\n\n try {\n socket.data = await authenticate(token);\n } finally {\n next();\n }\n });\n\n socketServer.on('connection', (socket: Socket) => {\n socket.on('disconnect', () => {\n handleLiveQueryDisconnect(socket);\n });\n\n socket.on('joinChannel', async (channelName: string) => {\n const [category] = channelName.split(':');\n let authorized = false;\n\n for (const channel of channels) {\n if (channel.category === category) {\n if (!channel.canAccessChannel || (await channel.canAccessChannel(socket.data))) {\n socket.join(channelName);\n authorized = true;\n socket.emit('joinedChannel', channelName);\n }\n break; // Found matching channel - stop searching\n }\n }\n\n if (!authorized) {\n socket.emit('joinError', { channel: channelName, error: 'Access denied' });\n }\n });\n\n socket.on('leaveChannel', (channelName: string) => {\n socket.leave(channelName);\n console.log(`User ${socket.id} left channel ${channelName}`);\n socket.emit('leftChannel', channelName);\n });\n\n socket.on('subscribeLiveQuery', (payload) => handleSubscribeLiveQuery(socket, payload));\n socket.on('unsubscribeLiveQuery', (payload) => handleUnsubscribeLiveQuery(socket, payload));\n });\n\n console.log('Socket.IO server initialized');\n}\n\nfunction broadcast<T>({ category, id, data }: { category: string; id: string; data: T }) {\n socketServer?.to(`${category}:${id}`).emit(category, data);\n}\n\nexport default {\n init,\n broadcast,\n} as WebsocketServerProvider;\n","import { time } from '../time';\nimport { dbDisposableEmailDomains } from './db';\n\nexport async function isDisposableEmail(email: string): Promise<boolean> {\n const emailParts = email.toLowerCase().trim().split('@');\n if (emailParts.length !== 2) {\n return false;\n }\n\n const domain = emailParts[1];\n const result = await dbDisposableEmailDomains.findOne({ domain });\n return Boolean(result);\n}\n\nexport const updateDisposableEmailListCron = {\n interval: time.days(1),\n async handler() {\n const response = await fetch(\n 'https://disposable.github.io/disposable-email-domains/domains.txt'\n );\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const domainsText = await response.text();\n\n const domains = domainsText\n .split('\\n')\n .map((domain) => domain.trim().toLowerCase())\n .filter((domain) => domain.length > 0);\n\n const now = new Date();\n\n // Insert domains in batches to avoid overwhelming the database\n const batchSize = 500;\n for (let i = 0; i < domains.length; i += batchSize) {\n const batch = domains.slice(i, i + batchSize);\n\n try {\n await dbDisposableEmailDomains.insertMany(\n batch.map((domain) => ({\n domain,\n addedAt: now,\n }))\n );\n } catch (error: unknown) {\n // MongoDB throws BulkWriteError when some documents are duplicates\n if (\n error &&\n typeof error === 'object' &&\n 'name' in error &&\n error.name === 'MongoBulkWriteError'\n ) {\n // console.warn(`Error inserting batch starting at index ${i}:`, error.message);\n }\n }\n }\n },\n};\n","import { z } from 'zod';\nimport { UpdateProfileProps } from '../methods/types';\n\nexport const MIN_HANDLE_LENGTH = 3;\nexport const MAX_HANDLE_LENGTH = 50;\n\n// Reusable string validators\nconst trimmedNonEmptyString = (opts: { min?: number; max: number }) =>\n z\n .string()\n .trim()\n .min(opts.min ?? 1, { message: `must be at least ${opts.min ?? 1} characters` })\n .max(opts.max, { message: `must be at most ${opts.max} characters` });\n\nconst trimmedOptionalString = (opts: { max: number }) =>\n z\n .string()\n .trim()\n .max(opts.max, { message: `must be at most ${opts.max} characters` })\n .transform((val) => (val === '' ? undefined : val))\n .optional();\n\n// Base schema (used for both full & partial validation)\nconst profileFieldsSchema = z\n .object({\n firstName: trimmedOptionalString({ max: 50 }),\n lastName: trimmedOptionalString({ max: 50 }),\n avatarUrl: trimmedOptionalString({ max: 400 }),\n handle: trimmedNonEmptyString({ min: MIN_HANDLE_LENGTH, max: MAX_HANDLE_LENGTH }),\n })\n .strict();\n\n/**\n * Validates and trims profile fields against the defined rules.\n *\n * For each field present in `fields`:\n * - Trims whitespace\n * - Sets fields to `undefined` when cleared (empty string)\n * - Enforces min/max length constraints\n *\n * @returns An object containing only the validated, trimmed fields that were provided.\n */\nexport function validateProfileFields(\n fields: Partial<UpdateProfileProps>\n): Partial<UpdateProfileProps> {\n const result = profileFieldsSchema.partial().safeParse(fields);\n\n if (!result.success) {\n const issue = result.error.issues[0];\n const path = issue.path.join('.');\n const msg = path ? `${path}: ${issue.message}` : issue.message;\n throw new Error(msg);\n }\n\n return result.data;\n}\n\nexport function validatePassword(value: string) {\n return z.string().min(8, { message: 'Password must contain at least 8 characters' }).parse(value);\n}\n\nexport function validateEmail(value: string) {\n return z.string().email({ message: 'Invalid email address' }).parse(value).toLowerCase();\n}\n\nexport function validateHandle(value: string) {\n return trimmedNonEmptyString({ min: MIN_HANDLE_LENGTH, max: MAX_HANDLE_LENGTH }).parse(value);\n}\n","import { randomBytes } from 'crypto';\nimport { usersCollection } from './db';\nimport { User } from './types';\nimport { validateHandle, MAX_HANDLE_LENGTH, MIN_HANDLE_LENGTH } from './validators';\n\nexport function serializeUserForClient(userDoc: User) {\n return {\n id: userDoc._id,\n handle: userDoc.handle,\n roles: userDoc.roles || [],\n firstName: userDoc.firstName ?? undefined,\n lastName: userDoc.lastName ?? undefined,\n avatarUrl: userDoc.avatarUrl ?? undefined,\n };\n}\n\n/**\nFinds an available handle by appending incremental suffixes (_2, _3, …)\nto the base handle until a unique one is found.\nThe base handle is truncated so that the suffixed candidate never exceeds MAX_HANDLE_LENGTH.\n */\nasync function findAvailableHandle(baseHandle: string): Promise<string> {\n // Truncate base handle to MAX_HANDLE_LENGTH so the unsuffixed form is valid.\n const truncatedBase = baseHandle.slice(0, MAX_HANDLE_LENGTH);\n\n // Check the unsuffixed base handle first.\n try {\n const firstCheck = await usersCollection.findOne(\n { handle: truncatedBase },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (!firstCheck) {\n return truncatedBase;\n }\n } catch (err) {\n throw new Error(`Database error while checking handle availability: ${err}`);\n }\n\n // Try sequential suffixes _2 through _51 (50 attempts).\n const MAX_SUFFIX_VALUE = 51;\n\n for (let suffix = 2; suffix <= MAX_SUFFIX_VALUE; suffix++) {\n const suffixStr = `_${suffix}`;\n const candidate = `${truncatedBase.slice(0, MAX_HANDLE_LENGTH - suffixStr.length)}${suffixStr}`;\n\n try {\n const conflict = await usersCollection.findOne(\n { handle: candidate },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (!conflict) {\n return candidate;\n }\n } catch (err) {\n throw new Error(`Database error while checking handle \"${candidate}\": ${err}`);\n }\n }\n\n // Fallback: sequential suffixes exhausted — use random hex suffixes.\n // Limit the number of attempts to avoid an infinite loop in case of persistent DB issues\n const MAX_RANDOM_ATTEMPTS = 10;\n\n for (let attempt = 0; attempt < MAX_RANDOM_ATTEMPTS; attempt++) {\n const randomSuffix = `_${randomBytes(3).toString('hex')}`;\n const candidate = `${truncatedBase.slice(0, MAX_HANDLE_LENGTH - randomSuffix.length)}${randomSuffix}`;\n\n try {\n const conflict = await usersCollection.findOne(\n { handle: candidate },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (!conflict) {\n return candidate;\n }\n } catch (err) {\n throw new Error(`Database error while checking handle \"${candidate}\": ${err}`);\n }\n }\n\n throw new Error(\n `Could not generate a unique handle for base \"${baseHandle}\" after exhausting all attempts.`\n );\n}\n\n/**\n * Resolves a unique handle for a new user.\n *\n * If the caller supplied a handle it is validated and checked for uniqueness.\n * - When `throwOnConflict` is true (default), an error is thrown if the handle is taken.\n * - When `throwOnConflict` is false, a numeric suffix (_2, _3, …) is appended to make\n * it unique. This is intended for system-generated handles (e.g. from `generateHandle`).\n *\n * If no handle is supplied, the local part of the email address is used as the base handle,\n * and a numeric suffix is appended until an unused handle is found.\n */\nexport async function resolveUniqueHandle(\n rawHandle: string | undefined,\n email: string,\n { throwOnConflict = true }: { throwOnConflict?: boolean } = {}\n): Promise<string> {\n if (rawHandle !== undefined && rawHandle !== null && String(rawHandle).trim() !== '') {\n // Caller explicitly provided a handle – trim and validate it.\n const handle = validateHandle(String(rawHandle).trim());\n\n if (throwOnConflict) {\n const existing = await usersCollection.findOne(\n { handle },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (existing) {\n throw new Error('Handle already taken.');\n }\n\n return handle;\n }\n\n // System-generated handle – find an available variant with suffix if needed.\n return findAvailableHandle(handle);\n }\n\n // Derive handle from the email local-part (everything before '@').\n // Truncate to MAX_HANDLE_LENGTH since RFC 5321 allows local parts up to 64 chars.\n const baseHandle = email.split('@')[0].padEnd(MIN_HANDLE_LENGTH, '_').slice(0, MAX_HANDLE_LENGTH);\n return findAvailableHandle(baseHandle);\n}\n","import type { EmailProvider } from '../types';\n\nexport type EmailConfig = {\n provider?: EmailProvider;\n from?: string;\n verification?: {\n subject?: string;\n template?: (props: { name: string; email: string; verificationUrl: string }) => string;\n redirectUrl?: string;\n };\n passwordReset?: {\n subject?: string;\n template?: (props: { name: string; email: string; resetUrl: string }) => string;\n redirectUrl?: string;\n };\n // @deprecated use verification.redirectUrl instead\n emailVerifiedRedirectUrl?: string;\n};\n\nlet emailConfig: EmailConfig = Object.freeze({});\n\nexport function setEmailConfig(newEmailConfig: EmailConfig) {\n emailConfig = Object.freeze(Object.assign({}, emailConfig, newEmailConfig));\n}\n\nexport function getEmailConfig() {\n return emailConfig;\n}\n","import { AuthErrorProps, AuthSuccessProps, User } from '@/auth/types';\nimport { UpdateProfileProps, SignupProps } from '@/methods/types';\n\ntype GenerateHandleProps = {\n email: string;\n firstName?: string;\n lastName?: string;\n};\n\n/**\n * Callback options for authentication operations\n */\nexport type AuthOption = {\n /** Callback executed when authentication succeeds */\n onSuccess?: (user: User) => void;\n /** Callback executed when authentication fails */\n onError?: (error: Error) => void;\n};\n\n/**\n * Authentication configuration for the application\n *\n * @example\n * ```typescript\n * import { startApp } from 'modelence/server';\n *\n * startApp({\n * auth: {\n * validateSignup: ({ email, firstName, lastName, password, handle, avatarUrl }) => {\n * // Validating the signup data\n * if (!email || !password) {\n * throw new Error('Email and password are required');\n * }\n * },\n * onAfterLogin: ({ user }) => {\n * console.log('User logged in:', user.name);\n * // Redirect to dashboard\n * },\n * onLoginError: ({ error }) => {\n * console.error('Login failed:', error.message);\n * // Show error toast\n * },\n * onAfterSignup: ({ user }) => {\n * console.log('User signed up:', user.email);\n * // Send welcome email\n * },\n * onSignupError: ({ error }) => {\n * console.error('Signup failed:', error.message);\n * },\n * generateHandle: ({ email }) => {\n * console.log('Generating handle for:', email);\n * // Generate handle\n * return 'user123';\n * },\n * }\n * });\n * ```\n */\nexport type AuthConfig = {\n // Optional pre-signup validation hook.\n validateSignup?: (props: SignupProps) => void | Promise<void>;\n validateProfileUpdate?: (props: UpdateProfileProps) => void | Promise<void>;\n\n // After Authentication callbacks\n onAfterLogin?: (props: AuthSuccessProps) => void;\n onLoginError?: (props: AuthErrorProps) => void;\n onAfterSignup?: (props: AuthSuccessProps) => void;\n onSignupError?: (props: AuthErrorProps) => void;\n onAfterEmailVerification?: (props: AuthSuccessProps) => void;\n onEmailVerificationError?: (props: AuthErrorProps) => void;\n // OAuth account linking callbacks\n onAfterOAuthLink?: (props: AuthSuccessProps) => void;\n onOAuthLinkError?: (props: AuthErrorProps) => void;\n // Custom handle generator.\n // If provided, this overrides the default handle generation logic.\n generateHandle?: (props: GenerateHandleProps) => Promise<string> | string;\n\n /** deprecated: use onAfterLogin and onLoginError */\n login?: AuthOption;\n /** deprecated: user onAfterSignup and onSignupError */\n signup?: AuthOption;\n\n /**\n * Controls how OAuth providers handle existing accounts with matching email.\n * - 'manual' (default): Returns an error when an OAuth login matches an existing email.\n * - 'auto': Automatically links the OAuth provider to the existing account\n * if the provider email is verified.\n */\n oauthAccountLinking?: 'auto' | 'manual';\n};\n\nlet authConfig: AuthConfig = Object.freeze({});\n\nexport function setAuthConfig(newAuthConfig: AuthConfig) {\n authConfig = Object.freeze(Object.assign({}, authConfig, newAuthConfig));\n}\n\nexport function getAuthConfig() {\n return authConfig;\n}\n","import bcrypt from 'bcrypt';\nimport { z } from 'zod';\n\nimport { Args, Context } from '../methods/types';\nimport { usersCollection } from './db';\nimport { serializeUserForClient } from './utils';\nimport { clearSessionUser, setSessionUser } from './session';\nimport { getEmailConfig } from '@/app/emailConfig';\nimport { consumeRateLimit } from '@/server';\nimport { validateEmail } from './validators';\nimport { getAuthConfig } from '@/app/authConfig';\n\nexport async function handleLoginWithPassword(\n args: Args,\n { user, session, connectionInfo }: Context\n) {\n try {\n if (!session) {\n throw new Error('Session is not initialized');\n }\n\n const ip = connectionInfo?.ip;\n if (ip) {\n await consumeRateLimit({\n bucket: 'signin',\n type: 'ip',\n value: ip,\n });\n }\n\n const email = validateEmail(args.email as string);\n // password is accepted just as a string, so users can still sign in if the password validation rules are changed\n const password = z.string().parse(args.password);\n\n // TODO: add rate limiting by email (and perhaps IP address overall)\n\n if (user) {\n // TODO: handle cases where a user is already logged in\n }\n\n const userDoc = await usersCollection.findOne(\n { 'emails.address': email, status: { $nin: ['deleted', 'disabled'] } },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n const passwordHash = userDoc?.authMethods?.password?.hash;\n if (!passwordHash) {\n throw incorrectCredentialsError();\n }\n\n const emailDoc = userDoc.emails?.find((e) => e.address.toLowerCase() === email);\n\n if (!emailDoc?.verified && getEmailConfig()?.provider) {\n throw new Error(\n \"Your email address hasn't been verified yet. Please check your inbox for the verification email.\"\n );\n }\n\n const isValidPassword = await bcrypt.compare(password, passwordHash);\n if (!isValidPassword) {\n throw incorrectCredentialsError();\n }\n\n await setSessionUser(session.authToken, userDoc._id);\n\n getAuthConfig().onAfterLogin?.({\n provider: 'email',\n user: userDoc,\n session,\n connectionInfo,\n });\n getAuthConfig().login?.onSuccess?.(userDoc);\n\n return {\n user: serializeUserForClient(userDoc),\n };\n } catch (error) {\n if (error instanceof Error) {\n getAuthConfig().onLoginError?.({\n provider: 'email',\n error,\n session,\n connectionInfo,\n });\n getAuthConfig().login?.onError?.(error);\n }\n throw error;\n }\n}\n\nexport async function handleLogout(args: Args, { session }: Context) {\n if (!session) {\n throw new Error('Session is not initialized');\n }\n\n await clearSessionUser(session.authToken);\n}\n\n/*\n It is important to return the same exact error both in case the email\n or password is incorrect so that the client cannot tell the difference,\n otherwise it would allow for an enumeration attack.\n*/\nfunction incorrectCredentialsError() {\n return new Error('Incorrect email/password combination');\n}\n","import { usersCollection } from './db';\nimport { Args, Context, UpdateProfileProps } from '../methods/types';\nimport { serializeUserForClient } from './utils';\nimport { validateProfileFields } from './validators';\nimport { getAuthConfig } from '@/app/authConfig';\n\nexport async function getOwnProfile(props: Args, { user }: Context) {\n if (!user) {\n throw new Error('Not authenticated');\n }\n\n const profile = await usersCollection.requireById(user.id);\n\n return {\n handle: profile.handle,\n emails: profile.emails,\n authMethods: Object.keys(profile.authMethods || {}),\n firstName: profile.firstName ?? undefined,\n lastName: profile.lastName ?? undefined,\n avatarUrl: profile.avatarUrl ?? undefined,\n };\n}\n\nexport async function handleUpdateProfile(props: Args, { user }: Context) {\n if (!user) {\n throw new Error('Not authenticated');\n }\n\n let profile = await usersCollection.requireById(user.id);\n\n const update = validateProfileFields(props as UpdateProfileProps);\n\n await getAuthConfig().validateProfileUpdate?.(update);\n\n //Check if handle is already taken\n if ('handle' in update && update.handle !== undefined) {\n const existing = await usersCollection.findOne(\n {\n handle: update.handle,\n _id: { $ne: profile._id }, // excludes the current user\n },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (existing) {\n throw new Error('Handle already taken.');\n }\n }\n\n //Update profile\n if (Object.keys(update).length > 0) {\n const setFields: Record<string, unknown> = {}; //Used to set the fields\n const unsetFields: Record<string, ''> = {}; //Used to clear the fields the mongodb, because mongodb rejects undefined values when updating fields\n\n for (const [key, value] of Object.entries(update)) {\n if (value === undefined) {\n unsetFields[key] = '';\n } else {\n setFields[key] = value;\n }\n }\n\n const mongoUpdate: Record<string, unknown> = {};\n if (Object.keys(setFields).length > 0) mongoUpdate.$set = setFields;\n if (Object.keys(unsetFields).length > 0) mongoUpdate.$unset = unsetFields;\n\n try {\n await usersCollection.updateOne({ _id: profile._id }, mongoUpdate);\n\n //Also pass Cleared Fields as UNDEFINED in profile\n const clearedFields = Object.fromEntries(\n Object.keys(unsetFields).map((key) => [key, undefined])\n );\n profile = { ...profile, ...setFields, ...clearedFields } as typeof profile;\n } catch (error) {\n if (error instanceof Error && 'code' in error && (error as { code: number }).code === 11000) {\n throw new Error('Handle already taken.');\n }\n throw error;\n }\n }\n\n return {\n user: serializeUserForClient(profile),\n };\n}\n","import { Document, ObjectId } from 'mongodb';\nimport { ConnectionInfo } from '@/methods/types';\n\nexport interface UserEmail {\n address: string;\n verified: boolean;\n}\n\nexport interface User extends Document {\n _id: ObjectId;\n\n handle: string;\n\n emails?: UserEmail[];\n\n status?: 'active' | 'disabled' | 'deleted';\n\n firstName?: string;\n lastName?: string;\n avatarUrl?: string;\n\n createdAt: Date;\n disabledAt?: Date;\n deletedAt?: Date;\n\n roles?: string[];\n\n authMethods: {\n password?: {\n hash: string;\n };\n google?: {\n id: string;\n };\n github?: {\n id: string;\n };\n };\n}\n\nexport type UserInfo = {\n /** The user's unique identifier. */\n id: string;\n /** The user's display handle. */\n handle: string;\n /** The role strings assigned to this user in the database. */\n roles: string[];\n /** Returns `true` if the user has the given role. */\n hasRole: (role: string) => boolean;\n /** Throws an error if the user does not have the given role. */\n requireRole: (role: string) => void;\n firstName?: string;\n lastName?: string;\n avatarUrl?: string;\n};\n\nexport type Role = string;\n\nexport type DefaultRoles = Record<'authenticated' | 'unauthenticated', Role | null>;\n\nexport type Session = {\n authToken: string;\n expiresAt: Date;\n userId: ObjectId | null;\n};\n\nexport type Permission = string;\n\n/**\n * Defines a role that can be assigned to users.\n *\n * Roles are registered via the `roles` option in {@link AppOptions} and\n * are synced to the Modelence Cloud dashboard for user management.\n *\n * @example\n * ```typescript\n * import { startApp } from 'modelence/server';\n *\n * startApp({\n * roles: {\n * admin: { description: 'Full access to all features' },\n * editor: { description: 'Can edit content' },\n * viewer: {},\n * },\n * });\n * ```\n */\nexport type RoleDefinition = {\n /** Human-readable description of the role, shown in the Modelence Cloud dashboard. */\n description?: string;\n /** @internal */\n permissions?: Permission[];\n};\n\nexport const SUPPORTED_OAUTH_PROVIDERS = ['google', 'github'] as const;\nexport type OAuthProvider = (typeof SUPPORTED_OAUTH_PROVIDERS)[number];\n\nexport type AuthProvider = OAuthProvider | 'email';\n\nexport type AuthSuccessProps = {\n provider: AuthProvider;\n user: User;\n session: Session | null;\n connectionInfo: ConnectionInfo;\n};\n\nexport type AuthErrorProps = {\n provider: AuthProvider;\n error: Error;\n session: Session | null;\n connectionInfo: ConnectionInfo;\n};\n","import { usersCollection } from './db';\nimport { Args, Context } from '@/methods/types';\nimport { OAuthProvider, SUPPORTED_OAUTH_PROVIDERS } from './types';\n\nexport async function handleUnlinkOAuthProvider({ provider }: Args, { user }: Context) {\n if (!user) {\n throw new Error('You must be signed in to unlink a provider.');\n }\n\n if (\n typeof provider !== 'string' ||\n !SUPPORTED_OAUTH_PROVIDERS.includes(provider as OAuthProvider)\n ) {\n throw new Error(\n `Invalid provider. Supported providers are: ${SUPPORTED_OAUTH_PROVIDERS.join(', ')}.`\n );\n }\n\n // requireById throws if user is not found, so no null check needed\n const userDoc = await usersCollection.requireById(user.id);\n\n const methods = userDoc.authMethods ?? {};\n const providerKey = provider as keyof typeof methods;\n\n if (!methods[providerKey]) {\n throw new Error(`${provider} is not linked to your account.`);\n }\n\n const activeMethodsCount = Object.values(methods).filter(Boolean).length;\n if (activeMethodsCount <= 1) {\n throw new Error(\n 'Cannot unlink your only authentication method. Please add another method first.'\n );\n }\n\n // Determine the OTHER auth method fields that must still exist for lockout prevention.\n // This atomic filter ensures that between our read and write, at least one other method\n // hasn't been concurrently removed (prevents two simultaneous unlinks from both succeeding).\n const otherMethods = Object.keys(methods).filter(\n (key) => key !== provider && methods[key as keyof typeof methods]\n );\n const otherMethodGuard =\n otherMethods.length > 0\n ? { $or: otherMethods.map((key) => ({ [`authMethods.${key}`]: { $exists: true } })) }\n : {};\n\n const result = await usersCollection.updateOne(\n { _id: userDoc._id, ...otherMethodGuard },\n { $unset: { [`authMethods.${provider}`]: '' } }\n );\n\n if (result.matchedCount === 0) {\n throw new Error(\n 'Cannot unlink your only authentication method. Please add another method first.'\n );\n }\n}\n","import { Store } from '../data/store';\nimport { schema } from '../data/types';\n\n/**\n * Two-bucket sliding window approximation to track rate limits.\n * This is a trade-off between storage and accuracy.\n * We're not keeping exact event logs, so we can't track the exact number of events in a window.\n * Instead, we're adding a weighted average from the previous window to the current window.\n */\nexport const dbRateLimits = new Store('_modelenceRateLimits', {\n schema: {\n bucket: schema.string(),\n type: schema.enum(['ip', 'user', 'email']),\n value: schema.string(),\n windowMs: schema.number(),\n\n windowStart: schema.date(),\n windowCount: schema.number(),\n prevWindowCount: schema.number(),\n\n expiresAt: schema.date(),\n },\n indexes: [\n { key: { bucket: 1, type: 1, value: 1, windowMs: 1 }, unique: true },\n { key: { expiresAt: 1 }, expireAfterSeconds: 0 },\n ],\n});\n","import { RateLimitRule, RateLimitType } from './types';\nimport { dbRateLimits } from './db';\nimport { RateLimitError } from '../error';\n\nlet allRules: Array<RateLimitRule> = [];\n\nexport function initRateLimits(rateLimits: RateLimitRule[]) {\n if (allRules.length > 0) {\n throw new Error('Duplicate call to initRateLimits - already initialized');\n }\n\n allRules = rateLimits;\n}\n\n/**\n * This function will check all rate limit rules on the specified bucket and type,\n * throw an error if any of them are exceeded and increase the count of the rate limit record.\n *\n * @category Rate Limits\n *\n * @example\n * ```ts\n * await consumeRateLimit({ bucket: 'api', type: 'ip', value: '127.0.0.1' });\n * ```\n * @param options.bucket - The bucket for the rate limit.\n * @param options.type - The type of the rate limit.\n * @param options.value - The value for the rate limit.\n * @param options.message - Optional custom error message when the rate limit is exceeded.\n */\nexport async function consumeRateLimit(options: {\n bucket: string;\n type: RateLimitType;\n value: string;\n message?: string;\n}) {\n const { bucket, type, value, message } = options;\n const rules = allRules.filter((rule) => rule.bucket === bucket && rule.type === type);\n const createError = message ? () => new RateLimitError(message) : undefined;\n\n for (const rule of rules) {\n await checkRateLimitRule(rule, value, createError);\n }\n}\n\n// Two-bucket sliding window approximation to track rate limits.\nasync function checkRateLimitRule(rule: RateLimitRule, value: string, createError?: () => Error) {\n const createRateLimitError = () => {\n return createError\n ? createError()\n : new RateLimitError(`Rate limit exceeded for ${rule.bucket}`);\n };\n\n const record = await dbRateLimits.findOne({\n bucket: rule.bucket,\n type: rule.type,\n value,\n windowMs: rule.window,\n });\n\n const now = Date.now();\n const currentWindowStart = Math.floor(now / rule.window) * rule.window;\n\n const { count, modifier } = record\n ? getCount(record, currentWindowStart, now)\n : {\n count: 0,\n modifier: {\n $setOnInsert: {\n windowStart: new Date(currentWindowStart),\n windowCount: 1,\n prevWindowCount: 0,\n expiresAt: new Date(currentWindowStart + rule.window + rule.window),\n },\n },\n };\n\n if (count >= rule.limit) {\n throw createRateLimitError();\n }\n\n /*\n Always use upsert, because there is a small chance the document might be auto-removed\n based on the expiration TTL index in between the check and the update\n */\n await dbRateLimits.upsertOne(\n { bucket: rule.bucket, type: rule.type, value, windowMs: rule.window },\n modifier\n );\n}\n\nfunction getCount(record: (typeof dbRateLimits)['Doc'], currentWindowStart: number, now: number) {\n const prevWindowStart = currentWindowStart - record.windowMs;\n\n if (record.windowStart.getTime() === currentWindowStart) {\n const currentWindowCount = record.windowCount;\n const prevWindowCount = record.prevWindowCount;\n const prevWindowWeight = 1 - (now - currentWindowStart) / record.windowMs;\n return {\n count: Math.round(currentWindowCount + prevWindowCount * prevWindowWeight),\n modifier: {\n $inc: { windowCount: 1 },\n $setOnInsert: {\n windowStart: new Date(currentWindowStart),\n prevWindowCount: 0,\n expiresAt: new Date(currentWindowStart + record.windowMs + record.windowMs),\n },\n },\n };\n }\n\n if (record.windowStart.getTime() === prevWindowStart) {\n const weight = 1 - (now - currentWindowStart) / record.windowMs;\n return {\n count: Math.round(record.windowCount * weight),\n modifier: {\n $set: {\n windowStart: new Date(currentWindowStart),\n windowCount: 1,\n prevWindowCount: record.windowCount,\n expiresAt: new Date(currentWindowStart + record.windowMs + record.windowMs),\n },\n },\n };\n }\n\n return {\n count: 0,\n modifier: {\n $set: {\n windowStart: new Date(currentWindowStart),\n windowCount: 1,\n prevWindowCount: 0,\n expiresAt: new Date(currentWindowStart + record.windowMs + record.windowMs),\n },\n },\n };\n}\n","export function emailVerificationTemplate({\n name,\n email,\n verificationUrl,\n}: {\n name?: string;\n email: string;\n verificationUrl: string;\n}) {\n return `\n <p>Hi${name ? ` ${name}` : ''},</p>\n <p>Please verify your email address ${email} by clicking the link below:</p>\n <p><a href=\"${verificationUrl}\">${verificationUrl}</a></p>\n <p>If you did not request this, please ignore this email.</p>\n `;\n}\n","import { z } from 'zod';\n\nimport { usersCollection, emailVerificationTokensCollection } from './db';\nimport { ObjectId, RouteParams, RouteResponse } from '@/server';\nimport { getEmailConfig } from '@/app/emailConfig';\nimport { randomBytes } from 'crypto';\nimport { time } from '@/time';\nimport { htmlToText } from '@/utils';\nimport { emailVerificationTemplate } from './templates/emailVerficationTemplate';\nimport { getAuthConfig } from '@/app/authConfig';\nimport { User } from './types';\nimport { Args, Context } from '@/methods/types';\nimport { validateEmail } from './validators';\nimport { consumeRateLimit } from '@/rate-limit/rules';\nimport { getConfig } from '@/config/server';\nimport { createSession, setAuthTokenCookie } from './session';\n\nasync function verifyEmailToken(token: string) {\n const tokenDoc = await emailVerificationTokensCollection.findOne({\n token,\n expiresAt: { $gt: new Date() },\n });\n\n if (!tokenDoc) {\n throw new Error('Invalid or expired verification token');\n }\n\n const userDoc = await usersCollection.findOne({\n _id: tokenDoc.userId,\n status: { $nin: ['deleted', 'disabled'] },\n });\n\n if (!userDoc) {\n throw new Error('User not found');\n }\n\n const email = tokenDoc.email;\n\n if (!email) {\n throw new Error('Email not found in token');\n }\n\n // Mark the specific email as verified atomically, returning the updated doc\n const updatedUserDoc = await usersCollection.findOneAndUpdate(\n {\n _id: tokenDoc.userId,\n status: { $nin: ['deleted', 'disabled'] },\n 'emails.address': email,\n 'emails.verified': { $ne: true },\n },\n { $set: { 'emails.$.verified': true } },\n { returnDocument: 'after' }\n );\n\n if (!updatedUserDoc) {\n const existingUser = await usersCollection.findOne({\n _id: tokenDoc.userId,\n 'emails.address': email,\n });\n\n if (existingUser) {\n throw new Error('Email is already verified');\n } else {\n throw new Error('Email address not found for this user');\n }\n }\n\n // Delete the used token\n await emailVerificationTokensCollection.deleteOne({ _id: tokenDoc._id });\n\n return { userDoc: updatedUserDoc, email };\n}\n\nexport async function handleVerifyEmail(params: RouteParams): Promise<RouteResponse> {\n const baseUrl = getConfig('_system.site.url') as string | undefined;\n const emailVerifiedRedirectUrl =\n getEmailConfig().verification?.redirectUrl ||\n getEmailConfig().emailVerifiedRedirectUrl ||\n baseUrl ||\n '/';\n try {\n const token = z.string().parse(params.query.token);\n const { userDoc } = await verifyEmailToken(token);\n\n const authConfig = getAuthConfig();\n authConfig.onAfterEmailVerification?.({\n provider: 'email',\n user: userDoc as User,\n session: null,\n connectionInfo: {\n baseUrl,\n ip: params.req.ip || params.req.socket.remoteAddress,\n userAgent: params.headers['user-agent'],\n acceptLanguage: params.headers['accept-language'],\n referrer: params.headers['referer'],\n },\n });\n\n const { authToken } = await createSession(userDoc._id);\n\n setAuthTokenCookie(params.res, authToken);\n\n return {\n status: 301,\n redirect: `${emailVerifiedRedirectUrl}?status=verified`,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'An unexpected error occurred';\n if (error instanceof Error) {\n const authConfig = getAuthConfig();\n authConfig.onEmailVerificationError?.({\n provider: 'email',\n error,\n session: null,\n connectionInfo: {\n baseUrl,\n ip: params.req.ip || params.req.socket.remoteAddress,\n userAgent: params.headers['user-agent'],\n acceptLanguage: params.headers['accept-language'],\n referrer: params.headers['referer'],\n },\n });\n console.error('Error verifying email:', error);\n }\n\n return {\n status: 301,\n redirect: `${emailVerifiedRedirectUrl}?status=error&message=${encodeURIComponent(message)}`,\n };\n }\n}\n\nexport async function sendVerificationEmail({\n userId,\n email,\n baseUrl = getConfig('_system.site.url') as string | undefined,\n}: {\n userId: ObjectId;\n email: string;\n baseUrl?: string;\n}) {\n if (getEmailConfig().provider) {\n const emailProvider = getEmailConfig().provider;\n\n // Generate verification token\n const verificationToken = randomBytes(32).toString('hex');\n const expiresAt = new Date(Date.now() + time.hours(24));\n\n // Store token in database\n await emailVerificationTokensCollection.insertOne({\n userId,\n email,\n token: verificationToken,\n createdAt: new Date(),\n expiresAt,\n });\n\n const verificationUrl = `${baseUrl}/api/_internal/auth/verify-email?token=${verificationToken}`;\n\n const template = getEmailConfig()?.verification?.template || emailVerificationTemplate;\n // TODO: we should have also the name on this step\n const htmlTemplate = template({ name: '', email, verificationUrl });\n const textContent = htmlToText(htmlTemplate);\n\n await emailProvider?.sendEmail({\n to: email,\n from: getEmailConfig()?.from || 'noreply@modelence.com',\n subject: getEmailConfig()?.verification?.subject || 'Verify your email address',\n text: textContent,\n html: htmlTemplate,\n });\n }\n}\n\nconst resendVerificationResponse = {\n success: true,\n message: 'If that email is registered and not yet verified, a verification email has been sent',\n};\n\nexport async function handleResendEmailVerification(args: Args, { connectionInfo }: Context) {\n const email = validateEmail(args.email as string);\n\n // Find user by email, excluding deleted/disabled accounts\n const userDoc = await usersCollection.findOne(\n { 'emails.address': email, status: { $nin: ['deleted', 'disabled'] } },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n // Return the same generic response whether the email is unknown,\n // already verified, or successfully sent — to prevent user enumeration.\n if (!userDoc) {\n return resendVerificationResponse;\n }\n\n const emailDoc = userDoc.emails?.find((e) => e.address.toLowerCase() === email);\n\n if (!emailDoc || emailDoc.verified) {\n return resendVerificationResponse;\n }\n\n if (!getEmailConfig().provider) {\n throw new Error('Email provider is not configured');\n }\n\n await consumeRateLimit({\n bucket: 'verification',\n type: 'user',\n value: userDoc._id.toString(),\n message: 'Please wait at least 60 seconds before requesting another verification email',\n });\n\n await sendVerificationEmail({\n userId: userDoc._id,\n email,\n baseUrl: connectionInfo?.baseUrl,\n });\n\n return resendVerificationResponse;\n}\n","import bcrypt from 'bcrypt';\nimport { SignupProps, Context, Args } from '../methods/types';\nimport { usersCollection } from './db';\nimport { isDisposableEmail } from './disposableEmails';\nimport { consumeRateLimit } from '../rate-limit/rules';\nimport { sendVerificationEmail } from './verification';\nimport { validateEmail, validatePassword, validateProfileFields } from './validators';\nimport { getAuthConfig } from '@/app/authConfig';\nimport { resolveUniqueHandle } from './utils';\n\nexport async function handleSignupWithPassword(\n props: Args,\n { user, session, connectionInfo }: Context\n) {\n const authConfig = getAuthConfig();\n try {\n // Narrow once at the boundary\n const signupProps = props as SignupProps;\n const { firstName, lastName, avatarUrl, handle } = signupProps;\n\n const email = validateEmail(signupProps.email);\n const password = validatePassword(signupProps.password);\n\n const ip = connectionInfo?.ip;\n if (ip) {\n await consumeRateLimit({\n bucket: 'signupAttempt',\n type: 'ip',\n value: ip,\n });\n }\n\n if (await isDisposableEmail(email)) {\n throw new Error('Please use a permanent email address');\n }\n\n // TODO: captcha check\n\n if (user) {\n // TODO: handle cases where a user is already logged in\n }\n\n const existingUser = await usersCollection.findOne(\n { 'emails.address': email },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (existingUser) {\n const existingEmail = existingUser.emails?.find((e) => e.address.toLowerCase() === email);\n if (existingUser.status === 'disabled') {\n throw new Error(\n `User is marked for deletion, please contact support if you want to restore the account.`\n );\n }\n throw new Error(`User with email already exists: ${existingEmail?.address}`);\n }\n\n if (ip) {\n await consumeRateLimit({\n bucket: 'signup',\n type: 'ip',\n value: ip,\n });\n }\n\n // Validate optional profile fields (firstName, lastName, avatarUrl, handle)\n const profileFields = validateProfileFields({\n firstName,\n lastName,\n avatarUrl,\n handle,\n });\n\n await authConfig.validateSignup?.({\n email,\n password,\n ...profileFields,\n });\n\n // Resolve unique handle\n let resolvedHandle: string;\n\n if (profileFields.handle) {\n resolvedHandle = await resolveUniqueHandle(profileFields.handle, email);\n } else if (authConfig.generateHandle) {\n const generated = await authConfig.generateHandle({\n email,\n firstName: profileFields.firstName,\n lastName: profileFields.lastName,\n });\n\n resolvedHandle = await resolveUniqueHandle(generated, email, {\n throwOnConflict: false,\n });\n } else {\n resolvedHandle = await resolveUniqueHandle(undefined, email);\n }\n\n // Hash password with bcrypt (salt is automatically generated)\n const hash = await bcrypt.hash(password, 10);\n\n const result = await usersCollection.insertOne({\n handle: resolvedHandle,\n status: 'active',\n emails: [\n {\n address: email,\n verified: false,\n },\n ],\n createdAt: new Date(),\n authMethods: {\n password: {\n hash,\n },\n },\n ...(profileFields.firstName !== undefined && { firstName: profileFields.firstName }),\n ...(profileFields.lastName !== undefined && { lastName: profileFields.lastName }),\n ...(profileFields.avatarUrl !== undefined && { avatarUrl: profileFields.avatarUrl }),\n });\n\n const userDocument = await usersCollection.findOne(\n { _id: result.insertedId },\n { readPreference: 'primary' }\n );\n\n if (!userDocument) {\n throw new Error('User not found');\n }\n\n await sendVerificationEmail({\n userId: result?.insertedId,\n email,\n baseUrl: connectionInfo?.baseUrl,\n });\n\n authConfig.onAfterSignup?.({\n provider: 'email',\n user: userDocument,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onSuccess?.(userDocument);\n\n return result.insertedId;\n } catch (error) {\n if (error instanceof Error) {\n authConfig.onSignupError?.({\n provider: 'email',\n error,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onError?.(error);\n }\n throw error;\n }\n}\n","import { z } from 'zod';\nimport bcrypt from 'bcrypt';\nimport { randomBytes } from 'crypto';\n\nimport { Args, Context } from '@/methods/types';\nimport { usersCollection, resetPasswordTokensCollection } from './db';\nimport { getEmailConfig } from '@/app/emailConfig';\nimport { time } from '@/time';\nimport { htmlToText } from '@/utils';\nimport { validateEmail, validatePassword } from './validators';\nimport { consumeRateLimit } from '@/server';\nimport { getConfig } from '@/config/server';\nimport { invalidateAllUserSessions } from './session';\n\nfunction resolveUrl(baseUrl: string, configuredUrl?: string): string {\n if (!configuredUrl) {\n return baseUrl;\n }\n\n if (configuredUrl.startsWith('http://') || configuredUrl.startsWith('https://')) {\n return configuredUrl;\n }\n\n // Handle relative URL\n return `${baseUrl}${configuredUrl.startsWith('/') ? '' : '/'}${configuredUrl}`;\n}\n\nfunction defaultPasswordResetTemplate({ email, resetUrl }: { email: string; resetUrl: string }) {\n return `\n <p>Hi,</p>\n <p>We received a request to reset your password for ${email}.</p>\n <p>Click the link below to reset your password:</p>\n <p><a href=\"${resetUrl}\">${resetUrl}</a></p>\n <p>This link will expire in 1 hour.</p>\n <p>If you did not request this password reset, please ignore this email.</p>\n `;\n}\n\nconst passwordResetSent = {\n success: true,\n message: 'If an account with that email exists, a password reset link has been sent',\n};\n\nexport async function handleSendResetPasswordToken(args: Args, { connectionInfo }: Context) {\n const email = validateEmail(args.email as string);\n const ip = connectionInfo?.ip;\n\n if (ip) {\n await consumeRateLimit({\n bucket: 'passwordReset',\n type: 'ip',\n value: ip,\n });\n }\n\n await consumeRateLimit({\n bucket: 'passwordReset',\n type: 'email',\n value: email,\n });\n\n // Find user by email\n const userDoc = await usersCollection.findOne(\n { 'emails.address': email, status: { $nin: ['deleted', 'disabled'] } },\n { collation: { locale: 'en', strength: 2 } }\n );\n\n if (!userDoc) {\n // For security, don't reveal if email exists or not\n return passwordResetSent;\n }\n\n // Check if user has password auth method\n if (!userDoc.authMethods?.password) {\n return passwordResetSent;\n }\n\n const emailProvider = getEmailConfig().provider;\n if (!emailProvider) {\n throw new Error('Email provider is not configured');\n }\n\n // Generate reset token\n const resetToken = randomBytes(32).toString('hex');\n const now = Date.now();\n const createdAt = new Date(now);\n const expiresAt = new Date(now + time.hours(1)); // 1 hour expiry\n\n // Store reset token\n await resetPasswordTokensCollection.insertOne({\n userId: userDoc._id,\n email,\n token: resetToken,\n createdAt,\n expiresAt,\n });\n\n // Build reset URL\n const baseUrl = (getConfig('_system.site.url') as string | undefined) || connectionInfo?.baseUrl;\n const resetPasswordUrl = resolveUrl(baseUrl!, getEmailConfig().passwordReset?.redirectUrl);\n const resetUrl = `${resetPasswordUrl}?token=${resetToken}`;\n\n // Send email\n const template = getEmailConfig()?.passwordReset?.template || defaultPasswordResetTemplate;\n const htmlTemplate = template({ email, resetUrl, name: '' });\n const textContent = htmlToText(htmlTemplate);\n\n await emailProvider.sendEmail({\n to: email,\n from: getEmailConfig()?.from || 'noreply@modelence.com',\n subject: getEmailConfig()?.passwordReset?.subject || 'Reset your password',\n text: textContent,\n html: htmlTemplate,\n });\n\n return passwordResetSent;\n}\n\nexport async function handleResetPassword(args: Args, {}: Context) {\n const token = z.string().parse(args.token);\n const password = validatePassword(args.password as string);\n\n // Find the reset token\n const resetTokenDoc = await resetPasswordTokensCollection.findOne({ token });\n if (!resetTokenDoc) {\n throw new Error('Invalid or expired reset token');\n }\n\n // Check if token is expired\n if (resetTokenDoc.expiresAt < new Date()) {\n await resetPasswordTokensCollection.deleteOne({ token });\n throw new Error('Reset token has expired');\n }\n\n // Find the user\n const userDoc = await usersCollection.findOne({ _id: resetTokenDoc.userId });\n if (!userDoc) {\n throw new Error('User not found');\n }\n\n // Hash the new password\n const hash = await bcrypt.hash(password, 10);\n\n // Update user's password\n await usersCollection.updateOne(\n { _id: userDoc._id },\n { $set: { 'authMethods.password.hash': hash } }\n );\n\n // Mark the email as verified since the user proved ownership via the reset token\n if (resetTokenDoc.email) {\n await usersCollection.updateOne(\n { _id: userDoc._id, 'emails.address': resetTokenDoc.email },\n { $set: { 'emails.$.verified': true } }\n );\n }\n\n // Invalidate all existing sessions for this user so that other browsers/devices\n // are forced to re-authenticate with the new password\n await invalidateAllUserSessions(userDoc._id);\n\n // Delete the used reset token\n await resetPasswordTokensCollection.deleteOne({ token });\n\n return { success: true, message: 'Password has been reset successfully' };\n}\n","import { randomBytes } from 'crypto';\n\nimport { Module } from '../app/module';\nimport { time } from '../time';\nimport {\n dbDisposableEmailDomains,\n emailVerificationTokensCollection,\n resetPasswordTokensCollection,\n usersCollection,\n} from './db';\nimport { updateDisposableEmailListCron } from './disposableEmails';\nimport { handleLoginWithPassword, handleLogout } from './login';\nimport { getOwnProfile, handleUpdateProfile } from './profile';\nimport { handleUnlinkOAuthProvider } from './unlinkOAuthProvider';\nimport { handleSignupWithPassword } from './signup';\nimport { handleVerifyEmail, handleResendEmailVerification } from './verification';\nimport { handleResetPassword, handleSendResetPasswordToken } from './resetPassword';\n\nexport async function createGuestUser() {\n // TODO: add rate-limiting and captcha handling\n\n const guestId = randomBytes(9)\n .toString('base64')\n .replace(/[+/]/g, (c) => (c === '+' ? 'a' : 'b'));\n\n const handle = `guest_${guestId}`;\n // TODO: re-try on handle collision\n\n const result = await usersCollection.insertOne({\n handle,\n status: 'active',\n createdAt: new Date(),\n authMethods: {},\n });\n\n return result.insertedId;\n}\n\nexport default new Module('_system.user', {\n stores: [\n usersCollection,\n dbDisposableEmailDomains,\n emailVerificationTokensCollection,\n resetPasswordTokensCollection,\n ],\n queries: {\n getOwnProfile,\n },\n mutations: {\n signupWithPassword: handleSignupWithPassword,\n loginWithPassword: handleLoginWithPassword,\n logout: handleLogout,\n resendEmailVerification: handleResendEmailVerification,\n sendResetPasswordToken: handleSendResetPasswordToken,\n resetPassword: handleResetPassword,\n updateProfile: handleUpdateProfile,\n unlinkOAuthProvider: handleUnlinkOAuthProvider,\n },\n cronJobs: {\n updateDisposableEmailList: updateDisposableEmailListCron,\n },\n rateLimits: [\n {\n bucket: 'signup',\n type: 'ip',\n window: time.minutes(15),\n limit: 20,\n },\n {\n bucket: 'signup',\n type: 'ip',\n window: time.days(1),\n limit: 200,\n },\n {\n bucket: 'signupAttempt',\n type: 'ip',\n window: time.minutes(15),\n limit: 50,\n },\n {\n bucket: 'signupAttempt',\n type: 'ip',\n window: time.days(1),\n limit: 500,\n },\n {\n bucket: 'signin',\n type: 'ip',\n window: time.minutes(15),\n limit: 50,\n },\n {\n bucket: 'signin',\n type: 'ip',\n window: time.days(1),\n limit: 500,\n },\n {\n bucket: 'verification',\n type: 'user',\n window: time.seconds(60),\n limit: 1,\n },\n {\n bucket: 'verification',\n type: 'user',\n window: time.days(1),\n limit: 10,\n },\n {\n bucket: 'passwordReset',\n type: 'ip',\n window: time.minutes(15),\n limit: 10,\n },\n {\n bucket: 'passwordReset',\n type: 'ip',\n window: time.days(1),\n limit: 100,\n },\n {\n bucket: 'passwordReset',\n type: 'email',\n window: time.hours(1),\n limit: 5,\n },\n {\n bucket: 'passwordReset',\n type: 'email',\n window: time.days(1),\n limit: 10,\n },\n ],\n configSchema: {\n 'auth.email.enabled': {\n type: 'boolean',\n isPublic: true,\n default: true,\n },\n 'auth.email.from': {\n type: 'string',\n isPublic: false,\n default: '',\n },\n 'auth.email.verification': {\n type: 'boolean',\n isPublic: true,\n default: false,\n },\n 'auth.google.enabled': {\n type: 'boolean',\n isPublic: true,\n default: false,\n },\n 'auth.google.clientId': {\n type: 'string',\n isPublic: false,\n default: '',\n },\n 'auth.google.clientSecret': {\n type: 'secret',\n isPublic: false,\n default: '',\n },\n 'auth.github.enabled': {\n type: 'boolean',\n isPublic: true,\n default: false,\n },\n 'auth.github.clientId': {\n type: 'string',\n isPublic: false,\n default: '',\n },\n 'auth.github.clientSecret': {\n type: 'secret',\n isPublic: false,\n default: '',\n },\n },\n routes: [\n {\n path: '/api/_internal/auth/verify-email',\n handlers: {\n get: handleVerifyEmail,\n },\n },\n ],\n});\n","import { AppConfig, ConfigSchema, ConfigType } from './types';\n\ntype LocalConfigVariant = 'withRemoteServer' | 'withoutRemoteServer';\n\nconst localConfigMap = {\n withoutRemoteServer: {\n MONGODB_URI: '_system.mongodbUri',\n MONGODB_POOL_SIZE: '_system.mongodbPoolSize',\n MODELENCE_AUTH_GOOGLE_ENABLED: '_system.user.auth.google.enabled',\n MODELENCE_AUTH_GOOGLE_CLIENT_ID: '_system.user.auth.google.clientId',\n MODELENCE_AUTH_GOOGLE_CLIENT_SECRET: '_system.user.auth.google.clientSecret',\n MODELENCE_AUTH_GITHUB_ENABLED: '_system.user.auth.github.enabled',\n MODELENCE_AUTH_GITHUB_CLIENT_ID: '_system.user.auth.github.clientId',\n MODELENCE_AUTH_GITHUB_CLIENT_SECRET: '_system.user.auth.github.clientSecret',\n MODELENCE_AUTH_GITHUB_CLIENT_SCOPES: '_system.user.auth.github.scopes',\n MODELENCE_EMAIL_RESEND_API_KEY: '_system.email.resend.apiKey',\n MODELENCE_EMAIL_AWS_SES_REGION: '_system.email.awsSes.region',\n MODELENCE_EMAIL_AWS_SES_ACCESS_KEY_ID: '_system.email.awsSes.accessKeyId',\n MODELENCE_EMAIL_AWS_SES_SECRET_ACCESS_KEY: '_system.email.awsSes.secretAccessKey',\n MODELENCE_EMAIL_SMTP_HOST: '_system.email.smtp.host',\n MODELENCE_EMAIL_SMTP_PORT: '_system.email.smtp.port',\n MODELENCE_EMAIL_SMTP_USER: '_system.email.smtp.user',\n MODELENCE_EMAIL_SMTP_PASS: '_system.email.smtp.pass',\n MODELENCE_SITE_URL: '_system.site.url',\n MODELENCE_ENV_TYPE: '_system.env.type',\n MODELENCE_MULTI_INSTANCE: '_system.multiInstance',\n // deprecated\n MODELENCE_ENV: '_system.env',\n GOOGLE_AUTH_ENABLED: '_system.user.auth.google.enabled',\n GOOGLE_AUTH_CLIENT_ID: '_system.user.auth.google.clientId',\n GOOGLE_AUTH_CLIENT_SECRET: '_system.user.auth.google.clientSecret',\n },\n withRemoteServer: {\n MODELENCE_SITE_URL: '_system.site.url',\n },\n} as const;\n\nfunction formatLocalConfigValue(value: string, type: ConfigType): string | number | boolean {\n if (type === 'number') {\n const numValue = Number(value);\n if (isNaN(numValue)) {\n throw new Error(`Invalid number value for config: ${value}`);\n }\n return numValue;\n }\n if (type === 'boolean') {\n if (value.toLowerCase() === 'true') {\n return true;\n }\n if (value.toLowerCase() === 'false') {\n return false;\n }\n throw new Error(`Invalid boolean value for config: ${value}`);\n }\n return value;\n}\n\nfunction getConfigsFromEnvMap(\n configMap: Record<string, string>,\n configSchema: ConfigSchema\n): AppConfig[] {\n const configs: AppConfig[] = [];\n\n for (const [envVar, configKey] of Object.entries(configMap)) {\n const value = process.env[envVar];\n const configSchemaEntry = configSchema[configKey];\n if (value) {\n const type = configSchemaEntry?.type ?? 'string';\n configs.push({\n key: configKey,\n type: type,\n value: formatLocalConfigValue(value, type),\n });\n }\n }\n\n return configs;\n}\n\nexport function getLocalConfigs(\n configSchema: ConfigSchema,\n variant: LocalConfigVariant = 'withoutRemoteServer'\n): AppConfig[] {\n const configMap = localConfigMap[variant];\n return getConfigsFromEnvMap(configMap, configSchema);\n}\n","import os from 'os';\nimport { ConfigSchema } from '../config/types';\nimport { CronJobMetadata } from '../cron/types';\nimport { RoleDefinition } from '../auth/types';\nimport { Store } from '../data/store';\nimport { AppConfig } from '../config/types';\nimport { ModelSchema } from '../data/types';\n\ntype CloudBackendConnectOkResponse = {\n status: 'ok';\n configs: AppConfig[];\n environmentId: string;\n appAlias: string;\n environmentAlias: string;\n telemetry: {\n isEnabled: boolean;\n serviceName: string;\n };\n};\n\ntype CloudBackendConnectErrorResponse = {\n status: 'error';\n error: string;\n};\n\nexport type CloudBackendConnectResponse =\n | CloudBackendConnectOkResponse\n | CloudBackendConnectErrorResponse;\n\nexport async function connectCloudBackend({\n configSchema,\n cronJobsMetadata,\n stores,\n roles,\n}: {\n configSchema?: ConfigSchema;\n cronJobsMetadata?: CronJobMetadata[];\n stores?: Store<ModelSchema, Record<string, never>>[];\n roles?: Record<string, RoleDefinition>;\n}): Promise<CloudBackendConnectOkResponse> {\n const containerId = process.env.MODELENCE_CONTAINER_ID;\n if (!containerId) {\n throw new Error('Unable to connect to Modelence Cloud: MODELENCE_CONTAINER_ID is not set');\n }\n\n try {\n const dataStores = (stores ?? []).map((store) => ({\n name: store.getName(),\n schema: store.getSerializedSchema(),\n collections: [store.getName()],\n version: 2,\n indexes: store.getIndexes(),\n searchIndexes: store.getSearchIndexes(),\n indexCreationMode: store.getIndexCreationMode(),\n }));\n\n const data = await callApi<CloudBackendConnectResponse>('/api/connect', 'POST', {\n hostname: os.hostname(),\n containerId,\n dataModels: dataStores,\n configSchema,\n cronJobsMetadata,\n roles,\n });\n\n if (data.status === 'error') {\n throw new Error(data.error);\n }\n\n console.log('Successfully connected to Modelence Cloud');\n\n return data;\n } catch (error) {\n console.error('Unable to connect to Modelence Cloud:', error);\n throw error;\n }\n}\n\nexport async function fetchConfigs() {\n return callApi<{ configs: AppConfig[] }>('/api/configs', 'GET');\n}\n\nexport async function syncStatus() {\n const data = await callApi('/api/sync', 'POST', {\n containerId: process.env.MODELENCE_CONTAINER_ID,\n });\n return data;\n}\n\nasync function callApi<T = unknown>(endpoint: string, method: string, payload?: object) {\n return callCloudApi<T>(\n endpoint,\n method,\n payload ? JSON.stringify(payload) : undefined,\n payload ? { 'Content-Type': 'application/json' } : {}\n );\n}\n\nexport async function callCloudApi<T>(\n endpoint: string,\n method: string,\n body?: BodyInit,\n extraHeaders?: Record<string, string>\n): Promise<T> {\n const { MODELENCE_SERVICE_ENDPOINT, MODELENCE_SERVICE_TOKEN } = process.env;\n\n if (!MODELENCE_SERVICE_ENDPOINT) {\n throw new Error('Unable to connect to Modelence Cloud: MODELENCE_SERVICE_ENDPOINT is not set');\n }\n\n const response = await fetch(`${MODELENCE_SERVICE_ENDPOINT}${endpoint}`, {\n method,\n headers: {\n Authorization: `Bearer ${MODELENCE_SERVICE_TOKEN}`,\n ...extraHeaders,\n },\n body,\n });\n\n if (!response.ok) {\n const data = await response.text();\n try {\n const json = JSON.parse(data);\n throw new Error(\n `Unable to connect to Modelence Cloud: HTTP status: ${response.status}, ${json?.error}`\n );\n } catch {\n throw new Error(\n `Unable to connect to Modelence Cloud: HTTP status: ${response.status}, ${data}`\n );\n }\n }\n\n if (response.status === 204 || response.headers?.get('content-length') === '0') {\n return undefined as T;\n }\n\n return (await response.json()) as T;\n}\n","import { time } from '../time';\nimport { fetchConfigs, syncStatus } from '../app/backendApi';\nimport { getLocalConfigs } from './local';\nimport { loadConfigs, getSchema } from './server';\nimport { AppConfig } from './types';\n\nlet isSyncing = false;\n\nconst SYNC_INTERVAL = time.seconds(10);\n\nexport function startConfigSync() {\n setInterval(async () => {\n if (isSyncing) {\n return;\n }\n\n isSyncing = true;\n\n // TODO: move this sync outside of config\n try {\n await syncStatus();\n } catch (error) {\n console.error('Error syncing status', error);\n }\n\n try {\n await syncConfig();\n } catch (error) {\n console.error('Error syncing config', error);\n }\n\n isSyncing = false;\n }, SYNC_INTERVAL);\n}\n\nexport function loadRemoteConfigs(configs: AppConfig[]) {\n loadConfigs(configs);\n loadConfigs(getLocalConfigs(getSchema(), 'withRemoteServer'));\n}\n\nasync function syncConfig() {\n const { configs } = await fetchConfigs();\n loadRemoteConfigs(configs);\n}\n","import { schema } from '../data/types';\nimport { Store } from '../data/store';\n\n/**\n * Database collection for storing distributed locks.\n *\n * Locks are used to ensure that only one instance of the application can perform\n * a specific action at a time, such as running cron jobs or migrations\n */\nexport const locksCollection = new Store('_modelenceLocks', {\n schema: {\n _id: schema.string(), // unique identifier for the lock, used as the primary key\n instanceId: schema.string(),\n acquiredAt: schema.date(),\n\n resource: schema.string(), // deprecated, will be dropped in v1.0.0 (use _id instead)\n },\n indexes: [\n {\n // TODO(v1.0.0): remove after dropping legacy `resource` compatibility.\n key: { resource: 1 },\n unique: true,\n },\n {\n // TODO(v1.0.0): remove after dropping legacy `resource` compatibility.\n key: { resource: 1, instanceId: 1 },\n },\n {\n // TODO(v1.0.0): remove after dropping legacy `resource` compatibility.\n key: { resource: 1, acquiredAt: 1 },\n },\n ],\n indexCreationMode: 'blocking',\n});\n","import { randomBytes } from 'crypto';\nimport { MongoError } from 'mongodb';\nimport { locksCollection } from './db';\nimport { logDebug } from '../telemetry';\nimport { time } from '@/time';\n\n/**\n * In-memory cache to avoid frequent lock acquisition attempts\n * for the same resource within a short time frame.\n */\nconst lockCache: Record<\n string,\n {\n value: boolean;\n expiresAt: number;\n }\n> = {};\n\n/**\n * Time duration to consider a cached lock acquisition valid\n */\nconst DEFAULT_CACHE_DURATION = time.seconds(10);\n\n/**\n * Unique identifier for this application instance.\n * Generated once per application instance to track which container owns which locks.\n */\nconst INSTANCE_ID = randomBytes(32).toString('base64url');\n\n/**\n * Time after which a lock is expired\n */\nconst DEFAULT_LOCK_DURATION = time.seconds(30);\n\ntype LockOptions = {\n lockDuration?: number;\n successfulLockCacheDuration?: number;\n failedLockCacheDuration?: number;\n heartbeat?: boolean;\n bypassCache?: boolean;\n instanceId?: string;\n};\n\ntype LockHeartbeat = {\n timer: ReturnType<typeof setTimeout> | null;\n stopRequested: boolean;\n lockDuration: number;\n heartbeatInterval: number;\n};\n\nconst lockHeartbeats = new Map<string, LockHeartbeat>();\n\ntype DuplicateKeyMongoError = MongoError & {\n code?: number;\n keyPattern?: Record<string, unknown>;\n};\n\nconst isDuplicateKeyError = (error: unknown): error is DuplicateKeyMongoError =>\n error instanceof MongoError && error.code === 11000;\n\nconst hasKeyPatternField = (error: DuplicateKeyMongoError, field: string): boolean =>\n typeof error.keyPattern === 'object' &&\n error.keyPattern !== null &&\n Object.prototype.hasOwnProperty.call(error.keyPattern, field);\n\n/**\n * TODO(v1.0.0): Remove legacy `resource` fallback support.\n * This helper only exists for pre-1.0.0 lock documents where `_id !== resource`.\n * Delete this function and its call sites when releasing 1.0.0.\n */\nconst shouldFallbackToLegacyStrategy = async ({\n error,\n resource,\n}: {\n error: DuplicateKeyMongoError;\n resource: string;\n}): Promise<boolean> => {\n if (hasKeyPatternField(error, 'resource')) {\n return true;\n }\n\n if (hasKeyPatternField(error, '_id')) {\n return false;\n }\n\n const existingLock = (await locksCollection.findOne({ resource })) as {\n _id?: unknown;\n } | null;\n\n return !!existingLock && existingLock._id !== resource;\n};\n\nconst tryAcquireLockById = async ({\n resource,\n staleThresholdDate,\n instanceId,\n}: {\n resource: string;\n staleThresholdDate: Date;\n instanceId: string;\n}): Promise<boolean> => {\n const result = await locksCollection.upsertOne(\n {\n _id: resource,\n $or: [{ instanceId }, { acquiredAt: { $lt: staleThresholdDate } }],\n },\n {\n $set: {\n resource,\n instanceId,\n acquiredAt: new Date(),\n },\n $setOnInsert: {\n _id: resource,\n },\n }\n );\n\n return result.upsertedCount > 0 || result.modifiedCount > 0;\n};\n\nconst deleteLegacyLock = async ({\n resource,\n instanceId,\n staleThresholdDate,\n}: {\n resource: string;\n instanceId: string;\n staleThresholdDate?: Date;\n}): Promise<boolean> => {\n const selector = staleThresholdDate\n ? {\n resource,\n _id: { $ne: resource },\n $or: [{ instanceId }, { acquiredAt: { $lt: staleThresholdDate } }],\n }\n : {\n resource,\n instanceId,\n };\n\n const legacyDeleteResult = await locksCollection.deleteOne(selector);\n\n return legacyDeleteResult.deletedCount > 0;\n};\n\nconst stopLockHeartbeat = (resource: string) => {\n const heartbeatKey = resource;\n const heartbeat = lockHeartbeats.get(heartbeatKey);\n if (!heartbeat) {\n return;\n }\n\n heartbeat.stopRequested = true;\n if (heartbeat.timer) {\n clearTimeout(heartbeat.timer);\n heartbeat.timer = null;\n }\n\n lockHeartbeats.delete(heartbeatKey);\n};\n\nconst startLockHeartbeat = ({\n resource,\n lockDuration,\n instanceId,\n}: {\n resource: string;\n lockDuration: number;\n instanceId: string;\n}) => {\n const heartbeatInterval = Math.floor(lockDuration / 3);\n const heartbeatKey = resource;\n const existingHeartbeat = lockHeartbeats.get(heartbeatKey);\n\n if (\n existingHeartbeat &&\n !existingHeartbeat.stopRequested &&\n existingHeartbeat.heartbeatInterval === heartbeatInterval &&\n existingHeartbeat.lockDuration === lockDuration\n ) {\n return;\n }\n\n if (existingHeartbeat) {\n existingHeartbeat.stopRequested = true;\n if (existingHeartbeat.timer) {\n clearTimeout(existingHeartbeat.timer);\n existingHeartbeat.timer = null;\n }\n lockHeartbeats.delete(heartbeatKey);\n }\n\n const heartbeat: LockHeartbeat = {\n timer: null,\n stopRequested: false,\n lockDuration,\n heartbeatInterval,\n };\n\n const scheduleRefresh = () => {\n heartbeat.timer = setTimeout(() => {\n acquireLock(resource, {\n lockDuration,\n bypassCache: true,\n instanceId,\n })\n .then((isLockAcquired) => {\n if (!isLockAcquired) {\n heartbeat.stopRequested = true;\n logDebug(`Lost lock while refreshing heartbeat: ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n }\n })\n .finally(() => {\n if (heartbeat.stopRequested) {\n lockHeartbeats.delete(heartbeatKey);\n return;\n }\n scheduleRefresh();\n });\n }, heartbeatInterval);\n };\n\n lockHeartbeats.set(heartbeatKey, heartbeat);\n scheduleRefresh();\n};\n\n/**\n * Acquires a lock of the specified resource.\n * If the lock already exists and is owned by another container, this will fail.\n * If the lock is expired (no recent heartbeat), it will be taken over.\n *\n * @param resource - The type of lock to acquire\n * @param options.lockDuration - Time in ms after which a lock is considered expired (default: 30s)\n * @param options.successfulLockCacheDuration - Time in ms to cache successful lock acquisition\n * @param options.failedLockCacheDuration - Time in ms to cache failed lock acquisition\n * @param options.heartbeat - If true, auto-refreshes lock ownership at lockDuration/3 intervals\n * @param options.bypassCache - If true, skips the in-memory cache and always hits the DB\n * @param options.instanceId - The unique identifier for this application instance\n * @returns true if lock was acquired, false otherwise\n */\nexport async function acquireLock(\n resource: string,\n {\n lockDuration = DEFAULT_LOCK_DURATION,\n successfulLockCacheDuration = DEFAULT_CACHE_DURATION,\n failedLockCacheDuration = DEFAULT_CACHE_DURATION,\n heartbeat,\n bypassCache,\n instanceId = INSTANCE_ID,\n }: LockOptions = {}\n): Promise<boolean> {\n const now = Date.now();\n if (!bypassCache && lockCache[resource] && now < lockCache[resource].expiresAt) {\n if (lockCache[resource].value && heartbeat) {\n startLockHeartbeat({\n resource,\n lockDuration,\n instanceId,\n });\n }\n return lockCache[resource].value;\n }\n\n const staleThresholdDate = new Date(now - lockDuration);\n\n logDebug(`Attempting to acquire lock: ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n\n try {\n const isLockAcquired = await acquireLockById({\n resource,\n staleThresholdDate,\n instanceId,\n });\n\n lockCache[resource] = {\n value: isLockAcquired,\n expiresAt: now + (isLockAcquired ? successfulLockCacheDuration : failedLockCacheDuration),\n };\n\n if (isLockAcquired) {\n if (heartbeat) {\n startLockHeartbeat({\n resource,\n lockDuration,\n instanceId,\n });\n }\n\n logDebug(`Lock acquired: ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n } else {\n logDebug(`Failed to acquire lock (already held): ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n }\n\n return isLockAcquired;\n } catch {\n lockCache[resource] = {\n value: false,\n expiresAt: now + failedLockCacheDuration,\n };\n logDebug(`Failed to acquire lock (already held): ${resource}`, {\n source: 'lock',\n resource,\n instanceId,\n });\n return false;\n }\n}\n\nconst acquireLockById = async ({\n resource,\n staleThresholdDate,\n instanceId,\n}: {\n resource: string;\n staleThresholdDate: Date;\n instanceId: string;\n}): Promise<boolean> => {\n try {\n return await tryAcquireLockById({ resource, staleThresholdDate, instanceId });\n } catch (error) {\n // TODO(v1.0.0): Remove the legacy fallback\n // Backward compatibility: if an old lock doc exists with a non-resource _id and\n // a unique `resource` index, upserting the new `_id = resource` shape can fail.\n // Migrate that legacy lock document to `_id = resource` and retry current strategy.\n if (isDuplicateKeyError(error) && (await shouldFallbackToLegacyStrategy({ error, resource }))) {\n const hasDeletedLegacyLock = await deleteLegacyLock({\n resource,\n staleThresholdDate,\n instanceId,\n });\n\n if (!hasDeletedLegacyLock) {\n return false;\n }\n\n try {\n return await tryAcquireLockById({ resource, staleThresholdDate, instanceId });\n } catch (retryError) {\n if (isDuplicateKeyError(retryError)) {\n return false;\n }\n throw retryError;\n }\n }\n\n // Duplicate _id means the lock exists but was not eligible for update (owned + fresh).\n if (isDuplicateKeyError(error)) {\n return false;\n }\n\n throw error;\n }\n};\n\n/**\n * Releases a lock of the specified resource owned by this container.\n *\n * @param resource - The resource to release the lock for\n * @param options.instanceId - The unique identifier for this application instance\n * @returns true if lock was released, false if lock wasn't owned by this container or release failed.\n */\nexport async function releaseLock(\n resource: string,\n {\n instanceId = INSTANCE_ID,\n }: {\n instanceId?: string;\n } = {}\n): Promise<boolean> {\n stopLockHeartbeat(resource);\n\n try {\n const result = await locksCollection.deleteOne({\n _id: resource,\n instanceId,\n });\n\n // TODO(v1.0.0): Remove the legacy fallback\n if (result.deletedCount === 0) {\n const hasDeletedLegacyLock = await deleteLegacyLock({\n resource,\n instanceId,\n });\n\n return hasDeletedLegacyLock;\n }\n\n return result.deletedCount > 0;\n } catch {\n return false;\n } finally {\n delete lockCache[resource];\n }\n}\n","// import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';\n\nimport { time } from '../time';\nimport { CronJob, CronJobInputParams } from './types';\nimport { startTransaction, captureError } from '@/telemetry';\nimport { Module } from '../app/module';\nimport { schema } from '../data/types';\nimport { Store } from '../data/store';\nimport { acquireLock } from '../lock/helpers';\n\nconst cronJobs: Record<string, CronJob> = {};\nlet cronJobsInterval: NodeJS.Timeout | null = null;\n\nconst cronJobsCollection = new Store('_modelenceCronJobs', {\n schema: {\n alias: schema.string(),\n lastStartDate: schema.date().optional(),\n },\n indexes: [{ key: { alias: 1 }, unique: true, background: true }],\n});\n\n// TODO: allow changing interval and timeout with cron jobconfigs\nexport function defineCronJob(\n alias: CronJob['alias'],\n {\n description = '',\n interval,\n timeout = Math.min(Math.max(interval, time.minutes(1)), time.days(1)),\n handler,\n }: CronJobInputParams\n) {\n if (cronJobs[alias]) {\n throw new Error(`Duplicate cron job declaration: '${alias}' already exists`);\n }\n\n if (cronJobsInterval) {\n throw new Error(\n `Unable to add a cron job - cron jobs have already been initialized: [${alias}]`\n );\n }\n\n if (interval < time.seconds(5)) {\n throw new Error(`Cron job interval should not be less than 5 second [${alias}]`);\n }\n\n if (timeout > time.days(1)) {\n throw new Error(`Cron job timeout should not be longer than 1 day [${alias}]`);\n }\n\n cronJobs[alias] = {\n alias,\n params: { description, interval, timeout },\n handler,\n state: {\n isRunning: false,\n },\n };\n}\n\nexport async function startCronJobs() {\n if (cronJobsInterval) {\n throw new Error('Cron jobs already started');\n }\n\n const aliasList = Object.keys(cronJobs);\n if (aliasList.length > 0) {\n const aliasSelector = { alias: { $in: aliasList } };\n\n const cronJobRecords = await cronJobsCollection.fetch(aliasSelector);\n const now = Date.now();\n cronJobRecords.forEach((record) => {\n const job = cronJobs[record.alias];\n if (!job) {\n return;\n }\n job.state.scheduledRunTs = record.lastStartDate\n ? record.lastStartDate.getTime() + job.params.interval\n : now;\n });\n Object.values(cronJobs).forEach((job) => {\n if (!job.state.scheduledRunTs) {\n job.state.scheduledRunTs = now;\n }\n });\n\n cronJobsInterval = setInterval(tickCronJobs, time.seconds(1));\n }\n}\n\nasync function tickCronJobs() {\n const now = Date.now();\n\n const ownsLock = await acquireLock('cron', {\n successfulLockCacheDuration: time.seconds(10),\n failedLockCacheDuration: time.seconds(30),\n });\n\n if (!ownsLock) {\n return;\n }\n\n Object.values(cronJobs).forEach(async (job) => {\n const { params, state } = job;\n if (state.isRunning) {\n if (state.startTs && state.startTs + params.timeout < now) {\n // TODO: log cron trace timeout error\n state.isRunning = false;\n }\n return;\n }\n\n // TODO: limit the number of jobs running concurrently\n\n if (state.scheduledRunTs && state.scheduledRunTs <= now) {\n await runCronJob(job);\n }\n });\n}\n\nasync function runCronJob(job: CronJob) {\n const { alias, params, handler, state } = job;\n state.isRunning = true;\n state.startTs = Date.now();\n\n await cronJobsCollection.updateOne(\n { alias },\n {\n $set: {\n lastStartDate: new Date(state.startTs),\n },\n }\n );\n\n const transaction = startTransaction('cron', `cron:${alias}`);\n // TODO: enforce job timeout\n try {\n await handler();\n handleCronJobCompletion(state, params);\n transaction.end('success');\n } catch (err) {\n handleCronJobCompletion(state, params);\n const error = err instanceof Error ? err : new Error(String(err));\n captureError(error);\n transaction.end('error');\n console.error(`Error in cron job '${alias}':`, err);\n }\n}\n\nfunction handleCronJobCompletion(state: CronJob['state'], params: CronJob['params']) {\n state.scheduledRunTs = state.startTs ? state.startTs + params.interval : Date.now();\n state.startTs = undefined;\n state.isRunning = false;\n}\n\nexport function getCronJobsMetadata() {\n return Object.values(cronJobs).map(({ alias, params }) => ({\n alias,\n description: params.description,\n interval: params.interval,\n timeout: params.timeout,\n }));\n}\n\nexport default new Module('_system.cron', {\n stores: [cronJobsCollection],\n});\n\n// const runCronJob = () => {\n// const worker = new Worker(filePath, {\n// workerData: {},\n// execArgv: ['--loader', 'tsx'],\n// });\n\n// const timeoutId = setTimeout(() => {\n// worker.terminate();\n// console.error(`Cron job '${alias}' timed out after ${timeout}ms`);\n// }, timeout);\n\n// worker.on('message', (message) => {\n// if (message === 'done') {\n// clearTimeout(timeoutId);\n// worker.terminate();\n// }\n// });\n\n// worker.on('error', (err) => {\n// clearTimeout(timeoutId);\n// console.error(`Error in cron job '${alias}':`, err);\n// });\n\n// worker.on('exit', (code) => {\n// console.error(`Cron job '${alias}' exited with code ${code}`);\n// setTimeout(runCronJob, interval);\n// });\n// };\n","import { Store } from './store';\nimport { ModelSchema } from './types';\n\ntype NormalizedStore = Store<ModelSchema, Record<string, never>>;\n\nexport type ResolvedStores = {\n storesToInit: NormalizedStore[];\n effectiveStores: NormalizedStore[];\n};\n\n/**\n * Resolves module stores into two sets:\n *\n * - `storesToInit`: unique runtime instances that must be initialized.\n * - `effectiveStores`: the latest tail of each extension chain, used for\n * index reconciliation and cloud metadata.\n *\n * Throws if two unrelated chains share the same collection name.\n *\n * @internal\n */\nexport function resolveStores(stores: NormalizedStore[]): ResolvedStores {\n const uniqueStores = [...new Set(stores)];\n\n // Collect the chain tail for each unique root\n const rootToTail = new Map<NormalizedStore, NormalizedStore>();\n for (const store of uniqueStores) {\n const root = store.getChainRoot();\n rootToTail.set(root, root.getChainTail());\n }\n\n const effectiveStores = [...new Set(rootToTail.values())] as NormalizedStore[];\n\n // Detect collisions: different chains with the same collection name\n const nameToRoot = new Map<string, NormalizedStore>();\n for (const [root, tail] of rootToTail) {\n const name = tail.getName();\n const existing = nameToRoot.get(name);\n if (existing !== undefined && existing !== root) {\n throw new Error(\n `Store collision: multiple unrelated stores use collection name '${name}'. ` +\n `Use .extend() to create a single extension chain instead of independent stores.`\n );\n }\n nameToRoot.set(name, root);\n }\n\n return { storesToInit: uniqueStores, effectiveStores };\n}\n","import { Module } from '../app/module';\nimport { locksCollection } from './db';\n\n/**\n * Lock module for distributed locking across multiple instances.\n */\nexport default new Module('_system.lock', {\n stores: [locksCollection],\n});\n","import { Store } from '../data/store';\nimport { schema } from '../data/types';\n\nexport const dbMigrations = new Store('_modelenceMigrations', {\n schema: {\n version: schema.number(),\n status: schema.enum(['completed', 'failed']),\n description: schema.string().optional(),\n output: schema.string().optional(),\n appliedAt: schema.date(),\n },\n indexes: [{ key: { version: 1 }, unique: true }, { key: { version: 1, status: 1 } }],\n});\n","import { acquireLock, releaseLock } from '@/lock';\nimport { Module } from '../app/module';\nimport { dbMigrations } from './db';\nimport { logInfo } from '../telemetry';\n\nexport type MigrationScript = {\n version: number;\n description: string;\n handler: () => Promise<string | void>;\n};\n\ntype MigrationRunOptions = {\n lockMode?: 'acquire' | 'skip';\n};\n\nexport async function runMigrations(\n migrations: MigrationScript[],\n { lockMode = 'acquire' }: MigrationRunOptions = {}\n) {\n if (migrations.length === 0) {\n return;\n }\n\n if (lockMode === 'acquire') {\n const hasLock = await acquireLock('migrations');\n\n if (!hasLock) {\n logInfo('Another instance is running migrations. Skipping migration run.', {\n source: 'migrations',\n });\n return;\n }\n }\n\n try {\n const versions = migrations.map(({ version }) => version);\n\n const existingVersions = await dbMigrations.fetch({\n version: { $in: versions },\n });\n const existingVersionSet = new Set(existingVersions.map(({ version }) => version));\n const pendingMigrations = migrations.filter(({ version }) => !existingVersionSet.has(version));\n\n if (pendingMigrations.length === 0) {\n return;\n }\n\n logInfo(`Running migrations (${pendingMigrations.length})...`, {\n source: 'migrations',\n });\n for (const { version, description, handler } of pendingMigrations) {\n logInfo(`Running migration v${version}: ${description}`, {\n source: 'migrations',\n });\n try {\n const output = await handler();\n const outputStr = (output || '').toString().trim();\n const maxSize = 15 * 1024 * 1024; // 15MB (leaving 1MB buffer for other fields and MongoDB overhead)\n const truncatedOutput =\n outputStr.length > maxSize\n ? outputStr.slice(0, maxSize) + '\\n[Output truncated - exceeded size limit]'\n : outputStr;\n await dbMigrations.upsertOne(\n {\n version,\n },\n {\n $set: {\n version,\n status: 'completed',\n description,\n output: truncatedOutput,\n appliedAt: new Date(),\n },\n }\n );\n logInfo(`Migration v${version} complete`, {\n source: 'migrations',\n });\n } catch (e) {\n if (e instanceof Error) {\n await dbMigrations.upsertOne(\n {\n version,\n },\n {\n $set: {\n version,\n status: 'failed',\n description,\n output: e.message || '',\n appliedAt: new Date(),\n },\n }\n );\n logInfo(`Migration v${version} is failed: ${e.message}`, {\n source: 'migrations',\n });\n }\n }\n }\n } finally {\n if (lockMode === 'acquire') {\n await releaseLock('migrations');\n }\n }\n}\n\nexport function startMigrations(migrations: MigrationScript[]) {\n setTimeout(() => {\n runMigrations(migrations).catch((err) => {\n console.error('Error running migrations:', err);\n });\n }, 0);\n}\n\nexport default new Module('_system.migration', {\n stores: [dbMigrations],\n});\n","import { Module } from '../app/module';\nimport { dbRateLimits } from './db';\n\nexport default new Module('_system.rateLimit', {\n stores: [dbRateLimits],\n});\n","import { Module } from '../app/module';\nimport { callCloudApi } from '../app/backendApi';\nexport type { FileVisibility, GetUploadUrlResult } from './types';\nimport type { FileVisibility, GetUploadUrlResult } from './types';\n\ntype DownloadFileResult = {\n downloadUrl: string;\n};\n\ntype GetFileUrlResult = {\n url: string;\n};\n\nexport async function getUploadUrl({\n filePath,\n contentType,\n visibility,\n}: {\n filePath: string;\n contentType: string;\n visibility: FileVisibility;\n}): Promise<GetUploadUrlResult> {\n return await callCloudApi<GetUploadUrlResult>(\n '/api/files/upload',\n 'POST',\n JSON.stringify({ filePath, contentType, visibility }),\n {\n 'Content-Type': 'application/json',\n }\n );\n}\n\nexport async function deleteFile(filePath: string): Promise<void> {\n await callCloudApi<void>('/api/files/delete', 'POST', JSON.stringify({ filePath }), {\n 'Content-Type': 'application/json',\n });\n}\n\nexport async function downloadFile(filePath: string): Promise<DownloadFileResult> {\n return await callCloudApi<DownloadFileResult>(\n '/api/files/download',\n 'POST',\n JSON.stringify({ filePath }),\n {\n 'Content-Type': 'application/json',\n }\n );\n}\n\nexport async function getFileUrl(filePath: string): Promise<GetFileUrlResult> {\n return await callCloudApi<GetFileUrlResult>(\n '/api/files/url',\n 'POST',\n JSON.stringify({ filePath }),\n {\n 'Content-Type': 'application/json',\n }\n );\n}\n\nexport default new Module('_system.files', {\n queries: {\n async downloadFile({ filePath }) {\n return downloadFile(filePath as string);\n },\n async getFileUrl({ filePath }) {\n return getFileUrl(filePath as string);\n },\n },\n mutations: {\n async getUploadUrl({ filePath, contentType, visibility }) {\n return getUploadUrl({\n filePath: filePath as string,\n contentType: contentType as string,\n visibility: visibility as FileVisibility,\n });\n },\n async deleteFile({ filePath }) {\n return deleteFile(filePath as string);\n },\n },\n});\n","import {\n createServer,\n defineConfig,\n ViteDevServer,\n loadConfigFromFile,\n UserConfig,\n mergeConfig,\n Plugin,\n PluginOption,\n} from 'vite';\nimport reactPlugin from '@vitejs/plugin-react';\nimport path from 'path';\nimport fs from 'fs';\nimport express from 'express';\nimport type { AppServer, AppServerInitOptions, ExpressMiddleware } from './types';\n\nclass ViteServer implements AppServer {\n private viteServer?: ViteDevServer;\n private config?: UserConfig;\n\n async init({ httpServer }: AppServerInitOptions) {\n this.config = await getConfig(this.isDev() ? httpServer : undefined);\n if (this.isDev()) {\n console.log('Starting Vite dev server...');\n this.viteServer = await createServer(this.config);\n }\n }\n\n middlewares(): ExpressMiddleware[] {\n if (this.isDev()) {\n return (this.viteServer?.middlewares ?? []) as ExpressMiddleware[];\n }\n\n const staticFolders = [express.static('./.modelence/build/client'.replace(/\\\\/g, '/'))];\n if (this.config?.publicDir) {\n staticFolders.push(express.static(this.config.publicDir));\n }\n return staticFolders;\n }\n\n handler(req: express.Request, res: express.Response) {\n if (this.isDev()) {\n try {\n // Prevent browser from caching the HTML entrypoint in dev mode.\n // Vite's transformMiddleware uses no-cache + ETag for .ts/.tsx modules,\n // which revalidates correctly. But the HTML served by Express's sendFile\n // can be cached by the browser (e.g. bfcache on back/forward navigation).\n // Without HMR WebSocket, stale HTML leads to dynamic import() URLs that\n // reference modules the current Vite instance doesn't recognize.\n res.setHeader('Cache-Control', 'no-store');\n res.sendFile('index.html', { root: './src/client' });\n } catch (e) {\n console.error('Error serving index.html:', e);\n res.status(500).send('Internal Server Error');\n }\n } else {\n res.sendFile('index.html', { root: './.modelence/build/client'.replace(/\\\\/g, '/') });\n }\n }\n\n private isDev() {\n return process.env.NODE_ENV !== 'production';\n }\n}\n\nasync function loadUserViteConfig() {\n const appDir = process.cwd();\n\n try {\n const result = await loadConfigFromFile(\n { command: 'serve', mode: 'development' },\n undefined,\n appDir\n );\n return result?.config || {};\n } catch (error) {\n console.warn(`Could not load vite config:`, error);\n return {};\n }\n}\n\nfunction safelyMergeConfig(baseConfig: UserConfig, userConfig: UserConfig) {\n const mergedConfig = mergeConfig(baseConfig, userConfig);\n\n // Deduplicate plugins by name, keeping user plugins over framework plugins\n if (mergedConfig.plugins && Array.isArray(mergedConfig.plugins)) {\n const seenPlugins = new Set<string>();\n mergedConfig.plugins = mergedConfig.plugins\n .flat()\n .filter((plugin: PluginOption) => {\n if (!plugin || typeof plugin !== 'object' || Array.isArray(plugin)) {\n return true;\n }\n const pluginName = (plugin as Plugin).name;\n if (!pluginName || seenPlugins.has(pluginName)) {\n return false;\n }\n seenPlugins.add(pluginName);\n return true;\n })\n .reverse(); // Reverse to prioritize user plugins over framework plugins\n mergedConfig.plugins.reverse(); // Reverse back to maintain original order\n }\n\n return mergedConfig;\n}\n\nasync function getConfig(httpServer?: import('http').Server) {\n const appDir = process.cwd();\n const userConfig = await loadUserViteConfig();\n\n const eslintConfigFile = [\n '.eslintrc.js',\n '.eslintrc.json',\n '.eslintrc',\n 'eslint.config.js',\n '.eslintrc.yml',\n '.eslintrc.yaml',\n ].find((file) => fs.existsSync(path.join(appDir, file)));\n\n const plugins = [reactPlugin(), modelenceAssetPlugin()];\n\n if (eslintConfigFile) {\n const eslintPlugin = (await import('vite-plugin-eslint')).default;\n plugins.push(\n eslintPlugin({\n failOnError: false,\n include: ['src/**/*.js', 'src/**/*.jsx', 'src/**/*.ts', 'src/**/*.tsx'],\n cwd: appDir,\n overrideConfigFile: path.resolve(appDir, eslintConfigFile),\n })\n );\n }\n\n const baseConfig = defineConfig({\n plugins,\n build: {\n outDir: '.modelence/build/client'.replace(/\\\\/g, '/'),\n emptyOutDir: true,\n },\n server: {\n middlewareMode: true,\n hmr: httpServer ? { server: httpServer } : undefined,\n },\n root: './src/client',\n resolve: {\n alias: {\n '@': path.resolve(appDir, 'src').replace(/\\\\/g, '/'),\n },\n },\n });\n\n return safelyMergeConfig(baseConfig, userConfig);\n}\n\nfunction modelenceAssetPlugin(): Plugin {\n return {\n name: 'modelence-asset-handler',\n async transform(code: string, id: string) {\n const assetRegex = /\\.(png|jpe?g|gif|svg|mpwebm|ogg|mp3|wav|flac|aac)$/;\n if (assetRegex.test(id)) {\n if (process.env.NODE_ENV === 'development') {\n return code;\n }\n // TODO: Upload to CDN\n // return `export default \"${cdnUrl}\"`;\n return code;\n }\n },\n };\n}\n\nexport const viteServer = new ViteServer();\n","import { type Request, type Response } from 'express';\nimport { MongoServerError, ObjectId } from 'mongodb';\nimport { usersCollection } from '@/auth/db';\nimport { createSession, setAuthTokenCookie } from '@/auth/session';\nimport { getAuthConfig } from '@/app/authConfig';\nimport { getCallContext } from '@/app/server';\nimport { getConfig } from '@/config/server';\nimport { resolveUniqueHandle } from '../utils';\nimport { User, Session, UserEmail, OAuthProvider } from '@/auth/types';\nimport { ConnectionInfo } from '@/methods/types';\n\nexport interface OAuthUserData {\n id: string;\n email: string;\n emailVerified: boolean;\n providerName: OAuthProvider;\n firstName?: string;\n lastName?: string;\n avatarUrl?: string;\n}\n\nexport async function authenticateUser(res: Response, userId: ObjectId) {\n const { authToken } = await createSession(userId);\n\n setAuthTokenCookie(res, authToken);\n res.status(302);\n res.redirect('/');\n}\n\nasync function handleExistingProviderLogin(\n res: Response,\n userData: OAuthUserData,\n existingUser: User,\n session: Session | null,\n connectionInfo: ConnectionInfo\n) {\n const authConfig = getAuthConfig();\n\n try {\n if (existingUser.status === 'disabled' || existingUser.status === 'deleted') {\n res.status(400).json({\n error: 'User account is not active.',\n });\n return;\n }\n\n //Add User FirstName,LastName, AvatarURL if not exists\n const update: Partial<Pick<OAuthUserData, 'firstName' | 'lastName' | 'avatarUrl'>> = {};\n\n if (existingUser.firstName === undefined && userData.firstName) {\n update.firstName = userData.firstName;\n }\n if (existingUser.lastName === undefined && userData.lastName) {\n update.lastName = userData.lastName;\n }\n if (existingUser.avatarUrl === undefined && userData.avatarUrl) {\n update.avatarUrl = userData.avatarUrl;\n }\n\n let user = existingUser;\n\n if (Object.keys(update).length > 0) {\n await usersCollection.updateOne({ _id: existingUser._id }, { $set: update });\n user = { ...existingUser, ...update } as typeof existingUser;\n }\n\n await authenticateUser(res, existingUser._id);\n authConfig.onAfterLogin?.({\n provider: userData.providerName,\n user,\n session,\n connectionInfo,\n });\n authConfig.login?.onSuccess?.(user);\n } catch (error) {\n if (error instanceof Error) {\n authConfig.login?.onError?.(error);\n\n authConfig.onLoginError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n });\n }\n throw error;\n }\n}\n\nasync function handleExistingEmailLogin(\n res: Response,\n userData: OAuthUserData,\n existingUserByEmail: User,\n session: Session | null,\n connectionInfo: ConnectionInfo\n) {\n const authConfig = getAuthConfig();\n const linkingMode = authConfig.oauthAccountLinking ?? 'manual';\n\n if (linkingMode === 'auto' && userData.emailVerified) {\n if (existingUserByEmail.status === 'disabled' || existingUserByEmail.status === 'deleted') {\n res.status(400).json({\n error: 'User account is not active.',\n });\n return;\n }\n\n const matchedEmail = existingUserByEmail.emails?.find(\n (emailDoc: UserEmail) => emailDoc.address.toLowerCase() === userData.email.toLowerCase()\n );\n\n // Prevent pre-registration takeover by requiring local ownership verification too.\n if (!matchedEmail?.verified) {\n res.status(400).json({\n error: 'User with this email already exists. Please log in instead.',\n });\n return;\n }\n\n try {\n // Build profile fields to backfill from provider data if missing\n const profileUpdate: Partial<Pick<OAuthUserData, 'firstName' | 'lastName' | 'avatarUrl'>> = {\n ...(existingUserByEmail.firstName === undefined &&\n userData.firstName && { firstName: userData.firstName }),\n ...(existingUserByEmail.lastName === undefined &&\n userData.lastName && { lastName: userData.lastName }),\n ...(existingUserByEmail.avatarUrl === undefined &&\n userData.avatarUrl && { avatarUrl: userData.avatarUrl }),\n };\n\n // Single atomic update — link provider + backfill profile in one round trip\n const updateResult = await usersCollection.updateOne(\n {\n _id: existingUserByEmail._id,\n status: { $nin: ['deleted', 'disabled'] },\n $or: [\n { [`authMethods.${userData.providerName}.id`]: { $exists: false } },\n { [`authMethods.${userData.providerName}.id`]: userData.id },\n ],\n },\n {\n $set: {\n [`authMethods.${userData.providerName}.id`]: userData.id,\n ...profileUpdate,\n },\n }\n );\n\n const autoLinkSuccessful = updateResult.matchedCount > 0;\n\n if (!autoLinkSuccessful) {\n // User was deleted/disabled between findOne and updateOne, or linked to a *different* ID\n res.status(400).json({\n error: 'User with this email already exists. Please log in instead.',\n });\n return;\n }\n\n await authenticateUser(res, existingUserByEmail._id);\n\n // Construct updated user in-memory to provide fresh data to callbacks\n const updatedUser: User = {\n ...existingUserByEmail,\n ...profileUpdate,\n authMethods: {\n ...existingUserByEmail.authMethods,\n [userData.providerName]: {\n id: userData.id,\n },\n },\n };\n\n authConfig.onAfterLogin?.({\n provider: userData.providerName,\n user: updatedUser,\n session,\n connectionInfo,\n });\n authConfig.login?.onSuccess?.(updatedUser);\n\n return;\n } catch (error) {\n if (error instanceof Error) {\n authConfig.login?.onError?.(error);\n\n authConfig.onLoginError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n });\n }\n throw error;\n }\n }\n\n // Manual mode (default) or unverified email — reject\n // TODO: handle case with an HTML page\n res.status(400).json({\n error: 'User with this email already exists. Please log in instead.',\n });\n return;\n}\n\nasync function handleNewUserSignup(\n res: Response,\n userData: OAuthUserData,\n session: Session | null,\n connectionInfo: ConnectionInfo\n) {\n const authConfig = getAuthConfig();\n\n try {\n let handle: string;\n\n if (authConfig.generateHandle) {\n const generated = await authConfig.generateHandle!({\n email: userData.email,\n firstName: userData.firstName,\n lastName: userData.lastName,\n });\n //Don't throw error if handle is already taken, instead add a suffix '_2', '_3', etc. to the handle\n handle = await resolveUniqueHandle(generated, userData.email, {\n throwOnConflict: false,\n });\n } else {\n handle = await resolveUniqueHandle(undefined, userData.email);\n }\n\n const userDoc = {\n handle: handle,\n status: 'active' as const,\n emails: [\n {\n address: userData.email,\n verified: userData.emailVerified,\n },\n ],\n createdAt: new Date(),\n authMethods: {\n [userData.providerName]: {\n id: userData.id,\n },\n },\n ...(userData.firstName !== undefined && { firstName: userData.firstName }),\n ...(userData.lastName !== undefined && { lastName: userData.lastName }),\n ...(userData.avatarUrl !== undefined && { avatarUrl: userData.avatarUrl }),\n };\n\n const newUser = await usersCollection.insertOne(userDoc);\n\n await authenticateUser(res, newUser.insertedId);\n\n const userDocument = await usersCollection.findOne(\n { _id: newUser.insertedId },\n { readPreference: 'primary' }\n );\n\n if (userDocument) {\n authConfig.onAfterSignup?.({\n provider: userData.providerName,\n user: userDocument,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onSuccess?.(userDocument);\n }\n } catch (error) {\n if (error instanceof Error) {\n authConfig.onSignupError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onError?.(error);\n }\n throw error;\n }\n}\n\nexport function getRedirectUri(provider: string): string {\n return `${getConfig('_system.site.url')}/api/_internal/auth/${provider}/callback`;\n}\n\nexport async function handleOAuthUserAuthentication(\n req: Request,\n res: Response,\n userData: OAuthUserData\n): Promise<void> {\n // 1. Try to fetch existing user by OAuth ID\n const existingUser = await usersCollection.findOne({\n [`authMethods.${userData.providerName}.id`]: userData.id,\n });\n\n const { session, connectionInfo } = await getCallContext(req);\n\n if (existingUser) {\n return handleExistingProviderLogin(res, userData, existingUser, session, connectionInfo);\n }\n\n // 2. Validate Email is provided by Provider\n if (!userData.email) {\n res.status(400).json({\n error: `Email address is required for ${userData.providerName} authentication.`,\n });\n return;\n }\n\n // 3. Try to fetch existing user by Email\n let existingUserByEmail;\n\n try {\n existingUserByEmail = await usersCollection.findOne(\n { 'emails.address': userData.email, status: { $ne: 'deleted' } },\n { collation: { locale: 'en', strength: 2 } }\n );\n } catch (error) {\n if (error instanceof Error) {\n const authConfig = getAuthConfig();\n authConfig.onSignupError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n });\n\n authConfig.signup?.onError?.(error);\n }\n throw error;\n }\n\n //User Already existed via email verification but now trying to login via OAuth Providers from the same email\n if (existingUserByEmail) {\n return handleExistingEmailLogin(res, userData, existingUserByEmail, session, connectionInfo);\n }\n\n //New User\n return handleNewUserSignup(res, userData, session, connectionInfo);\n}\n\nexport function clearOAuthLinkCookie(res: Response) {\n // Important: must clear the httpOnly cookie used during OAuth linking\n res.cookie('oauthLinkToken', '', {\n httpOnly: true,\n maxAge: 0,\n path: '/api/_internal/auth/',\n sameSite: 'lax',\n secure: process.env.NODE_ENV === 'production',\n });\n}\n\nfunction safelyCallHook(hook?: () => void) {\n if (!hook) return;\n\n try {\n hook();\n } catch (err) {\n console.error('Error executing OAuth hook:', err);\n }\n}\n\nexport function validateOAuthStateAndGetMode(\n req: Request,\n res: Response,\n stateCookieName: string\n): string | null {\n const state = req.query.state as string;\n const storedState = req.cookies[stateCookieName];\n\n const [storedStateValue, storedMode] = (storedState || '').split(':');\n\n if (!state || !storedState || state !== storedStateValue) {\n res.status(400).json({ error: 'Invalid OAuth state - possible CSRF attack' });\n return null;\n }\n\n res.clearCookie(stateCookieName);\n return storedMode || 'login';\n}\n\nexport async function handleOAuthProviderLink(\n req: Request,\n res: Response,\n userData: OAuthUserData\n): Promise<void> {\n const authConfig = getAuthConfig();\n const { session, connectionInfo } = await getCallContext(req);\n\n if (!session?.userId) {\n clearOAuthLinkCookie(res);\n res.status(401).json({\n error: 'You must be signed in to link a provider.',\n });\n return;\n }\n\n const userId = session.userId;\n\n try {\n // Atomically attach the provider to the current user while preventing\n // overwriting an existing provider ID on the same user.\n // A unique index on the provider ID ensures it cannot be linked to another user.\n const providerField = `authMethods.${userData.providerName}.id`;\n\n const updateResult = await usersCollection.updateOne(\n {\n _id: userId,\n status: { $nin: ['deleted', 'disabled'] },\n $or: [{ [providerField]: { $exists: false } }, { [providerField]: userData.id }],\n },\n {\n $set: {\n [providerField]: userData.id,\n },\n }\n );\n\n // If no document matched, figure out why\n if (updateResult.matchedCount === 0) {\n const currentUser = await usersCollection.findOne({ _id: userId });\n\n if (!currentUser || currentUser.status === 'deleted' || currentUser.status === 'disabled') {\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error: new Error('User account not found or not active'),\n session,\n connectionInfo,\n })\n );\n\n clearOAuthLinkCookie(res);\n\n res.status(400).json({ error: 'User account is not active.' });\n return;\n }\n\n // Detect if the user already linked a different OAuth account\n const existingProviderId = currentUser?.authMethods?.[userData.providerName]?.id;\n\n if (existingProviderId && existingProviderId !== userData.id) {\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error: new Error(\n `User already has a different ${userData.providerName} account linked`\n ),\n session,\n connectionInfo,\n })\n );\n\n clearOAuthLinkCookie(res);\n\n res.status(400).json({\n error: `You have already linked a different ${userData.providerName} account.`,\n });\n\n return;\n }\n\n // Fallback safety guard in case the DB state does not match any expected branch\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error: new Error(`Unexpected OAuth linking state for ${userData.providerName}`),\n session,\n connectionInfo,\n })\n );\n\n clearOAuthLinkCookie(res);\n\n res.status(400).json({\n error: `Unable to link ${userData.providerName} account.`,\n });\n\n return;\n }\n\n const updatedUser = await usersCollection.findOne(\n { _id: userId },\n { readPreference: 'primary' }\n );\n\n if (updatedUser) {\n safelyCallHook(() =>\n authConfig.onAfterOAuthLink?.({\n provider: userData.providerName,\n user: updatedUser,\n session,\n connectionInfo,\n })\n );\n }\n\n // Redirect back to the app after successful link\n clearOAuthLinkCookie(res);\n\n res.status(302).redirect('/');\n } catch (error) {\n if (error instanceof MongoServerError && error.code === 11000) {\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n })\n );\n\n clearOAuthLinkCookie(res);\n\n res.status(400).json({\n error: `This ${userData.providerName} account is already linked to a different user.`,\n });\n\n return;\n }\n\n if (error instanceof Error) {\n safelyCallHook(() =>\n authConfig.onOAuthLinkError?.({\n provider: userData.providerName,\n error,\n session,\n connectionInfo,\n })\n );\n }\n\n clearOAuthLinkCookie(res);\n if (!res.headersSent) {\n throw error;\n }\n }\n}\n\nexport function validateOAuthCode(code: unknown): string | null {\n if (!code || typeof code !== 'string') {\n return null;\n }\n return code;\n}\n","import { getConfig } from '@/server';\nimport { time } from '@/time';\nimport { randomBytes } from 'crypto';\nimport {\n Router,\n type Request,\n type Response,\n type NextFunction,\n type Router as ExpressRouter,\n} from 'express';\nimport {\n getRedirectUri,\n handleOAuthUserAuthentication,\n handleOAuthProviderLink,\n validateOAuthCode,\n type OAuthUserData,\n clearOAuthLinkCookie,\n validateOAuthStateAndGetMode,\n} from './oauth-common';\n\ninterface GoogleTokenResponse {\n access_token: string;\n expires_in: number;\n scope: string;\n token_type: string;\n id_token: string;\n}\n\ninterface GoogleUserInfo {\n id: string;\n name: string;\n given_name?: string;\n family_name?: string;\n email: string;\n verified_email: boolean;\n picture?: string;\n}\n\nasync function exchangeCodeForToken(\n code: string,\n clientId: string,\n clientSecret: string,\n redirectUri: string\n): Promise<GoogleTokenResponse> {\n const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n code,\n client_id: clientId,\n client_secret: clientSecret,\n redirect_uri: redirectUri,\n grant_type: 'authorization_code',\n }),\n });\n\n if (!tokenResponse.ok) {\n throw new Error(`Failed to exchange code for token: ${tokenResponse.statusText}`);\n }\n\n return tokenResponse.json();\n}\n\nasync function fetchGoogleUserInfo(accessToken: string): Promise<GoogleUserInfo> {\n const userInfoResponse = await fetch('https://www.googleapis.com/oauth2/v2/userinfo', {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!userInfoResponse.ok) {\n throw new Error(`Failed to fetch user info: ${userInfoResponse.statusText}`);\n }\n\n return userInfoResponse.json();\n}\n\nasync function handleGoogleAuthenticationCallback(req: Request, res: Response) {\n const code = validateOAuthCode(req.query.code);\n\n if (!code) {\n res.status(400).json({ error: 'Missing authorization code' });\n return;\n }\n\n const mode = validateOAuthStateAndGetMode(req, res, 'authStateGoogle');\n if (!mode) return;\n\n const googleClientId = String(getConfig('_system.user.auth.google.clientId'));\n const googleClientSecret = String(getConfig('_system.user.auth.google.clientSecret'));\n const redirectUri = getRedirectUri('google');\n\n try {\n // Exchange code for tokens\n const tokenData = await exchangeCodeForToken(\n code,\n googleClientId,\n googleClientSecret,\n redirectUri\n );\n\n // Fetch user info\n const googleUser = await fetchGoogleUserInfo(tokenData.access_token);\n\n const userData: OAuthUserData = {\n id: googleUser.id,\n email: googleUser.email,\n emailVerified: googleUser.verified_email,\n providerName: 'google',\n firstName: googleUser.given_name || undefined,\n lastName: googleUser.family_name || undefined,\n avatarUrl: googleUser.picture || undefined,\n };\n if (mode === 'link') {\n await handleOAuthProviderLink(req, res, userData);\n } else {\n await handleOAuthUserAuthentication(req, res, userData);\n }\n } catch (error) {\n console.error('Google OAuth error:', error);\n if (mode === 'link') {\n clearOAuthLinkCookie(res);\n }\n res.status(500).json({ error: 'Authentication failed' });\n }\n}\n\nfunction getRouter(): ExpressRouter {\n const googleAuthRouter = Router();\n\n // Middleware to check if Google auth is enabled and configured\n const checkGoogleEnabled = (_req: Request, res: Response, next: NextFunction) => {\n const googleEnabled = Boolean(getConfig('_system.user.auth.google.enabled'));\n const googleClientId = String(getConfig('_system.user.auth.google.clientId'));\n const googleClientSecret = String(getConfig('_system.user.auth.google.clientSecret'));\n\n if (!googleEnabled || !googleClientId || !googleClientSecret) {\n res.status(503).json({ error: 'Google authentication is not configured' });\n return;\n }\n\n next();\n };\n\n // Initiate OAuth flow\n googleAuthRouter.get(\n '/api/_internal/auth/google',\n checkGoogleEnabled,\n (req: Request, res: Response) => {\n const googleClientId = String(getConfig('_system.user.auth.google.clientId'));\n const redirectUri = getRedirectUri('google');\n\n const state = randomBytes(32).toString('hex');\n\n const mode = req.query.mode === 'link' ? 'link' : 'login';\n\n res.cookie('authStateGoogle', `${state}:${mode}`, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n maxAge: time.minutes(10), // 10 minutes\n });\n\n const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');\n authUrl.searchParams.append('client_id', googleClientId);\n authUrl.searchParams.append('redirect_uri', redirectUri);\n authUrl.searchParams.append('response_type', 'code');\n authUrl.searchParams.append('scope', 'profile email');\n authUrl.searchParams.append('access_type', 'online');\n authUrl.searchParams.append('state', state);\n\n res.redirect(authUrl.toString());\n }\n );\n\n // Handle OAuth callback\n googleAuthRouter.get(\n '/api/_internal/auth/google/callback',\n checkGoogleEnabled,\n handleGoogleAuthenticationCallback\n );\n\n return googleAuthRouter;\n}\n\nexport default getRouter;\n","import { getConfig } from '@/server';\nimport { time } from '@/time';\nimport { randomBytes } from 'crypto';\nimport {\n Router,\n type Request,\n type Response,\n type NextFunction,\n type Router as ExpressRouter,\n} from 'express';\nimport {\n getRedirectUri,\n handleOAuthUserAuthentication,\n handleOAuthProviderLink,\n validateOAuthCode,\n type OAuthUserData,\n clearOAuthLinkCookie,\n validateOAuthStateAndGetMode,\n} from './oauth-common';\n\ninterface GitHubTokenResponse {\n access_token: string;\n token_type: string;\n scope: string;\n}\n\ninterface GitHubUserInfo {\n id: number;\n login: string;\n name: string;\n email: string | null;\n avatar_url?: string;\n}\n\ninterface GitHubEmail {\n email: string;\n primary: boolean;\n verified: boolean;\n visibility: 'public' | 'private' | null;\n}\n\nasync function exchangeCodeForToken(\n code: string,\n clientId: string,\n clientSecret: string,\n redirectUri: string\n): Promise<GitHubTokenResponse> {\n const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify({\n client_id: clientId,\n client_secret: clientSecret,\n code,\n redirect_uri: redirectUri,\n }),\n });\n\n if (!tokenResponse.ok) {\n throw new Error(`Failed to exchange code for token: ${tokenResponse.statusText}`);\n }\n\n return tokenResponse.json();\n}\n\nasync function fetchGitHubUserInfo(accessToken: string): Promise<GitHubUserInfo> {\n const userInfoResponse = await fetch('https://api.github.com/user', {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!userInfoResponse.ok) {\n throw new Error(`Failed to fetch user info: ${userInfoResponse.statusText}`);\n }\n\n return userInfoResponse.json();\n}\n\nasync function fetchGitHubUserEmails(accessToken: string): Promise<GitHubEmail[]> {\n const response = await fetch('https://api.github.com/user/emails', {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch user emails: ${response.statusText}`);\n }\n\n return response.json();\n}\n\nasync function getGitHubUserEmail(\n githubUser: GitHubUserInfo,\n accessToken: string\n): Promise<string | null> {\n if (githubUser.email) {\n return githubUser.email;\n }\n\n const emails = await fetchGitHubUserEmails(accessToken);\n return emails.find((e) => e.primary && e.verified)?.email ?? null;\n}\n\nasync function handleGitHubAuthenticationCallback(req: Request, res: Response) {\n const code = validateOAuthCode(req.query.code);\n\n if (!code) {\n res.status(400).json({ error: 'Missing authorization code' });\n return;\n }\n\n const mode = validateOAuthStateAndGetMode(req, res, 'authStateGithub');\n if (!mode) return;\n\n const githubClientId = String(getConfig('_system.user.auth.github.clientId'));\n const githubClientSecret = String(getConfig('_system.user.auth.github.clientSecret'));\n const redirectUri = getRedirectUri('github');\n\n try {\n // Exchange code for access token\n const tokenData = await exchangeCodeForToken(\n code,\n githubClientId,\n githubClientSecret,\n redirectUri\n );\n\n // Fetch user info\n const githubUser = await fetchGitHubUserInfo(tokenData.access_token);\n\n // Resolve a usable GitHub email (public email or fallback to primary verified email)\n const githubEmail = await getGitHubUserEmail(githubUser, tokenData.access_token);\n\n if (!githubEmail) {\n if (mode === 'link') {\n clearOAuthLinkCookie(res);\n }\n\n res.status(400).json({\n error:\n 'Unable to retrieve a primary verified email from GitHub. Please ensure your GitHub account has a verified email set as primary.',\n });\n return;\n }\n\n const nameParts = githubUser.name ? githubUser.name.trim().split(/\\s+/) : [];\n const firstName = nameParts[0] || undefined;\n const lastName = nameParts.length > 1 ? nameParts.slice(1).join(' ') : undefined;\n\n const userData: OAuthUserData = {\n id: String(githubUser.id),\n email: githubEmail,\n emailVerified: true, // Assume public email is verified\n providerName: 'github',\n firstName,\n lastName,\n avatarUrl: githubUser.avatar_url || undefined,\n };\n\n if (mode === 'link') {\n await handleOAuthProviderLink(req, res, userData);\n } else {\n await handleOAuthUserAuthentication(req, res, userData);\n }\n } catch (error) {\n console.error('GitHub OAuth error:', error);\n if (mode === 'link') {\n clearOAuthLinkCookie(res);\n }\n res.status(500).json({ error: 'Authentication failed' });\n }\n}\n\nfunction getRouter(): ExpressRouter {\n const githubAuthRouter = Router();\n\n // Middleware to check if GitHub auth is enabled and configured\n const checkGitHubEnabled = (_req: Request, res: Response, next: NextFunction) => {\n const githubEnabled = Boolean(getConfig('_system.user.auth.github.enabled'));\n const githubClientId = String(getConfig('_system.user.auth.github.clientId'));\n const githubClientSecret = String(getConfig('_system.user.auth.github.clientSecret'));\n\n if (!githubEnabled || !githubClientId || !githubClientSecret) {\n res.status(503).json({ error: 'GitHub authentication is not configured' });\n return;\n }\n\n next();\n };\n\n // Initiate OAuth flow\n githubAuthRouter.get(\n '/api/_internal/auth/github',\n checkGitHubEnabled,\n (req: Request, res: Response) => {\n const githubClientId = String(getConfig('_system.user.auth.github.clientId'));\n const redirectUri = getRedirectUri('github');\n const githubScopes = getConfig('_system.user.auth.github.scopes');\n const scopes = githubScopes\n ? String(githubScopes)\n .split(',')\n .map((s) => s.trim())\n .join(' ')\n : 'user:email';\n\n const state = randomBytes(32).toString('hex');\n\n const mode = req.query.mode === 'link' ? 'link' : 'login';\n\n res.cookie('authStateGithub', `${state}:${mode}`, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n maxAge: time.minutes(10), // 10 minutes\n });\n\n const authUrl = new URL('https://github.com/login/oauth/authorize');\n authUrl.searchParams.append('client_id', githubClientId);\n authUrl.searchParams.append('redirect_uri', redirectUri);\n authUrl.searchParams.append('scope', scopes);\n authUrl.searchParams.append('state', state);\n\n res.redirect(authUrl.toString());\n }\n );\n\n // Handle OAuth callback\n githubAuthRouter.get(\n '/api/_internal/auth/github/callback',\n checkGitHubEnabled,\n handleGitHubAuthenticationCallback\n );\n\n return githubAuthRouter;\n}\n\nexport default getRouter;\n","import { Request, Response, NextFunction } from 'express';\nimport { RouteHandler } from './types';\nimport { ModelenceError } from '../error';\nimport { authenticate } from '../auth';\nimport { getMongodbUri } from '../db/client';\nimport type { Context } from '../methods/types';\nimport { startTransaction } from '../telemetry';\n\n// TODO: Use cookies for authentication and automatically add session/user to context if accessing from browser\nexport function createRouteHandler(method: string, path: string, handler: RouteHandler) {\n return async (req: Request, res: Response, next: NextFunction) => {\n const authToken = req.headers['x-modelence-auth-token'];\n let context: Pick<Context, 'session' | 'user'> = { session: null, user: null };\n\n if (typeof authToken === 'string' && getMongodbUri()) {\n try {\n const { session, user } = await authenticate(authToken);\n context = { session, user };\n } catch {\n // If authentication fails, context remains null\n }\n }\n\n const transaction = startTransaction('route', `route:${method.toLowerCase()}:${path}`, {\n method,\n path,\n query: req.query,\n body: req.body,\n params: req.params,\n });\n\n try {\n const response = await handler(\n {\n query: req.query as Record<string, string>,\n body: req.body,\n params: req.params,\n headers: req.headers as Record<string, string>,\n cookies: req.cookies,\n rawBody: Buffer.isBuffer(req.body) ? req.body : undefined,\n req,\n res,\n next,\n },\n context\n );\n\n transaction.end();\n\n // If the handler returns null, we expect it to handle the response itself\n if (response) {\n res.status(response.status || 200);\n\n if (response.redirect) {\n res.redirect(response.redirect);\n }\n\n if (response.headers) {\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n }\n\n res.send(response.data);\n }\n } catch (error) {\n transaction.end('error');\n\n if (error instanceof ModelenceError) {\n res.status(error.status).send(error.message);\n } else {\n console.error(`Error in route handler: ${req.path}`);\n console.error(error);\n res.status(500).send(String(error));\n }\n }\n };\n}\n","/**\n * Security configuration for the application\n *\n * By default, the app is protected against clickjacking by setting\n * `Content-Security-Policy: frame-ancestors 'self'` and `X-Frame-Options: SAMEORIGIN`\n * on all responses, preventing the app from being embedded in iframes on other domains.\n *\n * @example\n * ```typescript\n * import { startApp } from 'modelence/server';\n *\n * // Allow embedding in iframes on specific domains\n * startApp({\n * security: {\n * frameAncestors: ['https://modelence.com', 'https://app.example.com'],\n * },\n * });\n * ```\n */\nexport type SecurityConfig = {\n /**\n * Additional origins allowed to embed this app in an iframe.\n * The app's own origin (`'self'`) is always included automatically.\n *\n * When not set, only same-origin framing is allowed.\n * When set, `X-Frame-Options` is omitted since it cannot express multiple origins.\n */\n frameAncestors?: string[];\n};\n\nlet securityConfig: SecurityConfig = Object.freeze({});\n\nexport function setSecurityConfig(newSecurityConfig: SecurityConfig) {\n securityConfig = Object.freeze(Object.assign({}, securityConfig, newSecurityConfig));\n}\n\nexport function getSecurityConfig() {\n return securityConfig;\n}\n","import { WebsocketServerProvider } from '@/websocket/types';\n\nexport type WebsocketConfig = {\n provider?: WebsocketServerProvider;\n};\n\nlet websocketConfig: WebsocketConfig = Object.freeze({});\n\nexport function setWebsocketConfig(newWebsocketConfig: WebsocketConfig) {\n websocketConfig = Object.freeze(Object.assign({}, websocketConfig, newWebsocketConfig));\n}\n\nexport function getWebsocketConfig() {\n return websocketConfig;\n}\n","import googleAuthRouter from '@/auth/providers/google';\nimport githubAuthRouter from '@/auth/providers/github';\nimport { runMethod } from '@/methods';\nimport { getResponseTypeMap, sanitizeResult } from '@/methods/serialize';\nimport { createRouteHandler } from '@/routes/handler';\nimport { HttpMethod } from '@/server';\nimport { logInfo } from '@/telemetry';\nimport cookieParser from 'cookie-parser';\nimport express, { Request, Response } from 'express';\nimport http from 'http';\nimport z from 'zod';\nimport type { AppServer } from '../types';\nimport { authenticate } from '../auth';\nimport { getUnauthenticatedRoles } from '../auth/role';\nimport { getMongodbUri } from '../db/client';\nimport { ModelenceError } from '../error';\nimport { Module } from './module';\nimport { ConnectionInfo } from '@/methods/types';\nimport { ServerChannel } from '@/websocket/serverChannel';\nimport { getSecurityConfig } from './securityConfig';\nimport { getWebsocketConfig } from './websocketConfig';\nimport { getConfig } from '@/config/server';\n\nfunction getBodyParserMiddleware(config?: {\n json?: boolean | { limit?: string };\n urlencoded?: boolean | { limit?: string; extended?: boolean };\n raw?: boolean | { limit?: string; type?: string | string[] };\n}) {\n const middlewares: express.RequestHandler[] = [];\n\n if (!config) {\n // Default: apply JSON and urlencoded parsing\n middlewares.push(express.json({ limit: '16mb' }));\n middlewares.push(express.urlencoded({ extended: true, limit: '16mb' }));\n return middlewares;\n }\n\n // Handle JSON parsing\n if (config.json !== false) {\n const jsonOptions = typeof config.json === 'object' ? config.json : { limit: '16mb' };\n middlewares.push(express.json(jsonOptions));\n }\n\n // Handle URL-encoded parsing\n if (config.urlencoded !== false) {\n const urlencodedOptions =\n typeof config.urlencoded === 'object' ? config.urlencoded : { extended: true, limit: '16mb' };\n middlewares.push(express.urlencoded(urlencodedOptions));\n }\n\n // Handle raw body parsing\n if (config.raw) {\n const rawOptions = typeof config.raw === 'object' ? config.raw : {};\n const defaultRawOptions = {\n limit: rawOptions.limit || '16mb',\n type: rawOptions.type || '*/*',\n };\n middlewares.push(express.raw(defaultRawOptions));\n }\n\n return middlewares;\n}\n\nfunction registerModuleRoutes(app: express.Application, modules: Module[]) {\n for (const module of modules) {\n for (const route of module.routes) {\n const { path, handlers, body } = route;\n const middlewares = getBodyParserMiddleware(body);\n\n Object.entries(handlers).forEach(([method, handler]) => {\n app[method as HttpMethod](path, ...middlewares, createRouteHandler(method, path, handler));\n });\n }\n }\n}\n\nexport async function startServer(\n server: AppServer,\n {\n combinedModules,\n channels,\n }: {\n combinedModules: Module[];\n channels: ServerChannel[];\n }\n) {\n const app = express();\n\n app.use(cookieParser());\n\n app.use(securityHeadersMiddleware());\n\n // Register module routes first (with per-route body parser config)\n registerModuleRoutes(app, combinedModules);\n\n // Apply global body parsing for remaining routes\n app.use(express.json({ limit: '16mb' }));\n app.use(express.urlencoded({ extended: true, limit: '16mb' }));\n\n app.use(googleAuthRouter());\n app.use(githubAuthRouter());\n\n // Set httpOnly cookie for OAuth linking flow\n app.post('/api/_internal/auth/set-link-cookie', async (req: Request, res: Response) => {\n const { session } = await getCallContext(req);\n\n if (!session?.userId) {\n res.status(401).json({ error: 'Not authenticated' });\n return;\n }\n\n res.cookie('oauthLinkToken', session.authToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n path: '/api/_internal/auth/',\n maxAge: 10 * 60 * 1000, // 10 minutes\n });\n\n res.json({ ok: true });\n });\n\n app.post('/api/_internal/method/:methodName(*)', async (req: Request, res: Response) => {\n const { methodName } = req.params;\n const context = await getCallContext(req);\n\n try {\n const result = sanitizeResult(await runMethod(methodName, req.body.args, context));\n res.json({\n data: result,\n typeMap: getResponseTypeMap(result),\n });\n } catch (error) {\n handleMethodError(res, methodName, error);\n }\n });\n\n const httpServer = http.createServer(app);\n\n await server.init({ httpServer });\n\n if (server.middlewares) {\n app.use(server.middlewares());\n }\n\n app.all('*', (req: Request, res: Response) => {\n return server.handler(req, res);\n });\n\n process.on('unhandledRejection', (reason, promise) => {\n console.error('Unhandled Promise Rejection:');\n console.error(reason instanceof Error ? reason.stack : reason);\n console.error('Promise:', promise);\n });\n\n // Global uncaught exceptions\n process.on('uncaughtException', (error) => {\n console.error('Uncaught Exception:');\n console.error(error.stack); // This gives you the full stack trace\n console.trace('Full application stack:'); // Additional context\n });\n\n const websocketProvider = getWebsocketConfig()?.provider;\n if (websocketProvider) {\n websocketProvider.init({\n httpServer,\n channels,\n });\n }\n\n const port = process.env.MODELENCE_PORT || process.env.PORT || 3000;\n httpServer.listen(port, () => {\n logInfo(`Application started`, { source: 'app' });\n const siteUrl = getConfig('_system.site.url') || `http://localhost:${port}`;\n console.log(`\\nApplication started on ${siteUrl}\\n`);\n });\n}\n\nexport async function getCallContext(req: Request) {\n const path = (req.path ?? req.url ?? '').split('?')[0];\n\n const isOAuthCallback = path.startsWith('/api/_internal/auth/') && path.endsWith('/callback');\n\n const authToken = z\n .string()\n .nullish()\n .transform((val) => val ?? null)\n .parse(\n req.cookies.authToken ||\n (isOAuthCallback ? req.cookies.oauthLinkToken : null) ||\n req.body.authToken\n );\n\n const clientInfo = z\n .object({\n screenWidth: z.number(),\n screenHeight: z.number(),\n windowWidth: z.number(),\n windowHeight: z.number(),\n pixelRatio: z.number(),\n orientation: z.string().nullable(),\n })\n .nullish()\n .parse(req.body.clientInfo) ?? {\n screenWidth: 0,\n screenHeight: 0,\n windowWidth: 0,\n windowHeight: 0,\n pixelRatio: 1,\n orientation: null,\n };\n\n const connectionInfo: ConnectionInfo = {\n ip: getClientIp(req),\n userAgent: req.get('user-agent'),\n acceptLanguage: req.get('accept-language'),\n referrer: req.get('referrer'),\n baseUrl: req.protocol + '://' + req.get('host'),\n };\n\n const hasDatabase = Boolean(getMongodbUri());\n if (hasDatabase) {\n const { session, user, roles } = await authenticate(authToken);\n return {\n clientInfo,\n connectionInfo,\n session,\n user,\n roles,\n };\n }\n\n return {\n clientInfo,\n connectionInfo,\n session: null,\n user: null,\n roles: getUnauthenticatedRoles(),\n };\n}\n\nfunction handleMethodError(res: Response, methodName: string, error: unknown) {\n // TODO: add an option to silence these error console logs, especially when Elastic logs are configured\n\n if (error instanceof ModelenceError) {\n if (error.status >= 500 && error.status < 600) {\n console.error(`Error calling ${methodName}:`, error);\n }\n res.status(error.status).send(error.message);\n return;\n }\n\n if (error instanceof Error && error?.constructor?.name === 'ZodError' && 'errors' in error) {\n let errorMessage = '';\n try {\n errorMessage = parseZodError(error as z.ZodError);\n } catch (parsingError) {\n console.error(`Error parsing Zod error in ${methodName}:`, parsingError);\n errorMessage = 'Validation failed';\n }\n res.status(400).send(errorMessage);\n return;\n }\n\n console.error(`Error calling ${methodName}:`, error);\n res.status(500).send(error instanceof Error ? error.message : String(error));\n}\n\nfunction parseZodError(zodError: z.ZodError): string {\n const flattened = zodError.flatten();\n const fieldMessages = Object.entries(flattened.fieldErrors).map(\n ([key, errors]) => `${key}: ${(errors ?? []).join(', ')}`\n );\n const formMessages = flattened.formErrors;\n const allMessages = [...fieldMessages, ...formMessages].filter(Boolean);\n return allMessages.join('; ');\n}\n\nfunction securityHeadersMiddleware(): express.RequestHandler {\n const { frameAncestors } = getSecurityConfig();\n const hasCustomAncestors = frameAncestors && frameAncestors.length > 0;\n const ancestors = hasCustomAncestors ? [\"'self'\", ...frameAncestors].join(' ') : \"'self'\";\n\n return (_req, res, next) => {\n res.setHeader('Content-Security-Policy', `frame-ancestors ${ancestors}`);\n // X-Frame-Options only supports DENY and SAMEORIGIN (ALLOW-FROM is deprecated).\n // When custom ancestors are configured, only CSP frame-ancestors can express that,\n // so we omit X-Frame-Options to avoid conflicting with the CSP directive.\n if (!hasCustomAncestors) {\n res.setHeader('X-Frame-Options', 'SAMEORIGIN');\n }\n next();\n };\n}\n\nfunction getClientIp(req: Request): string | undefined {\n // On Heroku and other proxies, X-Forwarded-For contains the real client IP\n const forwardedFor = req.headers['x-forwarded-for'];\n if (forwardedFor) {\n const firstIp = Array.isArray(forwardedFor) ? forwardedFor[0] : forwardedFor.split(',')[0];\n return firstIp.trim();\n }\n\n const directIp = req.ip || req.socket?.remoteAddress;\n if (directIp) {\n // Remove IPv6-to-IPv4 mapping prefix\n return directIp.startsWith('::ffff:') ? directIp.substring(7) : directIp;\n }\n\n return undefined;\n}\n","import dotenv from 'dotenv';\nimport fs from 'fs/promises';\nimport os from 'os';\nimport path from 'path';\n\nimport type { AppServer, ModelSchema } from '../types';\nimport socketioServer from '@/websocket/socketio/server';\nimport { initRoles } from '../auth/role';\nimport sessionModule from '../auth/session';\nimport { RoleDefinition } from '../auth/types';\nimport userModule from '../auth/user';\nimport { getLocalConfigs } from '../config/local';\nimport { loadConfigs, setSchema } from '../config/server';\nimport { startConfigSync, loadRemoteConfigs } from '../config/sync';\nimport { ConfigSchema } from '../config/types';\nimport cronModule, { defineCronJob, getCronJobsMetadata, startCronJobs } from '../cron/jobs';\nimport { type IndexReconcileMode, Store } from '../data/store';\nimport { resolveStores } from '../data/resolveStores';\nimport { connect, getClient, getMongodbUri } from '../db/client';\nimport { _createSystemMutation, _createSystemQuery, createMutation, createQuery } from '../methods';\nimport {\n MigrationScript,\n default as migrationModule,\n runMigrations,\n startMigrations,\n} from '../migration';\nimport rateLimitModule from '../rate-limit';\nimport { initRateLimits } from '../rate-limit/rules';\nimport systemModule from '../system';\nimport lockModule, { acquireLock, releaseLock } from '../lock';\nimport filesModule from '../files';\nimport { viteServer } from '../viteServer';\nimport { connectCloudBackend } from './backendApi';\nimport { initMetrics } from './metrics';\nimport { Module } from './module';\nimport { startServer } from './server';\nimport { markAppStarted, setMetadata } from './state';\nimport { time } from '@/time';\nimport { EmailConfig, setEmailConfig } from './emailConfig';\nimport { AuthConfig, setAuthConfig } from './authConfig';\nimport { SecurityConfig, setSecurityConfig } from './securityConfig';\nimport { WebsocketConfig, setWebsocketConfig } from './websocketConfig';\n\nexport type AppOptions = {\n modules?: Module[];\n server?: AppServer;\n email?: EmailConfig;\n auth?: AuthConfig;\n /** Security settings such as clickjacking protection. See {@link SecurityConfig}. */\n security?: SecurityConfig;\n /**\n * Custom role definitions keyed by role name. Defined roles are synced to the\n * Modelence Cloud dashboard for user management. See {@link RoleDefinition}.\n *\n * @example\n * ```typescript\n * startApp({\n * roles: {\n * admin: { description: 'Full access to all features' },\n * editor: { description: 'Can edit content' },\n * viewer: {},\n * },\n * });\n * ```\n */\n roles?: Record<string, RoleDefinition>;\n /** @internal */\n defaultRoles?: Record<string, string>;\n migrations?: Array<MigrationScript>;\n websocket?: WebsocketConfig;\n};\n\nexport async function startApp({\n modules = [],\n roles = {},\n defaultRoles = {},\n server = viteServer,\n migrations = [],\n email = {},\n auth = {},\n security = {},\n websocket = {},\n}: AppOptions) {\n dotenv.config();\n\n dotenv.config({ path: '.modelence.env' });\n\n const hasRemoteBackend = Boolean(process.env.MODELENCE_SERVICE_ENDPOINT);\n\n trackAppStart()\n .then(() => {\n // Do nothing\n })\n .catch(() => {\n // Silently ignore tracking errors to not disrupt app startup\n });\n\n // TODO: verify that user modules don't start with `_system.` prefix\n const systemModules = [\n userModule,\n sessionModule,\n cronModule,\n migrationModule,\n rateLimitModule,\n systemModule,\n lockModule,\n filesModule,\n ];\n const combinedModules = [...systemModules, ...modules];\n\n markAppStarted();\n\n initSystemMethods(systemModules);\n initCustomMethods(modules);\n\n initRoles(roles, defaultRoles);\n\n const configSchema = getConfigSchema(combinedModules);\n setSchema(configSchema);\n const rawStores = getStores(combinedModules) as Store<ModelSchema, never>[];\n const channels = getChannels(combinedModules);\n\n defineCronJobs(combinedModules);\n\n const rateLimits = getRateLimits(combinedModules);\n initRateLimits(rateLimits);\n\n const { storesToInit, effectiveStores } = resolveStores(rawStores) as {\n storesToInit: Store<ModelSchema, never>[];\n effectiveStores: Store<ModelSchema, never>[];\n };\n\n if (hasRemoteBackend) {\n const { configs, environmentId, appAlias, environmentAlias, telemetry } =\n await connectCloudBackend({\n configSchema,\n cronJobsMetadata: getCronJobsMetadata(),\n stores: effectiveStores,\n roles,\n });\n loadRemoteConfigs(configs);\n setMetadata({ environmentId, appAlias, environmentAlias, telemetry });\n } else {\n loadConfigs(getLocalConfigs(configSchema));\n }\n\n setEmailConfig(email);\n setAuthConfig(auth);\n setSecurityConfig(security);\n setWebsocketConfig({\n ...websocket,\n provider: websocket.provider || socketioServer,\n });\n\n const mongodbUri = getMongodbUri();\n if (mongodbUri) {\n await connect();\n const allStoresToInit = [...new Set([...storesToInit, ...effectiveStores])];\n initStores(allStoresToInit);\n await createIndexesAndMigrationsWithLock(effectiveStores, migrations);\n } else {\n startMigrations(migrations);\n }\n\n if (hasRemoteBackend) {\n await initMetrics();\n startConfigSync();\n }\n\n startCronJobs().catch(console.error);\n\n await startServer(server, { combinedModules, channels });\n}\n\nfunction initCustomMethods(modules: Module[]) {\n for (const module of modules) {\n for (const [key, handler] of Object.entries(module.queries)) {\n createQuery(`${module.name}.${key}`, handler);\n }\n for (const [key, handler] of Object.entries(module.mutations)) {\n createMutation(`${module.name}.${key}`, handler);\n }\n }\n}\n\nfunction initSystemMethods(modules: Module[]) {\n for (const module of modules) {\n for (const [key, handler] of Object.entries(module.queries)) {\n _createSystemQuery(`${module.name}.${key}`, handler);\n }\n for (const [key, handler] of Object.entries(module.mutations)) {\n _createSystemMutation(`${module.name}.${key}`, handler);\n }\n }\n}\n\nfunction getStores(modules: Module[]) {\n return modules.flatMap((module) => module.stores);\n}\n\nfunction getChannels(modules: Module[]) {\n return modules.flatMap((module) => module.channels);\n}\n\nfunction getRateLimits(modules: Module[]) {\n return modules.flatMap((module) => module.rateLimits);\n}\n\nfunction warnIndexCreationFailure(storeName: string, error: unknown) {\n console.warn(`Failed to create indexes for store '${storeName}'. Continuing startup.`, error);\n}\n\nconst MIGRATIONS_LOCK_RESOURCE = 'migrations';\n\nasync function createIndexesAndMigrationsWithLock(\n effectiveStores: Store<ModelSchema, never>[],\n migrations: MigrationScript[]\n) {\n const hasLock = await acquireLock(MIGRATIONS_LOCK_RESOURCE, {\n lockDuration: time.seconds(30),\n heartbeat: true,\n });\n if (!hasLock) {\n return;\n }\n\n let blockingStores: Store<ModelSchema, never>[];\n let backgroundStores: Store<ModelSchema, never>[];\n\n try {\n blockingStores = effectiveStores.filter((store) => store.getIndexCreationMode() === 'blocking');\n backgroundStores = effectiveStores.filter(\n (store) => store.getIndexCreationMode() === 'background'\n );\n\n for (const store of blockingStores) {\n await createStoreIndexes(store, 'full');\n }\n for (const store of backgroundStores) {\n await createStoreIndexes(store, 'drop-only');\n }\n } catch (error) {\n await releaseLock(MIGRATIONS_LOCK_RESOURCE);\n throw error;\n }\n\n const backgroundIndexCreationPromise = (async () => {\n for (const store of backgroundStores) {\n await createStoreIndexes(store, 'create-only');\n }\n })();\n const migrationPromise = runMigrations(migrations, { lockMode: 'skip' });\n\n void Promise.allSettled([backgroundIndexCreationPromise, migrationPromise])\n .then(([backgroundIndexesResult, migrationResult]) => {\n if (backgroundIndexesResult.status === 'rejected') {\n console.error('Error creating background indexes:', backgroundIndexesResult.reason);\n }\n\n if (migrationResult.status === 'rejected') {\n console.error('Error running migrations:', migrationResult.reason);\n }\n })\n .finally(async () => {\n await releaseLock(MIGRATIONS_LOCK_RESOURCE);\n });\n}\n\nasync function createStoreIndexes(\n store: Store<ModelSchema, never>,\n reconcileMode: IndexReconcileMode = 'full'\n) {\n const storeName = store.getName();\n\n try {\n await store.createIndexes(reconcileMode);\n } catch (error) {\n warnIndexCreationFailure(storeName, error);\n }\n}\n\nfunction getConfigSchema(modules: Module[]): ConfigSchema {\n const merged: ConfigSchema = {};\n\n for (const module of modules) {\n for (const [key, value] of Object.entries(module.configSchema)) {\n const absoluteKey = `${module.name}.${key}`;\n if (absoluteKey in merged) {\n throw new Error(`Duplicate config schema key: ${absoluteKey} (${module.name})`);\n }\n\n merged[absoluteKey] = value;\n }\n }\n\n return merged;\n}\n\nfunction defineCronJobs(modules: Module[]) {\n for (const module of modules) {\n for (const [cronAlias, cronJobParams] of Object.entries(module.cronJobs)) {\n defineCronJob(`${module.name}.${cronAlias}`, cronJobParams);\n }\n }\n}\n\nfunction initStores(stores: Store<ModelSchema, never>[]) {\n const client = getClient();\n if (!client) {\n throw new Error('Failed to initialize stores: MongoDB client not initialized');\n }\n\n for (const store of stores) {\n store.init(client);\n }\n}\n\nasync function trackAppStart() {\n const isTrackingEnabled = process.env.MODELENCE_TRACKING_ENABLED !== 'false';\n\n if (isTrackingEnabled) {\n const serviceEndpoint = process.env.MODELENCE_SERVICE_ENDPOINT ?? 'https://cloud.modelence.com';\n const environmentId = process.env.MODELENCE_ENVIRONMENT_ID;\n\n const appDetails = await getAppDetails();\n const modelencePackageJson = await import('../../package.json');\n\n await fetch(`${serviceEndpoint}/api/track/app-start`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n projectName: appDetails.name,\n version: modelencePackageJson.default.version,\n localHostname: os.hostname(),\n environmentId,\n }),\n });\n }\n}\n\nasync function getAppDetails() {\n try {\n const packageJsonPath = path.join(process.cwd(), 'package.json');\n const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(packageJsonContent);\n\n return {\n name: packageJson.name || 'unknown',\n };\n } catch {\n return {\n name: 'unknown',\n };\n }\n}\n","import { ObjectId } from 'mongodb';\nimport { randomUUID } from 'crypto';\nimport {\n usersCollection,\n emailVerificationTokensCollection,\n resetPasswordTokensCollection,\n} from './db';\n\nexport async function clearTokens(userId: ObjectId) {\n await emailVerificationTokensCollection.deleteMany({\n userId,\n });\n\n await resetPasswordTokensCollection.deleteMany({\n userId,\n });\n}\n\nexport async function disableUser(userId: ObjectId) {\n await clearTokens(userId);\n\n await usersCollection.updateOne(userId, {\n $set: {\n status: 'disabled',\n disabledAt: new Date(),\n },\n });\n}\n\nexport async function deleteUser(userId: ObjectId) {\n await clearTokens(userId);\n\n await usersCollection.updateOne(\n {\n _id: userId,\n },\n {\n $set: {\n handle: `deleted-${userId}-${randomUUID()}`,\n status: 'deleted',\n deletedAt: new Date(),\n authMethods: {},\n emails: [],\n },\n }\n );\n}\n","import { Session, User } from '@/auth/types';\nimport { getWebsocketConfig } from '@/app/websocketConfig';\nimport { logError } from '../telemetry';\n\ntype canAccessChannel = (props: {\n user: User | null;\n session: Session | null;\n roles: string[];\n}) => Promise<boolean>;\n\nexport class ServerChannel<T = unknown> {\n public readonly category: string;\n public readonly canAccessChannel: canAccessChannel | null;\n\n constructor(category: string, canAccessChannel?: canAccessChannel) {\n this.category = category;\n this.canAccessChannel = canAccessChannel || null;\n }\n\n broadcast(id: string, data: T) {\n const websocketProvider = getWebsocketConfig().provider;\n if (!websocketProvider) {\n logError('Websockets provider should be added to startApp', {});\n return;\n }\n\n websocketProvider.broadcast({\n category: this.category,\n id,\n data,\n });\n }\n}\n","import { getEmailConfig } from '@/app/emailConfig';\nimport { EmailPayload } from '../types';\n\nexport function sendEmail(payload: EmailPayload) {\n if (!getEmailConfig().provider) {\n throw new Error(\n 'Email provider is not configured, see https://docs.modelence.com/email for more details.'\n );\n }\n return getEmailConfig().provider?.sendEmail(payload);\n}\n"]}
|