@whanext/core 0.19.2 → 0.19.4
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/CHANGELOG.md +25 -0
- package/MIGRATING_TO_ZAPO.md +1 -1
- package/README.md +2 -0
- package/dist/index.js +145 -64
- package/dist/index.js.map +1 -1
- package/package.json +1 -4
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cache/memory-cache.ts","../src/errors/error.ts","../src/models/identity.ts","../src/models/user.ts","../src/commands/args-parser.ts","../src/commands/command.ts","../src/commands/concurrency.ts","../src/commands/context.ts","../src/commands/load-commands.ts","../src/commands/options.ts","../src/services/user-service.ts","../src/commands/router.ts","../src/logger/logger.ts","../src/mute/mute-service.ts","../src/mute/sqlite-mute-store.ts","../src/provider/event-emitter.ts","../src/services/account-service.ts","../src/services/chat-service.ts","../src/services/group-service.ts","../src/services/media-service.ts","../src/services/member-service.ts","../src/services/message-service.ts","../src/app/whanext-app.ts","../src/auth/browser.ts","../src/provider/zapo/zapo-provider.ts","../src/provider/zapo/normalize-message.ts","../src/app/create.ts","../src/app/multi-app.ts","../src/commands/guards.ts"],"sourcesContent":["import type { CacheStore } from '@/cache/cache-store.js';\n\ninterface CacheEntry {\n value: unknown;\n expiresAt?: number;\n}\n\nexport interface MemoryCacheStats {\n size: number;\n maxEntries: number;\n hits: number;\n misses: number;\n sets: number;\n evictions: number;\n expirations: number;\n}\n\nexport class MemoryCache implements CacheStore {\n readonly #entries = new Map<string, CacheEntry>();\n readonly #maxEntries: number;\n #hits = 0;\n #misses = 0;\n #sets = 0;\n #evictions = 0;\n #expirations = 0;\n\n constructor(options: { maxEntries?: number } = {}) {\n this.#maxEntries = Math.max(1, options.maxEntries ?? 1_000);\n }\n\n async get<T>(key: string): Promise<T | undefined> {\n const entry = this.#entries.get(key);\n\n if (!entry) {\n this.#misses += 1;\n return undefined;\n }\n\n if (entry.expiresAt !== undefined && entry.expiresAt <= Date.now()) {\n this.#entries.delete(key);\n this.#misses += 1;\n this.#expirations += 1;\n return undefined;\n }\n\n this.#hits += 1;\n this.#entries.delete(key);\n this.#entries.set(key, entry);\n return entry.value as T;\n }\n\n async set<T>(key: string, value: T, ttlMs?: number): Promise<void> {\n const entry: CacheEntry = { value };\n\n if (ttlMs !== undefined) {\n entry.expiresAt = Date.now() + ttlMs;\n }\n\n this.#sets += 1;\n this.#entries.delete(key);\n this.#entries.set(key, entry);\n\n while (this.#entries.size > this.#maxEntries) {\n const oldest = this.#entries.keys().next().value as string | undefined;\n if (oldest === undefined) return;\n this.#entries.delete(oldest);\n this.#evictions += 1;\n }\n }\n\n async delete(key: string): Promise<void> {\n this.#entries.delete(key);\n }\n\n async clear(): Promise<void> {\n this.#entries.clear();\n }\n\n prune(now = Date.now()): number {\n let removed = 0;\n\n for (const [key, entry] of this.#entries) {\n if (entry.expiresAt !== undefined && entry.expiresAt <= now) {\n this.#entries.delete(key);\n removed += 1;\n }\n }\n\n this.#expirations += removed;\n return removed;\n }\n\n stats(): Readonly<MemoryCacheStats> {\n return {\n size: this.#entries.size,\n maxEntries: this.#maxEntries,\n hits: this.#hits,\n misses: this.#misses,\n sets: this.#sets,\n evictions: this.#evictions,\n expirations: this.#expirations,\n };\n }\n}\n","export type WhaNextErrorCode =\n | 'AUTH_INVALID_PHONE'\n | 'AUTH_EXPIRED'\n | 'CONNECTION_CLOSED'\n | 'CONNECTION_FAILED'\n | 'GROUP_NOT_FOUND'\n | 'MEMBER_NOT_FOUND'\n | 'BOT_NOT_ADMIN'\n | 'MESSAGE_NOT_FOUND'\n | 'MEDIA_NOT_AVAILABLE'\n | 'MUTE_DISABLED'\n | 'STORAGE_ERROR'\n | 'ARGUMENT_MISSING'\n | 'ARGUMENT_INVALID'\n | 'COMMAND_NOT_ALLOWED'\n | 'COMMAND_COOLDOWN'\n | 'COMMAND_BUSY'\n | 'COMMAND_LOAD_FAILED'\n | 'PROVIDER_ERROR'\n | 'UNKNOWN_ERROR';\n\nexport interface WhaNextErrorOptions {\n cause?: unknown;\n context?: Readonly<Record<string, unknown>>;\n recoverable?: boolean;\n}\n\nexport class WhaNextError extends Error {\n readonly code: WhaNextErrorCode;\n readonly context: Readonly<Record<string, unknown>>;\n readonly recoverable: boolean;\n\n constructor(\n code: WhaNextErrorCode,\n message: string,\n options: WhaNextErrorOptions = {},\n ) {\n super(message, { cause: options.cause });\n this.name = 'WhaNextError';\n this.code = code;\n this.context = options.context ?? {};\n this.recoverable = options.recoverable ?? false;\n }\n}\n\nexport function toWhaNextError(\n error: unknown,\n context?: Readonly<Record<string, unknown>>,\n): WhaNextError {\n if (error instanceof WhaNextError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : 'An unknown error occurred.';\n return new WhaNextError('UNKNOWN_ERROR', message, {\n cause: error,\n ...(context ? { context } : {}),\n });\n}\n","export function normalizeIdentity(identity: string): string {\n const value = identity.trim().toLowerCase();\n const separator = value.lastIndexOf('@');\n\n if (separator === -1) {\n return value.replace(/\\D/g, '');\n }\n\n const user = value.slice(0, separator).replace(/:\\d+$/, '');\n const rawServer = value.slice(separator + 1);\n const server = rawServer === 'c.us' ? 's.whatsapp.net' : rawServer;\n return `${user}@${server}`;\n}\n\nexport function identityUsername(identity: string): string {\n const normalized = normalizeIdentity(identity);\n const separator = normalized.lastIndexOf('@');\n return separator === -1 ? normalized : normalized.slice(0, separator);\n}\n\nexport function identityPhoneNumber(identity: string): string | undefined {\n const normalized = normalizeIdentity(identity);\n\n if (normalized.endsWith('@lid')) {\n return undefined;\n }\n\n const username = identityUsername(normalized);\n return /^\\d+$/.test(username) ? username : undefined;\n}\n\nexport function identitiesMatch(left: string, right: string): boolean {\n return normalizeIdentity(left) === normalizeIdentity(right);\n}\n\nexport function uniqueIdentities(identities: ReadonlyArray<string | null | undefined>): string[] {\n const values = identities.filter((identity): identity is string => Boolean(identity));\n return [...new Map(values.map((identity) => [normalizeIdentity(identity), identity])).values()];\n}\n","import {\n identityPhoneNumber,\n identityUsername,\n identitiesMatch,\n uniqueIdentities,\n} from '@/models/identity.js';\n\nexport interface UserData {\n id: string;\n identities?: readonly string[];\n jid?: string;\n lid?: string;\n phoneNumber?: string;\n name?: string;\n}\n\nexport class User {\n readonly id: string;\n readonly identities: string[];\n readonly jid: string | undefined;\n readonly lid: string | undefined;\n readonly phoneNumber: string | undefined;\n readonly name: string | undefined;\n\n constructor(data: UserData) {\n const identities = uniqueIdentities([\n data.id,\n data.jid,\n data.lid,\n data.phoneNumber,\n ...(data.identities ?? []),\n ]);\n\n this.jid = data.jid ?? identities.find((identity) =>\n identity.endsWith('@s.whatsapp.net') || identity.endsWith('@c.us'));\n this.lid = data.lid ?? identities.find((identity) => identity.endsWith('@lid'));\n this.phoneNumber = data.phoneNumber ?? this.jid;\n this.name = data.name;\n this.id = this.jid ?? this.phoneNumber ?? this.lid ?? data.id;\n this.identities = identities;\n }\n\n get mentionId(): string {\n return this.jid ?? this.phoneNumber ?? this.lid ?? this.id;\n }\n\n get mention(): string {\n return `@${this.username}`;\n }\n\n get phone(): string | undefined {\n return this.phoneNumber ? identityPhoneNumber(this.phoneNumber) : undefined;\n }\n\n get username(): string {\n return identityUsername(this.mentionId);\n }\n\n get displayName(): string {\n return this.name ?? this.mention;\n }\n\n matches(identity: string | User): boolean {\n const candidates = typeof identity === 'string' ? [identity] : identity.identities;\n return this.identities.some((ownIdentity) =>\n candidates.some((candidate) => identitiesMatch(ownIdentity, candidate)));\n }\n\n toJSON(): UserData {\n return {\n id: this.id,\n identities: this.identities,\n ...(this.jid ? { jid: this.jid } : {}),\n ...(this.lid ? { lid: this.lid } : {}),\n ...(this.phoneNumber ? { phoneNumber: this.phoneNumber } : {}),\n ...(this.name ? { name: this.name } : {}),\n };\n }\n\n static fromIdentities(identities: readonly string[]): User {\n const [id] = identities;\n\n if (!id) {\n throw new TypeError('A user requires at least one identity.');\n }\n\n return new User({ id, identities });\n }\n\n static fromPhoneNumber(phoneNumber: string): User {\n const normalized = phoneNumber.replace(/\\D/g, '');\n\n if (normalized.length < 8) {\n throw new TypeError('A user phone number must include country and area codes.');\n }\n\n return User.fromIdentities([`${normalized}@s.whatsapp.net`]);\n }\n}\n","import { WhaNextError } from '@/errors/error.js';\nimport { User } from '@/models/user.js';\n\nexport interface ArgumentOptions {\n optional?: boolean;\n}\n\nexport class ArgsParser {\n readonly #values: string[];\n #cursor = 0;\n\n constructor(values: readonly string[]) {\n this.#values = [...values];\n }\n\n get remaining(): number {\n return this.#values.length - this.#cursor;\n }\n\n peek(): string | undefined {\n return this.#values[this.#cursor];\n }\n\n skip(count = 1): this {\n this.#cursor = Math.min(this.#values.length, this.#cursor + Math.max(0, count));\n return this;\n }\n\n string(name = 'argument', options: ArgumentOptions = {}): string | undefined {\n return this.#consume(name, options);\n }\n\n number(name = 'number', options: ArgumentOptions = {}): number | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n const value = Number(raw);\n\n if (!Number.isFinite(value)) {\n throw new WhaNextError('ARGUMENT_INVALID', `The argument \"${name}\" must be a number.`, {\n context: { name, received: raw },\n });\n }\n\n return value;\n }\n\n boolean(name = 'boolean', options: ArgumentOptions = {}): boolean | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n const normalized = raw.toLowerCase();\n const truthy = new Set(['true', 'on', 'yes', 'sim', '1']);\n const falsy = new Set(['false', 'off', 'no', 'não', 'nao', '0']);\n\n if (truthy.has(normalized)) {\n return true;\n }\n\n if (falsy.has(normalized)) {\n return false;\n }\n\n throw new WhaNextError('ARGUMENT_INVALID', `The argument \"${name}\" must be a boolean.`, {\n context: { name, received: raw },\n });\n }\n\n enum<const Values extends readonly string[]>(\n values: Values,\n name = 'option',\n options: ArgumentOptions = {},\n ): Values[number] | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n if (!values.includes(raw)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The argument \"${name}\" must be one of: ${values.join(', ')}.`,\n {\n context: { name, received: raw, expected: values },\n },\n );\n }\n\n return raw as Values[number];\n }\n\n user(name?: string): User;\n user(name: string, options: { optional: true }): User | undefined;\n user(name = 'user', options: ArgumentOptions = {}): User | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n const normalized = raw.replace(/^@/, '').replace(/\\D/g, '');\n\n if (normalized.length < 8) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The argument \"${name}\" must be a mention or phone number.`,\n {\n context: { name, received: raw },\n },\n );\n }\n\n return User.fromPhoneNumber(normalized);\n }\n\n duration(name = 'duration', options: ArgumentOptions = {}): number | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n const normalized = raw.toLowerCase();\n const permanent = new Set([\n 'forever',\n 'indefinido',\n 'permanent',\n 'permanente',\n 'sempre',\n ]);\n\n if (permanent.has(normalized)) {\n return undefined;\n }\n\n const match = /^(\\d+)(ms|s|m|h|d)$/.exec(normalized);\n\n if (!match) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The argument \"${name}\" must be a duration such as 30s or 5m.`,\n {\n context: { name, received: raw },\n },\n );\n }\n\n const amount = Number(match[1]);\n const unit = match[2] as 'ms' | 's' | 'm' | 'h' | 'd';\n const multiplier = { ms: 1, s: 1_000, m: 60_000, h: 3_600_000, d: 86_400_000 }[unit];\n return amount * multiplier;\n }\n\n rest(): string {\n const value = this.#values.slice(this.#cursor).join(' ');\n this.#cursor = this.#values.length;\n return value;\n }\n\n #consume(name: string, options: ArgumentOptions): string | undefined {\n const value = this.#values[this.#cursor];\n\n if (value === undefined) {\n if (options.optional) {\n return undefined;\n }\n\n throw new WhaNextError('ARGUMENT_MISSING', `The argument \"${name}\" is required.`, {\n context: { name, position: this.#cursor },\n });\n }\n\n this.#cursor += 1;\n return value;\n }\n}\n","import type { ArgsParser } from '@/commands/args-parser.js';\nimport type { CommandContext } from '@/commands/context.js';\nimport type { CommandGuard } from '@/commands/guards.js';\nimport type { CommandOptionSchema } from '@/commands/options.js';\n\nexport type CommandScope = 'global' | 'user' | 'chat' | 'user-chat' | 'user-group';\nexport type ConcurrencyStrategy = 'parallel' | 'reject' | 'queue' | 'replace';\n\nexport interface CommandCooldown {\n durationMs: number;\n scope?: CommandScope;\n}\n\nexport interface CommandConcurrency {\n max?: number;\n scope?: CommandScope;\n strategy?: ConcurrencyStrategy;\n}\n\nexport interface CommandLocalization {\n name?: string;\n aliases?: readonly string[];\n description?: string;\n}\n\nexport type CommandMiddleware = (\n context: CommandContext,\n next: () => Promise<void>,\n) => void | Promise<void>;\n\nexport interface CommandHooks {\n beforeExecute?: (context: CommandContext) => void | Promise<void>;\n afterExecute?: (context: CommandContext) => void | Promise<void>;\n onError?: (context: CommandContext, error: Error) => void | Promise<void>;\n}\n\nexport interface CommandMetadata {\n name: string;\n description: string;\n aliases?: readonly string[];\n prefixless?: boolean | readonly string[];\n category?: string;\n usage?: string;\n examples?: readonly string[];\n hidden?: boolean;\n localizations?: Readonly<Record<string, CommandLocalization>>;\n guards?: readonly CommandGuard[];\n middleware?: readonly CommandMiddleware[];\n cooldown?: CommandCooldown;\n concurrency?: CommandConcurrency;\n hooks?: CommandHooks;\n onlyGroup?: boolean;\n onlyPrivate?: boolean;\n onlyAdmin?: boolean;\n botMustBeAdmin?: boolean;\n onlyOwner?: boolean;\n}\n\nexport interface ExecutableCommandDefinition<\n Schema extends CommandOptionSchema = CommandOptionSchema,\n> extends CommandMetadata {\n options?: Schema;\n execute(\n context: CommandContext<Schema>,\n args: ArgsParser,\n ): void | Promise<void>;\n}\n\nexport interface CommandGroupDefinition extends CommandMetadata {\n subcommands: readonly CommandDefinition[];\n}\n\nexport type CommandDefinition<Schema extends CommandOptionSchema = CommandOptionSchema> =\n | ExecutableCommandDefinition<Schema>\n | CommandGroupDefinition;\n\nexport interface RegisteredCommand {\n definition: ExecutableCommandDefinition;\n root: CommandDefinition;\n path: readonly string[];\n aliases: readonly string[];\n category: string;\n}\n\nexport function defineCommand<const Schema extends CommandOptionSchema = CommandOptionSchema>(\n command: ExecutableCommandDefinition<Schema>,\n): ExecutableCommandDefinition<Schema> {\n return command;\n}\n\nexport function defineSubcommand<const Schema extends CommandOptionSchema = CommandOptionSchema>(\n command: ExecutableCommandDefinition<Schema>,\n): ExecutableCommandDefinition<Schema> {\n return command;\n}\n\nexport function defineCommandGroup<const Group extends CommandGroupDefinition>(group: Group): Group {\n return group;\n}\n\nexport function defineCommands<const Commands extends readonly CommandDefinition[]>(\n ...commands: Commands\n): Commands {\n return commands;\n}\n\nexport function isCommandGroup(\n definition: CommandDefinition,\n): definition is CommandGroupDefinition {\n return 'subcommands' in definition;\n}\n","import type {\n CommandConcurrency,\n ConcurrencyStrategy,\n} from '@/commands/command.js';\nimport { WhaNextError } from '@/errors/error.js';\n\ninterface ExecutionState {\n active: number;\n queue: Array<() => void>;\n controllers: Set<AbortController>;\n}\n\nexport class CommandConcurrencyController {\n readonly #states = new Map<string, ExecutionState>();\n\n async run(\n key: string,\n options: CommandConcurrency | undefined,\n execute: (signal: AbortSignal) => Promise<void>,\n ): Promise<void> {\n const strategy = options?.strategy ?? 'parallel';\n if (strategy === 'parallel') {\n await execute(new AbortController().signal);\n return;\n }\n\n const max = Math.max(1, options?.max ?? 1);\n const state = this.#states.get(key) ?? { active: 0, queue: [], controllers: new Set() };\n this.#states.set(key, state);\n\n if (strategy === 'replace') {\n for (const controller of state.controllers) controller.abort();\n state.controllers.clear();\n } else if (strategy === 'reject' && state.active >= max) {\n throw new WhaNextError('COMMAND_BUSY', 'This command is already running.', {\n context: { key, max },\n recoverable: true,\n });\n } else if (strategy === 'queue' && state.active >= max) {\n await new Promise<void>((resolve) => state.queue.push(resolve));\n }\n\n const controller = new AbortController();\n state.controllers.add(controller);\n state.active += 1;\n\n try {\n await execute(controller.signal);\n } finally {\n state.controllers.delete(controller);\n state.active -= 1;\n state.queue.shift()?.();\n\n if (state.active === 0 && state.queue.length === 0) {\n this.#states.delete(key);\n }\n }\n }\n}\n\nexport function normalizeConcurrencyStrategy(\n strategy: ConcurrencyStrategy | undefined,\n): ConcurrencyStrategy {\n return strategy ?? 'parallel';\n}\n","import type {\n CommandOptionSchema,\n ParsedCommandOptions,\n} from '@/commands/options.js';\nimport type { ArgsParser } from '@/commands/args-parser.js';\nimport type { RegisteredCommand } from '@/commands/command.js';\nimport { WhaNextError } from '@/errors/error.js';\nimport type {\n Message,\n MessageContent,\n SentMessage,\n} from '@/models/message.js';\nimport type { User } from '@/models/user.js';\nimport type { MuteService } from '@/mute/mute-service.js';\nimport type { ChatService } from '@/services/chat-service.js';\nimport type { GroupService } from '@/services/group-service.js';\nimport type { MediaService } from '@/services/media-service.js';\nimport type { MemberService } from '@/services/member-service.js';\nimport type { MessageService } from '@/services/message-service.js';\nimport type { UserService } from '@/services/user-service.js';\n\nexport interface CommandCatalogView {\n readonly prefix: string;\n readonly prefixes: readonly string[];\n readonly size: number;\n catalog(options?: { category?: string; includeHidden?: boolean }): readonly RegisteredCommand[];\n categories(): readonly string[];\n has(path: string): boolean;\n find(path: string): RegisteredCommand | undefined;\n}\n\nexport interface CommandAccountContext {\n readonly id: string | undefined;\n readonly ids: readonly string[];\n isOwner(message: Pick<Message, 'keys' | 'senderIds'>): boolean;\n}\n\nexport interface CommandRuntimeServices {\n account: CommandAccountContext;\n messages: MessageService;\n media: MediaService;\n groups: GroupService;\n members: MemberService;\n chats: ChatService;\n users: UserService;\n mute: MuteService;\n}\n\nexport interface CommandChatContext {\n id: string;\n isGroup: boolean;\n}\n\nexport interface CommandGroupContext {\n id: string;\n metadata(refresh?: boolean): ReturnType<GroupService['metadata']>;\n isUserAdmin(): Promise<boolean>;\n isBotAdmin(): Promise<boolean>;\n}\n\nexport interface ReplyOptions {\n deleteAfterMs?: number;\n}\n\nexport interface CommandContext<Schema extends CommandOptionSchema = CommandOptionSchema>\n extends Message {\n readonly message: Message;\n readonly user: User;\n readonly account: CommandAccountContext;\n readonly isOwner: boolean;\n readonly chat: CommandChatContext;\n readonly group: CommandGroupContext | undefined;\n readonly command: RegisteredCommand;\n readonly commands: CommandCatalogView;\n readonly prefix: string;\n readonly options: ParsedCommandOptions<Schema>;\n readonly args: ArgsParser;\n readonly locale: string | undefined;\n readonly signal: AbortSignal;\n readonly client: CommandRuntimeServices;\n readonly messages: MessageService;\n readonly mediaService: MediaService;\n readonly groups: GroupService;\n readonly members: MemberService;\n readonly chats: ChatService;\n readonly users: UserService;\n readonly muteService: MuteService;\n\n reply(content: string | MessageContent, options?: ReplyOptions): Promise<SentMessage>;\n defer(content?: string | MessageContent): Promise<DeferredReply>;\n edit(content: string): Promise<SentMessage>;\n react(emoji: string): Promise<SentMessage>;\n unreact(): Promise<SentMessage>;\n delete(): Promise<void>;\n deleteReply(options?: ReplyOptions): Promise<void>;\n}\n\ninterface CreateCommandContextOptions<Schema extends CommandOptionSchema> {\n message: Message;\n command: RegisteredCommand;\n options: ParsedCommandOptions<Schema>;\n args: ArgsParser;\n services: CommandRuntimeServices;\n commands: CommandCatalogView;\n signal: AbortSignal;\n prefix?: string;\n locale?: string;\n}\n\nclass CommandContextImplementation<Schema extends CommandOptionSchema> {\n readonly message: Message;\n readonly user: User;\n readonly account: CommandAccountContext;\n readonly isOwner: boolean;\n readonly chat: CommandChatContext;\n readonly group: CommandGroupContext | undefined;\n readonly command: RegisteredCommand;\n readonly commands: CommandCatalogView;\n readonly prefix: string;\n readonly options: ParsedCommandOptions<Schema>;\n readonly args: ArgsParser;\n readonly locale: string | undefined;\n readonly signal: AbortSignal;\n readonly client: CommandRuntimeServices;\n readonly messages: MessageService;\n readonly mediaService: MediaService;\n readonly groups: GroupService;\n readonly members: MemberService;\n readonly chats: ChatService;\n readonly users: UserService;\n readonly muteService: MuteService;\n #lastReply: SentMessage | undefined;\n\n constructor(options: CreateCommandContextOptions<Schema>) {\n this.message = options.message;\n this.user = options.message.sender;\n this.account = options.services.account;\n this.isOwner = this.account.isOwner(options.message);\n this.chat = { id: options.message.chatId, isGroup: options.message.isGroup };\n this.command = options.command;\n this.commands = options.commands;\n this.prefix = options.prefix ?? options.commands.prefix;\n this.options = options.options;\n this.args = options.args;\n this.locale = options.locale;\n this.signal = options.signal;\n this.client = options.services;\n this.messages = options.services.messages;\n this.mediaService = options.services.media;\n this.groups = options.services.groups;\n this.members = options.services.members;\n this.chats = options.services.chats;\n this.users = options.services.users;\n this.muteService = options.services.mute;\n this.group = options.message.isGroup\n ? this.#createGroupContext(options.message)\n : undefined;\n Object.assign(this, options.message);\n }\n\n async reply(content: string | MessageContent, options: ReplyOptions = {}): Promise<SentMessage> {\n const sent = await this.messages.reply(this.message, normalizeContent(content));\n this.#lastReply = sent;\n this.#scheduleDeletion(sent, options.deleteAfterMs);\n return sent;\n }\n\n async defer(\n content: string | MessageContent = '⏳ _Processando..._',\n ): Promise<DeferredReply> {\n const sent = await this.reply(content);\n return new DeferredReply(this.messages, sent, (message) => {\n this.#lastReply = message;\n });\n }\n\n async edit(content: string): Promise<SentMessage> {\n if (!this.#lastReply) {\n throw new WhaNextError(\n 'MESSAGE_NOT_FOUND',\n 'There is no command reply to edit. Call reply() or defer() first.',\n );\n }\n\n const edited = await this.messages.edit(this.#lastReply, content);\n this.#lastReply = edited;\n return edited;\n }\n\n react(emoji: string): Promise<SentMessage> {\n return this.messages.react(this.message, emoji);\n }\n\n unreact(): Promise<SentMessage> {\n return this.messages.unreact(this.message);\n }\n\n delete(): Promise<void> {\n return this.messages.delete(this.message);\n }\n\n async deleteReply(options: ReplyOptions = {}): Promise<void> {\n if (!this.#lastReply) return;\n\n if (options.deleteAfterMs !== undefined && options.deleteAfterMs > 0) {\n this.#scheduleDeletion(this.#lastReply, options.deleteAfterMs);\n return;\n }\n\n await this.messages.delete(this.#lastReply);\n this.#lastReply = undefined;\n }\n\n #createGroupContext(message: Message): CommandGroupContext {\n return {\n id: message.chatId,\n metadata: (refresh) => this.groups.metadata(message.chatId, refresh),\n isUserAdmin: () => this.groups.isAdmin(message.chatId, message.senderIds),\n isBotAdmin: () => this.groups.isCurrentUserAdmin(message.chatId),\n };\n }\n\n #scheduleDeletion(message: SentMessage, delayMs?: number): void {\n if (delayMs === undefined || delayMs <= 0) return;\n\n const timer = setTimeout(() => {\n void this.messages.delete(message).catch(() => undefined);\n }, delayMs);\n timer.unref?.();\n }\n}\n\nexport class DeferredReply {\n readonly #messages: MessageService;\n #message: SentMessage;\n readonly #onEdit: (message: SentMessage) => void;\n\n constructor(\n messages: MessageService,\n message: SentMessage,\n onEdit: (message: SentMessage) => void,\n ) {\n this.#messages = messages;\n this.#message = message;\n this.#onEdit = onEdit;\n }\n\n async edit(content: string): Promise<SentMessage> {\n this.#message = await this.#messages.edit(this.#message, content);\n this.#onEdit(this.#message);\n return this.#message;\n }\n\n delete(): Promise<void> {\n return this.#messages.delete(this.#message);\n }\n}\n\nexport function createCommandContext<Schema extends CommandOptionSchema>(\n options: CreateCommandContextOptions<Schema>,\n): CommandContext<Schema> {\n return new CommandContextImplementation(options) as unknown as CommandContext<Schema>;\n}\n\nfunction normalizeContent(content: string | MessageContent): MessageContent {\n return typeof content === 'string' ? { text: content } : content;\n}\n","import type { Dirent } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nimport type { CommandDefinition } from '@/commands/command.js';\nimport { WhaNextError } from '@/errors/error.js';\n\nexport interface CommandRegistrar {\n command(definition: CommandDefinition): unknown;\n}\n\nexport interface LoadCommandsOptions {\n extensions?: readonly string[];\n recursive?: boolean;\n}\n\nexport interface LoadCommandsResult {\n loaded: readonly string[];\n skipped: readonly string[];\n commands: readonly LoadedCommand[];\n}\n\nexport interface LoadedCommand {\n name: string;\n filePath: string;\n}\n\nconst DEFAULT_EXTENSIONS = ['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts'] as const;\n\nexport async function loadCommands(\n registrar: CommandRegistrar,\n dirPath: string | URL,\n options: LoadCommandsOptions = {},\n): Promise<LoadCommandsResult> {\n const extensions = options.extensions ?? DEFAULT_EXTENSIONS;\n const recursive = options.recursive ?? true;\n const resolvedDirPath = dirPath instanceof URL ? fileURLToPath(dirPath) : dirPath;\n\n const entries = await readEntries(resolvedDirPath, recursive);\n const loaded: string[] = [];\n const skipped: string[] = [];\n const commands: LoadedCommand[] = [];\n\n for (const filePath of entries) {\n if (isDeclarationFile(filePath) || !extensions.includes(path.extname(filePath))) {\n skipped.push(filePath);\n continue;\n }\n\n const definitions = await importCommands(filePath);\n\n for (const definition of definitions) {\n registrar.command(definition);\n commands.push({ name: definition.name, filePath });\n }\n\n loaded.push(filePath);\n }\n\n return { loaded, skipped, commands };\n}\n\nasync function readEntries(dirPath: string, recursive: boolean): Promise<string[]> {\n let dirents: Dirent[];\n\n try {\n dirents = await readdir(dirPath, { recursive, withFileTypes: true });\n } catch (error) {\n throw new WhaNextError('COMMAND_LOAD_FAILED', `Could not read the commands directory \"${dirPath}\".`, {\n cause: error,\n context: { dirPath },\n });\n }\n\n return dirents\n .filter((dirent) => dirent.isFile())\n .map((dirent) => path.join(dirent.parentPath, dirent.name))\n .sort((left, right) => left.localeCompare(right));\n}\n\nasync function importCommands(filePath: string): Promise<CommandDefinition[]> {\n let module: Record<string, unknown>;\n\n try {\n module = await import(pathToFileURL(filePath).href);\n } catch (error) {\n throw new WhaNextError('COMMAND_LOAD_FAILED', `Could not import the command file \"${filePath}\".`, {\n cause: error,\n context: { filePath },\n });\n }\n\n const definitions: CommandDefinition[] = [];\n const seen = new Set<CommandDefinition>();\n const exports = [\n module.default,\n ...Object.entries(module)\n .filter(([name]) => name !== 'default')\n .map(([, value]) => value),\n ];\n\n for (const value of exports) {\n const candidates = Array.isArray(value) ? value : [value];\n\n for (const candidate of candidates) {\n if (isCommandDefinition(candidate) && !seen.has(candidate)) {\n seen.add(candidate);\n definitions.push(candidate);\n }\n }\n }\n\n if (definitions.length === 0) {\n throw new WhaNextError('COMMAND_LOAD_FAILED', `The file \"${filePath}\" does not export any valid commands.`, {\n context: { filePath },\n });\n }\n\n return definitions;\n}\n\nfunction isCommandDefinition(value: unknown): value is CommandDefinition {\n const candidate = value as Partial<CommandDefinition> & { subcommands?: unknown };\n return (\n typeof value === 'object'\n && value !== null\n && typeof candidate.name === 'string'\n && (\n typeof (candidate as { execute?: unknown }).execute === 'function'\n || Array.isArray(candidate.subcommands)\n )\n );\n}\n\nfunction isDeclarationFile(filePath: string): boolean {\n return /\\.d\\.(?:ts|mts|cts)$/.test(filePath);\n}\n","import { ArgsParser } from '@/commands/args-parser.js';\nimport { WhaNextError } from '@/errors/error.js';\nimport type { Message } from '@/models/message.js';\nimport type { User } from '@/models/user.js';\nimport type { UserService } from '@/services/user-service.js';\n\ninterface BaseOption<TKind extends string> {\n kind: TKind;\n description: string;\n required?: boolean;\n}\n\nexport interface StringOption extends BaseOption<'string'> {\n rest?: boolean;\n minLength?: number;\n maxLength?: number;\n}\n\nexport interface NumberOption extends BaseOption<'number'> {\n min?: number;\n max?: number;\n}\n\nexport interface BooleanOption extends BaseOption<'boolean'> {}\nexport interface UserOption extends BaseOption<'user'> {}\nexport interface DurationOption extends BaseOption<'duration'> {}\n\nexport interface EnumOption<Values extends readonly string[] = readonly string[]>\n extends BaseOption<'enum'> {\n values: Values;\n}\n\nexport type CommandOptionDefinition =\n | StringOption\n | NumberOption\n | BooleanOption\n | UserOption\n | DurationOption\n | EnumOption;\n\nexport type CommandOptionSchema = Readonly<Record<string, CommandOptionDefinition>>;\n\ntype RawOptionValue<Definition extends CommandOptionDefinition> =\n Definition extends StringOption ? string\n : Definition extends NumberOption ? number\n : Definition extends BooleanOption ? boolean\n : Definition extends UserOption ? User\n : Definition extends DurationOption ? number | undefined\n : Definition extends EnumOption<infer Values> ? Values[number]\n : never;\n\nexport type CommandOptionValue<Definition extends CommandOptionDefinition> =\n Definition['required'] extends true\n ? RawOptionValue<Definition>\n : RawOptionValue<Definition> | undefined;\n\nexport type CommandOptionValues<Schema extends CommandOptionSchema> = {\n readonly [Name in keyof Schema]: CommandOptionValue<Schema[Name]>;\n};\n\nexport const option = {\n string<const Definition extends Omit<StringOption, 'kind'>>(definition: Definition) {\n return { kind: 'string' as const, ...definition };\n },\n number<const Definition extends Omit<NumberOption, 'kind'>>(definition: Definition) {\n return { kind: 'number' as const, ...definition };\n },\n boolean<const Definition extends Omit<BooleanOption, 'kind'>>(definition: Definition) {\n return { kind: 'boolean' as const, ...definition };\n },\n user<const Definition extends Omit<UserOption, 'kind'>>(definition: Definition) {\n return { kind: 'user' as const, ...definition };\n },\n duration<const Definition extends Omit<DurationOption, 'kind'>>(definition: Definition) {\n return { kind: 'duration' as const, ...definition };\n },\n enum<\n const Values extends readonly string[],\n const Definition extends Omit<EnumOption<Values>, 'kind' | 'values'>,\n >(values: Values, definition: Definition) {\n return { kind: 'enum' as const, values, ...definition };\n },\n};\n\nexport class ParsedCommandOptions<Schema extends CommandOptionSchema = CommandOptionSchema> {\n readonly #values: CommandOptionValues<Schema>;\n\n constructor(values: CommandOptionValues<Schema>) {\n this.#values = values;\n }\n\n get<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.#values[name];\n }\n\n string<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n number<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n boolean<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n user<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n duration<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n enum<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n toJSON(): CommandOptionValues<Schema> {\n return { ...this.#values };\n }\n}\n\nexport async function parseCommandOptions<Schema extends CommandOptionSchema>(\n schema: Schema | undefined,\n tokens: readonly string[],\n message: Message,\n users: UserService,\n): Promise<ParsedCommandOptions<Schema>> {\n const args = new ArgsParser(tokens);\n const values: Record<string, unknown> = {};\n\n for (const [name, definition] of Object.entries(schema ?? {})) {\n const optional = definition.required !== true;\n\n if (definition.kind === 'user') {\n const hasImplicitUser = message.mentionedUsers.length > 0 || message.quoted?.sender !== undefined;\n if (optional && !hasImplicitUser && args.remaining === 0) {\n values[name] = undefined;\n } else {\n values[name] = await users.resolve(message, args);\n }\n continue;\n }\n\n const argumentOptions = optional ? { optional: true as const } : undefined;\n\n if (definition.kind === 'string') {\n const value = definition.rest ? args.rest() : args.string(name, argumentOptions);\n if (definition.required && !value) {\n throw missing(name);\n }\n if (value !== undefined && definition.minLength !== undefined && value.length < definition.minLength) {\n throw invalid(name, value, `at least ${definition.minLength} characters`);\n }\n if (value !== undefined && definition.maxLength !== undefined && value.length > definition.maxLength) {\n throw invalid(name, value, `at most ${definition.maxLength} characters`);\n }\n values[name] = value || undefined;\n } else if (definition.kind === 'number') {\n const value = args.number(name, argumentOptions);\n if (value !== undefined && definition.min !== undefined && value < definition.min) {\n throw invalid(name, value, `at least ${definition.min}`);\n }\n if (value !== undefined && definition.max !== undefined && value > definition.max) {\n throw invalid(name, value, `at most ${definition.max}`);\n }\n values[name] = value;\n } else if (definition.kind === 'boolean') {\n values[name] = args.boolean(name, argumentOptions);\n } else if (definition.kind === 'duration') {\n values[name] = args.duration(name, argumentOptions);\n } else {\n values[name] = args.enum(definition.values, name, argumentOptions);\n }\n }\n\n if (schema !== undefined && args.remaining > 0) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Too many arguments were provided.', {\n context: { remaining: args.remaining },\n });\n }\n\n return new ParsedCommandOptions(values as CommandOptionValues<Schema>);\n}\n\nfunction missing(name: string): WhaNextError {\n return new WhaNextError('ARGUMENT_MISSING', `The argument \"${name}\" is required.`, {\n context: { name },\n });\n}\n\nfunction invalid(name: string, received: unknown, expected: string): WhaNextError {\n return new WhaNextError('ARGUMENT_INVALID', `The argument \"${name}\" must be ${expected}.`, {\n context: { name, received, expected },\n });\n}\n","import type { ArgsParser } from '@/commands/args-parser.js';\nimport type { Message } from '@/models/message.js';\nimport { User } from '@/models/user.js';\nimport type { GroupService } from '@/services/group-service.js';\n\nexport class UserService {\n readonly #group: GroupService;\n\n constructor(group: GroupService) {\n this.#group = group;\n }\n\n async resolve(message: Message, args: ArgsParser): Promise<User> {\n const mentioned = message.mentionedUsers[0];\n let user: User;\n\n if (mentioned) {\n if (args.peek()?.startsWith('@')) {\n args.skip();\n }\n\n user = mentioned;\n } else if (message.quoted?.sender) {\n user = message.quoted.sender;\n } else {\n user = args.user('membro');\n }\n\n return this.#group.resolveUser(message.chatId, user);\n }\n\n from(identity: string): User {\n if (!identity.includes('@')) {\n return User.fromPhoneNumber(identity);\n }\n\n return User.fromIdentities([identity]);\n }\n}\n","import { ArgsParser } from '@/commands/args-parser.js';\nimport {\n type CommandDefinition,\n type CommandHooks,\n type CommandMiddleware,\n type CommandScope,\n type ExecutableCommandDefinition,\n isCommandGroup,\n type RegisteredCommand,\n} from '@/commands/command.js';\nimport { CommandConcurrencyController } from '@/commands/concurrency.js';\nimport {\n createCommandContext,\n type CommandContext,\n type CommandRuntimeServices,\n} from '@/commands/context.js';\nimport { loadCommands, type LoadCommandsOptions, type LoadCommandsResult } from '@/commands/load-commands.js';\nimport type { CommandGuard, GuardResult } from '@/commands/guards.js';\nimport {\n ParsedCommandOptions,\n parseCommandOptions,\n} from '@/commands/options.js';\nimport {\n WhaNextError,\n toWhaNextError,\n} from '@/errors/error.js';\nimport type { Message, SentMessage } from '@/models/message.js';\nimport type { GroupService } from '@/services/group-service.js';\nimport { UserService } from '@/services/user-service.js';\n\nexport interface RouterOptions {\n prefix?: string | readonly string[];\n onError?: (error: WhaNextError, message: Message) => void | Promise<void>;\n onCommandError?: CommandErrorHandler;\n beforeExecute?: (context: CommandContext) => void | Promise<void>;\n afterExecute?: (context: CommandContext) => void | Promise<void>;\n}\n\nexport interface CommandCatalogOptions {\n category?: string;\n includeHidden?: boolean;\n}\n\nexport interface CommandHelpOptions extends CommandCatalogOptions {\n title?: string;\n}\n\nexport type CommandErrorHandler = (\n context: CommandContext,\n error: WhaNextError,\n) => void | Promise<void>;\n\ninterface ResolvedCommand {\n registered: RegisteredCommand;\n layers: readonly CommandDefinition[];\n tokens: readonly string[];\n locale?: string;\n}\n\ninterface RegisteredRoot {\n definition: CommandDefinition;\n locale?: string;\n}\n\nexport class CommandRouter {\n readonly #roots = new Map<string, RegisteredRoot>();\n readonly #prefixlessRoots = new Map<string, RegisteredRoot>();\n readonly #definitions = new Set<CommandDefinition>();\n #prefix = '!';\n #prefixes: readonly string[] = ['!'];\n #matchingPrefixes: readonly string[] = ['!'];\n readonly #services: CommandRuntimeServices;\n readonly #legacyOnError?: RouterOptions['onError'];\n readonly #globalMiddleware: CommandMiddleware[] = [];\n readonly #errorHandlers: CommandErrorHandler[] = [];\n readonly #cooldowns = new Map<string, number>();\n readonly #concurrency = new CommandConcurrencyController();\n readonly #beforeExecute?: RouterOptions['beforeExecute'];\n readonly #afterExecute?: RouterOptions['afterExecute'];\n #cooldownOperations = 0;\n\n constructor(services: CommandRuntimeServices, options?: RouterOptions);\n constructor(group: GroupService, options?: RouterOptions);\n constructor(\n servicesOrGroup: CommandRuntimeServices | GroupService,\n options: RouterOptions = {},\n ) {\n this.#services = isRuntimeServices(servicesOrGroup)\n ? servicesOrGroup\n : createLegacyServices(servicesOrGroup);\n this.setPrefixes(options.prefix ?? '!');\n this.#legacyOnError = options.onError;\n this.#beforeExecute = options.beforeExecute;\n this.#afterExecute = options.afterExecute;\n if (options.onCommandError) this.#errorHandlers.push(options.onCommandError);\n }\n\n get prefix(): string {\n return this.#prefix;\n }\n\n get prefixes(): readonly string[] {\n return this.#prefixes;\n }\n\n setPrefixes(prefixes: string | readonly string[]): this {\n const normalized = normalizePrefixes(prefixes);\n this.#prefixes = normalized;\n this.#matchingPrefixes = [...normalized].sort((left, right) => right.length - left.length);\n this.#prefix = normalized[0]!;\n return this;\n }\n\n get size(): number {\n return this.catalog({ includeHidden: true }).length;\n }\n\n command(definition: CommandDefinition): this {\n this.#validateTree(definition, []);\n\n for (const name of commandNames(definition)) {\n const normalized = name.value.toLowerCase();\n\n if (this.#roots.has(normalized)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The command \"${normalized}\" is already registered.`,\n );\n }\n\n this.#roots.set(normalized, {\n definition,\n ...(name.locale ? { locale: name.locale } : {}),\n });\n }\n\n for (const name of prefixlessCommandNames(definition)) {\n const normalized = name.value.toLowerCase();\n\n if (this.#prefixlessRoots.has(normalized)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The prefixless command trigger \"${normalized}\" is already registered.`,\n );\n }\n\n this.#prefixlessRoots.set(normalized, {\n definition,\n ...(name.locale ? { locale: name.locale } : {}),\n });\n }\n\n this.#definitions.add(definition);\n return this;\n }\n\n load(dirPath: string | URL, options: LoadCommandsOptions = {}): Promise<LoadCommandsResult> {\n return loadCommands(this, dirPath, options);\n }\n\n use(middleware: CommandMiddleware): this {\n this.#globalMiddleware.push(middleware);\n return this;\n }\n\n onError(handler: CommandErrorHandler): () => void {\n this.#errorHandlers.push(handler);\n return () => {\n const index = this.#errorHandlers.indexOf(handler);\n if (index >= 0) this.#errorHandlers.splice(index, 1);\n };\n }\n\n catalog(options: CommandCatalogOptions = {}): readonly RegisteredCommand[] {\n const commands = [...this.#definitions].flatMap((definition) =>\n flattenCommands(definition));\n return commands.filter((command) => (\n (options.includeHidden || !command.definition.hidden)\n && (!options.category || command.category === options.category)\n ));\n }\n\n categories(): readonly string[] {\n return [...new Set(this.catalog().map((command) => command.category))].sort();\n }\n\n has(path: string): boolean {\n return this.find(path) !== undefined;\n }\n\n values(): readonly RegisteredCommand[] {\n return this.catalog({ includeHidden: true });\n }\n\n find(path: string): RegisteredCommand | undefined {\n const normalized = path.trim().toLowerCase().split(/\\s+/);\n return this.catalog({ includeHidden: true }).find((command) =>\n command.path.join(' ').toLowerCase() === normalized.join(' ')\n || command.aliases.some((alias) => alias.toLowerCase() === normalized.at(-1)));\n }\n\n async help(\n context: CommandContext,\n options: CommandHelpOptions = {},\n ): Promise<SentMessage> {\n const commands = this.catalog(options);\n const title = options.title ?? (options.category\n ? `📚 *${options.category}*`\n : '📚 *Comandos*');\n const lines = commands.map((command) => {\n const usage = command.definition.usage\n ?? `${this.#prefix}${command.path.join(' ')}${formatOptions(command.definition)}`;\n const description = context.locale\n ? command.definition.localizations?.[context.locale]?.description\n ?? command.definition.description\n : command.definition.description;\n return `• *${usage}*\\n ${description}`;\n });\n const text = lines.length > 0\n ? `${title}\\n\\n${lines.join('\\n\\n')}`\n : `${title}\\n\\n_Nenhum comando disponível._`;\n return context.reply(text);\n }\n\n async dispatch(message: Message): Promise<boolean> {\n const text = (message.interactive?.id ?? message.text)?.trim();\n if (!text) return false;\n\n const matchedPrefix = this.#matchPrefix(text);\n const tokens = tokenize(matchedPrefix === undefined ? text : text.slice(matchedPrefix.length));\n const rootName = tokens.shift()?.toLowerCase();\n if (!rootName) return false;\n\n const root = matchedPrefix === undefined\n ? this.#prefixlessRoots.get(rootName)\n : this.#roots.get(rootName);\n if (!root) return false;\n const invocationPrefix = matchedPrefix ?? '';\n\n let resolved: ResolvedCommand;\n\n try {\n resolved = this.#resolve(root, tokens);\n } catch (error) {\n const normalized = toWhaNextError(error, { command: root.definition.name, messageId: message.id });\n const fallbackDefinition: ExecutableCommandDefinition = {\n ...root.definition,\n execute: () => undefined,\n };\n const context = createCommandContext({\n message,\n command: {\n definition: fallbackDefinition,\n root: root.definition,\n path: [root.definition.name],\n aliases: root.definition.aliases ?? [],\n category: root.definition.category ?? 'general',\n },\n options: new ParsedCommandOptions({}),\n args: new ArgsParser(tokens),\n services: this.#services,\n commands: this,\n prefix: invocationPrefix,\n signal: new AbortController().signal,\n ...(root.locale ? { locale: root.locale } : {}),\n });\n if (root.definition.hooks?.onError) {\n await root.definition.hooks.onError(context, normalized);\n return true;\n }\n if (this.#errorHandlers.length > 0) {\n for (const handler of this.#errorHandlers) await handler(context, normalized);\n return true;\n }\n if (this.#legacyOnError) {\n await this.#legacyOnError(normalized, message);\n return true;\n }\n throw normalized;\n }\n\n const legacyArgs = new ArgsParser(resolved.tokens);\n let context: CommandContext | undefined;\n\n try {\n const parsedOptions = await parseCommandOptions(\n resolved.registered.definition.options,\n resolved.tokens,\n message,\n this.#services.users,\n );\n const concurrency = [...resolved.layers]\n .reverse()\n .find((layer) => layer.concurrency)?.concurrency;\n const concurrencyKey = this.#executionKey(\n resolved,\n message,\n concurrency?.scope ?? 'user-chat',\n );\n\n await this.#concurrency.run(\n concurrencyKey,\n concurrency,\n async (signal) => {\n context = createCommandContext({\n message,\n command: resolved.registered,\n options: parsedOptions,\n args: legacyArgs,\n services: this.#services,\n commands: this,\n prefix: invocationPrefix,\n signal,\n ...(resolved.locale ? { locale: resolved.locale } : {}),\n });\n\n await this.#authorize(resolved.layers, context);\n this.#consumeCooldown(resolved, context);\n await this.#execute(resolved, context);\n },\n );\n return true;\n } catch (error) {\n const normalized = toWhaNextError(error, {\n command: resolved.registered.path.join(' '),\n messageId: message.id,\n });\n context ??= createCommandContext({\n message,\n command: resolved.registered,\n options: new ParsedCommandOptions({}),\n args: legacyArgs,\n services: this.#services,\n commands: this,\n prefix: invocationPrefix,\n signal: new AbortController().signal,\n ...(resolved.locale ? { locale: resolved.locale } : {}),\n });\n\n if (await this.#handleError(resolved, context, normalized)) return true;\n throw normalized;\n }\n }\n\n #matchPrefix(text: string): string | undefined {\n return this.#matchingPrefixes.find((prefix) => text.startsWith(prefix));\n }\n\n #resolve(root: RegisteredRoot, inputTokens: readonly string[]): ResolvedCommand {\n const tokens = [...inputTokens];\n const layers: CommandDefinition[] = [root.definition];\n let current = root.definition;\n let locale = root.locale;\n\n while (isCommandGroup(current)) {\n const name = tokens.shift()?.toLowerCase();\n if (!name) {\n throw new WhaNextError('ARGUMENT_MISSING', `Choose a subcommand for \"${current.name}\".`, {\n context: { command: current.name },\n });\n }\n\n const found = findChild(current.subcommands, name);\n if (!found) {\n throw new WhaNextError('ARGUMENT_INVALID', `The subcommand \"${name}\" does not exist.`, {\n context: { command: current.name, subcommand: name },\n });\n }\n\n current = found.definition;\n locale ??= found.locale;\n layers.push(current);\n }\n\n const path = layers.map((definition) => definition.name);\n return {\n registered: {\n definition: current,\n root: root.definition,\n path,\n aliases: current.aliases ?? [],\n category: current.category ?? root.definition.category ?? 'general',\n },\n layers,\n tokens,\n ...(locale ? { locale } : {}),\n };\n }\n\n async #authorize(layers: readonly CommandDefinition[], context: CommandContext): Promise<void> {\n for (const command of layers) {\n await this.#authorizeLegacy(command, context);\n for (const guard of command.guards ?? []) await runGuard(guard, context);\n }\n }\n\n async #authorizeLegacy(command: CommandDefinition, context: CommandContext): Promise<void> {\n if (command.onlyOwner && !context.isOwner) {\n throw new WhaNextError(\n 'COMMAND_NOT_ALLOWED',\n 'This command can only be used by the connected WhatsApp account.',\n );\n }\n if (command.onlyGroup && !context.isGroup) {\n throw new WhaNextError('COMMAND_NOT_ALLOWED', 'This command can only be used in groups.');\n }\n if (command.onlyPrivate && context.isGroup) {\n throw new WhaNextError('COMMAND_NOT_ALLOWED', 'This command can only be used in private chats.');\n }\n if (command.onlyAdmin && !(await this.#services.groups.isAdmin(context.chatId, context.senderIds))) {\n throw new WhaNextError('COMMAND_NOT_ALLOWED', 'This command can only be used by group administrators.');\n }\n if (command.botMustBeAdmin && !(await this.#services.groups.isCurrentUserAdmin(context.chatId))) {\n throw new WhaNextError('BOT_NOT_ADMIN', 'The connected WhatsApp account must be a group administrator.');\n }\n }\n\n async #execute(resolved: ResolvedCommand, context: CommandContext): Promise<void> {\n const hooks = resolved.layers.map((layer) => layer.hooks).filter(Boolean) as CommandHooks[];\n if (this.#beforeExecute) await this.#beforeExecute(context);\n for (const hook of hooks) await hook.beforeExecute?.(context);\n\n const middleware = [\n ...this.#globalMiddleware,\n ...resolved.layers.flatMap((layer) => layer.middleware ?? []),\n ];\n await composeMiddleware(middleware, context, async () => {\n await resolved.registered.definition.execute(context, context.args);\n });\n\n for (const hook of [...hooks].reverse()) await hook.afterExecute?.(context);\n if (this.#afterExecute) await this.#afterExecute(context);\n }\n\n #consumeCooldown(resolved: ResolvedCommand, context: CommandContext): void {\n const config = [...resolved.layers].reverse().find((layer) => layer.cooldown)?.cooldown;\n if (!config || config.durationMs <= 0) return;\n\n const key = this.#executionKey(resolved, context, config.scope ?? 'user');\n const now = Date.now();\n this.#cooldownOperations += 1;\n if (this.#cooldownOperations % 256 === 0) this.#pruneCooldowns(now);\n const expiresAt = this.#cooldowns.get(key) ?? 0;\n\n if (expiresAt > now) {\n throw new WhaNextError('COMMAND_COOLDOWN', 'This command is on cooldown.', {\n context: { retryAfterMs: expiresAt - now, key },\n recoverable: true,\n });\n }\n\n this.#cooldowns.set(key, now + config.durationMs);\n }\n\n #pruneCooldowns(now: number): void {\n for (const [key, expiresAt] of this.#cooldowns) {\n if (expiresAt <= now) this.#cooldowns.delete(key);\n }\n }\n\n #executionKey(\n resolved: ResolvedCommand,\n message: Pick<Message, 'chatId' | 'senderId' | 'isGroup'>,\n scope: CommandScope,\n ): string {\n const command = resolved.registered.path.join('/').toLowerCase();\n if (scope === 'global') return command;\n if (scope === 'user') return `${command}:user:${message.senderId}`;\n if (scope === 'chat') return `${command}:chat:${message.chatId}`;\n return `${command}:user-chat:${message.senderId}:${message.chatId}`;\n }\n\n async #handleError(\n resolved: ResolvedCommand,\n context: CommandContext,\n error: WhaNextError,\n ): Promise<boolean> {\n for (const layer of [...resolved.layers].reverse()) {\n if (layer.hooks?.onError) {\n await layer.hooks.onError(context, error);\n return true;\n }\n }\n\n if (this.#errorHandlers.length > 0) {\n for (const handler of this.#errorHandlers) await handler(context, error);\n return true;\n }\n\n if (this.#legacyOnError) {\n await this.#legacyOnError(error, context.message);\n return true;\n }\n\n return false;\n }\n\n #validateTree(definition: CommandDefinition, parents: readonly string[]): void {\n if (!definition.name.trim() || /\\s/.test(definition.name)) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Command names cannot be empty or contain whitespace.', {\n context: { name: definition.name },\n });\n }\n\n for (const name of commandNames(definition)) {\n if (!name.value.trim() || /\\s/.test(name.value)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Command names and aliases cannot be empty or contain whitespace.',\n { context: { name: name.value } },\n );\n }\n }\n\n if (definition.prefixless && parents.length > 0) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Prefixless triggers are only supported on root commands and command groups.',\n { context: { command: definition.name } },\n );\n }\n\n if (Array.isArray(definition.prefixless)) {\n const available = new Set(commandNames(definition).map((name) => name.value.toLowerCase()));\n for (const trigger of definition.prefixless) {\n const normalized = trigger.trim().toLowerCase();\n if (!normalized || /\\s/.test(trigger) || !available.has(normalized)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Every prefixless trigger must match the command name or one of its aliases.',\n { context: { command: definition.name, trigger } },\n );\n }\n }\n }\n\n if (!isCommandGroup(definition)) return;\n if (definition.subcommands.length === 0) {\n throw new WhaNextError('ARGUMENT_INVALID', `The command group \"${definition.name}\" is empty.`);\n }\n\n const names = new Set<string>();\n for (const child of definition.subcommands) {\n for (const name of commandNames(child)) {\n const normalized = name.value.toLowerCase();\n if (names.has(normalized)) {\n throw new WhaNextError('ARGUMENT_INVALID', `Duplicate subcommand \"${normalized}\".`, {\n context: { path: [...parents, definition.name].join(' ') },\n });\n }\n names.add(normalized);\n }\n this.#validateTree(child, [...parents, definition.name]);\n }\n }\n}\n\nasync function runGuard(guard: CommandGuard, context: CommandContext): Promise<void> {\n const result = await guard(context);\n if (result === undefined || result === true) return;\n\n const normalized: GuardResult = result === false ? { allowed: false } : result;\n if (normalized.allowed) return;\n throw new WhaNextError(\n normalized.code ?? 'COMMAND_NOT_ALLOWED',\n normalized.message ?? 'This command is not allowed in the current context.',\n );\n}\n\nasync function composeMiddleware(\n middleware: readonly CommandMiddleware[],\n context: CommandContext,\n execute: () => Promise<void>,\n): Promise<void> {\n let index = -1;\n const dispatch = async (position: number): Promise<void> => {\n if (position <= index) throw new Error('next() was called more than once.');\n index = position;\n const current = middleware[position];\n if (!current) return execute();\n await current(context, () => dispatch(position + 1));\n };\n await dispatch(0);\n}\n\nfunction normalizePrefixes(input: string | readonly string[]): readonly string[] {\n const values = typeof input === 'string' ? [input] : [...input];\n const prefixes = [...new Set(values)];\n\n if (prefixes.length === 0) {\n throw new WhaNextError('ARGUMENT_INVALID', 'At least one command prefix is required.');\n }\n\n for (const prefix of prefixes) {\n if (prefix.length === 0 || /\\s/.test(prefix)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Command prefixes cannot be empty or contain whitespace.',\n { context: { prefix } },\n );\n }\n }\n\n return prefixes;\n}\n\nfunction prefixlessCommandNames(\n definition: CommandDefinition,\n): Array<{ value: string; locale?: string }> {\n if (!definition.prefixless) return [];\n\n const names = commandNames(definition);\n if (definition.prefixless === true) return names;\n\n const enabled = new Set(definition.prefixless.map((name) => name.toLowerCase()));\n return names.filter((name) => enabled.has(name.value.toLowerCase()));\n}\n\nfunction commandNames(definition: CommandDefinition): Array<{ value: string; locale?: string }> {\n const names: Array<{ value: string; locale?: string }> = [\n definition.name,\n ...(definition.aliases ?? []),\n ].map((value) => ({ value }));\n for (const [locale, localization] of Object.entries(definition.localizations ?? {})) {\n if (localization.name) names.push({ value: localization.name, locale });\n for (const alias of localization.aliases ?? []) names.push({ value: alias, locale });\n }\n return names;\n}\n\nfunction findChild(\n definitions: readonly CommandDefinition[],\n name: string,\n): { definition: CommandDefinition; locale?: string } | undefined {\n for (const definition of definitions) {\n const found = commandNames(definition).find((candidate) => candidate.value.toLowerCase() === name);\n if (found) return { definition, ...(found.locale ? { locale: found.locale } : {}) };\n }\n return undefined;\n}\n\nfunction flattenCommands(\n root: CommandDefinition,\n parents: readonly CommandDefinition[] = [],\n): RegisteredCommand[] {\n if (isCommandGroup(root)) {\n return root.subcommands.flatMap((child) => flattenCommands(child, [...parents, root]));\n }\n\n const pathDefinitions = [...parents, root];\n return [{\n definition: root,\n root: pathDefinitions[0] ?? root,\n path: pathDefinitions.map((definition) => definition.name),\n aliases: root.aliases ?? [],\n category: root.category\n ?? [...parents].reverse().find((parent) => parent.category)?.category\n ?? 'general',\n }];\n}\n\nfunction formatOptions(definition: ExecutableCommandDefinition): string {\n return Object.entries(definition.options ?? {}).map(([name, option]) =>\n option.required ? ` <${name}>` : ` [${name}]`).join('');\n}\n\nfunction tokenize(input: string): string[] {\n return input\n .match(/(?:[^\\s\"']+|\"[^\"]*\"|'[^']*')+/g)\n ?.map((token) => token.replace(/^([\"'])(.*)\\1$/, '$2'))\n ?? [];\n}\n\nfunction isRuntimeServices(value: CommandRuntimeServices | GroupService): value is CommandRuntimeServices {\n return 'groups' in value && 'messages' in value;\n}\n\nfunction createLegacyServices(group: GroupService): CommandRuntimeServices {\n const unavailable = new Proxy({}, {\n get() {\n return () => {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'This CommandRouter was created without the full application services.',\n );\n };\n },\n });\n return {\n account: {\n id: undefined,\n get ids() {\n return [];\n },\n isOwner(message) {\n return message.keys.fromMe;\n },\n },\n groups: group,\n users: new UserService(group),\n messages: unavailable as CommandRuntimeServices['messages'],\n media: unavailable as CommandRuntimeServices['media'],\n members: unavailable as CommandRuntimeServices['members'],\n chats: unavailable as CommandRuntimeServices['chats'],\n mute: unavailable as CommandRuntimeServices['mute'],\n };\n}\n","import { WhaNextError } from '@/errors/error.js';\n\nexport type LogLevel = \n | 'debug'\n | 'info'\n | 'warn'\n | 'error'\n | 'silent';\n \nexport type LogFormat = \n | 'pretty'\n | 'json';\n \nexport type LogContext = Readonly<Record<string, unknown>>;\n\nexport interface LogEntry {\n timestamp: string;\n level: Exclude<LogLevel, 'silent'>;\n scope: string;\n message: string;\n context: LogContext;\n}\n\nexport type LogWriter = (entry: LogEntry) => unknown;\n\nexport interface LoggerOptions {\n level?: LogLevel;\n format?: LogFormat;\n writer?: LogWriter;\n scope?: string;\n redact?: readonly string[];\n}\n\nexport type LoggerConfig = LogLevel | LoggerOptions;\n\nconst priorities: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n silent: Number.POSITIVE_INFINITY,\n};\n\nconst defaultRedactions = [\n 'auth',\n 'pairingcode',\n 'password',\n 'phone',\n 'secret',\n 'session',\n 'token',\n];\n\ninterface LoggerState {\n level: LogLevel;\n}\n\nexport class Logger {\n #state: LoggerState;\n readonly #scope: string;\n readonly #writer: LogWriter;\n readonly #redactions: Set<string>;\n\n constructor(config: LoggerConfig = 'info') {\n const options = typeof config === 'string' ? { level: config } : config;\n const level = options.level ?? 'info';\n assertLevel(level);\n\n if (options.writer !== undefined && typeof options.writer !== 'function') {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Logger writer must be a function.',\n );\n }\n\n if (options.format !== undefined && !['pretty', 'json'].includes(options.format)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Logger format must be \"pretty\" or \"json\".',\n { context: { format: options.format } },\n );\n }\n\n this.#state = { level };\n this.#scope = options.scope ?? 'whanext';\n this.#redactions = new Set(\n [...defaultRedactions, ...(options.redact ?? [])]\n .map((key) => key.toLowerCase()),\n );\n this.#writer = options.writer ?? consoleWriter(options.format ?? 'pretty');\n }\n\n get level(): LogLevel {\n return this.#state.level;\n }\n\n setLevel(level: LogLevel): this {\n assertLevel(level);\n this.#state.level = level;\n return this;\n }\n\n isEnabled(level: Exclude<LogLevel, 'silent'>): boolean {\n return priorities[level] >= priorities[this.#state.level];\n }\n\n child(scope: string): Logger {\n const childScope = this.#scope ? `${this.#scope}:${scope}` : scope;\n const child = new Logger({\n level: this.#state.level,\n scope: childScope,\n writer: this.#writer,\n redact: [...this.#redactions],\n });\n child.#state = this.#state;\n return child;\n }\n\n debug(message: string, context: LogContext = {}): void {\n this.#write('debug', message, context);\n }\n\n info(message: string, context: LogContext = {}): void {\n this.#write('info', message, context);\n }\n\n warn(message: string, context: LogContext = {}): void {\n this.#write('warn', message, context);\n }\n\n error(message: string, context: LogContext = {}): void {\n this.#write('error', message, context);\n }\n\n #write(\n level: Exclude<LogLevel, 'silent'>,\n message: string,\n context: LogContext,\n ): void {\n if (!this.isEnabled(level)) {\n return;\n }\n\n try {\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level,\n scope: this.#scope,\n message,\n context: normalizeContext(context, this.#redactions),\n };\n const result = this.#writer(entry);\n\n if (result instanceof Promise) {\n void result.catch(() => undefined);\n }\n } catch {\n return;\n }\n }\n}\n\nfunction assertLevel(level: LogLevel): void {\n if (!(level in priorities)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Logger level must be debug, info, warn, error or silent.',\n { context: { level } },\n );\n }\n}\n\nfunction consoleWriter(format: LogFormat): LogWriter {\n return (entry) => {\n const method = entry.level === 'debug'\n ? console.debug\n : entry.level === 'info'\n ? console.info\n : entry.level === 'warn'\n ? console.warn\n : console.error;\n\n if (format === 'json') {\n method(JSON.stringify(entry));\n return;\n }\n\n const details = Object.keys(entry.context).length > 0\n ? ` ${JSON.stringify(entry.context)}`\n : '';\n method(\n `[${entry.timestamp}] ${entry.level.toUpperCase()} ${entry.scope} ${entry.message}${details}`,\n );\n };\n}\n\nfunction normalizeContext(\n context: LogContext,\n redactions: ReadonlySet<string>,\n): LogContext {\n const seen = new WeakSet<object>();\n return Object.fromEntries(\n Object.entries(context).map(([key, value]) => [\n key,\n normalizeValue(value, key, redactions, seen),\n ]),\n );\n}\n\nfunction normalizeValue(\n value: unknown,\n key: string,\n redactions: ReadonlySet<string>,\n seen: WeakSet<object>,\n): unknown {\n if (isRedactedKey(key, redactions)) {\n return '[REDACTED]';\n }\n\n if (\n value === null\n || typeof value === 'string'\n || typeof value === 'number'\n || typeof value === 'boolean'\n || value === undefined\n ) {\n return value;\n }\n\n if (typeof value === 'bigint') {\n return value.toString();\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n ...('code' in value ? { code: value.code } : {}),\n };\n }\n\n if (typeof value !== 'object') {\n return String(value);\n }\n\n if (seen.has(value)) {\n return '[Circular]';\n }\n\n seen.add(value);\n\n if (Array.isArray(value)) {\n return value.map((item) =>\n normalizeValue(item, '', redactions, seen));\n }\n\n return Object.fromEntries(\n Object.entries(value).map(([nestedKey, nestedValue]) => [\n nestedKey,\n normalizeValue(nestedValue, nestedKey, redactions, seen),\n ]),\n );\n}\n\nfunction isRedactedKey(\n key: string,\n redactions: ReadonlySet<string>,\n): boolean {\n const normalized = key.toLowerCase();\n return [...redactions].some((redaction) =>\n normalized === redaction\n || normalized.startsWith(redaction)\n || normalized.endsWith(redaction));\n}\n","import { WhaNextError } from '@/errors/error.js';\nimport { normalizeIdentity } from '@/models/identity.js';\nimport type { Message } from '@/models/message.js';\nimport { User } from '@/models/user.js';\nimport type {\n MuteStore,\n StoredMute,\n} from '@/mute/mute-store.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport interface AddMuteOptions {\n durationMs?: number;\n}\n\nexport interface MuteRecord {\n groupId: string;\n user: User;\n createdAt: Date;\n expiresAt: Date | null;\n}\n\nexport type AddMuteResult =\n | {\n ok: true;\n changed: true;\n state: 'muted' | 'updated';\n record: MuteRecord;\n }\n | {\n ok: true;\n changed: false;\n state: 'already_muted';\n record: MuteRecord;\n };\n\nexport type RemoveMuteResult =\n | {\n ok: true;\n changed: true;\n state: 'unmuted';\n }\n | {\n ok: true;\n changed: false;\n state: 'already_unmuted';\n };\n\nexport type MuteChangeResult = AddMuteResult | RemoveMuteResult;\n\nexport interface MuteEnforcement {\n message: Message;\n record: MuteRecord;\n}\n\nexport class MuteService {\n readonly #provider: WhatsAppProvider;\n readonly #store: MuteStore | undefined;\n\n constructor(provider: WhatsAppProvider, store?: MuteStore) {\n this.#provider = provider;\n this.#store = store;\n }\n\n get enabled(): boolean {\n return this.#store !== undefined;\n }\n\n async add(\n groupId: string,\n user: User,\n options: AddMuteOptions = {},\n ): Promise<AddMuteResult> {\n const store = this.#requireStore();\n const now = Date.now();\n\n if (options.durationMs !== undefined && options.durationMs <= 0) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Mute duration must be greater than zero.');\n }\n\n const current = await this.#findActive(groupId, user.identities);\n\n if (current && current.expiresAt === null && options.durationMs === undefined) {\n return {\n ok: true,\n changed: false,\n state: 'already_muted',\n record: this.#record(current),\n };\n }\n\n const stored: StoredMute = {\n key: normalizeIdentity(user.id),\n groupId,\n user: user.toJSON(),\n identities: user.identities,\n createdAt: now,\n expiresAt: options.durationMs === undefined ? null : now + options.durationMs,\n };\n await this.#storage(\n 'upsert',\n () => store.upsert(stored),\n { groupId, userId: user.id },\n );\n return {\n ok: true,\n changed: true,\n state: current ? 'updated' : 'muted',\n record: this.#record(stored),\n };\n }\n\n async remove(groupId: string, user: User): Promise<RemoveMuteResult> {\n const store = this.#requireStore();\n const changed = await this.#storage(\n 'delete',\n () => store.delete(groupId, user.identities),\n { groupId, userId: user.id },\n );\n\n if (changed) {\n return {\n ok: true,\n changed: true,\n state: 'unmuted',\n };\n }\n\n return {\n ok: true,\n changed: false,\n state: 'already_unmuted',\n };\n }\n\n async get(groupId: string, user: User): Promise<MuteRecord | undefined> {\n this.#requireStore();\n const stored = await this.#findActive(groupId, user.identities);\n return stored ? this.#record(stored) : undefined;\n }\n\n async isMuted(groupId: string, user: User): Promise<boolean> {\n return (await this.get(groupId, user)) !== undefined;\n }\n\n async enforce(message: Message): Promise<MuteEnforcement | undefined> {\n if (!this.#store || !message.isGroup || message.keys.fromMe) {\n return undefined;\n }\n\n const stored = await this.#findActive(message.chatId, message.sender.identities);\n\n if (!stored) {\n return undefined;\n }\n\n try {\n await this.#provider.deleteMessage(message.keys);\n } catch (error) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'Could not delete a message sent by a muted member.',\n {\n cause: error,\n context: {\n groupId: message.chatId,\n messageId: message.id,\n userId: message.sender.id,\n },\n recoverable: true,\n },\n );\n }\n\n return {\n message,\n record: this.#record(stored),\n };\n }\n\n async purgeExpired(): Promise<number> {\n const store = this.#requireStore();\n return this.#storage(\n 'purge',\n () => store.purgeExpired(Date.now()),\n );\n }\n\n async close(): Promise<void> {\n if (this.#store?.close) {\n await this.#storage('close', () => this.#store?.close?.());\n }\n }\n\n #record(stored: StoredMute): MuteRecord {\n return {\n groupId: stored.groupId,\n user: new User(stored.user),\n createdAt: new Date(stored.createdAt),\n expiresAt: stored.expiresAt === null ? null : new Date(stored.expiresAt),\n };\n }\n\n async #findActive(\n groupId: string,\n identities: readonly string[],\n ): Promise<StoredMute | undefined> {\n const stored = await this.#storage(\n 'find',\n () => this.#store?.find(groupId, identities),\n { groupId },\n );\n\n if (!stored) {\n return undefined;\n }\n\n if (stored.expiresAt !== null && stored.expiresAt <= Date.now()) {\n await this.#storage(\n 'delete_expired',\n () => this.#store?.delete(groupId, stored.identities),\n { groupId },\n );\n return undefined;\n }\n\n return stored;\n }\n\n #requireStore(): MuteStore {\n if (!this.#store) {\n throw new WhaNextError(\n 'MUTE_DISABLED',\n 'Mute is disabled. Enable it in create({ mute: { enabled: true } }).',\n );\n }\n\n return this.#store;\n }\n\n async #storage<Result>(\n action: string,\n operation: () => Result | Promise<Result>,\n context: Readonly<Record<string, unknown>> = {},\n ): Promise<Result> {\n try {\n return await operation();\n } catch (error) {\n throw new WhaNextError(\n 'STORAGE_ERROR',\n `Mute storage operation \"${action}\" failed.`,\n {\n cause: error,\n context: { action, ...context },\n recoverable: true,\n },\n );\n }\n }\n}\n","import { mkdirSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport {\n dirname,\n resolve,\n} from 'node:path';\nimport type { DatabaseSync as NodeDatabaseSync } from 'node:sqlite';\nimport { WhaNextError } from '@/errors/error.js';\nimport { normalizeIdentity } from '@/models/identity.js';\nimport type {\n MuteStore,\n StoredMute,\n} from '@/mute/mute-store.js';\n\ninterface MuteRow {\n mute_key: string;\n group_id: string;\n user_json: string;\n created_at: number;\n expires_at: number | null;\n}\n\nexport class SqliteMuteStore implements MuteStore {\n readonly #database: NodeDatabaseSync;\n\n constructor(path = './data/whanext.sqlite') {\n const databasePath = path === ':memory:' ? path : resolve(path);\n\n if (databasePath !== ':memory:') {\n mkdirSync(dirname(databasePath), { recursive: true });\n }\n\n let database: NodeDatabaseSync | undefined;\n\n try {\n const require = createRequire(import.meta.url);\n const sqlite = require('node:sqlite') as typeof import('node:sqlite');\n database = new sqlite.DatabaseSync(databasePath);\n database.exec('PRAGMA journal_mode = WAL');\n database.exec('PRAGMA busy_timeout = 5000');\n database.exec(`\n CREATE TABLE IF NOT EXISTS whanext_mutes (\n group_id TEXT NOT NULL,\n identity TEXT NOT NULL,\n mute_key TEXT NOT NULL,\n user_json TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n expires_at INTEGER,\n PRIMARY KEY (group_id, identity)\n ) STRICT;\n CREATE INDEX IF NOT EXISTS whanext_mutes_expiration\n ON whanext_mutes (expires_at);\n CREATE INDEX IF NOT EXISTS whanext_mutes_key\n ON whanext_mutes (group_id, mute_key);\n `);\n } catch (error) {\n database?.close();\n throw new WhaNextError(\n 'STORAGE_ERROR',\n 'Could not initialize the SQLite mute store.',\n {\n cause: error,\n context: { database: databasePath },\n },\n );\n }\n\n this.#database = database;\n }\n\n upsert(mute: StoredMute): void {\n const identities = this.#identities(mute.identities);\n const existingKeys = this.#matchingKeys(mute.groupId, identities);\n\n this.#transaction(() => {\n for (const key of existingKeys) {\n this.#database.prepare(\n 'DELETE FROM whanext_mutes WHERE group_id = ? AND mute_key = ?',\n ).run(mute.groupId, key);\n }\n\n const insert = this.#database.prepare(`\n INSERT OR REPLACE INTO whanext_mutes (\n group_id,\n identity,\n mute_key,\n user_json,\n created_at,\n expires_at\n ) VALUES (?, ?, ?, ?, ?, ?)\n `);\n\n for (const identity of identities) {\n insert.run(\n mute.groupId,\n identity,\n mute.key,\n JSON.stringify(mute.user),\n mute.createdAt,\n mute.expiresAt,\n );\n }\n });\n }\n\n find(groupId: string, identities: readonly string[]): StoredMute | undefined {\n const normalized = this.#identities(identities);\n\n if (normalized.length === 0) {\n return undefined;\n }\n\n const placeholders = normalized.map(() => '?').join(', ');\n const row = this.#database.prepare(`\n SELECT mute_key, group_id, user_json, created_at, expires_at\n FROM whanext_mutes\n WHERE group_id = ? AND identity IN (${placeholders})\n LIMIT 1\n `).get(groupId, ...normalized) as unknown as MuteRow | undefined;\n\n if (!row) {\n return undefined;\n }\n\n if (row.expires_at !== null && row.expires_at <= Date.now()) {\n this.#database.prepare(\n 'DELETE FROM whanext_mutes WHERE group_id = ? AND mute_key = ?',\n ).run(groupId, row.mute_key);\n return undefined;\n }\n\n const identityRows = this.#database.prepare(`\n SELECT identity\n FROM whanext_mutes\n WHERE group_id = ? AND mute_key = ?\n `).all(groupId, row.mute_key) as unknown as Array<{ identity: string }>;\n\n return {\n key: row.mute_key,\n groupId: row.group_id,\n user: JSON.parse(row.user_json) as StoredMute['user'],\n identities: identityRows.map(({ identity }) => identity),\n createdAt: row.created_at,\n expiresAt: row.expires_at,\n };\n }\n\n delete(groupId: string, identities: readonly string[]): boolean {\n const keys = this.#matchingKeys(groupId, this.#identities(identities));\n\n if (keys.length === 0) {\n return false;\n }\n\n this.#transaction(() => {\n const statement = this.#database.prepare(\n 'DELETE FROM whanext_mutes WHERE group_id = ? AND mute_key = ?',\n );\n\n for (const key of keys) {\n statement.run(groupId, key);\n }\n });\n return true;\n }\n\n purgeExpired(now: number): number {\n const result = this.#database.prepare(`\n DELETE FROM whanext_mutes\n WHERE expires_at IS NOT NULL AND expires_at <= ?\n `).run(now);\n return Number(result.changes);\n }\n\n close(): void {\n this.#database.close();\n }\n\n #matchingKeys(groupId: string, identities: readonly string[]): string[] {\n if (identities.length === 0) {\n return [];\n }\n\n const placeholders = identities.map(() => '?').join(', ');\n const rows = this.#database.prepare(`\n SELECT DISTINCT mute_key\n FROM whanext_mutes\n WHERE group_id = ? AND identity IN (${placeholders})\n `).all(groupId, ...identities) as unknown as Array<{ mute_key: string }>;\n return rows.map(({ mute_key }) => mute_key);\n }\n\n #identities(identities: readonly string[]): string[] {\n return [...new Set(identities.map(normalizeIdentity).filter(Boolean))];\n }\n\n #transaction(operation: () => void): void {\n this.#database.exec('BEGIN IMMEDIATE');\n\n try {\n operation();\n this.#database.exec('COMMIT');\n } catch (error) {\n this.#database.exec('ROLLBACK');\n throw error;\n }\n }\n}\n","export class TypedEventEmitter<Events extends object> {\n readonly #listeners = new Map<keyof Events, Set<(payload: never) => void | Promise<void>>>();\n\n on<Event extends keyof Events>(\n event: Event,\n listener: (payload: Events[Event]) => void | Promise<void>,\n ): () => void {\n const listeners = this.#listeners.get(event) ?? new Set();\n listeners.add(listener as (payload: never) => void | Promise<void>);\n this.#listeners.set(event, listeners);\n\n return () => listeners.delete(listener as (payload: never) => void | Promise<void>);\n }\n\n async emit<Event extends keyof Events>(event: Event, payload: Events[Event]): Promise<void> {\n const listeners = this.#listeners.get(event);\n\n if (!listeners) {\n return;\n }\n\n await Promise.all([...listeners].map((listener) => listener(payload as never)));\n }\n}\n","import {\n identitiesMatch,\n identityPhoneNumber,\n normalizeIdentity,\n uniqueIdentities,\n} from '@/models/identity.js';\nimport type { Message } from '@/models/message.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class AccountService {\n readonly id: string | undefined;\n readonly #provider: WhatsAppProvider;\n\n constructor(provider: WhatsAppProvider, id?: string) {\n this.#provider = provider;\n this.id = id;\n }\n\n get ids(): readonly string[] {\n return uniqueIdentities(this.#provider.getCurrentUserIds());\n }\n\n get jid(): string | undefined {\n const identity = this.ids.find((candidate) =>\n candidate.endsWith('@s.whatsapp.net') || candidate.endsWith('@c.us'));\n\n if (identity) {\n return normalizeIdentity(identity);\n }\n\n const phone = this.ids\n .map((candidate) => identityPhoneNumber(candidate))\n .find((candidate): candidate is string => candidate !== undefined);\n\n return phone ? `${phone}@s.whatsapp.net` : undefined;\n }\n\n get lid(): string | undefined {\n const identity = this.ids.find((candidate) => candidate.endsWith('@lid'));\n return identity ? normalizeIdentity(identity) : undefined;\n }\n\n get phoneNumber(): string | undefined {\n const jid = this.jid;\n return jid ? identityPhoneNumber(jid) : undefined;\n }\n\n get selfChatId(): string | undefined {\n return this.jid ?? this.lid ?? this.ids[0];\n }\n\n isOwner(message: Pick<Message, 'keys' | 'senderIds'>): boolean {\n if (message.keys.fromMe) {\n return true;\n }\n\n const currentIds = this.ids;\n return message.senderIds.some((senderId) =>\n currentIds.some((currentId) => identitiesMatch(senderId, currentId)));\n }\n}\n","import type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class ChatService {\n readonly #provider: WhatsAppProvider;\n\n constructor(provider: WhatsAppProvider) {\n this.#provider = provider;\n }\n\n typing(chatId: string): Promise<void> {\n return this.#provider.setPresence(chatId, 'typing');\n }\n\n recording(chatId: string): Promise<void> {\n return this.#provider.setPresence(chatId, 'recording');\n }\n\n stop(chatId: string): Promise<void> {\n return this.#provider.setPresence(chatId, 'paused');\n }\n\n stopTyping(chatId: string): Promise<void> {\n return this.stop(chatId);\n }\n\n rejectCall(callId: string, from: string): Promise<void> {\n return this.#provider.rejectCall(callId, from);\n }\n}\n","import type { CacheStore } from '@/cache/cache-store.js';\nimport type {\n ChangeResult,\n GroupAccess,\n GroupSnapshot,\n InviteResult,\n} from '@/models/group.js';\nimport { identitiesMatch } from '@/models/identity.js';\nimport type { MessageKey } from '@/models/message.js';\nimport { User } from '@/models/user.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class GroupService {\n readonly #provider: WhatsAppProvider;\n readonly #cache: CacheStore;\n readonly #ttlMs: number;\n readonly #requests = new Map<string, Promise<GroupSnapshot>>();\n\n constructor(provider: WhatsAppProvider, cache: CacheStore, ttlMs = 300_000) {\n this.#provider = provider;\n this.#cache = cache;\n this.#ttlMs = ttlMs;\n }\n\n async open(groupId: string): Promise<ChangeResult<'open' | 'already_open'>> {\n const group = await this.metadata(groupId);\n\n if (group.access === 'open') {\n return { ok: true, changed: false, state: 'already_open' };\n }\n\n await this.#provider.setGroupAccess(groupId, 'open');\n await this.invalidate(groupId);\n return { ok: true, changed: true, state: 'open' };\n }\n\n async close(groupId: string): Promise<ChangeResult<'closed' | 'already_closed'>> {\n const group = await this.metadata(groupId);\n\n if (group.access === 'closed') {\n return { ok: true, changed: false, state: 'already_closed' };\n }\n\n await this.#provider.setGroupAccess(groupId, 'closed');\n await this.invalidate(groupId);\n return { ok: true, changed: true, state: 'closed' };\n }\n\n async invite(groupId: string): Promise<InviteResult> {\n const code = await this.#provider.getGroupInviteCode(groupId);\n return { ok: true, code, url: `https://chat.whatsapp.com/${code}` };\n }\n\n async revokeInvite(groupId: string): Promise<InviteResult> {\n const code = await this.#provider.revokeGroupInvite(groupId);\n return { ok: true, code, url: `https://chat.whatsapp.com/${code}` };\n }\n\n async pin(groupId: string, key: MessageKey): Promise<ChangeResult<'pinned'>> {\n await this.#provider.setMessagePin(groupId, key, true);\n return { ok: true, changed: true, state: 'pinned' };\n }\n\n async unpin(groupId: string, key: MessageKey): Promise<ChangeResult<'unpinned'>> {\n await this.#provider.setMessagePin(groupId, key, false);\n return { ok: true, changed: true, state: 'unpinned' };\n }\n\n async metadata(groupId: string, refresh = false): Promise<GroupSnapshot> {\n const key = this.#key(groupId);\n\n if (!refresh) {\n const cached = await this.#cache.get<GroupSnapshot>(key);\n\n if (cached) {\n return cached;\n }\n }\n\n const pending = this.#requests.get(key);\n\n if (pending) {\n return pending;\n }\n\n const request = this.#loadMetadata(key, groupId);\n this.#requests.set(key, request);\n\n try {\n return await request;\n } finally {\n this.#requests.delete(key);\n }\n }\n\n async isAdmin(\n groupId: string,\n memberIds: string | readonly string[],\n ): Promise<boolean> {\n if (!groupId.endsWith('@g.us')) {\n return false;\n }\n\n const group = await this.metadata(groupId);\n const identities = typeof memberIds === 'string' ? [memberIds] : memberIds;\n const participant = group.participants.find((item) =>\n this.#matchesParticipant(item, identities));\n return participant?.role === 'admin' || participant?.role === 'owner';\n }\n\n async isCurrentUserAdmin(groupId: string): Promise<boolean> {\n const ids = this.#provider.getCurrentUserIds();\n\n if (ids.length === 0 || !groupId.endsWith('@g.us')) {\n return false;\n }\n\n const group = await this.metadata(groupId);\n return group.participants.some((participant) =>\n this.#matchesParticipant(participant, ids)\n && (participant.role === 'admin' || participant.role === 'owner'));\n }\n\n async resolveUser(groupId: string, user: User): Promise<User> {\n if (!groupId.endsWith('@g.us')) {\n return user;\n }\n\n const group = await this.metadata(groupId);\n const participant = group.participants.find((item) =>\n this.#matchesParticipant(item, user.identities));\n\n if (!participant) {\n return user;\n }\n\n return new User({\n id: participant.id,\n identities: [\n participant.id,\n ...(participant.lid ? [participant.lid] : []),\n ...(participant.phoneNumber ? [participant.phoneNumber] : []),\n ],\n ...(participant.lid ? { lid: participant.lid } : {}),\n ...(participant.phoneNumber ? {\n jid: participant.phoneNumber,\n phoneNumber: participant.phoneNumber,\n } : {}),\n ...(user.name ? { name: user.name } : {}),\n });\n }\n\n invalidate(groupId: string): Promise<void> {\n return this.#cache.delete(this.#key(groupId));\n }\n\n #key(groupId: string): string {\n return `group:${groupId}`;\n }\n\n async #loadMetadata(key: string, groupId: string): Promise<GroupSnapshot> {\n const group = await this.#provider.getGroup(groupId);\n await this.#cache.set(key, group, this.#ttlMs);\n return group;\n }\n\n #matchesParticipant(\n participant: GroupSnapshot['participants'][number],\n identities: readonly string[],\n ): boolean {\n const participantIds = [participant.id, participant.lid, participant.phoneNumber]\n .filter((identity): identity is string => identity !== undefined);\n return identities.some((identity) =>\n participantIds.some((participantId) =>\n identitiesMatch(identity, participantId)));\n }\n}\n","import type {\n AudioContent,\n DownloadedMedia,\n ImageContent,\n Message,\n MessageKey,\n QuotedMessage,\n SentMessage,\n StickerContent,\n VideoContent,\n} from '@/models/message.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class MediaService {\n readonly #provider: WhatsAppProvider;\n\n constructor(provider: WhatsAppProvider) {\n this.#provider = provider;\n }\n\n image(chatId: string, content: ImageContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n video(chatId: string, content: VideoContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n audio(chatId: string, content: AudioContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n sticker(chatId: string, content: StickerContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n download(message: Message | QuotedMessage | MessageKey): Promise<DownloadedMedia> {\n const key = 'keys' in message\n ? message.keys\n : 'key' in message\n ? message.key\n : message;\n\n return this.#provider.downloadMedia(key);\n }\n}\n","import { WhaNextError } from '@/errors/error.js';\nimport type {\n ChangeResult,\n GroupParticipant,\n GroupSnapshot,\n MemberActionState,\n} from '@/models/group.js';\nimport { identitiesMatch } from '@/models/identity.js';\nimport type { User } from '@/models/user.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\nimport type { GroupService } from '@/services/group-service.js';\n\nexport class MemberService {\n readonly #provider: WhatsAppProvider;\n readonly #group: GroupService;\n\n constructor(provider: WhatsAppProvider, group: GroupService) {\n this.#provider = provider;\n this.#group = group;\n }\n\n async remove(groupId: string, member: string | User): Promise<ChangeResult<MemberActionState>> {\n const { group, participant } = await this.#participant(groupId, member);\n\n if (!participant) {\n return { ok: true, changed: false, state: 'already_removed' };\n }\n\n await this.#update(groupId, this.#actionId(group, participant), 'remove');\n await this.#group.invalidate(groupId);\n return { ok: true, changed: true, state: 'removed' };\n }\n\n async promote(groupId: string, member: string | User): Promise<ChangeResult<MemberActionState>> {\n const { group, participant } = await this.#participant(groupId, member);\n\n if (!participant) {\n return { ok: true, changed: false, state: 'not_in_group' };\n }\n\n if (participant.role === 'admin' || participant.role === 'owner') {\n return { ok: true, changed: false, state: 'already_admin' };\n }\n\n await this.#update(groupId, this.#actionId(group, participant), 'promote');\n await this.#group.invalidate(groupId);\n return { ok: true, changed: true, state: 'promoted' };\n }\n\n async demote(groupId: string, member: string | User): Promise<ChangeResult<MemberActionState>> {\n const { group, participant } = await this.#participant(groupId, member);\n\n if (!participant) {\n return { ok: true, changed: false, state: 'not_in_group' };\n }\n\n if (participant.role === 'member') {\n return { ok: true, changed: false, state: 'not_admin' };\n }\n\n await this.#update(groupId, this.#actionId(group, participant), 'demote');\n await this.#group.invalidate(groupId);\n return { ok: true, changed: true, state: 'demoted' };\n }\n\n async #participant(groupId: string, member: string | User): Promise<{\n group: GroupSnapshot;\n participant: GroupParticipant | undefined;\n }> {\n const group = await this.#group.metadata(groupId);\n const memberIds = typeof member === 'string' ? [member] : member.identities;\n const participant = group.participants.find((item) =>\n [item.id, item.lid, item.phoneNumber]\n .filter((identity): identity is string => identity !== undefined)\n .some((identity) =>\n memberIds.some((memberId) => identitiesMatch(identity, memberId))));\n return { group, participant };\n }\n\n #actionId(group: GroupSnapshot, participant: GroupParticipant): string {\n if (group.addressingMode === 'lid') {\n return participant.lid\n ?? (participant.id.endsWith('@lid')\n ? participant.id\n : participant.phoneNumber ?? participant.id);\n }\n\n return participant.phoneNumber\n ?? (participant.id.endsWith('@s.whatsapp.net')\n ? participant.id\n : participant.lid ?? participant.id);\n }\n\n async #update(\n groupId: string,\n memberId: string,\n action: 'remove' | 'promote' | 'demote',\n ): Promise<void> {\n const result = await this.#provider.updateParticipant(groupId, memberId, action);\n\n if (!result.success) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n `WhatsApp rejected the member action with status ${result.status}.`,\n {\n context: { groupId, memberId, action, status: result.status },\n recoverable: true,\n },\n );\n }\n }\n}\n","import type {\n ButtonsContent,\n ListContent,\n MentionTarget,\n Message,\n MessageContent,\n MessageKey,\n PollContent,\n RepostMessageOptions,\n SentMessage,\n TextContent,\n} from '@/models/message.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class MessageService {\n readonly #provider: WhatsAppProvider;\n\n constructor(provider: WhatsAppProvider) {\n this.#provider = provider;\n }\n\n send(chatId: string, content: MessageContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n reply(message: Message, content: MessageContent): Promise<SentMessage> {\n return this.#provider.sendMessage(message.chatId, content, message.keys);\n }\n\n /**\n * Reposts a cached received message into a chat without creating a reply.\n * The original payload is preserved by the provider, so this works for\n * media and structured WhatsApp messages as well as text.\n */\n repost(\n source: Message | MessageKey,\n chatId: string,\n options: RepostMessageOptions = {},\n ): Promise<SentMessage> {\n const key = 'keys' in source ? source.keys : source;\n return this.#provider.repostMessage(key, chatId, options);\n }\n\n edit(message: Message | SentMessage | MessageKey, text: string): Promise<SentMessage> {\n const key = 'keys' in message ? message.keys : message;\n return this.#provider.editMessage(key, text);\n }\n\n delete(message: Message | SentMessage | MessageKey): Promise<void> {\n const key = 'keys' in message ? message.keys : message;\n return this.#provider.deleteMessage(key);\n }\n\n react(message: Message | SentMessage | MessageKey, emoji: string): Promise<SentMessage> {\n const key = 'keys' in message ? message.keys : message;\n return this.#provider.reactToMessage(key, emoji);\n }\n\n unreact(message: Message | SentMessage | MessageKey): Promise<SentMessage> {\n const key = 'keys' in message ? message.keys : message;\n return this.#provider.reactToMessage(key);\n }\n\n text(chatId: string, text: string, mentions?: MentionTarget[]): Promise<SentMessage> {\n const content: TextContent = { text };\n\n if (mentions !== undefined) {\n content.mentions = mentions;\n }\n\n return this.send(chatId, content);\n }\n\n buttons(chatId: string, content: ButtonsContent): Promise<SentMessage> {\n return this.send(chatId, content);\n }\n\n list(chatId: string, content: ListContent): Promise<SentMessage> {\n return this.send(chatId, content);\n }\n\n poll(chatId: string, content: PollContent): Promise<SentMessage> {\n return this.send(chatId, content);\n }\n}\n","import type { CacheOptions } from '@/cache/cache-store.js';\nimport { MemoryCache } from '@/cache/memory-cache.js';\nimport {\n CommandRouter,\n type RouterOptions,\n} from '@/commands/router.js';\nimport {\n WhaNextError,\n toWhaNextError,\n} from '@/errors/error.js';\nimport {\n Logger,\n type LogLevel,\n type LoggerConfig,\n} from '@/logger/logger.js';\nimport type { CallEvent } from '@/models/call.js';\nimport type { GroupParticipantsChanged } from '@/models/group.js';\nimport type {\n Message,\n MessageDeleted,\n MessageEdited,\n} from '@/models/message.js';\nimport type { MuteOptions } from '@/mute/mute-store.js';\nimport {\n MuteService,\n type MuteEnforcement,\n} from '@/mute/mute-service.js';\nimport { SqliteMuteStore } from '@/mute/sqlite-mute-store.js';\nimport { TypedEventEmitter } from '@/provider/event-emitter.js';\nimport type {\n ConnectionUpdate,\n WhatsAppProvider,\n} from '@/provider/provider.js';\nimport { AccountService } from '@/services/account-service.js';\nimport { ChatService } from '@/services/chat-service.js';\nimport { GroupService } from '@/services/group-service.js';\nimport { MediaService } from '@/services/media-service.js';\nimport { MemberService } from '@/services/member-service.js';\nimport { MessageService } from '@/services/message-service.js';\nimport { UserService } from '@/services/user-service.js';\n\nexport interface AppEvents {\n message: Message;\n messageDeleted: MessageDeleted;\n messageEdited: MessageEdited;\n connection: ConnectionUpdate;\n error: WhaNextError;\n mute: MuteEnforcement;\n call: CallEvent;\n groupParticipantsChanged: GroupParticipantsChanged;\n}\n\nexport interface LoginOptions {\n onCode?: (code: string) => void | Promise<void>;\n timeoutMs?: number;\n}\n\nexport type AppHealthStatus = 'idle' | 'starting' | 'ready' | 'stopped';\n\nexport interface AppHealth {\n status: AppHealthStatus;\n state: ConnectionUpdate['state'];\n ready: boolean;\n uptimeMs: number;\n timestamp: Date;\n muteEnabled: boolean;\n logLevel: LogLevel;\n}\n\nexport interface WhaNextAppOptions {\n phone?: string;\n prefix?: string | readonly string[];\n cache?: CacheOptions;\n logger?: LoggerConfig;\n mute?: MuteOptions;\n router?: Omit<RouterOptions, 'prefix'>;\n accountId?: string;\n}\n\nexport class WhaNextApp {\n readonly account: AccountService;\n readonly message: MessageService;\n readonly media: MediaService;\n readonly group: GroupService;\n readonly member: MemberService;\n readonly chat: ChatService;\n readonly user: UserService;\n readonly mute: MuteService;\n readonly logger: Logger;\n readonly commands: CommandRouter;\n readonly #provider: WhatsAppProvider;\n readonly #phone: string | undefined;\n readonly #events = new TypedEventEmitter<AppEvents>();\n readonly #router: CommandRouter;\n readonly #startedAt = Date.now();\n #state: ConnectionUpdate['state'] = 'idle';\n\n constructor(\n provider: WhatsAppProvider,\n options: WhaNextAppOptions = {},\n logger = new Logger(options.logger),\n ) {\n this.#provider = provider;\n this.#phone = options.phone;\n this.account = new AccountService(provider, options.accountId);\n this.logger = logger;\n const cache = options.cache?.store ?? new MemoryCache(\n options.cache?.memoryMaxEntries === undefined\n ? undefined\n : { maxEntries: options.cache.memoryMaxEntries },\n );\n this.group = new GroupService(provider, cache, options.cache?.groupTtlMs);\n this.member = new MemberService(provider, this.group);\n this.message = new MessageService(provider);\n this.media = new MediaService(provider);\n this.chat = new ChatService(provider);\n this.user = new UserService(this.group);\n const muteEnabled = options.mute?.enabled === true || options.mute?.store !== undefined;\n const muteStore = muteEnabled\n ? options.mute?.store ?? new SqliteMuteStore(options.mute?.database)\n : undefined;\n this.mute = new MuteService(provider, muteStore);\n this.commands = new CommandRouter({\n account: this.account,\n messages: this.message,\n media: this.media,\n groups: this.group,\n members: this.member,\n chats: this.chat,\n users: this.user,\n mute: this.mute,\n }, {\n ...options.router,\n ...(options.prefix !== undefined ? { prefix: options.prefix } : {}),\n });\n this.#router = this.commands;\n this.#bind();\n this.logger.debug('Application initialized', {\n muteEnabled: this.mute.enabled,\n prefix: options.prefix ?? '!',\n });\n }\n\n get state(): ConnectionUpdate['state'] {\n return this.#state;\n }\n\n get isReady(): boolean {\n return this.#state === 'connected';\n }\n\n health(): AppHealth {\n return {\n status: this.#healthStatus(),\n state: this.#state,\n ready: this.isReady,\n uptimeMs: Date.now() - this.#startedAt,\n timestamp: new Date(),\n muteEnabled: this.mute.enabled,\n logLevel: this.logger.level,\n };\n }\n\n router(): CommandRouter {\n return this.#router;\n }\n\n on<Event extends keyof AppEvents>(\n event: Event,\n listener: (payload: AppEvents[Event]) => void | Promise<void>,\n ) {\n return this.#events.on(event, listener);\n }\n\n async login(options: LoginOptions = {}): Promise<void> {\n if (this.#state === 'connected') {\n return;\n }\n\n this.logger.info('Login started');\n\n let unsubscribe: () => void = () => undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const connected = new Promise<void>((resolve, reject) => {\n unsubscribe = this.#provider.on('connection', (update) => {\n if (update.state === 'connected') resolve();\n if (update.state === 'closed') {\n reject(\n new WhaNextError(\n 'CONNECTION_FAILED',\n 'WhatsApp closed the connection before login completed.',\n {\n cause: update.error,\n recoverable: true,\n },\n ),\n );\n }\n });\n\n timer = setTimeout(() => {\n reject(\n new WhaNextError(\n 'CONNECTION_FAILED',\n 'WhatsApp login timed out.',\n { recoverable: true },\n ),\n );\n }, options.timeoutMs ?? 300_000);\n });\n\n void connected.catch(() => undefined);\n\n try {\n await this.#provider.connect();\n\n if (this.#phone) {\n const code = await this.#provider.requestPairingCode(this.#phone);\n\n if (code) {\n this.logger.info('Pairing code generated');\n\n if (options.onCode) {\n await options.onCode(code);\n }\n }\n }\n\n await connected;\n } finally {\n unsubscribe();\n if (timer) clearTimeout(timer);\n }\n }\n\n async disconnect(): Promise<void> {\n this.logger.info('Disconnecting application');\n\n try {\n await this.#provider.disconnect();\n } finally {\n await this.mute.close();\n }\n }\n\n #bind(): void {\n this.#provider.on('connection', async (update) => {\n this.#state = update.state;\n this.#logConnection(update);\n await this.#events.emit('connection', update);\n });\n\n this.#provider.on('groupChanged', ({ groupId }) => this.group.invalidate(groupId));\n\n this.#provider.on('groupParticipantsChanged', async (change) => {\n await this.group.invalidate(change.groupId);\n await this.#events.emit('groupParticipantsChanged', change);\n });\n\n this.#provider.on('call', async (call) => {\n this.logger.debug('Call received', {\n callId: call.id,\n from: call.from,\n status: call.status,\n });\n await this.#events.emit('call', call);\n });\n\n this.#provider.on('messageDeleted', async (deletion) => {\n this.logger.debug('Message deleted', {\n chatId: deletion.key.chatId,\n messageId: deletion.key.id,\n deletedByMe: deletion.deletedByMe,\n cached: deletion.message !== undefined,\n });\n await this.#events.emit('messageDeleted', deletion);\n });\n\n this.#provider.on('messageEdited', async (edit) => {\n this.logger.debug('Message edited', {\n chatId: edit.key.chatId,\n messageId: edit.key.id,\n editedByMe: edit.editedByMe,\n cached: edit.previous !== undefined,\n });\n await this.#events.emit('messageEdited', edit);\n });\n\n this.#provider.on('message', async (message) => {\n try {\n const enforcement = await this.mute.enforce(message);\n\n if (enforcement) {\n this.logger.info('Muted message deleted', {\n groupId: message.chatId,\n messageId: message.id,\n userId: message.sender.id,\n });\n await this.#events.emit('mute', enforcement);\n return;\n }\n } catch (error) {\n await this.#reportError(error, { messageId: message.id });\n return;\n }\n\n try {\n this.logger.debug('Message received', {\n chatId: message.chatId,\n messageId: message.id,\n senderId: message.sender.id,\n });\n await this.#events.emit('message', message);\n const dispatched = await this.#router.dispatch(message);\n\n if (dispatched) {\n this.logger.debug('Command dispatched', {\n chatId: message.chatId,\n messageId: message.id,\n });\n }\n } catch (error) {\n await this.#reportError(error, { messageId: message.id });\n }\n });\n }\n\n #healthStatus(): AppHealthStatus {\n if (this.#state === 'connected') {\n return 'ready';\n }\n\n if (this.#state === 'closed') {\n return 'stopped';\n }\n\n if (this.#state === 'connecting' || this.#state === 'reconnecting') {\n return 'starting';\n }\n\n return 'idle';\n }\n\n #logConnection(update: ConnectionUpdate): void {\n const context = {\n ...(update.attempt !== undefined ? { attempt: update.attempt } : {}),\n ...(update.error ? { error: update.error } : {}),\n };\n\n if (update.state === 'connected') {\n this.logger.info('WhatsApp connected');\n } else if (update.state === 'reconnecting') {\n this.logger.warn('WhatsApp reconnecting', context);\n } else if (update.state === 'closed' && update.error) {\n this.logger.warn('WhatsApp connection closed', context);\n } else if (update.state === 'closed') {\n this.logger.info('WhatsApp connection closed');\n } else {\n this.logger.debug('WhatsApp connecting', context);\n }\n }\n\n async #reportError(\n error: unknown,\n context: Readonly<Record<string, unknown>>,\n ): Promise<void> {\n const normalized = toWhaNextError(error, context);\n this.logger.error(normalized.message, {\n code: normalized.code,\n ...normalized.context,\n });\n await this.#events.emit('error', normalized);\n }\n}\n","export enum Browser {\n Windows = 'windows',\n MacOS = 'macos',\n Ubuntu = 'ubuntu',\n}","import { mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { createMediaProcessor } from '@zapo-js/media-utils';\nimport { createSqliteStore } from '@zapo-js/store-sqlite';\nimport type { voipPlugin as ZapoVoipPluginFactory } from '@zapo-js/voip';\nimport {\n WaClient,\n createStore,\n proto,\n type Logger as ZapoLogger,\n type LogLevel as ZapoLogLevel,\n type Proto,\n type WaIncomingMessageEvent,\n} from 'zapo-js';\nimport { Browser } from '@/auth/browser.js';\nimport { WhaNextError } from '@/errors/error.js';\nimport { Logger } from '@/logger/logger.js';\nimport type { CallEvent, CallStatus } from '@/models/call.js';\nimport type {\n GroupAccess,\n GroupParticipantAction,\n GroupParticipantsChanged,\n GroupSnapshot,\n} from '@/models/group.js';\nimport { uniqueIdentities } from '@/models/identity.js';\nimport type {\n ButtonsContent,\n DownloadedMedia,\n ListContent,\n MediaSource,\n MentionTarget,\n MessageContent,\n MessageKey,\n PollContent,\n RepostMessageOptions,\n SentMessage,\n} from '@/models/message.js';\nimport { TypedEventEmitter } from '@/provider/event-emitter.js';\nimport type {\n ParticipantAction,\n ParticipantUpdateResult,\n PresenceState,\n ProviderEvents,\n WhatsAppProvider,\n} from '@/provider/provider.js';\nimport {\n extractQuotedZapoMessage,\n unwrapZapoMessageContent,\n normalizeZapoKey,\n normalizeZapoMessage,\n type ZapoMessageKeyLike,\n} from '@/provider/zapo/normalize-message.js';\n\nexport interface ZapoProviderOptions {\n auth: string;\n browser: Browser;\n logger?: Logger;\n messageCacheSize?: number;\n sessionId?: string;\n processOfflineMessages?: boolean;\n reconnect?: {\n enabled?: boolean;\n maxAttempts?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n };\n}\n\ninterface StoredZapoMessage {\n key: ZapoMessageKeyLike;\n message?: Proto.IMessage | null;\n timestampSeconds?: number | null;\n pushName?: string | null;\n offline?: boolean | null;\n}\n\ninterface ZapoPublishResultLike {\n id?: string | null;\n}\n\ninterface ZapoCredentialsLike {\n meJid?: string | null;\n meLid?: string | null;\n}\n\ninterface ZapoProtocolEventLike extends StoredZapoMessage {\n protocolMessage?: {\n type?: number | null;\n key?: ZapoMessageKeyLike | null;\n editedMessage?: Proto.IMessage | null;\n timestampMs?: number | LongLike | null;\n } | null;\n}\n\ninterface ZapoGroupEventParticipantLike {\n jid?: string | null;\n lidJid?: string | null;\n phoneJid?: string | null;\n}\n\ninterface ZapoGroupEventLike {\n groupJid?: string | null;\n action?: string | null;\n authorJid?: string | null;\n participants?: readonly ZapoGroupEventParticipantLike[] | null;\n}\n\n\ninterface ZapoVoipCallLike {\n callId?: string | null;\n peerJid?: string | null;\n callCreator?: string | null;\n callerPn?: string | null;\n groupJid?: string | null;\n mediaType?: string | null;\n createdAt?: Date | null;\n stateData?: {\n state?: string | null;\n endReason?: string | null;\n } | null;\n}\n\ninterface ZapoGroupMetadataLike {\n jid?: string | null;\n id?: string | null;\n subject?: string | null;\n announce?: boolean | null;\n addressingMode?: string | null;\n participants?: readonly ZapoGroupParticipantLike[] | null;\n}\n\ninterface ZapoGroupParticipantLike {\n jid?: string | null;\n id?: string | null;\n lid?: string | null;\n phoneNumber?: string | null;\n isAdmin?: boolean | null;\n isSuperAdmin?: boolean | null;\n admin?: string | null;\n}\n\ninterface LongLike {\n toNumber?: () => number;\n low?: number;\n}\n\ntype ZapoVoipPlugin = ReturnType<typeof ZapoVoipPluginFactory>;\ntype ZapoChatstateState = 'composing' | 'recording' | 'paused';\n\ninterface ZapoPresenceLike {\n sendChatstate(jid: string, value: { state: ZapoChatstateState }): Promise<void>;\n}\n\ninterface ZapoVoipCoordinatorLike {\n rejectCall(callId: string): Promise<void>;\n}\n\ninterface ZapoVoipEventClient {\n on(\n event: 'voip_call_incoming' | 'voip_call_state' | 'voip_call_ended',\n listener: (event: ZapoVoipCallLike) => void,\n ): unknown;\n}\n\nexport class ZapoProvider implements WhatsAppProvider {\n readonly #options: ZapoProviderOptions;\n readonly #events = new TypedEventEmitter<ProviderEvents>();\n readonly #logger: Logger;\n readonly #messageStore = new Map<string, StoredZapoMessage>();\n readonly #messageKeyStore = new WeakMap<MessageKey, StoredZapoMessage>();\n readonly #messageCacheSize: number;\n #client: WaClient | undefined;\n #voip: ZapoVoipCoordinatorLike | undefined;\n #intentionalClose = false;\n #reconnectAttempt = 0;\n #reconnectTimer: ReturnType<typeof setTimeout> | undefined;\n #connectPromise: Promise<void> | undefined;\n #pairingRequired = false;\n #connected = false;\n #connectedAtSeconds = 0;\n #pairingReady: Promise<void> = Promise.resolve();\n #resolvePairingReady: (() => void) | undefined;\n\n constructor(options: ZapoProviderOptions) {\n this.#options = options;\n this.#logger = options.logger ?? new Logger('silent');\n this.#messageCacheSize = Math.max(1, options.messageCacheSize ?? 1_000);\n }\n\n on<Event extends keyof ProviderEvents>(\n event: Event,\n listener: (payload: ProviderEvents[Event]) => void | Promise<void>,\n ) {\n return this.#events.on(event, listener);\n }\n\n async connect(): Promise<void> {\n this.#intentionalClose = false;\n const client = await this.#ensureClient();\n\n if (this.#connected || this.#connectPromise) {\n return;\n }\n\n this.#preparePairingGate();\n await this.#events.emit('connection', {\n state: this.#reconnectAttempt > 0 ? 'reconnecting' : 'connecting',\n attempt: this.#reconnectAttempt,\n });\n this.#startConnect(client);\n }\n\n async disconnect(): Promise<void> {\n this.#intentionalClose = true;\n\n if (this.#reconnectTimer) {\n clearTimeout(this.#reconnectTimer);\n this.#reconnectTimer = undefined;\n }\n\n const client = this.#client;\n this.#connectPromise = undefined;\n\n if (client) {\n await client.disconnect();\n } else {\n await this.#events.emit('connection', { state: 'closed' });\n }\n\n this.#connected = false;\n }\n\n getCurrentUserIds(): string[] {\n const credentials = this.#client?.getCredentials() as ZapoCredentialsLike | null | undefined;\n return uniqueIdentities([\n credentials?.meJid,\n credentials?.meLid,\n ]);\n }\n\n async requestPairingCode(phone: string): Promise<string> {\n const normalized = phone.replace(/\\D/g, '');\n\n if (normalized.length < 10) {\n throw new WhaNextError(\n 'AUTH_INVALID_PHONE',\n 'The phone number must include its country code.',\n );\n }\n\n const client = await this.#ensureClient();\n\n if (client.getCredentials()?.meJid) {\n return '';\n }\n\n if (!this.#connectPromise && !this.#connected) {\n await this.connect();\n }\n\n try {\n if (!this.#pairingRequired) {\n await this.#withTimeout(\n this.#pairingReady,\n 60_000,\n 'The WhatsApp pairing challenge was not received in time.',\n );\n }\n\n return await client.auth.requestPairingCode(normalized);\n } catch (error) {\n if (error instanceof WhaNextError) throw error;\n\n throw new WhaNextError(\n 'CONNECTION_FAILED',\n 'Could not request the pairing code after the authentication challenge.',\n { cause: error, recoverable: true },\n );\n }\n }\n\n async sendMessage(\n chatId: string,\n content: MessageContent,\n replyTo?: MessageKey,\n ): Promise<SentMessage> {\n if ('buttons' in content) {\n return this.#sendButtons(chatId, content, replyTo);\n }\n\n if ('list' in content) {\n return this.#sendList(chatId, content, replyTo);\n }\n\n const client = this.#requireClient();\n const { value, mentions, viewOnce } = await this.#toContent(content);\n const result = await client.message.send(chatId, value as never, {\n ...(replyTo ? { quote: this.#toZapoKey(replyTo) } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n ...(viewOnce !== undefined ? { viewOnce } : {}),\n });\n\n return this.#sent(result, chatId);\n }\n\n async repostMessage(\n source: MessageKey,\n chatId: string,\n options: RepostMessageOptions = {},\n ): Promise<SentMessage> {\n const original = this.#findStoredMessage(this.#toZapoKey(source));\n\n if (!original?.message) {\n throw new WhaNextError(\n 'MESSAGE_NOT_FOUND',\n 'The source message is no longer available in the recent-message cache.',\n {\n context: { messageId: source.id, chatId: source.chatId },\n recoverable: true,\n },\n );\n }\n\n const result = await this.#requireClient().message.send(\n chatId,\n original.message,\n {\n forward: true,\n ...(options.mentions && options.mentions.length > 0\n ? { mentions: this.#mentions(options.mentions) }\n : {}),\n },\n );\n\n return this.#sent(result, chatId);\n }\n\n async reactToMessage(key: MessageKey, emoji?: string): Promise<SentMessage> {\n const result = await this.#requireClient().message.send(key.chatId, {\n type: 'reaction',\n emoji: emoji ?? '',\n target: this.#toZapoKey(key),\n });\n\n return this.#sent(result, key.chatId);\n }\n\n async downloadMedia(key: MessageKey): Promise<DownloadedMedia> {\n const message = this.#messageKeyStore.get(key)\n ?? this.#findStoredMessage(this.#toZapoKey(key));\n\n if (!message?.message) {\n throw new WhaNextError(\n 'MEDIA_NOT_AVAILABLE',\n 'The media is unavailable. Download it from the received message event while it is cached.',\n { recoverable: true },\n );\n }\n\n const normalized = normalizeZapoMessage(message);\n\n if (!normalized?.media) {\n throw new WhaNextError(\n 'MEDIA_NOT_AVAILABLE',\n 'The selected message does not contain media.',\n );\n }\n\n try {\n const mediaMessage = unwrapZapoMessageContent(message.message)\n ?? message.message;\n const bytes = await this.#requireClient().message.downloadBytes(mediaMessage);\n\n return {\n data: Buffer.from(bytes),\n kind: normalized.media.kind,\n ...(normalized.media.mimetype ? { mimetype: normalized.media.mimetype } : {}),\n ...(normalized.media.fileName ? { fileName: normalized.media.fileName } : {}),\n };\n } catch (error) {\n throw new WhaNextError(\n 'MEDIA_NOT_AVAILABLE',\n 'WhatsApp could not download the selected media.',\n { cause: error, recoverable: true },\n );\n }\n }\n\n async editMessage(key: MessageKey, content: string): Promise<SentMessage> {\n const result = await this.#requireClient().message.send(\n key.chatId,\n content,\n { editKey: this.#toZapoKey(key) },\n );\n\n return this.#sent(result, key.chatId);\n }\n\n async deleteMessage(key: MessageKey): Promise<void> {\n await this.#requireClient().message.send(key.chatId, {\n type: 'revoke',\n target: this.#toZapoKey(key),\n });\n }\n\n async getGroup(groupId: string): Promise<GroupSnapshot> {\n const metadata = await this.#requireClient().group.queryGroupMetadata(groupId) as ZapoGroupMetadataLike;\n const participants = [...(metadata.participants ?? [])];\n const addressingMode = metadata.addressingMode === 'lid'\n || participants.some((participant) =>\n (participant.jid ?? participant.id ?? '').endsWith('@lid'))\n ? 'lid'\n : 'pn';\n\n return {\n id: metadata.jid ?? metadata.id ?? groupId,\n subject: metadata.subject ?? '',\n access: metadata.announce ? 'closed' : 'open',\n addressingMode,\n fetchedAt: new Date(),\n participants: participants.map((participant) => {\n const id = participant.jid ?? participant.id ?? participant.lid ?? participant.phoneNumber ?? '';\n return {\n id,\n ...(participant.lid ? { lid: participant.lid } : {}),\n ...(participant.phoneNumber ? { phoneNumber: participant.phoneNumber } : {}),\n role: participant.isSuperAdmin || participant.admin === 'superadmin'\n ? 'owner'\n : participant.isAdmin || participant.admin === 'admin'\n ? 'admin'\n : 'member',\n };\n }),\n };\n }\n\n async setGroupAccess(groupId: string, access: GroupAccess): Promise<void> {\n await this.#requireClient().group.setSetting(\n groupId,\n 'announcement',\n access === 'closed',\n );\n }\n\n async getGroupInviteCode(groupId: string): Promise<string> {\n const code = await this.#requireClient().group.queryInviteCode(groupId);\n\n if (!code) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'WhatsApp did not return a group invite code.',\n );\n }\n\n return code;\n }\n\n async revokeGroupInvite(groupId: string): Promise<string> {\n const result = await this.#requireClient().group.revokeInvite(groupId);\n\n if (!result.code) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'WhatsApp did not return a new group invite code.',\n );\n }\n\n return result.code;\n }\n\n async setMessagePin(\n groupId: string,\n key: MessageKey,\n pinned: boolean,\n ): Promise<void> {\n await this.#requireClient().message.send(groupId, pinned\n ? {\n type: 'pin',\n target: this.#toZapoKey(key),\n durationSecs: 604_800,\n }\n : {\n type: 'unpin',\n target: this.#toZapoKey(key),\n });\n }\n\n async updateParticipant(\n groupId: string,\n memberId: string,\n action: ParticipantAction,\n ): Promise<ParticipantUpdateResult> {\n const group = this.#requireClient().group;\n const results = action === 'remove'\n ? await group.removeParticipants(groupId, [memberId])\n : action === 'promote'\n ? await group.promoteParticipants(groupId, [memberId])\n : await group.demoteParticipants(groupId, [memberId]);\n const result = results[0];\n const success = result?.status === 'ok';\n const status = success ? '200' : String(result?.code ?? result?.status ?? 'unknown');\n\n return {\n success,\n status,\n ...(result?.jid ? { memberId: result.jid } : {}),\n };\n }\n\n async setPresence(chatId: string, state: PresenceState): Promise<void> {\n const value: ZapoChatstateState = state === 'typing'\n ? 'composing'\n : state === 'recording'\n ? 'recording'\n : 'paused';\n const presence = this.#requireClient().presence as unknown as ZapoPresenceLike;\n\n await presence.sendChatstate(chatId, { state: value });\n }\n\n async rejectCall(callId: string, _from: string): Promise<void> {\n this.#requireClient();\n\n if (!this.#voip) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'WhatsApp call support is unavailable because the Zapo VoIP plugin could not be loaded.',\n { recoverable: true },\n );\n }\n\n await this.#voip.rejectCall(callId);\n }\n\n async #ensureClient(): Promise<WaClient> {\n if (this.#client) return this.#client;\n\n await mkdir(this.#options.auth, { recursive: true });\n const store = createStore({\n backends: {\n sqlite: createSqliteStore({\n path: join(this.#options.auth, 'state.sqlite'),\n driver: 'auto',\n }),\n },\n providers: {\n auth: 'sqlite',\n signal: 'sqlite',\n preKey: 'sqlite',\n session: 'sqlite',\n identity: 'sqlite',\n senderKey: 'sqlite',\n appState: 'sqlite',\n privacyToken: 'sqlite',\n messages: 'none',\n threads: 'none',\n contacts: 'none',\n },\n cacheProviders: {\n messageSecret: 'sqlite',\n },\n });\n const plugins: ZapoVoipPlugin[] = [];\n\n try {\n const { voipPlugin } = await import('@zapo-js/voip');\n plugins.push(voipPlugin({ logLevel: 'warn' }));\n } catch (error) {\n this.#logger.warn('Zapo VoIP support is unavailable; call events and rejection are disabled.', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n const client = new WaClient({\n store,\n sessionId: this.#options.sessionId ?? 'default',\n markOnlineOnConnect: false,\n deviceBrowser: this.#deviceBrowser(),\n deviceOsDisplayName: this.#deviceOsDisplayName(),\n history: { enabled: false },\n addons: {\n autoDecrypt: true,\n persistAllSecrets: true,\n },\n media: { processor: createMediaProcessor() },\n plugins,\n }, new WhaNextZapoLogger(this.#logger));\n\n this.#client = client;\n this.#voip = (client as unknown as { voip?: ZapoVoipCoordinatorLike }).voip;\n this.#bind(client);\n return client;\n }\n\n #bind(client: WaClient): void {\n client.on('auth_pairing_required', () => {\n this.#markPairingReady();\n });\n\n client.on('auth_qr', () => {\n this.#markPairingReady();\n });\n\n client.on('auth_paired', () => {\n this.#pairingRequired = false;\n });\n\n client.on('message', (event) => {\n this.#handleMessage(event);\n });\n\n client.on('message_send', (event) => {\n if (!event.id || !event.message) return;\n\n this.#remember({\n key: {\n id: event.id,\n remoteJid: event.to,\n fromMe: true,\n },\n message: event.message,\n timestampSeconds: Math.floor(Date.now() / 1_000),\n });\n });\n\n client.on('message_protocol', (event) => {\n this.#handleProtocolEvent(event as unknown as ZapoProtocolEventLike);\n });\n\n client.on('group', (event) => {\n this.#handleGroupEvent(event as unknown as ZapoGroupEventLike);\n });\n\n if (this.#voip) {\n const voipClient = client as unknown as ZapoVoipEventClient;\n\n voipClient.on('voip_call_incoming', (event) => {\n const call = this.#normalizeVoipCall(event, 'offer');\n if (call) void this.#events.emit('call', call);\n });\n\n voipClient.on('voip_call_state', (event) => {\n if (event.stateData?.state === 'ended') return;\n\n const call = this.#normalizeVoipCall(event);\n if (call && call.status !== 'offer') void this.#events.emit('call', call);\n });\n\n voipClient.on('voip_call_ended', (event) => {\n const call = this.#normalizeVoipCall(\n event,\n this.#callEndStatus(event.stateData?.endReason),\n );\n if (call) void this.#events.emit('call', call);\n });\n }\n\n client.on('connection', (event) => {\n void this.#handleConnectionEvent(client, event);\n });\n }\n\n #handleMessage(event: WaIncomingMessageEvent): void {\n const stored = event as unknown as StoredZapoMessage;\n\n if (this.#isOfflineMessage(stored)) {\n this.#logger.debug('Ignored message queued before the current connection.', {\n messageId: stored.key.id ?? undefined,\n chatId: stored.key.remoteJid ?? undefined,\n timestampSeconds: stored.timestampSeconds ?? undefined,\n });\n return;\n }\n\n if (stored.key?.id && stored.message) this.#remember(stored);\n\n const quoted = extractQuotedZapoMessage(event);\n if (quoted?.key.id && quoted.message) {\n this.#remember(quoted as unknown as StoredZapoMessage);\n }\n\n const message = normalizeZapoMessage(event);\n if (!message) return;\n\n this.#messageKeyStore.set(message.keys, stored);\n if (message.quoted && quoted?.message) {\n this.#messageKeyStore.set(\n message.quoted.key,\n quoted as unknown as StoredZapoMessage,\n );\n }\n\n void this.#events.emit('message', message);\n }\n\n #handleProtocolEvent(event: ZapoProtocolEventLike): void {\n const protocol = event.protocolMessage\n ?? (event.message?.protocolMessage as ZapoProtocolEventLike['protocolMessage']);\n if (!protocol) return;\n\n const protocolKey = protocol.key;\n if (!protocolKey?.id) return;\n\n const remoteJid = protocolKey.remoteJid ?? event.key.remoteJid;\n const participant = protocolKey.participant ?? event.key.participant;\n const participantAlt = protocolKey.participantAlt ?? event.key.participantAlt;\n const target: ZapoMessageKeyLike = {\n ...protocolKey,\n ...(remoteJid !== undefined ? { remoteJid } : {}),\n ...(participant !== undefined ? { participant } : {}),\n ...(participantAlt !== undefined ? { participantAlt } : {}),\n };\n\n if (!target.remoteJid) return;\n\n const stored = this.#findStoredMessage(target);\n const type = protocol?.type;\n\n if (type === proto.Message.ProtocolMessage.Type.REVOKE) {\n const previous = stored ? normalizeZapoMessage(stored) : undefined;\n const deletedByMe = event.key.fromMe === true;\n const deletedById = event.key.participant\n ?? event.key.participantAlt\n ?? (deletedByMe ? this.getCurrentUserIds()[0] : event.key.remoteJid ?? undefined);\n\n void this.#events.emit('messageDeleted', {\n key: previous?.keys ?? normalizeZapoKey(target),\n ...(previous ? { message: previous } : {}),\n deletedByMe,\n ...(deletedById ? { deletedById } : {}),\n deletedAt: new Date(),\n });\n return;\n }\n\n if (type !== proto.Message.ProtocolMessage.Type.MESSAGE_EDIT || !protocol.editedMessage) {\n return;\n }\n\n const pushName = event.pushName ?? stored?.pushName;\n const edited: StoredZapoMessage = {\n ...(stored ?? {}),\n key: {\n ...(stored?.key ?? {}),\n ...target,\n },\n message: protocol.editedMessage,\n timestampSeconds: toSeconds(protocol.timestampMs)\n ?? event.timestampSeconds\n ?? stored?.timestampSeconds\n ?? Math.floor(Date.now() / 1_000),\n ...(pushName !== undefined ? { pushName } : {}),\n };\n const message = normalizeZapoMessage(edited);\n\n if (!message) return;\n\n const previous = stored ? normalizeZapoMessage(stored) : undefined;\n this.#remember(edited);\n const editedByMe = event.key.fromMe === true;\n const editedById = event.key.participant\n ?? event.key.participantAlt\n ?? (editedByMe ? this.getCurrentUserIds()[0] : event.key.remoteJid ?? undefined);\n\n void this.#events.emit('messageEdited', {\n key: message.keys,\n ...(previous ? { previous } : {}),\n message,\n editedByMe,\n ...(editedById ? { editedById } : {}),\n editedAt: message.timestamp,\n });\n }\n\n #handleGroupEvent(event: ZapoGroupEventLike): void {\n const groupId = event.groupJid;\n if (!groupId) return;\n\n const action = this.#groupAction(event.action);\n const participantIds = this.#groupParticipantIds(event);\n\n if (action && participantIds.length > 0) {\n const authorId = event.authorJid;\n const change: GroupParticipantsChanged = {\n groupId,\n action,\n participantIds,\n ...(authorId ? { authorId } : {}),\n };\n void this.#events.emit('groupParticipantsChanged', change);\n }\n\n void this.#events.emit('groupChanged', { groupId });\n }\n\n async #handleConnectionEvent(\n client: WaClient,\n event: { status: 'open' | 'close'; reason?: unknown; isLogout?: boolean },\n ): Promise<void> {\n if (client !== this.#client) return;\n\n if (event.status === 'open') {\n this.#connectPromise = undefined;\n this.#connected = true;\n this.#connectedAtSeconds = Math.floor(Date.now() / 1_000);\n this.#reconnectAttempt = 0;\n await this.#events.emit('connection', { state: 'connected' });\n return;\n }\n\n this.#connectPromise = undefined;\n this.#connected = false;\n const error = event.reason instanceof Error\n ? event.reason\n : event.reason\n ? new Error(String(event.reason))\n : undefined;\n\n if (this.#intentionalClose || event.isLogout) {\n await this.#events.emit('connection', {\n state: 'closed',\n ...(error ? { error } : {}),\n });\n return;\n }\n\n await this.#scheduleReconnect(error);\n }\n\n #startConnect(client: WaClient): void {\n const promise = client.connect();\n this.#connectPromise = promise;\n void promise.catch(async (error: unknown) => {\n if (this.#connectPromise !== promise) return;\n this.#connectPromise = undefined;\n\n if (this.#intentionalClose) return;\n\n const normalized = error instanceof Error ? error : new Error(String(error));\n this.#logger.warn('WhatsApp connection attempt failed.', { error: normalized });\n await this.#scheduleReconnect(normalized);\n });\n }\n\n async #scheduleReconnect(error?: Error): Promise<void> {\n if (this.#reconnectTimer) return;\n\n const options = this.#options.reconnect;\n const maxAttempts = options?.maxAttempts ?? 10;\n\n if (options?.enabled === false || this.#reconnectAttempt >= maxAttempts) {\n await this.#events.emit('connection', {\n state: 'closed',\n ...(error ? { error } : {}),\n });\n return;\n }\n\n this.#reconnectAttempt += 1;\n await this.#events.emit('connection', {\n state: 'reconnecting',\n attempt: this.#reconnectAttempt,\n ...(error ? { error } : {}),\n });\n\n const initial = options?.initialDelayMs ?? 1_000;\n const maximum = options?.maxDelayMs ?? 30_000;\n const delay = Math.min(maximum, initial * 2 ** (this.#reconnectAttempt - 1));\n this.#reconnectTimer = setTimeout(() => {\n this.#reconnectTimer = undefined;\n void this.connect();\n }, delay + Math.floor(Math.random() * 250));\n }\n\n async #sendButtons(\n chatId: string,\n content: ButtonsContent,\n replyTo?: MessageKey,\n ): Promise<SentMessage> {\n this.#validateButtons(content);\n const mentions = content.mentions ? this.#mentions(content.mentions) : [];\n const raw: Proto.IMessage = {\n interactiveMessage: {\n ...(content.title !== undefined\n ? {\n header: {\n title: content.title,\n hasMediaAttachment: false,\n },\n }\n : {}),\n body: { text: content.text },\n ...(content.footer !== undefined ? { footer: { text: content.footer } } : {}),\n ...(mentions.length > 0 ? { contextInfo: { mentionedJid: mentions } } : {}),\n nativeFlowMessage: {\n buttons: content.buttons.map((button) => {\n if (button.type === 'copy') {\n return {\n name: 'cta_copy',\n buttonParamsJson: JSON.stringify({\n display_text: button.label,\n copy_code: button.code,\n }),\n };\n }\n\n if (button.type === 'reply') {\n return {\n name: 'quick_reply',\n buttonParamsJson: JSON.stringify({\n display_text: button.label,\n id: button.id,\n }),\n };\n }\n\n return {\n name: 'cta_url',\n buttonParamsJson: JSON.stringify({\n display_text: button.label,\n url: button.url,\n merchant_url: button.url,\n }),\n };\n }),\n messageParamsJson: '{}',\n messageVersion: 1,\n },\n },\n };\n const result = await this.#requireClient().message.send(chatId, raw, {\n ...(replyTo ? { quote: this.#toZapoKey(replyTo) } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n });\n\n return this.#sent(result, chatId);\n }\n\n async #sendList(\n chatId: string,\n content: ListContent,\n replyTo?: MessageKey,\n ): Promise<SentMessage> {\n this.#validateList(content);\n const mentions = content.mentions ? this.#mentions(content.mentions) : [];\n const raw: Proto.IMessage = {\n interactiveMessage: {\n ...(content.title !== undefined\n ? {\n header: {\n title: content.title,\n hasMediaAttachment: false,\n },\n }\n : {}),\n body: { text: content.text },\n ...(content.footer !== undefined ? { footer: { text: content.footer } } : {}),\n ...(mentions.length > 0 ? { contextInfo: { mentionedJid: mentions } } : {}),\n nativeFlowMessage: {\n buttons: [\n {\n name: 'single_select',\n buttonParamsJson: JSON.stringify({\n title: content.buttonText,\n sections: content.list.map((section) => ({\n ...(section.title !== undefined ? { title: section.title } : {}),\n rows: section.rows.map((row) => ({\n id: row.id,\n title: row.title,\n ...(row.description !== undefined ? { description: row.description } : {}),\n })),\n })),\n }),\n },\n ],\n messageParamsJson: '{}',\n messageVersion: 1,\n },\n },\n };\n const result = await this.#requireClient().message.send(chatId, raw, {\n ...(replyTo ? { quote: this.#toZapoKey(replyTo) } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n });\n\n return this.#sent(result, chatId);\n }\n\n async #toContent(content: MessageContent): Promise<{\n value: unknown;\n mentions: string[];\n viewOnce?: boolean;\n }> {\n if ('text' in content) {\n return {\n value: { type: 'text', text: content.text },\n mentions: content.mentions ? this.#mentions(content.mentions) : [],\n };\n }\n\n if ('poll' in content) {\n return {\n value: this.#pollContent(content),\n mentions: [],\n };\n }\n\n if ('image' in content) {\n return {\n value: {\n type: 'image',\n media: await this.#media(content.image),\n ...(content.caption !== undefined ? { caption: content.caption } : {}),\n },\n mentions: content.mentions ? this.#mentions(content.mentions) : [],\n ...(content.viewOnce !== undefined ? { viewOnce: content.viewOnce } : {}),\n };\n }\n\n if ('video' in content) {\n return {\n value: {\n type: 'video',\n media: await this.#media(content.video),\n ...(content.caption !== undefined ? { caption: content.caption } : {}),\n ...(content.gif !== undefined ? { gifPlayback: content.gif } : {}),\n },\n mentions: content.mentions ? this.#mentions(content.mentions) : [],\n ...(content.viewOnce !== undefined ? { viewOnce: content.viewOnce } : {}),\n };\n }\n\n if ('sticker' in content) {\n return {\n value: {\n type: 'sticker',\n media: await this.#media(content.sticker),\n mimetype: 'image/webp',\n },\n mentions: [],\n };\n }\n\n return {\n value: {\n type: 'audio',\n media: await this.#media(content.audio),\n ...(content.mimetype ? { mimetype: content.mimetype } : {}),\n ...(content.voice !== undefined ? { ptt: content.voice } : {}),\n },\n mentions: [],\n };\n }\n\n #validateButtons(content: ButtonsContent): void {\n if (!content.text.trim() || content.buttons.length === 0) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Interactive buttons require body text and at least one button.',\n );\n }\n\n for (const button of content.buttons) {\n if (!button.label.trim()) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Interactive button labels cannot be empty.');\n }\n if (button.type === 'reply' && !button.id.trim()) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Reply button IDs cannot be empty.');\n }\n if (button.type === 'copy' && !button.code) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Copy buttons require a non-empty code.');\n }\n if (button.type === 'link' && !button.url.trim()) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Link buttons require a non-empty URL.');\n }\n }\n }\n\n #validateList(content: ListContent): void {\n if (!content.text.trim() || !content.buttonText.trim() || content.list.length === 0) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'List menus require body text, button text and at least one section.',\n );\n }\n\n let rowCount = 0;\n const ids = new Set<string>();\n for (const section of content.list) {\n for (const row of section.rows) {\n rowCount += 1;\n const id = row.id.trim();\n if (!id || !row.title.trim()) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Every list row requires a non-empty id and title.',\n );\n }\n if (ids.has(id)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `Duplicate list row id \"${id}\".`,\n );\n }\n ids.add(id);\n }\n }\n\n if (rowCount === 0) {\n throw new WhaNextError('ARGUMENT_INVALID', 'List menus require at least one row.');\n }\n }\n\n #pollContent(content: PollContent): unknown {\n const name = content.poll.trim();\n const options = content.options.map((option) => option.trim()).filter(Boolean);\n const selectableCount = content.selectableCount ?? 1;\n\n if (!name || options.length < 2) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Polls require a question and at least two non-empty options.',\n );\n }\n\n if (!Number.isInteger(selectableCount) || selectableCount < 1 || selectableCount > options.length) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'selectableCount must be an integer between 1 and the number of poll options.',\n { context: { selectableCount, options: options.length } },\n );\n }\n\n return {\n type: 'poll',\n name,\n options,\n selectableCount,\n ...(content.allowAddOption !== undefined ? { allowAddOption: content.allowAddOption } : {}),\n };\n }\n\n async #media(source: MediaSource): Promise<string | Uint8Array> {\n if (source instanceof Uint8Array) return source;\n if ('path' in source) return source.path;\n\n const response = await fetch(source.url);\n\n if (!response.ok) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'Could not download the remote media source.',\n {\n context: { status: response.status },\n recoverable: response.status >= 500,\n },\n );\n }\n\n return new Uint8Array(await response.arrayBuffer());\n }\n\n #mentions(mentions: readonly MentionTarget[]): string[] {\n return mentions.map((mention) =>\n typeof mention === 'string' ? mention : mention.mentionId);\n }\n\n #toZapoKey(key: MessageKey): {\n id: string;\n remoteJid: string;\n fromMe: boolean;\n participant?: string;\n } {\n return {\n id: key.id,\n remoteJid: key.chatId,\n fromMe: key.fromMe,\n ...(key.participantId ? { participant: key.participantId } : {}),\n };\n }\n\n #sent(result: ZapoPublishResultLike, chatId: string): SentMessage {\n if (!result.id) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'WhatsApp did not confirm the sent message.',\n );\n }\n\n return {\n id: result.id,\n chatId,\n keys: {\n id: result.id,\n chatId,\n fromMe: true,\n },\n timestamp: new Date(),\n };\n }\n\n\n #normalizeVoipCall(\n event: ZapoVoipCallLike,\n forcedStatus?: CallStatus,\n ): CallEvent | undefined {\n const id = event.callId;\n const from = event.callerPn ?? event.peerJid ?? event.callCreator;\n const chatId = event.groupJid ?? event.peerJid ?? from;\n\n if (!id || !from || !chatId) return undefined;\n\n return {\n id,\n chatId,\n from,\n status: forcedStatus ?? this.#callStatus(event.stateData?.state),\n isVideo: event.mediaType === 'video',\n isGroup: Boolean(event.groupJid),\n date: event.createdAt ?? new Date(),\n };\n }\n\n #callStatus(status: string | null | undefined): CallStatus {\n switch (status?.toLowerCase()) {\n case 'offer':\n case 'initiating':\n return 'offer';\n case 'ringing':\n case 'incoming_ringing':\n return 'ringing';\n case 'preaccept':\n case 'connecting':\n return 'preaccept';\n case 'accept':\n case 'accepted':\n case 'active':\n return 'accept';\n case 'reject':\n case 'rejected':\n case 'terminate':\n case 'terminated':\n case 'ended':\n return 'reject';\n default:\n return 'timeout';\n }\n }\n\n #callEndStatus(reason: string | null | undefined): CallStatus {\n return reason?.toLowerCase() === 'timeout' ? 'timeout' : 'reject';\n }\n\n #groupAction(action: string | null | undefined): GroupParticipantAction | undefined {\n const value = action?.toLowerCase() ?? '';\n if (value.includes('promote')) return 'promote';\n if (value.includes('demote')) return 'demote';\n if (value.includes('remove') || value.includes('leave')) return 'remove';\n if (value.includes('add') || value.includes('join')) return 'add';\n if (value.includes('participant') || value.includes('modify')) return 'modify';\n return undefined;\n }\n\n #groupParticipantIds(event: ZapoGroupEventLike): string[] {\n return uniqueIdentities((event.participants ?? []).map((participant) =>\n participant.jid ?? participant.lidJid ?? participant.phoneJid));\n }\n\n #findStoredMessage(key: ZapoMessageKeyLike): StoredZapoMessage | undefined {\n const direct = this.#messageStore.get(this.#messageStoreKey(key));\n if (direct) return direct;\n if (!key.id) return undefined;\n\n for (const message of this.#messageStore.values()) {\n if (message.key.id === key.id && message.message) return message;\n }\n\n for (const message of this.#messageStore.values()) {\n const embeddedQuoted = extractQuotedZapoMessage(message as WaIncomingMessageEvent);\n if (!embeddedQuoted?.key.id || embeddedQuoted.key.id !== key.id || !embeddedQuoted.message) {\n continue;\n }\n\n const storedQuoted = embeddedQuoted as unknown as StoredZapoMessage;\n this.#remember(storedQuoted);\n return storedQuoted;\n }\n\n return undefined;\n }\n\n #remember(message: StoredZapoMessage): void {\n if (!message.key.id || !message.message) return;\n\n const key = this.#messageStoreKey(message.key);\n this.#messageStore.delete(key);\n this.#messageStore.set(key, message);\n\n while (this.#messageStore.size > this.#messageCacheSize) {\n const oldest = this.#messageStore.keys().next().value as string | undefined;\n if (oldest) this.#messageStore.delete(oldest);\n }\n }\n\n #messageStoreKey(key: ZapoMessageKeyLike): string {\n return `${key.remoteJid ?? ''}:${key.id ?? ''}:${key.participant ?? key.participantAlt ?? ''}`;\n }\n\n #isOfflineMessage(message: StoredZapoMessage): boolean {\n if (this.#options.processOfflineMessages === true) return false;\n if (message.offline === true) return true;\n if (!this.#connectedAtSeconds || message.timestampSeconds == null) return false;\n\n const timestamp = toSeconds(message.timestampSeconds);\n if (timestamp === undefined) return false;\n\n return timestamp < this.#connectedAtSeconds - 3;\n }\n\n #markPairingReady(): void {\n this.#pairingRequired = true;\n this.#resolvePairingReady?.();\n this.#resolvePairingReady = undefined;\n }\n\n #preparePairingGate(): void {\n this.#pairingRequired = false;\n this.#pairingReady = new Promise<void>((resolve) => {\n this.#resolvePairingReady = resolve;\n });\n }\n\n #deviceBrowser(): string {\n return this.#options.browser === Browser.MacOS ? 'safari' : 'chrome';\n }\n\n #deviceOsDisplayName(): string {\n if (this.#options.browser === Browser.MacOS) return 'macOS';\n if (this.#options.browser === Browser.Ubuntu) return 'Ubuntu';\n return 'Windows';\n }\n\n #requireClient(): WaClient {\n const client = this.#client;\n\n if (!client || !this.#connected) {\n throw new WhaNextError(\n 'CONNECTION_CLOSED',\n 'WhatsApp is not connected.',\n { recoverable: true },\n );\n }\n\n return client;\n }\n\n async #withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message: string,\n ): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n reject(new WhaNextError(\n 'CONNECTION_FAILED',\n message,\n { recoverable: true },\n ));\n }, timeoutMs);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n}\n\n\nclass WhaNextZapoLogger implements ZapoLogger {\n readonly level: ZapoLogLevel;\n readonly #logger: Logger;\n readonly #context: Readonly<Record<string, unknown>>;\n\n constructor(\n logger: Logger,\n context: Readonly<Record<string, unknown>> = {},\n ) {\n this.#logger = logger;\n this.#context = context;\n this.level = logger.level === 'debug'\n ? 'debug'\n : logger.level === 'warn'\n ? 'warn'\n : logger.level === 'error' || logger.level === 'silent'\n ? 'error'\n : 'info';\n }\n\n trace(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.debug(message, this.#merge(context));\n }\n\n debug(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.debug(message, this.#merge(context));\n }\n\n info(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.info(message, this.#merge(context));\n }\n\n warn(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.warn(message, this.#merge(context));\n }\n\n error(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.error(message, this.#merge(context));\n }\n\n child(bindings: Readonly<Record<string, unknown>>): ZapoLogger {\n return new WhaNextZapoLogger(this.#logger, {\n ...this.#context,\n ...bindings,\n });\n }\n\n #merge(\n context?: Readonly<Record<string, unknown>>,\n ): Readonly<Record<string, unknown>> {\n return context\n ? { ...this.#context, ...context }\n : this.#context;\n }\n}\n\nfunction toSeconds(value: number | LongLike | null | undefined): number | undefined {\n const raw = typeof value === 'number'\n ? value\n : value?.toNumber\n ? value.toNumber()\n : value?.low;\n\n if (raw === undefined) return undefined;\n return raw > 10_000_000_000 ? Math.floor(raw / 1_000) : raw;\n}\n","import type { Proto, WaIncomingMessageEvent } from 'zapo-js';\nimport { uniqueIdentities } from '@/models/identity.js';\nimport type {\n InteractiveResponse,\n MediaKind,\n Message,\n MessageContentKind,\n MessageKey,\n MessageMedia,\n QuotedMessage,\n} from '@/models/message.js';\nimport { User } from '@/models/user.js';\n\nexport interface ZapoMessageKeyLike {\n remoteJid?: string | null;\n remoteJidAlt?: string | null;\n id?: string | null;\n fromMe?: boolean | null;\n participant?: string | null;\n participantAlt?: string | null;\n senderUsername?: string | null;\n}\n\ninterface EventLike {\n key: ZapoMessageKeyLike;\n message?: Proto.IMessage | null;\n timestampSeconds?: number | null;\n pushName?: string | null;\n}\n\ninterface ContextInfoLike {\n stanzaId?: string | null;\n remoteJid?: string | null;\n participant?: string | null;\n quotedMessage?: Proto.IMessage | null;\n mentionedJid?: string[] | null;\n}\n\ninterface LongLike {\n toNumber?: () => number;\n low?: number;\n}\n\nexport function unwrapZapoMessageContent(\n input: Proto.IMessage | null | undefined,\n): Proto.IMessage | undefined {\n if (!input) return undefined;\n\n const nested = input.ephemeralMessage?.message\n ?? input.viewOnceMessage?.message\n ?? input.viewOnceMessageV2?.message\n ?? viewOnceV2ExtensionMessage(input)\n ?? input.deviceSentMessage?.message\n ?? input.documentWithCaptionMessage?.message;\n\n return nested ? unwrapZapoMessageContent(nested) : input;\n}\n\nfunction viewOnceV2ExtensionMessage(\n input: Proto.IMessage,\n): Proto.IMessage | undefined {\n const extension = (input as Proto.IMessage & {\n viewOnceMessageV2Extension?: {\n message?: Proto.IMessage | null;\n } | null;\n }).viewOnceMessageV2Extension;\n\n return extension?.message ?? undefined;\n}\n\nexport function isZapoViewOnceContent(\n input: Proto.IMessage | null | undefined,\n): boolean {\n if (!input) return false;\n\n if (\n input.viewOnceMessage?.message\n || input.viewOnceMessageV2?.message\n || viewOnceV2ExtensionMessage(input)\n ) {\n return true;\n }\n\n return isZapoViewOnceContent(input.ephemeralMessage?.message);\n}\n\nexport function extractQuotedZapoMessage(\n input: WaIncomingMessageEvent | EventLike,\n): WaIncomingMessageEvent | undefined {\n const event = input as EventLike;\n const chatId = event.key.remoteJid;\n const content = unwrapZapoMessageContent(event.message);\n\n if (!chatId || !content) return undefined;\n\n const { node } = contentNode(content);\n const context = getContextInfo(node);\n\n if (!context?.stanzaId || !context.quotedMessage) return undefined;\n\n return {\n key: {\n id: context.stanzaId,\n remoteJid: context.remoteJid ?? chatId,\n fromMe: false,\n ...(context.participant ? { participant: context.participant } : {}),\n },\n message: context.quotedMessage,\n } as WaIncomingMessageEvent;\n}\n\nexport function normalizeZapoMessage(\n input: WaIncomingMessageEvent | EventLike,\n): Message | undefined {\n const event = input as EventLike;\n const chatId = event.key.remoteJid;\n const id = event.key.id;\n\n if (!chatId || !id || !event.message) {\n return undefined;\n }\n\n const content = unwrapZapoMessageContent(event.message);\n\n if (!content) {\n return undefined;\n }\n\n const { type, node } = contentNode(content);\n const context = getContextInfo(node);\n const isPrivateIncoming = !chatId.endsWith('@g.us') && event.key.fromMe !== true;\n const senderIds = uniqueIdentities([\n event.key.participant,\n event.key.participantAlt,\n event.key.senderUsername?.includes('@')\n ? event.key.senderUsername\n : undefined,\n isPrivateIncoming ? event.key.remoteJidAlt : undefined,\n isPrivateIncoming ? chatId : undefined,\n ]);\n const senderJid = senderIds.find((identity) =>\n identity.endsWith('@s.whatsapp.net') || identity.endsWith('@c.us'));\n const senderLid = senderIds.find((identity) => identity.endsWith('@lid'));\n const senderId = senderJid ?? senderLid ?? senderIds[0] ?? chatId;\n const sender = new User({\n id: senderId,\n identities: senderIds.length > 0 ? senderIds : [senderId],\n ...(event.pushName ? { name: event.pushName } : {}),\n });\n const mentionedIds = [...(context?.mentionedJid ?? [])];\n const mentionedUsers = mentionedIds.map((identity) => User.fromIdentities([identity]));\n const viewOnce = isZapoViewOnceContent(event.message);\n const media = getMedia(type, node, viewOnce);\n const contentKind = getContentKind(type);\n const text = getText(content);\n const caption = getCaption(content);\n const quoted = getQuoted(context, chatId);\n const interactive = getInteractiveResponse(content);\n\n const message: Message = {\n id,\n jid: chatId,\n chatId,\n senderId,\n senderIds: senderIds.length > 0 ? senderIds : [senderId],\n sender,\n keys: normalizeZapoKey(event.key),\n mentions: mentionedIds,\n mentionedUsers,\n timestamp: toDate(event.timestampSeconds),\n isGroup: chatId.endsWith('@g.us'),\n isReply: quoted !== undefined,\n isViewOnce: media?.viewOnce ?? false,\n hasMedia: media !== undefined,\n contentKind,\n };\n\n if (senderJid !== undefined) message.senderJid = senderJid;\n if (senderLid !== undefined) {\n message.lid = senderLid;\n message.senderLid = senderLid;\n }\n if (text !== undefined) message.text = text;\n if (caption !== undefined) message.caption = caption;\n if (media !== undefined) message.media = media;\n if (quoted !== undefined) message.quoted = quoted;\n if (interactive !== undefined) message.interactive = interactive;\n\n return message;\n}\n\nexport function normalizeZapoKey(key: ZapoMessageKeyLike): MessageKey {\n const normalized: MessageKey = {\n id: key.id ?? '',\n chatId: key.remoteJid ?? '',\n fromMe: key.fromMe ?? false,\n };\n const participantId = key.participant ?? key.participantAlt;\n\n if (participantId !== null && participantId !== undefined) {\n normalized.participantId = participantId;\n }\n\n return normalized;\n}\n\nfunction contentNode(content: Proto.IMessage): {\n type: keyof Proto.IMessage | undefined;\n node: unknown;\n} {\n const order: Array<keyof Proto.IMessage> = [\n 'conversation',\n 'extendedTextMessage',\n 'imageMessage',\n 'videoMessage',\n 'audioMessage',\n 'documentMessage',\n 'stickerMessage',\n 'locationMessage',\n 'liveLocationMessage',\n 'contactMessage',\n 'contactsArrayMessage',\n 'buttonsResponseMessage',\n 'listResponseMessage',\n 'templateButtonReplyMessage',\n 'pollCreationMessage',\n 'pollCreationMessageV2',\n 'pollCreationMessageV3',\n 'pollCreationMessageV5',\n 'productMessage',\n 'orderMessage',\n 'interactiveResponseMessage',\n ];\n\n const type = order.find((key) => content[key] !== null && content[key] !== undefined);\n return { type, node: type ? content[type] : undefined };\n}\n\nfunction getContentKind(type: keyof Proto.IMessage | undefined): MessageContentKind {\n switch (String(type ?? '')) {\n case 'conversation':\n case 'extendedTextMessage':\n case 'buttonsResponseMessage':\n case 'listResponseMessage':\n case 'templateButtonReplyMessage':\n case 'interactiveResponseMessage':\n return 'text';\n case 'imageMessage':\n return 'image';\n case 'videoMessage':\n return 'video';\n case 'audioMessage':\n return 'audio';\n case 'documentMessage':\n return 'document';\n case 'stickerMessage':\n return 'sticker';\n case 'locationMessage':\n case 'liveLocationMessage':\n return 'location';\n case 'contactMessage':\n case 'contactsArrayMessage':\n return 'contact';\n case 'pollCreationMessage':\n case 'pollCreationMessageV2':\n case 'pollCreationMessageV3':\n case 'pollCreationMessageV5':\n return 'poll';\n case 'productMessage':\n case 'orderMessage':\n return 'catalog';\n default:\n return 'unknown';\n }\n}\n\nfunction getText(content: Proto.IMessage): string | undefined {\n return content.conversation\n ?? content.extendedTextMessage?.text\n ?? content.buttonsResponseMessage?.selectedDisplayText\n ?? content.listResponseMessage?.title\n ?? content.templateButtonReplyMessage?.selectedDisplayText\n ?? content.pollCreationMessage?.name\n ?? content.pollCreationMessageV2?.name\n ?? content.pollCreationMessageV3?.name\n ?? content.pollCreationMessageV5?.name\n ?? getNativeFlowDisplayText(content)\n ?? undefined;\n}\n\nfunction getInteractiveResponse(content: Proto.IMessage): InteractiveResponse | undefined {\n const buttons = content.buttonsResponseMessage as {\n selectedButtonId?: string | null;\n selectedDisplayText?: string | null;\n } | null | undefined;\n if (buttons?.selectedButtonId) {\n return {\n kind: 'button',\n id: buttons.selectedButtonId,\n ...(buttons.selectedDisplayText ? { title: buttons.selectedDisplayText } : {}),\n };\n }\n\n const template = content.templateButtonReplyMessage as {\n selectedId?: string | null;\n selectedDisplayText?: string | null;\n } | null | undefined;\n if (template?.selectedId) {\n return {\n kind: 'button',\n id: template.selectedId,\n ...(template.selectedDisplayText ? { title: template.selectedDisplayText } : {}),\n };\n }\n\n const list = content.listResponseMessage as {\n title?: string | null;\n singleSelectReply?: { selectedRowId?: string | null } | null;\n } | null | undefined;\n const rowId = list?.singleSelectReply?.selectedRowId;\n if (rowId) {\n return {\n kind: 'list',\n id: rowId,\n ...(list?.title ? { title: list.title } : {}),\n };\n }\n\n const native = nativeFlowParams(content);\n const nativeId = stringField(native, ['id', 'selected_id', 'row_id', 'button_id']);\n if (nativeId) {\n const title = stringField(native, ['display_text', 'title']);\n const nativeName = nativeFlowName(content);\n return {\n kind: nativeName === 'single_select'\n || (native && ('row_id' in native || 'selected_id' in native))\n ? 'list'\n : 'button',\n id: nativeId,\n ...(title ? { title } : {}),\n };\n }\n\n return undefined;\n}\n\n\nfunction nativeFlowName(content: Proto.IMessage): string | undefined {\n const response = content.interactiveResponseMessage as {\n nativeFlowResponseMessage?: {\n name?: string | null;\n } | null;\n } | null | undefined;\n return response?.nativeFlowResponseMessage?.name ?? undefined;\n}\n\nfunction getNativeFlowDisplayText(content: Proto.IMessage): string | undefined {\n return stringField(nativeFlowParams(content), ['display_text', 'title']);\n}\n\nfunction nativeFlowParams(content: Proto.IMessage): Record<string, unknown> | undefined {\n const response = content.interactiveResponseMessage as {\n nativeFlowResponseMessage?: {\n name?: string | null;\n paramsJson?: string | null;\n } | null;\n } | null | undefined;\n const json = response?.nativeFlowResponseMessage?.paramsJson;\n if (!json) return undefined;\n\n try {\n const parsed = JSON.parse(json) as unknown;\n return typeof parsed === 'object' && parsed !== null\n ? parsed as Record<string, unknown>\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction stringField(\n value: Record<string, unknown> | undefined,\n keys: readonly string[],\n): string | undefined {\n if (!value) return undefined;\n for (const key of keys) {\n const field = value[key];\n if (typeof field === 'string' && field.length > 0) return field;\n }\n return undefined;\n}\n\nfunction getCaption(content: Proto.IMessage): string | undefined {\n return content.imageMessage?.caption\n ?? content.videoMessage?.caption\n ?? content.documentMessage?.caption\n ?? undefined;\n}\n\nfunction getContextInfo(node: unknown): ContextInfoLike | undefined {\n if (typeof node !== 'object' || node === null || !('contextInfo' in node)) {\n return undefined;\n }\n\n return (node as { contextInfo?: ContextInfoLike | null }).contextInfo ?? undefined;\n}\n\nfunction getMedia(\n type: keyof Proto.IMessage | undefined,\n node: unknown,\n wrapperViewOnce: boolean,\n): MessageMedia | undefined {\n const mapping: Partial<Record<keyof Proto.IMessage, MediaKind>> = {\n imageMessage: 'image',\n videoMessage: 'video',\n audioMessage: 'audio',\n documentMessage: 'document',\n stickerMessage: 'sticker',\n };\n const kind = type ? mapping[type] : undefined;\n\n if (!kind || typeof node !== 'object' || node === null) {\n return undefined;\n }\n\n const value = node as {\n mimetype?: string | null;\n fileName?: string | null;\n seconds?: number | LongLike | null;\n viewOnce?: boolean | null;\n };\n const media: MessageMedia = {\n kind,\n viewOnce: wrapperViewOnce || value.viewOnce === true,\n };\n\n if (value.mimetype) media.mimetype = value.mimetype;\n if (value.fileName) media.fileName = value.fileName;\n\n const seconds = toNumber(value.seconds);\n if (seconds !== undefined) media.seconds = seconds;\n\n return media;\n}\n\nfunction getQuoted(\n context: ContextInfoLike | undefined,\n chatId: string,\n): QuotedMessage | undefined {\n if (!context?.stanzaId || !context.quotedMessage) return undefined;\n\n const content = unwrapZapoMessageContent(context.quotedMessage);\n if (!content) return undefined;\n\n const { type, node } = contentNode(content);\n const media = getMedia(type, node, isZapoViewOnceContent(context.quotedMessage));\n const senderId = context.participant ?? undefined;\n const quoted: QuotedMessage = {\n key: {\n id: context.stanzaId,\n chatId: context.remoteJid ?? chatId,\n fromMe: false,\n ...(senderId ? { participantId: senderId } : {}),\n },\n hasMedia: media !== undefined,\n isViewOnce: media?.viewOnce ?? false,\n contentKind: getContentKind(type),\n };\n const text = getText(content) ?? getCaption(content);\n\n if (text !== undefined) quoted.text = text;\n if (senderId !== undefined) {\n quoted.senderId = senderId;\n quoted.sender = User.fromIdentities([senderId]);\n }\n if (media !== undefined) quoted.media = media;\n\n return quoted;\n}\n\nfunction toDate(value: number | LongLike | null | undefined): Date {\n const seconds = toNumber(value) ?? Math.floor(Date.now() / 1000);\n return new Date(seconds * 1_000);\n}\n\nfunction toNumber(value: number | LongLike | null | undefined): number | undefined {\n if (typeof value === 'number') return value;\n if (value?.toNumber) return value.toNumber();\n if (typeof value?.low === 'number') return value.low;\n return undefined;\n}\n","import { WhaNextApp } from '@/app/whanext-app.js';\nimport { Browser } from '@/auth/browser.js';\nimport type { CacheOptions } from '@/cache/cache-store.js';\nimport type { RouterOptions } from '@/commands/router.js';\nimport {\n Logger,\n type LoggerConfig,\n} from '@/logger/logger.js';\nimport type { MuteOptions } from '@/mute/mute-store.js';\nimport { ZapoProvider } from '@/provider/zapo/zapo-provider.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport interface ReconnectOptions {\n enabled?: boolean;\n maxAttempts?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n}\n\nexport interface CreateOptions {\n phone?: string;\n browser?: Browser;\n auth?: string;\n prefix?: string | readonly string[];\n cache?: CacheOptions;\n logger?: LoggerConfig;\n mute?: MuteOptions;\n router?: Omit<RouterOptions, 'prefix'>;\n reconnect?: ReconnectOptions;\n messageCacheSize?: number;\n processOfflineMessages?: boolean;\n provider?: WhatsAppProvider;\n accountId?: string;\n}\n\nexport async function create(options: CreateOptions = {}): Promise<WhaNextApp> {\n const logger = new Logger(options.logger);\n const provider = options.provider ?? new ZapoProvider({\n auth: options.auth ?? './session',\n browser: options.browser ?? Browser.Windows,\n logger: logger.child('provider'),\n ...(options.accountId ? { sessionId: options.accountId } : {}),\n ...(options.messageCacheSize !== undefined\n ? { messageCacheSize: options.messageCacheSize }\n : {}),\n ...(options.processOfflineMessages !== undefined\n ? { processOfflineMessages: options.processOfflineMessages }\n : {}),\n ...(options.reconnect ? { reconnect: options.reconnect } : {}),\n });\n\n return new WhaNextApp(provider, {\n ...(options.accountId ? { accountId: options.accountId } : {}),\n ...(options.phone ? { phone: options.phone } : {}),\n ...(options.prefix !== undefined ? { prefix: options.prefix } : {}),\n ...(options.cache ? { cache: options.cache } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n ...(options.mute ? { mute: options.mute } : {}),\n ...(options.router ? { router: options.router } : {}),\n }, logger);\n}\n","import {\n join,\n resolve,\n} from 'node:path';\nimport {\n create,\n type CreateOptions,\n} from '@/app/create.js';\nimport {\n type AppEvents,\n type AppHealth,\n type LoginOptions,\n WhaNextApp,\n} from '@/app/whanext-app.js';\nimport type {\n CommandDefinition,\n CommandMiddleware,\n} from '@/commands/command.js';\nimport type {\n CommandErrorHandler,\n} from '@/commands/router.js';\nimport type {\n LoadCommandsOptions,\n LoadCommandsResult,\n} from '@/commands/load-commands.js';\nimport { WhaNextError } from '@/errors/error.js';\n\nexport interface MultiAccountOptions extends Omit<CreateOptions, 'accountId'> {\n id: string;\n}\n\nexport interface CreateMultiOptions extends Omit<CreateOptions, 'accountId' | 'auth' | 'phone' | 'provider'> {\n accounts: readonly MultiAccountOptions[];\n authRoot?: string;\n}\n\nexport interface MultiLoginOptions extends Omit<LoginOptions, 'onCode'> {\n onCode?: (accountId: string, code: string) => void | Promise<void>;\n}\n\nexport interface MultiAppHealth extends AppHealth {\n accountId: string;\n}\n\nexport interface MultiAppEvent<Event extends keyof AppEvents> {\n accountId: string;\n app: WhaNextApp;\n payload: AppEvents[Event];\n}\n\nexport interface MultiLoadCommandsResult {\n accountId: string;\n result: LoadCommandsResult;\n}\n\nexport class MultiCommandRouter {\n readonly #apps: ReadonlyMap<string, WhaNextApp>;\n\n constructor(apps: ReadonlyMap<string, WhaNextApp>) {\n this.#apps = apps;\n }\n\n command(definition: CommandDefinition): this {\n for (const app of this.#apps.values()) {\n app.commands.command(definition);\n }\n return this;\n }\n\n use(middleware: CommandMiddleware): this {\n for (const app of this.#apps.values()) {\n app.commands.use(middleware);\n }\n return this;\n }\n\n onError(handler: CommandErrorHandler): () => void {\n const unsubscribe = [...this.#apps.values()].map((app) => app.commands.onError(handler));\n return () => {\n for (const remove of unsubscribe) remove();\n };\n }\n\n async load(\n dirPath: string | URL,\n options: LoadCommandsOptions = {},\n ): Promise<readonly MultiLoadCommandsResult[]> {\n return Promise.all([...this.#apps].map(async ([accountId, app]) => ({\n accountId,\n result: await app.commands.load(dirPath, options),\n })));\n }\n}\n\nexport class WhaNextMultiApp {\n readonly commands: MultiCommandRouter;\n readonly #apps: ReadonlyMap<string, WhaNextApp>;\n\n constructor(apps: ReadonlyMap<string, WhaNextApp>) {\n this.#apps = apps;\n this.commands = new MultiCommandRouter(apps);\n }\n\n get size(): number {\n return this.#apps.size;\n }\n\n get isReady(): boolean {\n return this.#apps.size > 0 && [...this.#apps.values()].every((app) => app.isReady);\n }\n\n ids(): readonly string[] {\n return [...this.#apps.keys()];\n }\n\n has(accountId: string): boolean {\n return this.#apps.has(accountId);\n }\n\n get(accountId: string): WhaNextApp | undefined {\n return this.#apps.get(accountId);\n }\n\n values(): readonly WhaNextApp[] {\n return [...this.#apps.values()];\n }\n\n router(): MultiCommandRouter {\n return this.commands;\n }\n\n on<Event extends keyof AppEvents>(\n event: Event,\n listener: (entry: MultiAppEvent<Event>) => void | Promise<void>,\n ): () => void {\n const unsubscribe = [...this.#apps].map(([accountId, app]) =>\n app.on(event, (payload) => listener({ accountId, app, payload })));\n\n return () => {\n for (const remove of unsubscribe) remove();\n };\n }\n\n health(): readonly MultiAppHealth[] {\n return [...this.#apps].map(([accountId, app]) => ({\n accountId,\n ...app.health(),\n }));\n }\n\n async login(options: MultiLoginOptions = {}): Promise<void> {\n const results = await Promise.allSettled(\n [...this.#apps].map(async ([accountId, app]) => {\n await app.login({\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n ...(options.onCode\n ? { onCode: (code: string) => options.onCode?.(accountId, code) }\n : {}),\n });\n }),\n );\n const failures = results\n .map((result, index) => ({ result, accountId: this.ids()[index] }))\n .filter((entry): entry is {\n result: PromiseRejectedResult;\n accountId: string;\n } => entry.result.status === 'rejected' && entry.accountId !== undefined);\n\n if (failures.length === 0) {\n return;\n }\n\n throw new WhaNextError(\n 'CONNECTION_FAILED',\n 'One or more WhatsApp accounts could not complete login.',\n {\n cause: new AggregateError(\n failures.map(({ result }) => result.reason),\n 'Multi-account login failed.',\n ),\n context: {\n accounts: failures.map(({ accountId }) => accountId),\n },\n recoverable: true,\n },\n );\n }\n\n async disconnect(): Promise<void> {\n const results = await Promise.allSettled(\n [...this.#apps.values()].map((app) => app.disconnect()),\n );\n const failures = results.filter((result): result is PromiseRejectedResult =>\n result.status === 'rejected');\n\n if (failures.length > 0) {\n throw new WhaNextError(\n 'CONNECTION_FAILED',\n 'One or more WhatsApp accounts could not disconnect cleanly.',\n {\n cause: new AggregateError(\n failures.map((result) => result.reason),\n 'Multi-account disconnect failed.',\n ),\n recoverable: true,\n },\n );\n }\n }\n}\n\nexport async function createMulti(options: CreateMultiOptions): Promise<WhaNextMultiApp> {\n if (options.accounts.length === 0) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'At least one WhatsApp account is required.',\n );\n }\n\n const {\n accounts,\n authRoot = './sessions',\n ...shared\n } = options;\n const normalizedIds = new Set<string>();\n const authPaths = new Set<string>();\n\n for (const account of accounts) {\n validateAccountId(account.id);\n const normalizedId = account.id.toLowerCase();\n\n if (normalizedIds.has(normalizedId)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The multi-account id \"${account.id}\" is duplicated.`,\n );\n }\n\n normalizedIds.add(normalizedId);\n\n if (account.provider === undefined) {\n const authPath = resolve(account.auth ?? join(authRoot, account.id));\n\n if (authPaths.has(authPath)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Each WhatsApp account must use a different auth directory.',\n { context: { auth: authPath } },\n );\n }\n\n authPaths.add(authPath);\n }\n }\n\n const apps = new Map<string, WhaNextApp>();\n\n for (const account of accounts) {\n const {\n id,\n ...overrides\n } = account;\n const merged = mergeCreateOptions(shared, overrides);\n\n if (\n merged.mute?.enabled === true\n && merged.mute.store === undefined\n && merged.mute.database === undefined\n ) {\n merged.mute = {\n ...merged.mute,\n database: join('./data', `whanext-${id}.sqlite`),\n };\n }\n\n const app = await create({\n ...merged,\n accountId: id,\n auth: overrides.auth ?? join(authRoot, id),\n });\n apps.set(id, app);\n }\n\n return new WhaNextMultiApp(apps);\n}\n\nfunction validateAccountId(accountId: string): void {\n if (!/^[a-z0-9][a-z0-9_-]{0,63}$/.test(accountId)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Multi-account ids must use lowercase letters, numbers, underscores or hyphens.',\n { context: { accountId } },\n );\n }\n}\n\nfunction mergeCreateOptions(\n shared: Omit<CreateMultiOptions, 'accounts' | 'authRoot'>,\n account: Omit<MultiAccountOptions, 'id'>,\n): CreateOptions {\n const merged: CreateOptions = {\n ...shared,\n ...account,\n };\n\n if (shared.cache || account.cache) {\n merged.cache = {\n ...shared.cache,\n ...account.cache,\n };\n }\n\n if (shared.mute || account.mute) {\n merged.mute = {\n ...shared.mute,\n ...account.mute,\n };\n }\n\n if (shared.router || account.router) {\n merged.router = {\n ...shared.router,\n ...account.router,\n };\n }\n\n if (shared.reconnect || account.reconnect) {\n merged.reconnect = {\n ...shared.reconnect,\n ...account.reconnect,\n };\n }\n\n if (\n shared.logger\n && account.logger\n && typeof shared.logger === 'object'\n && typeof account.logger === 'object'\n ) {\n merged.logger = {\n ...shared.logger,\n ...account.logger,\n };\n }\n\n return merged;\n}\n","import type { CommandContext } from '@/commands/context.js';\nimport type { WhaNextErrorCode } from '@/errors/error.js';\n\nexport interface GuardResult {\n allowed: boolean;\n code?: WhaNextErrorCode;\n message?: string;\n}\n\nexport type CommandGuard = (\n context: CommandContext,\n) => boolean | void | GuardResult | Promise<boolean | void | GuardResult>;\n\nexport const guards = {\n owner(): CommandGuard {\n return (context) => context.isOwner || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'This command can only be used by the connected WhatsApp account.',\n });\n },\n\n group(): CommandGuard {\n return (context) => context.isGroup || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'This command can only be used in groups.',\n });\n },\n\n private(): CommandGuard {\n return (context) => !context.isGroup || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'This command can only be used in private chats.',\n });\n },\n\n userAdmin(): CommandGuard {\n return async (context) => (\n context.isGroup\n && await context.groups.isAdmin(context.chatId, context.senderIds)\n ) || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'This command can only be used by group administrators.',\n });\n },\n\n botAdmin(): CommandGuard {\n return async (context) => (\n context.isGroup\n && await context.groups.isCurrentUserAdmin(context.chatId)\n ) || ({\n allowed: false,\n code: 'BOT_NOT_ADMIN',\n message: 'The connected WhatsApp account must be a group administrator.',\n });\n },\n\n botEnabled(\n check: (context: CommandContext) => boolean | Promise<boolean>,\n ): CommandGuard {\n return async (context) => await check(context) || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'Commands are disabled in this chat.',\n });\n },\n\n custom(guard: CommandGuard): CommandGuard {\n return guard;\n },\n};\n"],"mappings":";AAiBO,IAAM,cAAN,MAAwC;AAAA,EACpC,WAAW,oBAAI,IAAwB;AAAA,EACvC;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,eAAe;AAAA,EAEf,YAAY,UAAmC,CAAC,GAAG;AACjD,SAAK,cAAc,KAAK,IAAI,GAAG,QAAQ,cAAc,GAAK;AAAA,EAC5D;AAAA,EAEA,MAAM,IAAO,KAAqC;AAChD,UAAM,QAAQ,KAAK,SAAS,IAAI,GAAG;AAEnC,QAAI,CAAC,OAAO;AACV,WAAK,WAAW;AAChB,aAAO;AAAA,IACT;AAEA,QAAI,MAAM,cAAc,UAAa,MAAM,aAAa,KAAK,IAAI,GAAG;AAClE,WAAK,SAAS,OAAO,GAAG;AACxB,WAAK,WAAW;AAChB,WAAK,gBAAgB;AACrB,aAAO;AAAA,IACT;AAEA,SAAK,SAAS;AACd,SAAK,SAAS,OAAO,GAAG;AACxB,SAAK,SAAS,IAAI,KAAK,KAAK;AAC5B,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,IAAO,KAAa,OAAU,OAA+B;AACjE,UAAM,QAAoB,EAAE,MAAM;AAElC,QAAI,UAAU,QAAW;AACvB,YAAM,YAAY,KAAK,IAAI,IAAI;AAAA,IACjC;AAEA,SAAK,SAAS;AACd,SAAK,SAAS,OAAO,GAAG;AACxB,SAAK,SAAS,IAAI,KAAK,KAAK;AAE5B,WAAO,KAAK,SAAS,OAAO,KAAK,aAAa;AAC5C,YAAM,SAAS,KAAK,SAAS,KAAK,EAAE,KAAK,EAAE;AAC3C,UAAI,WAAW,OAAW;AAC1B,WAAK,SAAS,OAAO,MAAM;AAC3B,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,KAA4B;AACvC,SAAK,SAAS,OAAO,GAAG;AAAA,EAC1B;AAAA,EAEA,MAAM,QAAuB;AAC3B,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EAEA,MAAM,MAAM,KAAK,IAAI,GAAW;AAC9B,QAAI,UAAU;AAEd,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,UAAU;AACxC,UAAI,MAAM,cAAc,UAAa,MAAM,aAAa,KAAK;AAC3D,aAAK,SAAS,OAAO,GAAG;AACxB,mBAAW;AAAA,MACb;AAAA,IACF;AAEA,SAAK,gBAAgB;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,QAAoC;AAClC,WAAO;AAAA,MACL,MAAM,KAAK,SAAS;AAAA,MACpB,YAAY,KAAK;AAAA,MACjB,MAAM,KAAK;AAAA,MACX,QAAQ,KAAK;AAAA,MACb,MAAM,KAAK;AAAA,MACX,WAAW,KAAK;AAAA,MAChB,aAAa,KAAK;AAAA,IACpB;AAAA,EACF;AACF;;;AC5EO,IAAM,eAAN,cAA2B,MAAM;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,MACA,SACA,UAA+B,CAAC,GAChC;AACA,UAAM,SAAS,EAAE,OAAO,QAAQ,MAAM,CAAC;AACvC,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,UAAU,QAAQ,WAAW,CAAC;AACnC,SAAK,cAAc,QAAQ,eAAe;AAAA,EAC5C;AACF;AAEO,SAAS,eACd,OACA,SACc;AACd,MAAI,iBAAiB,cAAc;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,SAAO,IAAI,aAAa,iBAAiB,SAAS;AAAA,IAChD,OAAO;AAAA,IACP,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC/B,CAAC;AACH;;;AC1DO,SAAS,kBAAkB,UAA0B;AAC1D,QAAM,QAAQ,SAAS,KAAK,EAAE,YAAY;AAC1C,QAAM,YAAY,MAAM,YAAY,GAAG;AAEvC,MAAI,cAAc,IAAI;AACpB,WAAO,MAAM,QAAQ,OAAO,EAAE;AAAA,EAChC;AAEA,QAAM,OAAO,MAAM,MAAM,GAAG,SAAS,EAAE,QAAQ,SAAS,EAAE;AAC1D,QAAM,YAAY,MAAM,MAAM,YAAY,CAAC;AAC3C,QAAM,SAAS,cAAc,SAAS,mBAAmB;AACzD,SAAO,GAAG,IAAI,IAAI,MAAM;AAC1B;AAEO,SAAS,iBAAiB,UAA0B;AACzD,QAAM,aAAa,kBAAkB,QAAQ;AAC7C,QAAM,YAAY,WAAW,YAAY,GAAG;AAC5C,SAAO,cAAc,KAAK,aAAa,WAAW,MAAM,GAAG,SAAS;AACtE;AAEO,SAAS,oBAAoB,UAAsC;AACxE,QAAM,aAAa,kBAAkB,QAAQ;AAE7C,MAAI,WAAW,SAAS,MAAM,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,iBAAiB,UAAU;AAC5C,SAAO,QAAQ,KAAK,QAAQ,IAAI,WAAW;AAC7C;AAEO,SAAS,gBAAgB,MAAc,OAAwB;AACpE,SAAO,kBAAkB,IAAI,MAAM,kBAAkB,KAAK;AAC5D;AAEO,SAAS,iBAAiB,YAAgE;AAC/F,QAAM,SAAS,WAAW,OAAO,CAAC,aAAiC,QAAQ,QAAQ,CAAC;AACpF,SAAO,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC,kBAAkB,QAAQ,GAAG,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;AAChG;;;ACtBO,IAAM,OAAN,MAAM,MAAK;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,MAAgB;AAC1B,UAAM,aAAa,iBAAiB;AAAA,MAClC,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,GAAI,KAAK,cAAc,CAAC;AAAA,IAC1B,CAAC;AAED,SAAK,MAAM,KAAK,OAAO,WAAW,KAAK,CAAC,aACtC,SAAS,SAAS,iBAAiB,KAAK,SAAS,SAAS,OAAO,CAAC;AACpE,SAAK,MAAM,KAAK,OAAO,WAAW,KAAK,CAAC,aAAa,SAAS,SAAS,MAAM,CAAC;AAC9E,SAAK,cAAc,KAAK,eAAe,KAAK;AAC5C,SAAK,OAAO,KAAK;AACjB,SAAK,KAAK,KAAK,OAAO,KAAK,eAAe,KAAK,OAAO,KAAK;AAC3D,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,OAAO,KAAK,eAAe,KAAK,OAAO,KAAK;AAAA,EAC1D;AAAA,EAEA,IAAI,UAAkB;AACpB,WAAO,IAAI,KAAK,QAAQ;AAAA,EAC1B;AAAA,EAEA,IAAI,QAA4B;AAC9B,WAAO,KAAK,cAAc,oBAAoB,KAAK,WAAW,IAAI;AAAA,EACpE;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,iBAAiB,KAAK,SAAS;AAAA,EACxC;AAAA,EAEA,IAAI,cAAsB;AACxB,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC3B;AAAA,EAEA,QAAQ,UAAkC;AACxC,UAAM,aAAa,OAAO,aAAa,WAAW,CAAC,QAAQ,IAAI,SAAS;AACxE,WAAO,KAAK,WAAW,KAAK,CAAC,gBAC3B,WAAW,KAAK,CAAC,cAAc,gBAAgB,aAAa,SAAS,CAAC,CAAC;AAAA,EAC3E;AAAA,EAEA,SAAmB;AACjB,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,YAAY,KAAK;AAAA,MACjB,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;AAAA,MACpC,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;AAAA,MACpC,GAAI,KAAK,cAAc,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,MAC5D,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,OAAO,eAAe,YAAqC;AACzD,UAAM,CAAC,EAAE,IAAI;AAEb,QAAI,CAAC,IAAI;AACP,YAAM,IAAI,UAAU,wCAAwC;AAAA,IAC9D;AAEA,WAAO,IAAI,MAAK,EAAE,IAAI,WAAW,CAAC;AAAA,EACpC;AAAA,EAEA,OAAO,gBAAgB,aAA2B;AAChD,UAAM,aAAa,YAAY,QAAQ,OAAO,EAAE;AAEhD,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,IAAI,UAAU,0DAA0D;AAAA,IAChF;AAEA,WAAO,MAAK,eAAe,CAAC,GAAG,UAAU,iBAAiB,CAAC;AAAA,EAC7D;AACF;;;AC3FO,IAAM,aAAN,MAAiB;AAAA,EACb;AAAA,EACT,UAAU;AAAA,EAEV,YAAY,QAA2B;AACrC,SAAK,UAAU,CAAC,GAAG,MAAM;AAAA,EAC3B;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,QAAQ,SAAS,KAAK;AAAA,EACpC;AAAA,EAEA,OAA2B;AACzB,WAAO,KAAK,QAAQ,KAAK,OAAO;AAAA,EAClC;AAAA,EAEA,KAAK,QAAQ,GAAS;AACpB,SAAK,UAAU,KAAK,IAAI,KAAK,QAAQ,QAAQ,KAAK,UAAU,KAAK,IAAI,GAAG,KAAK,CAAC;AAC9E,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,OAAO,YAAY,UAA2B,CAAC,GAAuB;AAC3E,WAAO,KAAK,SAAS,MAAM,OAAO;AAAA,EACpC;AAAA,EAEA,OAAO,OAAO,UAAU,UAA2B,CAAC,GAAuB;AACzE,UAAM,MAAM,KAAK,SAAS,MAAM,OAAO;AAEvC,QAAI,QAAQ,QAAW;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,OAAO,GAAG;AAExB,QAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,YAAM,IAAI,aAAa,oBAAoB,iBAAiB,IAAI,uBAAuB;AAAA,QACrF,SAAS,EAAE,MAAM,UAAU,IAAI;AAAA,MACjC,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,OAAO,WAAW,UAA2B,CAAC,GAAwB;AAC5E,UAAM,MAAM,KAAK,SAAS,MAAM,OAAO;AAEvC,QAAI,QAAQ,QAAW;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,IAAI,YAAY;AACnC,UAAM,SAAS,oBAAI,IAAI,CAAC,QAAQ,MAAM,OAAO,OAAO,GAAG,CAAC;AACxD,UAAM,QAAQ,oBAAI,IAAI,CAAC,SAAS,OAAO,MAAM,UAAO,OAAO,GAAG,CAAC;AAE/D,QAAI,OAAO,IAAI,UAAU,GAAG;AAC1B,aAAO;AAAA,IACT;AAEA,QAAI,MAAM,IAAI,UAAU,GAAG;AACzB,aAAO;AAAA,IACT;AAEA,UAAM,IAAI,aAAa,oBAAoB,iBAAiB,IAAI,wBAAwB;AAAA,MACtF,SAAS,EAAE,MAAM,UAAU,IAAI;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAEA,KACE,QACA,OAAO,UACP,UAA2B,CAAC,GACA;AAC5B,UAAM,MAAM,KAAK,SAAS,MAAM,OAAO;AAEvC,QAAI,QAAQ,QAAW;AACrB,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,iBAAiB,IAAI,qBAAqB,OAAO,KAAK,IAAI,CAAC;AAAA,QAC3D;AAAA,UACE,SAAS,EAAE,MAAM,UAAU,KAAK,UAAU,OAAO;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAIA,KAAK,OAAO,QAAQ,UAA2B,CAAC,GAAqB;AACnE,UAAM,MAAM,KAAK,SAAS,MAAM,OAAO;AAEvC,QAAI,QAAQ,QAAW;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,IAAI,QAAQ,MAAM,EAAE,EAAE,QAAQ,OAAO,EAAE;AAE1D,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,iBAAiB,IAAI;AAAA,QACrB;AAAA,UACE,SAAS,EAAE,MAAM,UAAU,IAAI;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,gBAAgB,UAAU;AAAA,EACxC;AAAA,EAEA,SAAS,OAAO,YAAY,UAA2B,CAAC,GAAuB;AAC7E,UAAM,MAAM,KAAK,SAAS,MAAM,OAAO;AAEvC,QAAI,QAAQ,QAAW;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,IAAI,YAAY;AACnC,UAAM,YAAY,oBAAI,IAAI;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,UAAU,IAAI,UAAU,GAAG;AAC7B,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,sBAAsB,KAAK,UAAU;AAEnD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR;AAAA,QACA,iBAAiB,IAAI;AAAA,QACrB;AAAA,UACE,SAAS,EAAE,MAAM,UAAU,IAAI;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,OAAO,MAAM,CAAC,CAAC;AAC9B,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,aAAa,EAAE,IAAI,GAAG,GAAG,KAAO,GAAG,KAAQ,GAAG,MAAW,GAAG,MAAW,EAAE,IAAI;AACnF,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,OAAe;AACb,UAAM,QAAQ,KAAK,QAAQ,MAAM,KAAK,OAAO,EAAE,KAAK,GAAG;AACvD,SAAK,UAAU,KAAK,QAAQ;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,MAAc,SAA8C;AACnE,UAAM,QAAQ,KAAK,QAAQ,KAAK,OAAO;AAEvC,QAAI,UAAU,QAAW;AACvB,UAAI,QAAQ,UAAU;AACpB,eAAO;AAAA,MACT;AAEA,YAAM,IAAI,aAAa,oBAAoB,iBAAiB,IAAI,kBAAkB;AAAA,QAChF,SAAS,EAAE,MAAM,UAAU,KAAK,QAAQ;AAAA,MAC1C,CAAC;AAAA,IACH;AAEA,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AACF;;;AClGO,SAAS,cACd,SACqC;AACrC,SAAO;AACT;AAEO,SAAS,iBACd,SACqC;AACrC,SAAO;AACT;AAEO,SAAS,mBAA+D,OAAqB;AAClG,SAAO;AACT;AAEO,SAAS,kBACX,UACO;AACV,SAAO;AACT;AAEO,SAAS,eACd,YACsC;AACtC,SAAO,iBAAiB;AAC1B;;;AClGO,IAAM,+BAAN,MAAmC;AAAA,EAC/B,UAAU,oBAAI,IAA4B;AAAA,EAEnD,MAAM,IACJ,KACA,SACA,SACe;AACf,UAAM,WAAW,SAAS,YAAY;AACtC,QAAI,aAAa,YAAY;AAC3B,YAAM,QAAQ,IAAI,gBAAgB,EAAE,MAAM;AAC1C;AAAA,IACF;AAEA,UAAM,MAAM,KAAK,IAAI,GAAG,SAAS,OAAO,CAAC;AACzC,UAAM,QAAQ,KAAK,QAAQ,IAAI,GAAG,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,aAAa,oBAAI,IAAI,EAAE;AACtF,SAAK,QAAQ,IAAI,KAAK,KAAK;AAE3B,QAAI,aAAa,WAAW;AAC1B,iBAAWA,eAAc,MAAM,YAAa,CAAAA,YAAW,MAAM;AAC7D,YAAM,YAAY,MAAM;AAAA,IAC1B,WAAW,aAAa,YAAY,MAAM,UAAU,KAAK;AACvD,YAAM,IAAI,aAAa,gBAAgB,oCAAoC;AAAA,QACzE,SAAS,EAAE,KAAK,IAAI;AAAA,QACpB,aAAa;AAAA,MACf,CAAC;AAAA,IACH,WAAW,aAAa,WAAW,MAAM,UAAU,KAAK;AACtD,YAAM,IAAI,QAAc,CAACC,aAAY,MAAM,MAAM,KAAKA,QAAO,CAAC;AAAA,IAChE;AAEA,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,YAAY,IAAI,UAAU;AAChC,UAAM,UAAU;AAEhB,QAAI;AACF,YAAM,QAAQ,WAAW,MAAM;AAAA,IACjC,UAAE;AACA,YAAM,YAAY,OAAO,UAAU;AACnC,YAAM,UAAU;AAChB,YAAM,MAAM,MAAM,IAAI;AAEtB,UAAI,MAAM,WAAW,KAAK,MAAM,MAAM,WAAW,GAAG;AAClD,aAAK,QAAQ,OAAO,GAAG;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AACF;;;ACmDA,IAAM,+BAAN,MAAuE;AAAA,EAC5D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EAEA,YAAY,SAA8C;AACxD,SAAK,UAAU,QAAQ;AACvB,SAAK,OAAO,QAAQ,QAAQ;AAC5B,SAAK,UAAU,QAAQ,SAAS;AAChC,SAAK,UAAU,KAAK,QAAQ,QAAQ,QAAQ,OAAO;AACnD,SAAK,OAAO,EAAE,IAAI,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,QAAQ;AAC3E,SAAK,UAAU,QAAQ;AACvB,SAAK,WAAW,QAAQ;AACxB,SAAK,SAAS,QAAQ,UAAU,QAAQ,SAAS;AACjD,SAAK,UAAU,QAAQ;AACvB,SAAK,OAAO,QAAQ;AACpB,SAAK,SAAS,QAAQ;AACtB,SAAK,SAAS,QAAQ;AACtB,SAAK,SAAS,QAAQ;AACtB,SAAK,WAAW,QAAQ,SAAS;AACjC,SAAK,eAAe,QAAQ,SAAS;AACrC,SAAK,SAAS,QAAQ,SAAS;AAC/B,SAAK,UAAU,QAAQ,SAAS;AAChC,SAAK,QAAQ,QAAQ,SAAS;AAC9B,SAAK,QAAQ,QAAQ,SAAS;AAC9B,SAAK,cAAc,QAAQ,SAAS;AACpC,SAAK,QAAQ,QAAQ,QAAQ,UACzB,KAAK,oBAAoB,QAAQ,OAAO,IACxC;AACJ,WAAO,OAAO,MAAM,QAAQ,OAAO;AAAA,EACrC;AAAA,EAEA,MAAM,MAAM,SAAkC,UAAwB,CAAC,GAAyB;AAC9F,UAAM,OAAO,MAAM,KAAK,SAAS,MAAM,KAAK,SAAS,iBAAiB,OAAO,CAAC;AAC9E,SAAK,aAAa;AAClB,SAAK,kBAAkB,MAAM,QAAQ,aAAa;AAClD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MACJ,UAAmC,2BACX;AACxB,UAAM,OAAO,MAAM,KAAK,MAAM,OAAO;AACrC,WAAO,IAAI,cAAc,KAAK,UAAU,MAAM,CAAC,YAAY;AACzD,WAAK,aAAa;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,KAAK,SAAuC;AAChD,QAAI,CAAC,KAAK,YAAY;AACpB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,SAAS,KAAK,KAAK,YAAY,OAAO;AAChE,SAAK,aAAa;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAqC;AACzC,WAAO,KAAK,SAAS,MAAM,KAAK,SAAS,KAAK;AAAA,EAChD;AAAA,EAEA,UAAgC;AAC9B,WAAO,KAAK,SAAS,QAAQ,KAAK,OAAO;AAAA,EAC3C;AAAA,EAEA,SAAwB;AACtB,WAAO,KAAK,SAAS,OAAO,KAAK,OAAO;AAAA,EAC1C;AAAA,EAEA,MAAM,YAAY,UAAwB,CAAC,GAAkB;AAC3D,QAAI,CAAC,KAAK,WAAY;AAEtB,QAAI,QAAQ,kBAAkB,UAAa,QAAQ,gBAAgB,GAAG;AACpE,WAAK,kBAAkB,KAAK,YAAY,QAAQ,aAAa;AAC7D;AAAA,IACF;AAEA,UAAM,KAAK,SAAS,OAAO,KAAK,UAAU;AAC1C,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,oBAAoB,SAAuC;AACzD,WAAO;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ,UAAU,CAAC,YAAY,KAAK,OAAO,SAAS,QAAQ,QAAQ,OAAO;AAAA,MACnE,aAAa,MAAM,KAAK,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,SAAS;AAAA,MACxE,YAAY,MAAM,KAAK,OAAO,mBAAmB,QAAQ,MAAM;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,kBAAkB,SAAsB,SAAwB;AAC9D,QAAI,YAAY,UAAa,WAAW,EAAG;AAE3C,UAAM,QAAQ,WAAW,MAAM;AAC7B,WAAK,KAAK,SAAS,OAAO,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,IAC1D,GAAG,OAAO;AACV,UAAM,QAAQ;AAAA,EAChB;AACF;AAEO,IAAM,gBAAN,MAAoB;AAAA,EAChB;AAAA,EACT;AAAA,EACS;AAAA,EAET,YACE,UACA,SACA,QACA;AACA,SAAK,YAAY;AACjB,SAAK,WAAW;AAChB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,KAAK,SAAuC;AAChD,SAAK,WAAW,MAAM,KAAK,UAAU,KAAK,KAAK,UAAU,OAAO;AAChE,SAAK,QAAQ,KAAK,QAAQ;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,SAAwB;AACtB,WAAO,KAAK,UAAU,OAAO,KAAK,QAAQ;AAAA,EAC5C;AACF;AAEO,SAAS,qBACd,SACwB;AACxB,SAAO,IAAI,6BAA6B,OAAO;AACjD;AAEA,SAAS,iBAAiB,SAAkD;AAC1E,SAAO,OAAO,YAAY,WAAW,EAAE,MAAM,QAAQ,IAAI;AAC3D;;;ACzQA,SAAS,eAAe;AACxB,OAAO,UAAU;AACjB,SAAS,eAAe,qBAAqB;AAyB7C,IAAM,qBAAqB,CAAC,OAAO,QAAQ,QAAQ,OAAO,QAAQ,MAAM;AAExE,eAAsB,aACpB,WACA,SACA,UAA+B,CAAC,GACH;AAC7B,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,kBAAkB,mBAAmB,MAAM,cAAc,OAAO,IAAI;AAE1E,QAAM,UAAU,MAAM,YAAY,iBAAiB,SAAS;AAC5D,QAAM,SAAmB,CAAC;AAC1B,QAAM,UAAoB,CAAC;AAC3B,QAAM,WAA4B,CAAC;AAEnC,aAAW,YAAY,SAAS;AAC9B,QAAI,kBAAkB,QAAQ,KAAK,CAAC,WAAW,SAAS,KAAK,QAAQ,QAAQ,CAAC,GAAG;AAC/E,cAAQ,KAAK,QAAQ;AACrB;AAAA,IACF;AAEA,UAAM,cAAc,MAAM,eAAe,QAAQ;AAEjD,eAAW,cAAc,aAAa;AACpC,gBAAU,QAAQ,UAAU;AAC5B,eAAS,KAAK,EAAE,MAAM,WAAW,MAAM,SAAS,CAAC;AAAA,IACnD;AAEA,WAAO,KAAK,QAAQ;AAAA,EACtB;AAEA,SAAO,EAAE,QAAQ,SAAS,SAAS;AACrC;AAEA,eAAe,YAAY,SAAiB,WAAuC;AACjF,MAAI;AAEJ,MAAI;AACF,cAAU,MAAM,QAAQ,SAAS,EAAE,WAAW,eAAe,KAAK,CAAC;AAAA,EACrE,SAAS,OAAO;AACd,UAAM,IAAI,aAAa,uBAAuB,0CAA0C,OAAO,MAAM;AAAA,MACnG,OAAO;AAAA,MACP,SAAS,EAAE,QAAQ;AAAA,IACrB,CAAC;AAAA,EACH;AAEA,SAAO,QACJ,OAAO,CAAC,WAAW,OAAO,OAAO,CAAC,EAClC,IAAI,CAAC,WAAW,KAAK,KAAK,OAAO,YAAY,OAAO,IAAI,CAAC,EACzD,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC;AACpD;AAEA,eAAe,eAAe,UAAgD;AAC5E,MAAI;AAEJ,MAAI;AACF,aAAS,MAAM,OAAO,cAAc,QAAQ,EAAE;AAAA,EAChD,SAAS,OAAO;AACd,UAAM,IAAI,aAAa,uBAAuB,sCAAsC,QAAQ,MAAM;AAAA,MAChG,OAAO;AAAA,MACP,SAAS,EAAE,SAAS;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,QAAM,cAAmC,CAAC;AAC1C,QAAM,OAAO,oBAAI,IAAuB;AACxC,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,IACP,GAAG,OAAO,QAAQ,MAAM,EACrB,OAAO,CAAC,CAAC,IAAI,MAAM,SAAS,SAAS,EACrC,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,KAAK;AAAA,EAC7B;AAEA,aAAW,SAAS,SAAS;AAC3B,UAAM,aAAa,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAExD,eAAW,aAAa,YAAY;AAClC,UAAI,oBAAoB,SAAS,KAAK,CAAC,KAAK,IAAI,SAAS,GAAG;AAC1D,aAAK,IAAI,SAAS;AAClB,oBAAY,KAAK,SAAS;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY,WAAW,GAAG;AAC5B,UAAM,IAAI,aAAa,uBAAuB,aAAa,QAAQ,yCAAyC;AAAA,MAC1G,SAAS,EAAE,SAAS;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAA4C;AACvE,QAAM,YAAY;AAClB,SACE,OAAO,UAAU,YACd,UAAU,QACV,OAAO,UAAU,SAAS,aAE3B,OAAQ,UAAoC,YAAY,cACrD,MAAM,QAAQ,UAAU,WAAW;AAG5C;AAEA,SAAS,kBAAkB,UAA2B;AACpD,SAAO,uBAAuB,KAAK,QAAQ;AAC7C;;;AC7EO,IAAM,SAAS;AAAA,EACpB,OAA4D,YAAwB;AAClF,WAAO,EAAE,MAAM,UAAmB,GAAG,WAAW;AAAA,EAClD;AAAA,EACA,OAA4D,YAAwB;AAClF,WAAO,EAAE,MAAM,UAAmB,GAAG,WAAW;AAAA,EAClD;AAAA,EACA,QAA8D,YAAwB;AACpF,WAAO,EAAE,MAAM,WAAoB,GAAG,WAAW;AAAA,EACnD;AAAA,EACA,KAAwD,YAAwB;AAC9E,WAAO,EAAE,MAAM,QAAiB,GAAG,WAAW;AAAA,EAChD;AAAA,EACA,SAAgE,YAAwB;AACtF,WAAO,EAAE,MAAM,YAAqB,GAAG,WAAW;AAAA,EACpD;AAAA,EACA,KAGE,QAAgB,YAAwB;AACxC,WAAO,EAAE,MAAM,QAAiB,QAAQ,GAAG,WAAW;AAAA,EACxD;AACF;AAEO,IAAM,uBAAN,MAAqF;AAAA,EACjF;AAAA,EAET,YAAY,QAAqC;AAC/C,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,IAA+B,MAA8C;AAC3E,WAAO,KAAK,QAAQ,IAAI;AAAA,EAC1B;AAAA,EAEA,OAAkC,MAA8C;AAC9E,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,OAAkC,MAA8C;AAC9E,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,QAAmC,MAA8C;AAC/E,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,KAAgC,MAA8C;AAC5E,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,SAAoC,MAA8C;AAChF,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,KAAgC,MAA8C;AAC5E,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,SAAsC;AACpC,WAAO,EAAE,GAAG,KAAK,QAAQ;AAAA,EAC3B;AACF;AAEA,eAAsB,oBACpB,QACA,QACA,SACA,OACuC;AACvC,QAAM,OAAO,IAAI,WAAW,MAAM;AAClC,QAAM,SAAkC,CAAC;AAEzC,aAAW,CAAC,MAAM,UAAU,KAAK,OAAO,QAAQ,UAAU,CAAC,CAAC,GAAG;AAC7D,UAAM,WAAW,WAAW,aAAa;AAEzC,QAAI,WAAW,SAAS,QAAQ;AAC9B,YAAM,kBAAkB,QAAQ,eAAe,SAAS,KAAK,QAAQ,QAAQ,WAAW;AACxF,UAAI,YAAY,CAAC,mBAAmB,KAAK,cAAc,GAAG;AACxD,eAAO,IAAI,IAAI;AAAA,MACjB,OAAO;AACL,eAAO,IAAI,IAAI,MAAM,MAAM,QAAQ,SAAS,IAAI;AAAA,MAClD;AACA;AAAA,IACF;AAEA,UAAM,kBAAkB,WAAW,EAAE,UAAU,KAAc,IAAI;AAEjE,QAAI,WAAW,SAAS,UAAU;AAChC,YAAM,QAAQ,WAAW,OAAO,KAAK,KAAK,IAAI,KAAK,OAAO,MAAM,eAAe;AAC/E,UAAI,WAAW,YAAY,CAAC,OAAO;AACjC,cAAM,QAAQ,IAAI;AAAA,MACpB;AACA,UAAI,UAAU,UAAa,WAAW,cAAc,UAAa,MAAM,SAAS,WAAW,WAAW;AACpG,cAAM,QAAQ,MAAM,OAAO,YAAY,WAAW,SAAS,aAAa;AAAA,MAC1E;AACA,UAAI,UAAU,UAAa,WAAW,cAAc,UAAa,MAAM,SAAS,WAAW,WAAW;AACpG,cAAM,QAAQ,MAAM,OAAO,WAAW,WAAW,SAAS,aAAa;AAAA,MACzE;AACA,aAAO,IAAI,IAAI,SAAS;AAAA,IAC1B,WAAW,WAAW,SAAS,UAAU;AACvC,YAAM,QAAQ,KAAK,OAAO,MAAM,eAAe;AAC/C,UAAI,UAAU,UAAa,WAAW,QAAQ,UAAa,QAAQ,WAAW,KAAK;AACjF,cAAM,QAAQ,MAAM,OAAO,YAAY,WAAW,GAAG,EAAE;AAAA,MACzD;AACA,UAAI,UAAU,UAAa,WAAW,QAAQ,UAAa,QAAQ,WAAW,KAAK;AACjF,cAAM,QAAQ,MAAM,OAAO,WAAW,WAAW,GAAG,EAAE;AAAA,MACxD;AACA,aAAO,IAAI,IAAI;AAAA,IACjB,WAAW,WAAW,SAAS,WAAW;AACxC,aAAO,IAAI,IAAI,KAAK,QAAQ,MAAM,eAAe;AAAA,IACnD,WAAW,WAAW,SAAS,YAAY;AACzC,aAAO,IAAI,IAAI,KAAK,SAAS,MAAM,eAAe;AAAA,IACpD,OAAO;AACL,aAAO,IAAI,IAAI,KAAK,KAAK,WAAW,QAAQ,MAAM,eAAe;AAAA,IACnE;AAAA,EACF;AAEA,MAAI,WAAW,UAAa,KAAK,YAAY,GAAG;AAC9C,UAAM,IAAI,aAAa,oBAAoB,qCAAqC;AAAA,MAC9E,SAAS,EAAE,WAAW,KAAK,UAAU;AAAA,IACvC,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,qBAAqB,MAAqC;AACvE;AAEA,SAAS,QAAQ,MAA4B;AAC3C,SAAO,IAAI,aAAa,oBAAoB,iBAAiB,IAAI,kBAAkB;AAAA,IACjF,SAAS,EAAE,KAAK;AAAA,EAClB,CAAC;AACH;AAEA,SAAS,QAAQ,MAAc,UAAmB,UAAgC;AAChF,SAAO,IAAI,aAAa,oBAAoB,iBAAiB,IAAI,aAAa,QAAQ,KAAK;AAAA,IACzF,SAAS,EAAE,MAAM,UAAU,SAAS;AAAA,EACtC,CAAC;AACH;;;AChMO,IAAM,cAAN,MAAkB;AAAA,EACd;AAAA,EAET,YAAY,OAAqB;AAC/B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,QAAQ,SAAkB,MAAiC;AAC/D,UAAM,YAAY,QAAQ,eAAe,CAAC;AAC1C,QAAI;AAEJ,QAAI,WAAW;AACb,UAAI,KAAK,KAAK,GAAG,WAAW,GAAG,GAAG;AAChC,aAAK,KAAK;AAAA,MACZ;AAEA,aAAO;AAAA,IACT,WAAW,QAAQ,QAAQ,QAAQ;AACjC,aAAO,QAAQ,OAAO;AAAA,IACxB,OAAO;AACL,aAAO,KAAK,KAAK,QAAQ;AAAA,IAC3B;AAEA,WAAO,KAAK,OAAO,YAAY,QAAQ,QAAQ,IAAI;AAAA,EACrD;AAAA,EAEA,KAAK,UAAwB;AAC3B,QAAI,CAAC,SAAS,SAAS,GAAG,GAAG;AAC3B,aAAO,KAAK,gBAAgB,QAAQ;AAAA,IACtC;AAEA,WAAO,KAAK,eAAe,CAAC,QAAQ,CAAC;AAAA,EACvC;AACF;;;AC0BO,IAAM,gBAAN,MAAoB;AAAA,EAChB,SAAS,oBAAI,IAA4B;AAAA,EACzC,mBAAmB,oBAAI,IAA4B;AAAA,EACnD,eAAe,oBAAI,IAAuB;AAAA,EACnD,UAAU;AAAA,EACV,YAA+B,CAAC,GAAG;AAAA,EACnC,oBAAuC,CAAC,GAAG;AAAA,EAClC;AAAA,EACA;AAAA,EACA,oBAAyC,CAAC;AAAA,EAC1C,iBAAwC,CAAC;AAAA,EACzC,aAAa,oBAAI,IAAoB;AAAA,EACrC,eAAe,IAAI,6BAA6B;AAAA,EAChD;AAAA,EACA;AAAA,EACT,sBAAsB;AAAA,EAItB,YACE,iBACA,UAAyB,CAAC,GAC1B;AACA,SAAK,YAAY,kBAAkB,eAAe,IAC9C,kBACA,qBAAqB,eAAe;AACxC,SAAK,YAAY,QAAQ,UAAU,GAAG;AACtC,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,gBAAgB,QAAQ;AAC7B,QAAI,QAAQ,eAAgB,MAAK,eAAe,KAAK,QAAQ,cAAc;AAAA,EAC7E;AAAA,EAEA,IAAI,SAAiB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,WAA8B;AAChC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,UAA4C;AACtD,UAAM,aAAa,kBAAkB,QAAQ;AAC7C,SAAK,YAAY;AACjB,SAAK,oBAAoB,CAAC,GAAG,UAAU,EAAE,KAAK,CAAC,MAAM,UAAU,MAAM,SAAS,KAAK,MAAM;AACzF,SAAK,UAAU,WAAW,CAAC;AAC3B,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,QAAQ,EAAE,eAAe,KAAK,CAAC,EAAE;AAAA,EAC/C;AAAA,EAEA,QAAQ,YAAqC;AAC3C,SAAK,cAAc,YAAY,CAAC,CAAC;AAEjC,eAAW,QAAQ,aAAa,UAAU,GAAG;AAC3C,YAAM,aAAa,KAAK,MAAM,YAAY;AAE1C,UAAI,KAAK,OAAO,IAAI,UAAU,GAAG;AAC/B,cAAM,IAAI;AAAA,UACR;AAAA,UACA,gBAAgB,UAAU;AAAA,QAC5B;AAAA,MACF;AAEA,WAAK,OAAO,IAAI,YAAY;AAAA,QAC1B;AAAA,QACA,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,MAC/C,CAAC;AAAA,IACH;AAEA,eAAW,QAAQ,uBAAuB,UAAU,GAAG;AACrD,YAAM,aAAa,KAAK,MAAM,YAAY;AAE1C,UAAI,KAAK,iBAAiB,IAAI,UAAU,GAAG;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA,mCAAmC,UAAU;AAAA,QAC/C;AAAA,MACF;AAEA,WAAK,iBAAiB,IAAI,YAAY;AAAA,QACpC;AAAA,QACA,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,MAC/C,CAAC;AAAA,IACH;AAEA,SAAK,aAAa,IAAI,UAAU;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,SAAuB,UAA+B,CAAC,GAAgC;AAC1F,WAAO,aAAa,MAAM,SAAS,OAAO;AAAA,EAC5C;AAAA,EAEA,IAAI,YAAqC;AACvC,SAAK,kBAAkB,KAAK,UAAU;AACtC,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,SAA0C;AAChD,SAAK,eAAe,KAAK,OAAO;AAChC,WAAO,MAAM;AACX,YAAM,QAAQ,KAAK,eAAe,QAAQ,OAAO;AACjD,UAAI,SAAS,EAAG,MAAK,eAAe,OAAO,OAAO,CAAC;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,QAAQ,UAAiC,CAAC,GAAiC;AACzE,UAAM,WAAW,CAAC,GAAG,KAAK,YAAY,EAAE,QAAQ,CAAC,eAC/C,gBAAgB,UAAU,CAAC;AAC7B,WAAO,SAAS,OAAO,CAAC,aACrB,QAAQ,iBAAiB,CAAC,QAAQ,WAAW,YAC1C,CAAC,QAAQ,YAAY,QAAQ,aAAa,QAAQ,SACvD;AAAA,EACH;AAAA,EAEA,aAAgC;AAC9B,WAAO,CAAC,GAAG,IAAI,IAAI,KAAK,QAAQ,EAAE,IAAI,CAAC,YAAY,QAAQ,QAAQ,CAAC,CAAC,EAAE,KAAK;AAAA,EAC9E;AAAA,EAEA,IAAIC,OAAuB;AACzB,WAAO,KAAK,KAAKA,KAAI,MAAM;AAAA,EAC7B;AAAA,EAEA,SAAuC;AACrC,WAAO,KAAK,QAAQ,EAAE,eAAe,KAAK,CAAC;AAAA,EAC7C;AAAA,EAEA,KAAKA,OAA6C;AAChD,UAAM,aAAaA,MAAK,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK;AACxD,WAAO,KAAK,QAAQ,EAAE,eAAe,KAAK,CAAC,EAAE,KAAK,CAAC,YACjD,QAAQ,KAAK,KAAK,GAAG,EAAE,YAAY,MAAM,WAAW,KAAK,GAAG,KACzD,QAAQ,QAAQ,KAAK,CAAC,UAAU,MAAM,YAAY,MAAM,WAAW,GAAG,EAAE,CAAC,CAAC;AAAA,EACjF;AAAA,EAEA,MAAM,KACJ,SACA,UAA8B,CAAC,GACT;AACtB,UAAM,WAAW,KAAK,QAAQ,OAAO;AACrC,UAAM,QAAQ,QAAQ,UAAU,QAAQ,WACpC,cAAO,QAAQ,QAAQ,MACvB;AACJ,UAAM,QAAQ,SAAS,IAAI,CAAC,YAAY;AACtC,YAAM,QAAQ,QAAQ,WAAW,SAC5B,GAAG,KAAK,OAAO,GAAG,QAAQ,KAAK,KAAK,GAAG,CAAC,GAAG,cAAc,QAAQ,UAAU,CAAC;AACjF,YAAM,cAAc,QAAQ,SACxB,QAAQ,WAAW,gBAAgB,QAAQ,MAAM,GAAG,eACjD,QAAQ,WAAW,cACtB,QAAQ,WAAW;AACvB,aAAO,WAAM,KAAK;AAAA,IAAQ,WAAW;AAAA,IACvC,CAAC;AACD,UAAM,OAAO,MAAM,SAAS,IACxB,GAAG,KAAK;AAAA;AAAA,EAAO,MAAM,KAAK,MAAM,CAAC,KACjC,GAAG,KAAK;AAAA;AAAA;AACZ,WAAO,QAAQ,MAAM,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,SAAS,SAAoC;AACjD,UAAM,QAAQ,QAAQ,aAAa,MAAM,QAAQ,OAAO,KAAK;AAC7D,QAAI,CAAC,KAAM,QAAO;AAElB,UAAM,gBAAgB,KAAK,aAAa,IAAI;AAC5C,UAAM,SAAS,SAAS,kBAAkB,SAAY,OAAO,KAAK,MAAM,cAAc,MAAM,CAAC;AAC7F,UAAM,WAAW,OAAO,MAAM,GAAG,YAAY;AAC7C,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,OAAO,kBAAkB,SAC3B,KAAK,iBAAiB,IAAI,QAAQ,IAClC,KAAK,OAAO,IAAI,QAAQ;AAC5B,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,mBAAmB,iBAAiB;AAE1C,QAAI;AAEJ,QAAI;AACF,iBAAW,KAAK,SAAS,MAAM,MAAM;AAAA,IACvC,SAAS,OAAO;AACd,YAAM,aAAa,eAAe,OAAO,EAAE,SAAS,KAAK,WAAW,MAAM,WAAW,QAAQ,GAAG,CAAC;AACjG,YAAM,qBAAkD;AAAA,QACtD,GAAG,KAAK;AAAA,QACR,SAAS,MAAM;AAAA,MACjB;AACA,YAAMC,WAAU,qBAAqB;AAAA,QACnC;AAAA,QACA,SAAS;AAAA,UACP,YAAY;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,MAAM,CAAC,KAAK,WAAW,IAAI;AAAA,UAC3B,SAAS,KAAK,WAAW,WAAW,CAAC;AAAA,UACrC,UAAU,KAAK,WAAW,YAAY;AAAA,QACxC;AAAA,QACA,SAAS,IAAI,qBAAqB,CAAC,CAAC;AAAA,QACpC,MAAM,IAAI,WAAW,MAAM;AAAA,QAC3B,UAAU,KAAK;AAAA,QACf,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,QAAQ,IAAI,gBAAgB,EAAE;AAAA,QAC9B,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,MAC/C,CAAC;AACD,UAAI,KAAK,WAAW,OAAO,SAAS;AAClC,cAAM,KAAK,WAAW,MAAM,QAAQA,UAAS,UAAU;AACvD,eAAO;AAAA,MACT;AACA,UAAI,KAAK,eAAe,SAAS,GAAG;AAClC,mBAAW,WAAW,KAAK,eAAgB,OAAM,QAAQA,UAAS,UAAU;AAC5E,eAAO;AAAA,MACT;AACA,UAAI,KAAK,gBAAgB;AACvB,cAAM,KAAK,eAAe,YAAY,OAAO;AAC7C,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAEA,UAAM,aAAa,IAAI,WAAW,SAAS,MAAM;AACjD,QAAI;AAEJ,QAAI;AACF,YAAM,gBAAgB,MAAM;AAAA,QAC1B,SAAS,WAAW,WAAW;AAAA,QAC/B,SAAS;AAAA,QACT;AAAA,QACA,KAAK,UAAU;AAAA,MACjB;AACA,YAAM,cAAc,CAAC,GAAG,SAAS,MAAM,EACpC,QAAQ,EACR,KAAK,CAAC,UAAU,MAAM,WAAW,GAAG;AACvC,YAAM,iBAAiB,KAAK;AAAA,QAC1B;AAAA,QACA;AAAA,QACA,aAAa,SAAS;AAAA,MACxB;AAEA,YAAM,KAAK,aAAa;AAAA,QACtB;AAAA,QACA;AAAA,QACA,OAAO,WAAW;AAChB,oBAAU,qBAAqB;AAAA,YAC7B;AAAA,YACA,SAAS,SAAS;AAAA,YAClB,SAAS;AAAA,YACT,MAAM;AAAA,YACN,UAAU,KAAK;AAAA,YACf,UAAU;AAAA,YACV,QAAQ;AAAA,YACR;AAAA,YACA,GAAI,SAAS,SAAS,EAAE,QAAQ,SAAS,OAAO,IAAI,CAAC;AAAA,UACvD,CAAC;AAED,gBAAM,KAAK,WAAW,SAAS,QAAQ,OAAO;AAC9C,eAAK,iBAAiB,UAAU,OAAO;AACvC,gBAAM,KAAK,SAAS,UAAU,OAAO;AAAA,QACvC;AAAA,MACF;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,aAAa,eAAe,OAAO;AAAA,QACvC,SAAS,SAAS,WAAW,KAAK,KAAK,GAAG;AAAA,QAC1C,WAAW,QAAQ;AAAA,MACrB,CAAC;AACD,kBAAY,qBAAqB;AAAA,QAC/B;AAAA,QACA,SAAS,SAAS;AAAA,QAClB,SAAS,IAAI,qBAAqB,CAAC,CAAC;AAAA,QACpC,MAAM;AAAA,QACN,UAAU,KAAK;AAAA,QACf,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,QAAQ,IAAI,gBAAgB,EAAE;AAAA,QAC9B,GAAI,SAAS,SAAS,EAAE,QAAQ,SAAS,OAAO,IAAI,CAAC;AAAA,MACvD,CAAC;AAED,UAAI,MAAM,KAAK,aAAa,UAAU,SAAS,UAAU,EAAG,QAAO;AACnE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,aAAa,MAAkC;AAC7C,WAAO,KAAK,kBAAkB,KAAK,CAAC,WAAW,KAAK,WAAW,MAAM,CAAC;AAAA,EACxE;AAAA,EAEA,SAAS,MAAsB,aAAiD;AAC9E,UAAM,SAAS,CAAC,GAAG,WAAW;AAC9B,UAAM,SAA8B,CAAC,KAAK,UAAU;AACpD,QAAI,UAAU,KAAK;AACnB,QAAI,SAAS,KAAK;AAElB,WAAO,eAAe,OAAO,GAAG;AAC9B,YAAM,OAAO,OAAO,MAAM,GAAG,YAAY;AACzC,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,aAAa,oBAAoB,4BAA4B,QAAQ,IAAI,MAAM;AAAA,UACvF,SAAS,EAAE,SAAS,QAAQ,KAAK;AAAA,QACnC,CAAC;AAAA,MACH;AAEA,YAAM,QAAQ,UAAU,QAAQ,aAAa,IAAI;AACjD,UAAI,CAAC,OAAO;AACV,cAAM,IAAI,aAAa,oBAAoB,mBAAmB,IAAI,qBAAqB;AAAA,UACrF,SAAS,EAAE,SAAS,QAAQ,MAAM,YAAY,KAAK;AAAA,QACrD,CAAC;AAAA,MACH;AAEA,gBAAU,MAAM;AAChB,iBAAW,MAAM;AACjB,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAMD,QAAO,OAAO,IAAI,CAAC,eAAe,WAAW,IAAI;AACvD,WAAO;AAAA,MACL,YAAY;AAAA,QACV,YAAY;AAAA,QACZ,MAAM,KAAK;AAAA,QACX,MAAAA;AAAA,QACA,SAAS,QAAQ,WAAW,CAAC;AAAA,QAC7B,UAAU,QAAQ,YAAY,KAAK,WAAW,YAAY;AAAA,MAC5D;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,QAAsC,SAAwC;AAC7F,eAAW,WAAW,QAAQ;AAC5B,YAAM,KAAK,iBAAiB,SAAS,OAAO;AAC5C,iBAAW,SAAS,QAAQ,UAAU,CAAC,EAAG,OAAM,SAAS,OAAO,OAAO;AAAA,IACzE;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,SAA4B,SAAwC;AACzF,QAAI,QAAQ,aAAa,CAAC,QAAQ,SAAS;AACzC,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,QAAQ,aAAa,CAAC,QAAQ,SAAS;AACzC,YAAM,IAAI,aAAa,uBAAuB,0CAA0C;AAAA,IAC1F;AACA,QAAI,QAAQ,eAAe,QAAQ,SAAS;AAC1C,YAAM,IAAI,aAAa,uBAAuB,iDAAiD;AAAA,IACjG;AACA,QAAI,QAAQ,aAAa,CAAE,MAAM,KAAK,UAAU,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,GAAI;AAClG,YAAM,IAAI,aAAa,uBAAuB,wDAAwD;AAAA,IACxG;AACA,QAAI,QAAQ,kBAAkB,CAAE,MAAM,KAAK,UAAU,OAAO,mBAAmB,QAAQ,MAAM,GAAI;AAC/F,YAAM,IAAI,aAAa,iBAAiB,+DAA+D;AAAA,IACzG;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,UAA2B,SAAwC;AAChF,UAAM,QAAQ,SAAS,OAAO,IAAI,CAAC,UAAU,MAAM,KAAK,EAAE,OAAO,OAAO;AACxE,QAAI,KAAK,eAAgB,OAAM,KAAK,eAAe,OAAO;AAC1D,eAAW,QAAQ,MAAO,OAAM,KAAK,gBAAgB,OAAO;AAE5D,UAAM,aAAa;AAAA,MACjB,GAAG,KAAK;AAAA,MACR,GAAG,SAAS,OAAO,QAAQ,CAAC,UAAU,MAAM,cAAc,CAAC,CAAC;AAAA,IAC9D;AACA,UAAM,kBAAkB,YAAY,SAAS,YAAY;AACvD,YAAM,SAAS,WAAW,WAAW,QAAQ,SAAS,QAAQ,IAAI;AAAA,IACpE,CAAC;AAED,eAAW,QAAQ,CAAC,GAAG,KAAK,EAAE,QAAQ,EAAG,OAAM,KAAK,eAAe,OAAO;AAC1E,QAAI,KAAK,cAAe,OAAM,KAAK,cAAc,OAAO;AAAA,EAC1D;AAAA,EAEA,iBAAiB,UAA2B,SAA+B;AACzE,UAAM,SAAS,CAAC,GAAG,SAAS,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,MAAM,QAAQ,GAAG;AAC/E,QAAI,CAAC,UAAU,OAAO,cAAc,EAAG;AAEvC,UAAM,MAAM,KAAK,cAAc,UAAU,SAAS,OAAO,SAAS,MAAM;AACxE,UAAM,MAAM,KAAK,IAAI;AACrB,SAAK,uBAAuB;AAC5B,QAAI,KAAK,sBAAsB,QAAQ,EAAG,MAAK,gBAAgB,GAAG;AAClE,UAAM,YAAY,KAAK,WAAW,IAAI,GAAG,KAAK;AAE9C,QAAI,YAAY,KAAK;AACnB,YAAM,IAAI,aAAa,oBAAoB,gCAAgC;AAAA,QACzE,SAAS,EAAE,cAAc,YAAY,KAAK,IAAI;AAAA,QAC9C,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAEA,SAAK,WAAW,IAAI,KAAK,MAAM,OAAO,UAAU;AAAA,EAClD;AAAA,EAEA,gBAAgB,KAAmB;AACjC,eAAW,CAAC,KAAK,SAAS,KAAK,KAAK,YAAY;AAC9C,UAAI,aAAa,IAAK,MAAK,WAAW,OAAO,GAAG;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,cACE,UACA,SACA,OACQ;AACR,UAAM,UAAU,SAAS,WAAW,KAAK,KAAK,GAAG,EAAE,YAAY;AAC/D,QAAI,UAAU,SAAU,QAAO;AAC/B,QAAI,UAAU,OAAQ,QAAO,GAAG,OAAO,SAAS,QAAQ,QAAQ;AAChE,QAAI,UAAU,OAAQ,QAAO,GAAG,OAAO,SAAS,QAAQ,MAAM;AAC9D,WAAO,GAAG,OAAO,cAAc,QAAQ,QAAQ,IAAI,QAAQ,MAAM;AAAA,EACnE;AAAA,EAEA,MAAM,aACJ,UACA,SACA,OACkB;AAClB,eAAW,SAAS,CAAC,GAAG,SAAS,MAAM,EAAE,QAAQ,GAAG;AAClD,UAAI,MAAM,OAAO,SAAS;AACxB,cAAM,MAAM,MAAM,QAAQ,SAAS,KAAK;AACxC,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI,KAAK,eAAe,SAAS,GAAG;AAClC,iBAAW,WAAW,KAAK,eAAgB,OAAM,QAAQ,SAAS,KAAK;AACvE,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,gBAAgB;AACvB,YAAM,KAAK,eAAe,OAAO,QAAQ,OAAO;AAChD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,YAA+B,SAAkC;AAC7E,QAAI,CAAC,WAAW,KAAK,KAAK,KAAK,KAAK,KAAK,WAAW,IAAI,GAAG;AACzD,YAAM,IAAI,aAAa,oBAAoB,wDAAwD;AAAA,QACjG,SAAS,EAAE,MAAM,WAAW,KAAK;AAAA,MACnC,CAAC;AAAA,IACH;AAEA,eAAW,QAAQ,aAAa,UAAU,GAAG;AAC3C,UAAI,CAAC,KAAK,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC/C,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,UACA,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,EAAE;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,WAAW,cAAc,QAAQ,SAAS,GAAG;AAC/C,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,SAAS,EAAE,SAAS,WAAW,KAAK,EAAE;AAAA,MAC1C;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,WAAW,UAAU,GAAG;AACxC,YAAM,YAAY,IAAI,IAAI,aAAa,UAAU,EAAE,IAAI,CAAC,SAAS,KAAK,MAAM,YAAY,CAAC,CAAC;AAC1F,iBAAW,WAAW,WAAW,YAAY;AAC3C,cAAM,aAAa,QAAQ,KAAK,EAAE,YAAY;AAC9C,YAAI,CAAC,cAAc,KAAK,KAAK,OAAO,KAAK,CAAC,UAAU,IAAI,UAAU,GAAG;AACnE,gBAAM,IAAI;AAAA,YACR;AAAA,YACA;AAAA,YACA,EAAE,SAAS,EAAE,SAAS,WAAW,MAAM,QAAQ,EAAE;AAAA,UACnD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,eAAe,UAAU,EAAG;AACjC,QAAI,WAAW,YAAY,WAAW,GAAG;AACvC,YAAM,IAAI,aAAa,oBAAoB,sBAAsB,WAAW,IAAI,aAAa;AAAA,IAC/F;AAEA,UAAM,QAAQ,oBAAI,IAAY;AAC9B,eAAW,SAAS,WAAW,aAAa;AAC1C,iBAAW,QAAQ,aAAa,KAAK,GAAG;AACtC,cAAM,aAAa,KAAK,MAAM,YAAY;AAC1C,YAAI,MAAM,IAAI,UAAU,GAAG;AACzB,gBAAM,IAAI,aAAa,oBAAoB,yBAAyB,UAAU,MAAM;AAAA,YAClF,SAAS,EAAE,MAAM,CAAC,GAAG,SAAS,WAAW,IAAI,EAAE,KAAK,GAAG,EAAE;AAAA,UAC3D,CAAC;AAAA,QACH;AACA,cAAM,IAAI,UAAU;AAAA,MACtB;AACA,WAAK,cAAc,OAAO,CAAC,GAAG,SAAS,WAAW,IAAI,CAAC;AAAA,IACzD;AAAA,EACF;AACF;AAEA,eAAe,SAAS,OAAqB,SAAwC;AACnF,QAAM,SAAS,MAAM,MAAM,OAAO;AAClC,MAAI,WAAW,UAAa,WAAW,KAAM;AAE7C,QAAM,aAA0B,WAAW,QAAQ,EAAE,SAAS,MAAM,IAAI;AACxE,MAAI,WAAW,QAAS;AACxB,QAAM,IAAI;AAAA,IACR,WAAW,QAAQ;AAAA,IACnB,WAAW,WAAW;AAAA,EACxB;AACF;AAEA,eAAe,kBACb,YACA,SACA,SACe;AACf,MAAI,QAAQ;AACZ,QAAM,WAAW,OAAO,aAAoC;AAC1D,QAAI,YAAY,MAAO,OAAM,IAAI,MAAM,mCAAmC;AAC1E,YAAQ;AACR,UAAM,UAAU,WAAW,QAAQ;AACnC,QAAI,CAAC,QAAS,QAAO,QAAQ;AAC7B,UAAM,QAAQ,SAAS,MAAM,SAAS,WAAW,CAAC,CAAC;AAAA,EACrD;AACA,QAAM,SAAS,CAAC;AAClB;AAEA,SAAS,kBAAkB,OAAsD;AAC/E,QAAM,SAAS,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI,CAAC,GAAG,KAAK;AAC9D,QAAM,WAAW,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC;AAEpC,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,IAAI,aAAa,oBAAoB,0CAA0C;AAAA,EACvF;AAEA,aAAW,UAAU,UAAU;AAC7B,QAAI,OAAO,WAAW,KAAK,KAAK,KAAK,MAAM,GAAG;AAC5C,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,SAAS,EAAE,OAAO,EAAE;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBACP,YAC2C;AAC3C,MAAI,CAAC,WAAW,WAAY,QAAO,CAAC;AAEpC,QAAM,QAAQ,aAAa,UAAU;AACrC,MAAI,WAAW,eAAe,KAAM,QAAO;AAE3C,QAAM,UAAU,IAAI,IAAI,WAAW,WAAW,IAAI,CAAC,SAAS,KAAK,YAAY,CAAC,CAAC;AAC/E,SAAO,MAAM,OAAO,CAAC,SAAS,QAAQ,IAAI,KAAK,MAAM,YAAY,CAAC,CAAC;AACrE;AAEA,SAAS,aAAa,YAA0E;AAC9F,QAAM,QAAmD;AAAA,IACvD,WAAW;AAAA,IACX,GAAI,WAAW,WAAW,CAAC;AAAA,EAC7B,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE;AAC5B,aAAW,CAAC,QAAQ,YAAY,KAAK,OAAO,QAAQ,WAAW,iBAAiB,CAAC,CAAC,GAAG;AACnF,QAAI,aAAa,KAAM,OAAM,KAAK,EAAE,OAAO,aAAa,MAAM,OAAO,CAAC;AACtE,eAAW,SAAS,aAAa,WAAW,CAAC,EAAG,OAAM,KAAK,EAAE,OAAO,OAAO,OAAO,CAAC;AAAA,EACrF;AACA,SAAO;AACT;AAEA,SAAS,UACP,aACA,MACgE;AAChE,aAAW,cAAc,aAAa;AACpC,UAAM,QAAQ,aAAa,UAAU,EAAE,KAAK,CAAC,cAAc,UAAU,MAAM,YAAY,MAAM,IAAI;AACjG,QAAI,MAAO,QAAO,EAAE,YAAY,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC,EAAG;AAAA,EACpF;AACA,SAAO;AACT;AAEA,SAAS,gBACP,MACA,UAAwC,CAAC,GACpB;AACrB,MAAI,eAAe,IAAI,GAAG;AACxB,WAAO,KAAK,YAAY,QAAQ,CAAC,UAAU,gBAAgB,OAAO,CAAC,GAAG,SAAS,IAAI,CAAC,CAAC;AAAA,EACvF;AAEA,QAAM,kBAAkB,CAAC,GAAG,SAAS,IAAI;AACzC,SAAO,CAAC;AAAA,IACN,YAAY;AAAA,IACZ,MAAM,gBAAgB,CAAC,KAAK;AAAA,IAC5B,MAAM,gBAAgB,IAAI,CAAC,eAAe,WAAW,IAAI;AAAA,IACzD,SAAS,KAAK,WAAW,CAAC;AAAA,IAC1B,UAAU,KAAK,YACV,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,WAAW,OAAO,QAAQ,GAAG,YAC1D;AAAA,EACP,CAAC;AACH;AAEA,SAAS,cAAc,YAAiD;AACtE,SAAO,OAAO,QAAQ,WAAW,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAME,OAAM,MAChEA,QAAO,WAAW,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,EAAE,KAAK,EAAE;AAC1D;AAEA,SAAS,SAAS,OAAyB;AACzC,SAAO,MACJ,MAAM,gCAAgC,GACrC,IAAI,CAAC,UAAU,MAAM,QAAQ,kBAAkB,IAAI,CAAC,KACnD,CAAC;AACR;AAEA,SAAS,kBAAkB,OAA+E;AACxG,SAAO,YAAY,SAAS,cAAc;AAC5C;AAEA,SAAS,qBAAqB,OAA6C;AACzE,QAAM,cAAc,IAAI,MAAM,CAAC,GAAG;AAAA,IAChC,MAAM;AACJ,aAAO,MAAM;AACX,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO;AAAA,IACL,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,IAAI,MAAM;AACR,eAAO,CAAC;AAAA,MACV;AAAA,MACA,QAAQ,SAAS;AACf,eAAO,QAAQ,KAAK;AAAA,MACtB;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,IACR,OAAO,IAAI,YAAY,KAAK;AAAA,IAC5B,UAAU;AAAA,IACV,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AACF;;;AC/pBA,IAAM,aAAuC;AAAA,EAC3C,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ,OAAO;AACjB;AAEA,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,IAAM,SAAN,MAAM,QAAO;AAAA,EAClB;AAAA,EACS;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAuB,QAAQ;AACzC,UAAM,UAAU,OAAO,WAAW,WAAW,EAAE,OAAO,OAAO,IAAI;AACjE,UAAM,QAAQ,QAAQ,SAAS;AAC/B,gBAAY,KAAK;AAEjB,QAAI,QAAQ,WAAW,UAAa,OAAO,QAAQ,WAAW,YAAY;AACxE,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,UAAa,CAAC,CAAC,UAAU,MAAM,EAAE,SAAS,QAAQ,MAAM,GAAG;AAChF,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,SAAS,EAAE,QAAQ,QAAQ,OAAO,EAAE;AAAA,MACxC;AAAA,IACF;AAEA,SAAK,SAAS,EAAE,MAAM;AACtB,SAAK,SAAS,QAAQ,SAAS;AAC/B,SAAK,cAAc,IAAI;AAAA,MACrB,CAAC,GAAG,mBAAmB,GAAI,QAAQ,UAAU,CAAC,CAAE,EAC7C,IAAI,CAAC,QAAQ,IAAI,YAAY,CAAC;AAAA,IACnC;AACA,SAAK,UAAU,QAAQ,UAAU,cAAc,QAAQ,UAAU,QAAQ;AAAA,EAC3E;AAAA,EAEA,IAAI,QAAkB;AACpB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,SAAS,OAAuB;AAC9B,gBAAY,KAAK;AACjB,SAAK,OAAO,QAAQ;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,OAA6C;AACrD,WAAO,WAAW,KAAK,KAAK,WAAW,KAAK,OAAO,KAAK;AAAA,EAC1D;AAAA,EAEA,MAAM,OAAuB;AAC3B,UAAM,aAAa,KAAK,SAAS,GAAG,KAAK,MAAM,IAAI,KAAK,KAAK;AAC7D,UAAM,QAAQ,IAAI,QAAO;AAAA,MACvB,OAAO,KAAK,OAAO;AAAA,MACnB,OAAO;AAAA,MACP,QAAQ,KAAK;AAAA,MACb,QAAQ,CAAC,GAAG,KAAK,WAAW;AAAA,IAC9B,CAAC;AACD,UAAM,SAAS,KAAK;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAiB,UAAsB,CAAC,GAAS;AACrD,SAAK,OAAO,SAAS,SAAS,OAAO;AAAA,EACvC;AAAA,EAEA,KAAK,SAAiB,UAAsB,CAAC,GAAS;AACpD,SAAK,OAAO,QAAQ,SAAS,OAAO;AAAA,EACtC;AAAA,EAEA,KAAK,SAAiB,UAAsB,CAAC,GAAS;AACpD,SAAK,OAAO,QAAQ,SAAS,OAAO;AAAA,EACtC;AAAA,EAEA,MAAM,SAAiB,UAAsB,CAAC,GAAS;AACrD,SAAK,OAAO,SAAS,SAAS,OAAO;AAAA,EACvC;AAAA,EAEA,OACE,OACA,SACA,SACM;AACN,QAAI,CAAC,KAAK,UAAU,KAAK,GAAG;AAC1B;AAAA,IACF;AAEA,QAAI;AACF,YAAM,QAAkB;AAAA,QACtB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC;AAAA,QACA,OAAO,KAAK;AAAA,QACZ;AAAA,QACA,SAAS,iBAAiB,SAAS,KAAK,WAAW;AAAA,MACrD;AACA,YAAM,SAAS,KAAK,QAAQ,KAAK;AAEjC,UAAI,kBAAkB,SAAS;AAC7B,aAAK,OAAO,MAAM,MAAM,MAAS;AAAA,MACnC;AAAA,IACF,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,YAAY,OAAuB;AAC1C,MAAI,EAAE,SAAS,aAAa;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA,EAAE,SAAS,EAAE,MAAM,EAAE;AAAA,IACvB;AAAA,EACF;AACF;AAEA,SAAS,cAAc,QAA8B;AACnD,SAAO,CAAC,UAAU;AAChB,UAAM,SAAS,MAAM,UAAU,UAC3B,QAAQ,QACR,MAAM,UAAU,SACd,QAAQ,OACR,MAAM,UAAU,SACd,QAAQ,OACR,QAAQ;AAEhB,QAAI,WAAW,QAAQ;AACrB,aAAO,KAAK,UAAU,KAAK,CAAC;AAC5B;AAAA,IACF;AAEA,UAAM,UAAU,OAAO,KAAK,MAAM,OAAO,EAAE,SAAS,IAChD,IAAI,KAAK,UAAU,MAAM,OAAO,CAAC,KACjC;AACJ;AAAA,MACE,IAAI,MAAM,SAAS,KAAK,MAAM,MAAM,YAAY,CAAC,IAAI,MAAM,KAAK,IAAI,MAAM,OAAO,GAAG,OAAO;AAAA,IAC7F;AAAA,EACF;AACF;AAEA,SAAS,iBACP,SACA,YACY;AACZ,QAAM,OAAO,oBAAI,QAAgB;AACjC,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AAAA,MAC5C;AAAA,MACA,eAAe,OAAO,KAAK,YAAY,IAAI;AAAA,IAC7C,CAAC;AAAA,EACH;AACF;AAEA,SAAS,eACP,OACA,KACA,YACA,MACS;AACT,MAAI,cAAc,KAAK,UAAU,GAAG;AAClC,WAAO;AAAA,EACT;AAEA,MACE,UAAU,QACP,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,aACjB,UAAU,QACb;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,MAAM,SAAS;AAAA,EACxB;AAEA,MAAI,iBAAiB,MAAM;AACzB,WAAO,MAAM,YAAY;AAAA,EAC3B;AAEA,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf,GAAI,UAAU,QAAQ,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,IAChD;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,KAAK;AAAA,EACrB;AAEA,MAAI,KAAK,IAAI,KAAK,GAAG;AACnB,WAAO;AAAA,EACT;AAEA,OAAK,IAAI,KAAK;AAEd,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAChB,eAAe,MAAM,IAAI,YAAY,IAAI,CAAC;AAAA,EAC9C;AAEA,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,WAAW,WAAW,MAAM;AAAA,MACtD;AAAA,MACA,eAAe,aAAa,WAAW,YAAY,IAAI;AAAA,IACzD,CAAC;AAAA,EACH;AACF;AAEA,SAAS,cACP,KACA,YACS;AACT,QAAM,aAAa,IAAI,YAAY;AACnC,SAAO,CAAC,GAAG,UAAU,EAAE,KAAK,CAAC,cAC3B,eAAe,aACZ,WAAW,WAAW,SAAS,KAC/B,WAAW,SAAS,SAAS,CAAC;AACrC;;;AC/NO,IAAM,cAAN,MAAkB;AAAA,EACd;AAAA,EACA;AAAA,EAET,YAAY,UAA4B,OAAmB;AACzD,SAAK,YAAY;AACjB,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,MAAM,IACJ,SACA,MACA,UAA0B,CAAC,GACH;AACxB,UAAM,QAAQ,KAAK,cAAc;AACjC,UAAM,MAAM,KAAK,IAAI;AAErB,QAAI,QAAQ,eAAe,UAAa,QAAQ,cAAc,GAAG;AAC/D,YAAM,IAAI,aAAa,oBAAoB,0CAA0C;AAAA,IACvF;AAEA,UAAM,UAAU,MAAM,KAAK,YAAY,SAAS,KAAK,UAAU;AAE/D,QAAI,WAAW,QAAQ,cAAc,QAAQ,QAAQ,eAAe,QAAW;AAC7E,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,SAAS;AAAA,QACT,OAAO;AAAA,QACP,QAAQ,KAAK,QAAQ,OAAO;AAAA,MAC9B;AAAA,IACF;AAEA,UAAM,SAAqB;AAAA,MACzB,KAAK,kBAAkB,KAAK,EAAE;AAAA,MAC9B;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,WAAW;AAAA,MACX,WAAW,QAAQ,eAAe,SAAY,OAAO,MAAM,QAAQ;AAAA,IACrE;AACA,UAAM,KAAK;AAAA,MACT;AAAA,MACA,MAAM,MAAM,OAAO,MAAM;AAAA,MACzB,EAAE,SAAS,QAAQ,KAAK,GAAG;AAAA,IAC7B;AACA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,OAAO,UAAU,YAAY;AAAA,MAC7B,QAAQ,KAAK,QAAQ,MAAM;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,SAAiB,MAAuC;AACnE,UAAM,QAAQ,KAAK,cAAc;AACjC,UAAM,UAAU,MAAM,KAAK;AAAA,MACzB;AAAA,MACA,MAAM,MAAM,OAAO,SAAS,KAAK,UAAU;AAAA,MAC3C,EAAE,SAAS,QAAQ,KAAK,GAAG;AAAA,IAC7B;AAEA,QAAI,SAAS;AACX,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,SAAiB,MAA6C;AACtE,SAAK,cAAc;AACnB,UAAM,SAAS,MAAM,KAAK,YAAY,SAAS,KAAK,UAAU;AAC9D,WAAO,SAAS,KAAK,QAAQ,MAAM,IAAI;AAAA,EACzC;AAAA,EAEA,MAAM,QAAQ,SAAiB,MAA8B;AAC3D,WAAQ,MAAM,KAAK,IAAI,SAAS,IAAI,MAAO;AAAA,EAC7C;AAAA,EAEA,MAAM,QAAQ,SAAwD;AACpE,QAAI,CAAC,KAAK,UAAU,CAAC,QAAQ,WAAW,QAAQ,KAAK,QAAQ;AAC3D,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,MAAM,KAAK,YAAY,QAAQ,QAAQ,QAAQ,OAAO,UAAU;AAE/E,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,KAAK,UAAU,cAAc,QAAQ,IAAI;AAAA,IACjD,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,SAAS;AAAA,YACP,SAAS,QAAQ;AAAA,YACjB,WAAW,QAAQ;AAAA,YACnB,QAAQ,QAAQ,OAAO;AAAA,UACzB;AAAA,UACA,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,KAAK,QAAQ,MAAM;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,eAAgC;AACpC,UAAM,QAAQ,KAAK,cAAc;AACjC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,MAAM,MAAM,aAAa,KAAK,IAAI,CAAC;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK,QAAQ,OAAO;AACtB,YAAM,KAAK,SAAS,SAAS,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,QAAQ,QAAgC;AACtC,WAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,MAAM,IAAI,KAAK,OAAO,IAAI;AAAA,MAC1B,WAAW,IAAI,KAAK,OAAO,SAAS;AAAA,MACpC,WAAW,OAAO,cAAc,OAAO,OAAO,IAAI,KAAK,OAAO,SAAS;AAAA,IACzE;AAAA,EACF;AAAA,EAEA,MAAM,YACJ,SACA,YACiC;AACjC,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB;AAAA,MACA,MAAM,KAAK,QAAQ,KAAK,SAAS,UAAU;AAAA,MAC3C,EAAE,QAAQ;AAAA,IACZ;AAEA,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,QAAI,OAAO,cAAc,QAAQ,OAAO,aAAa,KAAK,IAAI,GAAG;AAC/D,YAAM,KAAK;AAAA,QACT;AAAA,QACA,MAAM,KAAK,QAAQ,OAAO,SAAS,OAAO,UAAU;AAAA,QACpD,EAAE,QAAQ;AAAA,MACZ;AACA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,gBAA2B;AACzB,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,SACJ,QACA,WACA,UAA6C,CAAC,GAC7B;AACjB,QAAI;AACF,aAAO,MAAM,UAAU;AAAA,IACzB,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR;AAAA,QACA,2BAA2B,MAAM;AAAA,QACjC;AAAA,UACE,OAAO;AAAA,UACP,SAAS,EAAE,QAAQ,GAAG,QAAQ;AAAA,UAC9B,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AClQA,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAiBA,IAAM,kBAAN,MAA2C;AAAA,EACvC;AAAA,EAET,YAAYC,QAAO,yBAAyB;AAC1C,UAAM,eAAeA,UAAS,aAAaA,QAAO,QAAQA,KAAI;AAE9D,QAAI,iBAAiB,YAAY;AAC/B,gBAAU,QAAQ,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,IACtD;AAEA,QAAI;AAEJ,QAAI;AACF,YAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,YAAM,SAASA,SAAQ,aAAa;AACpC,iBAAW,IAAI,OAAO,aAAa,YAAY;AAC/C,eAAS,KAAK,2BAA2B;AACzC,eAAS,KAAK,4BAA4B;AAC1C,eAAS,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAcb;AAAA,IACH,SAAS,OAAO;AACd,gBAAU,MAAM;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,SAAS,EAAE,UAAU,aAAa;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAEA,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,OAAO,MAAwB;AAC7B,UAAM,aAAa,KAAK,YAAY,KAAK,UAAU;AACnD,UAAM,eAAe,KAAK,cAAc,KAAK,SAAS,UAAU;AAEhE,SAAK,aAAa,MAAM;AACtB,iBAAW,OAAO,cAAc;AAC9B,aAAK,UAAU;AAAA,UACb;AAAA,QACF,EAAE,IAAI,KAAK,SAAS,GAAG;AAAA,MACzB;AAEA,YAAM,SAAS,KAAK,UAAU,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OASrC;AAED,iBAAW,YAAY,YAAY;AACjC,eAAO;AAAA,UACL,KAAK;AAAA,UACL;AAAA,UACA,KAAK;AAAA,UACL,KAAK,UAAU,KAAK,IAAI;AAAA,UACxB,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,KAAK,SAAiB,YAAuD;AAC3E,UAAM,aAAa,KAAK,YAAY,UAAU;AAE9C,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,WAAW,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AACxD,UAAM,MAAM,KAAK,UAAU,QAAQ;AAAA;AAAA;AAAA,4CAGK,YAAY;AAAA;AAAA,KAEnD,EAAE,IAAI,SAAS,GAAG,UAAU;AAE7B,QAAI,CAAC,KAAK;AACR,aAAO;AAAA,IACT;AAEA,QAAI,IAAI,eAAe,QAAQ,IAAI,cAAc,KAAK,IAAI,GAAG;AAC3D,WAAK,UAAU;AAAA,QACb;AAAA,MACF,EAAE,IAAI,SAAS,IAAI,QAAQ;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,KAAK,UAAU,QAAQ;AAAA;AAAA;AAAA;AAAA,KAI3C,EAAE,IAAI,SAAS,IAAI,QAAQ;AAE5B,WAAO;AAAA,MACL,KAAK,IAAI;AAAA,MACT,SAAS,IAAI;AAAA,MACb,MAAM,KAAK,MAAM,IAAI,SAAS;AAAA,MAC9B,YAAY,aAAa,IAAI,CAAC,EAAE,SAAS,MAAM,QAAQ;AAAA,MACvD,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,OAAO,SAAiB,YAAwC;AAC9D,UAAM,OAAO,KAAK,cAAc,SAAS,KAAK,YAAY,UAAU,CAAC;AAErE,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO;AAAA,IACT;AAEA,SAAK,aAAa,MAAM;AACtB,YAAM,YAAY,KAAK,UAAU;AAAA,QAC/B;AAAA,MACF;AAEA,iBAAW,OAAO,MAAM;AACtB,kBAAU,IAAI,SAAS,GAAG;AAAA,MAC5B;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,aAAa,KAAqB;AAChC,UAAM,SAAS,KAAK,UAAU,QAAQ;AAAA;AAAA;AAAA,KAGrC,EAAE,IAAI,GAAG;AACV,WAAO,OAAO,OAAO,OAAO;AAAA,EAC9B;AAAA,EAEA,QAAc;AACZ,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEA,cAAc,SAAiB,YAAyC;AACtE,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,eAAe,WAAW,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AACxD,UAAM,OAAO,KAAK,UAAU,QAAQ;AAAA;AAAA;AAAA,4CAGI,YAAY;AAAA,KACnD,EAAE,IAAI,SAAS,GAAG,UAAU;AAC7B,WAAO,KAAK,IAAI,CAAC,EAAE,SAAS,MAAM,QAAQ;AAAA,EAC5C;AAAA,EAEA,YAAY,YAAyC;AACnD,WAAO,CAAC,GAAG,IAAI,IAAI,WAAW,IAAI,iBAAiB,EAAE,OAAO,OAAO,CAAC,CAAC;AAAA,EACvE;AAAA,EAEA,aAAa,WAA6B;AACxC,SAAK,UAAU,KAAK,iBAAiB;AAErC,QAAI;AACF,gBAAU;AACV,WAAK,UAAU,KAAK,QAAQ;AAAA,IAC9B,SAAS,OAAO;AACd,WAAK,UAAU,KAAK,UAAU;AAC9B,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC/MO,IAAM,oBAAN,MAA+C;AAAA,EAC3C,aAAa,oBAAI,IAAiE;AAAA,EAE3F,GACE,OACA,UACY;AACZ,UAAM,YAAY,KAAK,WAAW,IAAI,KAAK,KAAK,oBAAI,IAAI;AACxD,cAAU,IAAI,QAAoD;AAClE,SAAK,WAAW,IAAI,OAAO,SAAS;AAEpC,WAAO,MAAM,UAAU,OAAO,QAAoD;AAAA,EACpF;AAAA,EAEA,MAAM,KAAiC,OAAc,SAAuC;AAC1F,UAAM,YAAY,KAAK,WAAW,IAAI,KAAK;AAE3C,QAAI,CAAC,WAAW;AACd;AAAA,IACF;AAEA,UAAM,QAAQ,IAAI,CAAC,GAAG,SAAS,EAAE,IAAI,CAAC,aAAa,SAAS,OAAgB,CAAC,CAAC;AAAA,EAChF;AACF;;;ACdO,IAAM,iBAAN,MAAqB;AAAA,EACjB;AAAA,EACA;AAAA,EAET,YAAY,UAA4B,IAAa;AACnD,SAAK,YAAY;AACjB,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,IAAI,MAAyB;AAC3B,WAAO,iBAAiB,KAAK,UAAU,kBAAkB,CAAC;AAAA,EAC5D;AAAA,EAEA,IAAI,MAA0B;AAC5B,UAAM,WAAW,KAAK,IAAI,KAAK,CAAC,cAC9B,UAAU,SAAS,iBAAiB,KAAK,UAAU,SAAS,OAAO,CAAC;AAEtE,QAAI,UAAU;AACZ,aAAO,kBAAkB,QAAQ;AAAA,IACnC;AAEA,UAAM,QAAQ,KAAK,IAChB,IAAI,CAAC,cAAc,oBAAoB,SAAS,CAAC,EACjD,KAAK,CAAC,cAAmC,cAAc,MAAS;AAEnE,WAAO,QAAQ,GAAG,KAAK,oBAAoB;AAAA,EAC7C;AAAA,EAEA,IAAI,MAA0B;AAC5B,UAAM,WAAW,KAAK,IAAI,KAAK,CAAC,cAAc,UAAU,SAAS,MAAM,CAAC;AACxE,WAAO,WAAW,kBAAkB,QAAQ,IAAI;AAAA,EAClD;AAAA,EAEA,IAAI,cAAkC;AACpC,UAAM,MAAM,KAAK;AACjB,WAAO,MAAM,oBAAoB,GAAG,IAAI;AAAA,EAC1C;AAAA,EAEA,IAAI,aAAiC;AACnC,WAAO,KAAK,OAAO,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,EAC3C;AAAA,EAEA,QAAQ,SAAuD;AAC7D,QAAI,QAAQ,KAAK,QAAQ;AACvB,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,KAAK;AACxB,WAAO,QAAQ,UAAU,KAAK,CAAC,aAC7B,WAAW,KAAK,CAAC,cAAc,gBAAgB,UAAU,SAAS,CAAC,CAAC;AAAA,EACxE;AACF;;;AC1DO,IAAM,cAAN,MAAkB;AAAA,EACd;AAAA,EAET,YAAY,UAA4B;AACtC,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,OAAO,QAA+B;AACpC,WAAO,KAAK,UAAU,YAAY,QAAQ,QAAQ;AAAA,EACpD;AAAA,EAEA,UAAU,QAA+B;AACvC,WAAO,KAAK,UAAU,YAAY,QAAQ,WAAW;AAAA,EACvD;AAAA,EAEA,KAAK,QAA+B;AAClC,WAAO,KAAK,UAAU,YAAY,QAAQ,QAAQ;AAAA,EACpD;AAAA,EAEA,WAAW,QAA+B;AACxC,WAAO,KAAK,KAAK,MAAM;AAAA,EACzB;AAAA,EAEA,WAAW,QAAgB,MAA6B;AACtD,WAAO,KAAK,UAAU,WAAW,QAAQ,IAAI;AAAA,EAC/C;AACF;;;AChBO,IAAM,eAAN,MAAmB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,oBAAI,IAAoC;AAAA,EAE7D,YAAY,UAA4B,OAAmB,QAAQ,KAAS;AAC1E,SAAK,YAAY;AACjB,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,KAAK,SAAiE;AAC1E,UAAM,QAAQ,MAAM,KAAK,SAAS,OAAO;AAEzC,QAAI,MAAM,WAAW,QAAQ;AAC3B,aAAO,EAAE,IAAI,MAAM,SAAS,OAAO,OAAO,eAAe;AAAA,IAC3D;AAEA,UAAM,KAAK,UAAU,eAAe,SAAS,MAAM;AACnD,UAAM,KAAK,WAAW,OAAO;AAC7B,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM,OAAO,OAAO;AAAA,EAClD;AAAA,EAEA,MAAM,MAAM,SAAqE;AAC/E,UAAM,QAAQ,MAAM,KAAK,SAAS,OAAO;AAEzC,QAAI,MAAM,WAAW,UAAU;AAC7B,aAAO,EAAE,IAAI,MAAM,SAAS,OAAO,OAAO,iBAAiB;AAAA,IAC7D;AAEA,UAAM,KAAK,UAAU,eAAe,SAAS,QAAQ;AACrD,UAAM,KAAK,WAAW,OAAO;AAC7B,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM,OAAO,SAAS;AAAA,EACpD;AAAA,EAEA,MAAM,OAAO,SAAwC;AACnD,UAAM,OAAO,MAAM,KAAK,UAAU,mBAAmB,OAAO;AAC5D,WAAO,EAAE,IAAI,MAAM,MAAM,KAAK,6BAA6B,IAAI,GAAG;AAAA,EACpE;AAAA,EAEA,MAAM,aAAa,SAAwC;AACzD,UAAM,OAAO,MAAM,KAAK,UAAU,kBAAkB,OAAO;AAC3D,WAAO,EAAE,IAAI,MAAM,MAAM,KAAK,6BAA6B,IAAI,GAAG;AAAA,EACpE;AAAA,EAEA,MAAM,IAAI,SAAiB,KAAkD;AAC3E,UAAM,KAAK,UAAU,cAAc,SAAS,KAAK,IAAI;AACrD,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM,OAAO,SAAS;AAAA,EACpD;AAAA,EAEA,MAAM,MAAM,SAAiB,KAAoD;AAC/E,UAAM,KAAK,UAAU,cAAc,SAAS,KAAK,KAAK;AACtD,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM,OAAO,WAAW;AAAA,EACtD;AAAA,EAEA,MAAM,SAAS,SAAiB,UAAU,OAA+B;AACvE,UAAM,MAAM,KAAK,KAAK,OAAO;AAE7B,QAAI,CAAC,SAAS;AACZ,YAAM,SAAS,MAAM,KAAK,OAAO,IAAmB,GAAG;AAEvD,UAAI,QAAQ;AACV,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,UAAU,KAAK,UAAU,IAAI,GAAG;AAEtC,QAAI,SAAS;AACX,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,KAAK,cAAc,KAAK,OAAO;AAC/C,SAAK,UAAU,IAAI,KAAK,OAAO;AAE/B,QAAI;AACF,aAAO,MAAM;AAAA,IACf,UAAE;AACA,WAAK,UAAU,OAAO,GAAG;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,MAAM,QACJ,SACA,WACkB;AAClB,QAAI,CAAC,QAAQ,SAAS,OAAO,GAAG;AAC9B,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,MAAM,KAAK,SAAS,OAAO;AACzC,UAAM,aAAa,OAAO,cAAc,WAAW,CAAC,SAAS,IAAI;AACjE,UAAM,cAAc,MAAM,aAAa,KAAK,CAAC,SAC3C,KAAK,oBAAoB,MAAM,UAAU,CAAC;AAC5C,WAAO,aAAa,SAAS,WAAW,aAAa,SAAS;AAAA,EAChE;AAAA,EAEA,MAAM,mBAAmB,SAAmC;AAC1D,UAAM,MAAM,KAAK,UAAU,kBAAkB;AAE7C,QAAI,IAAI,WAAW,KAAK,CAAC,QAAQ,SAAS,OAAO,GAAG;AAClD,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,MAAM,KAAK,SAAS,OAAO;AACzC,WAAO,MAAM,aAAa,KAAK,CAAC,gBAC9B,KAAK,oBAAoB,aAAa,GAAG,MACrC,YAAY,SAAS,WAAW,YAAY,SAAS,QAAQ;AAAA,EACrE;AAAA,EAEA,MAAM,YAAY,SAAiB,MAA2B;AAC5D,QAAI,CAAC,QAAQ,SAAS,OAAO,GAAG;AAC9B,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,MAAM,KAAK,SAAS,OAAO;AACzC,UAAM,cAAc,MAAM,aAAa,KAAK,CAAC,SAC3C,KAAK,oBAAoB,MAAM,KAAK,UAAU,CAAC;AAEjD,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,IACT;AAEA,WAAO,IAAI,KAAK;AAAA,MACd,IAAI,YAAY;AAAA,MAChB,YAAY;AAAA,QACV,YAAY;AAAA,QACZ,GAAI,YAAY,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;AAAA,QAC3C,GAAI,YAAY,cAAc,CAAC,YAAY,WAAW,IAAI,CAAC;AAAA,MAC7D;AAAA,MACA,GAAI,YAAY,MAAM,EAAE,KAAK,YAAY,IAAI,IAAI,CAAC;AAAA,MAClD,GAAI,YAAY,cAAc;AAAA,QAC5B,KAAK,YAAY;AAAA,QACjB,aAAa,YAAY;AAAA,MAC3B,IAAI,CAAC;AAAA,MACL,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,IACzC,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,SAAgC;AACzC,WAAO,KAAK,OAAO,OAAO,KAAK,KAAK,OAAO,CAAC;AAAA,EAC9C;AAAA,EAEA,KAAK,SAAyB;AAC5B,WAAO,SAAS,OAAO;AAAA,EACzB;AAAA,EAEA,MAAM,cAAc,KAAa,SAAyC;AACxE,UAAM,QAAQ,MAAM,KAAK,UAAU,SAAS,OAAO;AACnD,UAAM,KAAK,OAAO,IAAI,KAAK,OAAO,KAAK,MAAM;AAC7C,WAAO;AAAA,EACT;AAAA,EAEA,oBACE,aACA,YACS;AACT,UAAM,iBAAiB,CAAC,YAAY,IAAI,YAAY,KAAK,YAAY,WAAW,EAC7E,OAAO,CAAC,aAAiC,aAAa,MAAS;AAClE,WAAO,WAAW,KAAK,CAAC,aACtB,eAAe,KAAK,CAAC,kBACnB,gBAAgB,UAAU,aAAa,CAAC,CAAC;AAAA,EAC/C;AACF;;;ACnKO,IAAM,eAAN,MAAmB;AAAA,EACf;AAAA,EAET,YAAY,UAA4B;AACtC,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAM,QAAgB,SAA6C;AACjE,WAAO,KAAK,UAAU,YAAY,QAAQ,OAAO;AAAA,EACnD;AAAA,EAEA,MAAM,QAAgB,SAA6C;AACjE,WAAO,KAAK,UAAU,YAAY,QAAQ,OAAO;AAAA,EACnD;AAAA,EAEA,MAAM,QAAgB,SAA6C;AACjE,WAAO,KAAK,UAAU,YAAY,QAAQ,OAAO;AAAA,EACnD;AAAA,EAEA,QAAQ,QAAgB,SAA+C;AACrE,WAAO,KAAK,UAAU,YAAY,QAAQ,OAAO;AAAA,EACnD;AAAA,EAEA,SAAS,SAAyE;AAChF,UAAM,MAAM,UAAU,UAClB,QAAQ,OACR,SAAS,UACP,QAAQ,MACR;AAEN,WAAO,KAAK,UAAU,cAAc,GAAG;AAAA,EACzC;AACF;;;ACjCO,IAAM,gBAAN,MAAoB;AAAA,EAChB;AAAA,EACA;AAAA,EAET,YAAY,UAA4B,OAAqB;AAC3D,SAAK,YAAY;AACjB,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,OAAO,SAAiB,QAAiE;AAC7F,UAAM,EAAE,OAAO,YAAY,IAAI,MAAM,KAAK,aAAa,SAAS,MAAM;AAEtE,QAAI,CAAC,aAAa;AAChB,aAAO,EAAE,IAAI,MAAM,SAAS,OAAO,OAAO,kBAAkB;AAAA,IAC9D;AAEA,UAAM,KAAK,QAAQ,SAAS,KAAK,UAAU,OAAO,WAAW,GAAG,QAAQ;AACxE,UAAM,KAAK,OAAO,WAAW,OAAO;AACpC,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM,OAAO,UAAU;AAAA,EACrD;AAAA,EAEA,MAAM,QAAQ,SAAiB,QAAiE;AAC9F,UAAM,EAAE,OAAO,YAAY,IAAI,MAAM,KAAK,aAAa,SAAS,MAAM;AAEtE,QAAI,CAAC,aAAa;AAChB,aAAO,EAAE,IAAI,MAAM,SAAS,OAAO,OAAO,eAAe;AAAA,IAC3D;AAEA,QAAI,YAAY,SAAS,WAAW,YAAY,SAAS,SAAS;AAChE,aAAO,EAAE,IAAI,MAAM,SAAS,OAAO,OAAO,gBAAgB;AAAA,IAC5D;AAEA,UAAM,KAAK,QAAQ,SAAS,KAAK,UAAU,OAAO,WAAW,GAAG,SAAS;AACzE,UAAM,KAAK,OAAO,WAAW,OAAO;AACpC,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM,OAAO,WAAW;AAAA,EACtD;AAAA,EAEA,MAAM,OAAO,SAAiB,QAAiE;AAC7F,UAAM,EAAE,OAAO,YAAY,IAAI,MAAM,KAAK,aAAa,SAAS,MAAM;AAEtE,QAAI,CAAC,aAAa;AAChB,aAAO,EAAE,IAAI,MAAM,SAAS,OAAO,OAAO,eAAe;AAAA,IAC3D;AAEA,QAAI,YAAY,SAAS,UAAU;AACjC,aAAO,EAAE,IAAI,MAAM,SAAS,OAAO,OAAO,YAAY;AAAA,IACxD;AAEA,UAAM,KAAK,QAAQ,SAAS,KAAK,UAAU,OAAO,WAAW,GAAG,QAAQ;AACxE,UAAM,KAAK,OAAO,WAAW,OAAO;AACpC,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM,OAAO,UAAU;AAAA,EACrD;AAAA,EAEA,MAAM,aAAa,SAAiB,QAGjC;AACD,UAAM,QAAQ,MAAM,KAAK,OAAO,SAAS,OAAO;AAChD,UAAM,YAAY,OAAO,WAAW,WAAW,CAAC,MAAM,IAAI,OAAO;AACjE,UAAM,cAAc,MAAM,aAAa,KAAK,CAAC,SAC3C,CAAC,KAAK,IAAI,KAAK,KAAK,KAAK,WAAW,EACjC,OAAO,CAAC,aAAiC,aAAa,MAAS,EAC/D,KAAK,CAAC,aACL,UAAU,KAAK,CAAC,aAAa,gBAAgB,UAAU,QAAQ,CAAC,CAAC,CAAC;AACxE,WAAO,EAAE,OAAO,YAAY;AAAA,EAC9B;AAAA,EAEA,UAAU,OAAsB,aAAuC;AACrE,QAAI,MAAM,mBAAmB,OAAO;AAClC,aAAO,YAAY,QACb,YAAY,GAAG,SAAS,MAAM,IAC9B,YAAY,KACZ,YAAY,eAAe,YAAY;AAAA,IAC/C;AAEA,WAAO,YAAY,gBACb,YAAY,GAAG,SAAS,iBAAiB,IACzC,YAAY,KACZ,YAAY,OAAO,YAAY;AAAA,EACvC;AAAA,EAEA,MAAM,QACJ,SACA,UACA,QACe;AACf,UAAM,SAAS,MAAM,KAAK,UAAU,kBAAkB,SAAS,UAAU,MAAM;AAE/E,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,mDAAmD,OAAO,MAAM;AAAA,QAChE;AAAA,UACE,SAAS,EAAE,SAAS,UAAU,QAAQ,QAAQ,OAAO,OAAO;AAAA,UAC5D,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACjGO,IAAM,iBAAN,MAAqB;AAAA,EACjB;AAAA,EAET,YAAY,UAA4B;AACtC,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,KAAK,QAAgB,SAA+C;AAClE,WAAO,KAAK,UAAU,YAAY,QAAQ,OAAO;AAAA,EACnD;AAAA,EAEA,MAAM,SAAkB,SAA+C;AACrE,WAAO,KAAK,UAAU,YAAY,QAAQ,QAAQ,SAAS,QAAQ,IAAI;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OACE,QACA,QACA,UAAgC,CAAC,GACX;AACtB,UAAM,MAAM,UAAU,SAAS,OAAO,OAAO;AAC7C,WAAO,KAAK,UAAU,cAAc,KAAK,QAAQ,OAAO;AAAA,EAC1D;AAAA,EAEA,KAAK,SAA6C,MAAoC;AACpF,UAAM,MAAM,UAAU,UAAU,QAAQ,OAAO;AAC/C,WAAO,KAAK,UAAU,YAAY,KAAK,IAAI;AAAA,EAC7C;AAAA,EAEA,OAAO,SAA4D;AACjE,UAAM,MAAM,UAAU,UAAU,QAAQ,OAAO;AAC/C,WAAO,KAAK,UAAU,cAAc,GAAG;AAAA,EACzC;AAAA,EAEA,MAAM,SAA6C,OAAqC;AACtF,UAAM,MAAM,UAAU,UAAU,QAAQ,OAAO;AAC/C,WAAO,KAAK,UAAU,eAAe,KAAK,KAAK;AAAA,EACjD;AAAA,EAEA,QAAQ,SAAmE;AACzE,UAAM,MAAM,UAAU,UAAU,QAAQ,OAAO;AAC/C,WAAO,KAAK,UAAU,eAAe,GAAG;AAAA,EAC1C;AAAA,EAEA,KAAK,QAAgB,MAAc,UAAkD;AACnF,UAAM,UAAuB,EAAE,KAAK;AAEpC,QAAI,aAAa,QAAW;AAC1B,cAAQ,WAAW;AAAA,IACrB;AAEA,WAAO,KAAK,KAAK,QAAQ,OAAO;AAAA,EAClC;AAAA,EAEA,QAAQ,QAAgB,SAA+C;AACrE,WAAO,KAAK,KAAK,QAAQ,OAAO;AAAA,EAClC;AAAA,EAEA,KAAK,QAAgB,SAA4C;AAC/D,WAAO,KAAK,KAAK,QAAQ,OAAO;AAAA,EAClC;AAAA,EAEA,KAAK,QAAgB,SAA4C;AAC/D,WAAO,KAAK,KAAK,QAAQ,OAAO;AAAA,EAClC;AACF;;;ACLO,IAAM,aAAN,MAAiB;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,IAAI,kBAA6B;AAAA,EAC3C;AAAA,EACA,aAAa,KAAK,IAAI;AAAA,EAC/B,SAAoC;AAAA,EAEpC,YACE,UACA,UAA6B,CAAC,GAC9B,SAAS,IAAI,OAAO,QAAQ,MAAM,GAClC;AACA,SAAK,YAAY;AACjB,SAAK,SAAS,QAAQ;AACtB,SAAK,UAAU,IAAI,eAAe,UAAU,QAAQ,SAAS;AAC7D,SAAK,SAAS;AACd,UAAM,QAAQ,QAAQ,OAAO,SAAS,IAAI;AAAA,MACxC,QAAQ,OAAO,qBAAqB,SAChC,SACA,EAAE,YAAY,QAAQ,MAAM,iBAAiB;AAAA,IACnD;AACA,SAAK,QAAQ,IAAI,aAAa,UAAU,OAAO,QAAQ,OAAO,UAAU;AACxE,SAAK,SAAS,IAAI,cAAc,UAAU,KAAK,KAAK;AACpD,SAAK,UAAU,IAAI,eAAe,QAAQ;AAC1C,SAAK,QAAQ,IAAI,aAAa,QAAQ;AACtC,SAAK,OAAO,IAAI,YAAY,QAAQ;AACpC,SAAK,OAAO,IAAI,YAAY,KAAK,KAAK;AACtC,UAAM,cAAc,QAAQ,MAAM,YAAY,QAAQ,QAAQ,MAAM,UAAU;AAC9E,UAAM,YAAY,cACd,QAAQ,MAAM,SAAS,IAAI,gBAAgB,QAAQ,MAAM,QAAQ,IACjE;AACJ,SAAK,OAAO,IAAI,YAAY,UAAU,SAAS;AAC/C,SAAK,WAAW,IAAI,cAAc;AAAA,MAChC,SAAS,KAAK;AAAA,MACd,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,IACb,GAAG;AAAA,MACD,GAAG,QAAQ;AAAA,MACX,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IACnE,CAAC;AACD,SAAK,UAAU,KAAK;AACpB,SAAK,MAAM;AACX,SAAK,OAAO,MAAM,2BAA2B;AAAA,MAC3C,aAAa,KAAK,KAAK;AAAA,MACvB,QAAQ,QAAQ,UAAU;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,QAAmC;AACrC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,SAAoB;AAClB,WAAO;AAAA,MACL,QAAQ,KAAK,cAAc;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK,IAAI,IAAI,KAAK;AAAA,MAC5B,WAAW,oBAAI,KAAK;AAAA,MACpB,aAAa,KAAK,KAAK;AAAA,MACvB,UAAU,KAAK,OAAO;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,SAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,GACE,OACA,UACA;AACA,WAAO,KAAK,QAAQ,GAAG,OAAO,QAAQ;AAAA,EACxC;AAAA,EAEA,MAAM,MAAM,UAAwB,CAAC,GAAkB;AACrD,QAAI,KAAK,WAAW,aAAa;AAC/B;AAAA,IACF;AAEA,SAAK,OAAO,KAAK,eAAe;AAEhC,QAAI,cAA0B,MAAM;AACpC,QAAI;AACJ,UAAM,YAAY,IAAI,QAAc,CAACC,UAAS,WAAW;AACvD,oBAAc,KAAK,UAAU,GAAG,cAAc,CAAC,WAAW;AACxD,YAAI,OAAO,UAAU,YAAa,CAAAA,SAAQ;AAC1C,YAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,YACE,IAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA;AAAA,gBACE,OAAO,OAAO;AAAA,gBACd,aAAa;AAAA,cACf;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAED,cAAQ,WAAW,MAAM;AACvB;AAAA,UACE,IAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,EAAE,aAAa,KAAK;AAAA,UACtB;AAAA,QACF;AAAA,MACF,GAAG,QAAQ,aAAa,GAAO;AAAA,IACjC,CAAC;AAED,SAAK,UAAU,MAAM,MAAM,MAAS;AAEpC,QAAI;AACF,YAAM,KAAK,UAAU,QAAQ;AAE7B,UAAI,KAAK,QAAQ;AACf,cAAM,OAAO,MAAM,KAAK,UAAU,mBAAmB,KAAK,MAAM;AAEhE,YAAI,MAAM;AACR,eAAK,OAAO,KAAK,wBAAwB;AAEzC,cAAI,QAAQ,QAAQ;AAClB,kBAAM,QAAQ,OAAO,IAAI;AAAA,UAC3B;AAAA,QACF;AAAA,MACF;AAEA,YAAM;AAAA,IACR,UAAE;AACA,kBAAY;AACZ,UAAI,MAAO,cAAa,KAAK;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAM,aAA4B;AAChC,SAAK,OAAO,KAAK,2BAA2B;AAE5C,QAAI;AACF,YAAM,KAAK,UAAU,WAAW;AAAA,IAClC,UAAE;AACA,YAAM,KAAK,KAAK,MAAM;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,UAAU,GAAG,cAAc,OAAO,WAAW;AAChD,WAAK,SAAS,OAAO;AACrB,WAAK,eAAe,MAAM;AAC1B,YAAM,KAAK,QAAQ,KAAK,cAAc,MAAM;AAAA,IAC9C,CAAC;AAED,SAAK,UAAU,GAAG,gBAAgB,CAAC,EAAE,QAAQ,MAAM,KAAK,MAAM,WAAW,OAAO,CAAC;AAEjF,SAAK,UAAU,GAAG,4BAA4B,OAAO,WAAW;AAC9D,YAAM,KAAK,MAAM,WAAW,OAAO,OAAO;AAC1C,YAAM,KAAK,QAAQ,KAAK,4BAA4B,MAAM;AAAA,IAC5D,CAAC;AAED,SAAK,UAAU,GAAG,QAAQ,OAAO,SAAS;AACxC,WAAK,OAAO,MAAM,iBAAiB;AAAA,QACjC,QAAQ,KAAK;AAAA,QACb,MAAM,KAAK;AAAA,QACX,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,YAAM,KAAK,QAAQ,KAAK,QAAQ,IAAI;AAAA,IACtC,CAAC;AAED,SAAK,UAAU,GAAG,kBAAkB,OAAO,aAAa;AACtD,WAAK,OAAO,MAAM,mBAAmB;AAAA,QACnC,QAAQ,SAAS,IAAI;AAAA,QACrB,WAAW,SAAS,IAAI;AAAA,QACxB,aAAa,SAAS;AAAA,QACtB,QAAQ,SAAS,YAAY;AAAA,MAC/B,CAAC;AACD,YAAM,KAAK,QAAQ,KAAK,kBAAkB,QAAQ;AAAA,IACpD,CAAC;AAED,SAAK,UAAU,GAAG,iBAAiB,OAAO,SAAS;AACjD,WAAK,OAAO,MAAM,kBAAkB;AAAA,QAClC,QAAQ,KAAK,IAAI;AAAA,QACjB,WAAW,KAAK,IAAI;AAAA,QACpB,YAAY,KAAK;AAAA,QACjB,QAAQ,KAAK,aAAa;AAAA,MAC5B,CAAC;AACD,YAAM,KAAK,QAAQ,KAAK,iBAAiB,IAAI;AAAA,IAC/C,CAAC;AAED,SAAK,UAAU,GAAG,WAAW,OAAO,YAAY;AAC9C,UAAI;AACF,cAAM,cAAc,MAAM,KAAK,KAAK,QAAQ,OAAO;AAEnD,YAAI,aAAa;AACf,eAAK,OAAO,KAAK,yBAAyB;AAAA,YACxC,SAAS,QAAQ;AAAA,YACjB,WAAW,QAAQ;AAAA,YACnB,QAAQ,QAAQ,OAAO;AAAA,UACzB,CAAC;AACD,gBAAM,KAAK,QAAQ,KAAK,QAAQ,WAAW;AAC3C;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,cAAM,KAAK,aAAa,OAAO,EAAE,WAAW,QAAQ,GAAG,CAAC;AACxD;AAAA,MACF;AAEA,UAAI;AACF,aAAK,OAAO,MAAM,oBAAoB;AAAA,UACpC,QAAQ,QAAQ;AAAA,UAChB,WAAW,QAAQ;AAAA,UACnB,UAAU,QAAQ,OAAO;AAAA,QAC3B,CAAC;AACD,cAAM,KAAK,QAAQ,KAAK,WAAW,OAAO;AAC1C,cAAM,aAAa,MAAM,KAAK,QAAQ,SAAS,OAAO;AAEtD,YAAI,YAAY;AACd,eAAK,OAAO,MAAM,sBAAsB;AAAA,YACtC,QAAQ,QAAQ;AAAA,YAChB,WAAW,QAAQ;AAAA,UACrB,CAAC;AAAA,QACH;AAAA,MACF,SAAS,OAAO;AACd,cAAM,KAAK,aAAa,OAAO,EAAE,WAAW,QAAQ,GAAG,CAAC;AAAA,MAC1D;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,gBAAiC;AAC/B,QAAI,KAAK,WAAW,aAAa;AAC/B,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,WAAW,UAAU;AAC5B,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,WAAW,gBAAgB,KAAK,WAAW,gBAAgB;AAClE,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,QAAgC;AAC7C,UAAM,UAAU;AAAA,MACd,GAAI,OAAO,YAAY,SAAY,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,MAClE,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,IAChD;AAEA,QAAI,OAAO,UAAU,aAAa;AAChC,WAAK,OAAO,KAAK,oBAAoB;AAAA,IACvC,WAAW,OAAO,UAAU,gBAAgB;AAC1C,WAAK,OAAO,KAAK,yBAAyB,OAAO;AAAA,IACnD,WAAW,OAAO,UAAU,YAAY,OAAO,OAAO;AACpD,WAAK,OAAO,KAAK,8BAA8B,OAAO;AAAA,IACxD,WAAW,OAAO,UAAU,UAAU;AACpC,WAAK,OAAO,KAAK,4BAA4B;AAAA,IAC/C,OAAO;AACL,WAAK,OAAO,MAAM,uBAAuB,OAAO;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,MAAM,aACJ,OACA,SACe;AACf,UAAM,aAAa,eAAe,OAAO,OAAO;AAChD,SAAK,OAAO,MAAM,WAAW,SAAS;AAAA,MACpC,MAAM,WAAW;AAAA,MACjB,GAAG,WAAW;AAAA,IAChB,CAAC;AACD,UAAM,KAAK,QAAQ,KAAK,SAAS,UAAU;AAAA,EAC7C;AACF;;;ACrXO,IAAK,UAAL,kBAAKC,aAAL;AACL,EAAAA,SAAA,aAAU;AACV,EAAAA,SAAA,WAAQ;AACR,EAAAA,SAAA,YAAS;AAHC,SAAAA;AAAA,GAAA;;;ACAZ,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,4BAA4B;AACrC,SAAS,yBAAyB;AAElC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAKK;;;AC8BA,SAAS,yBACd,OAC4B;AAC5B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAAS,MAAM,kBAAkB,WAClC,MAAM,iBAAiB,WACvB,MAAM,mBAAmB,WACzB,2BAA2B,KAAK,KAChC,MAAM,mBAAmB,WACzB,MAAM,4BAA4B;AAEvC,SAAO,SAAS,yBAAyB,MAAM,IAAI;AACrD;AAEA,SAAS,2BACP,OAC4B;AAC5B,QAAM,YAAa,MAIhB;AAEH,SAAO,WAAW,WAAW;AAC/B;AAEO,SAAS,sBACd,OACS;AACT,MAAI,CAAC,MAAO,QAAO;AAEnB,MACE,MAAM,iBAAiB,WACpB,MAAM,mBAAmB,WACzB,2BAA2B,KAAK,GACnC;AACA,WAAO;AAAA,EACT;AAEA,SAAO,sBAAsB,MAAM,kBAAkB,OAAO;AAC9D;AAEO,SAAS,yBACd,OACoC;AACpC,QAAM,QAAQ;AACd,QAAM,SAAS,MAAM,IAAI;AACzB,QAAM,UAAU,yBAAyB,MAAM,OAAO;AAEtD,MAAI,CAAC,UAAU,CAAC,QAAS,QAAO;AAEhC,QAAM,EAAE,KAAK,IAAI,YAAY,OAAO;AACpC,QAAM,UAAU,eAAe,IAAI;AAEnC,MAAI,CAAC,SAAS,YAAY,CAAC,QAAQ,cAAe,QAAO;AAEzD,SAAO;AAAA,IACL,KAAK;AAAA,MACH,IAAI,QAAQ;AAAA,MACZ,WAAW,QAAQ,aAAa;AAAA,MAChC,QAAQ;AAAA,MACR,GAAI,QAAQ,cAAc,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IACpE;AAAA,IACA,SAAS,QAAQ;AAAA,EACnB;AACF;AAEO,SAAS,qBACd,OACqB;AACrB,QAAM,QAAQ;AACd,QAAM,SAAS,MAAM,IAAI;AACzB,QAAM,KAAK,MAAM,IAAI;AAErB,MAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,SAAS;AACpC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,yBAAyB,MAAM,OAAO;AAEtD,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,MAAM,KAAK,IAAI,YAAY,OAAO;AAC1C,QAAM,UAAU,eAAe,IAAI;AACnC,QAAM,oBAAoB,CAAC,OAAO,SAAS,OAAO,KAAK,MAAM,IAAI,WAAW;AAC5E,QAAM,YAAY,iBAAiB;AAAA,IACjC,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,MAAM,IAAI,gBAAgB,SAAS,GAAG,IAClC,MAAM,IAAI,iBACV;AAAA,IACJ,oBAAoB,MAAM,IAAI,eAAe;AAAA,IAC7C,oBAAoB,SAAS;AAAA,EAC/B,CAAC;AACD,QAAM,YAAY,UAAU,KAAK,CAAC,aAChC,SAAS,SAAS,iBAAiB,KAAK,SAAS,SAAS,OAAO,CAAC;AACpE,QAAM,YAAY,UAAU,KAAK,CAAC,aAAa,SAAS,SAAS,MAAM,CAAC;AACxE,QAAM,WAAW,aAAa,aAAa,UAAU,CAAC,KAAK;AAC3D,QAAM,SAAS,IAAI,KAAK;AAAA,IACtB,IAAI;AAAA,IACJ,YAAY,UAAU,SAAS,IAAI,YAAY,CAAC,QAAQ;AAAA,IACxD,GAAI,MAAM,WAAW,EAAE,MAAM,MAAM,SAAS,IAAI,CAAC;AAAA,EACnD,CAAC;AACD,QAAM,eAAe,CAAC,GAAI,SAAS,gBAAgB,CAAC,CAAE;AACtD,QAAM,iBAAiB,aAAa,IAAI,CAAC,aAAa,KAAK,eAAe,CAAC,QAAQ,CAAC,CAAC;AACrF,QAAM,WAAW,sBAAsB,MAAM,OAAO;AACpD,QAAM,QAAQ,SAAS,MAAM,MAAM,QAAQ;AAC3C,QAAM,cAAc,eAAe,IAAI;AACvC,QAAM,OAAO,QAAQ,OAAO;AAC5B,QAAM,UAAU,WAAW,OAAO;AAClC,QAAM,SAAS,UAAU,SAAS,MAAM;AACxC,QAAM,cAAc,uBAAuB,OAAO;AAElD,QAAM,UAAmB;AAAA,IACvB;AAAA,IACA,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW,UAAU,SAAS,IAAI,YAAY,CAAC,QAAQ;AAAA,IACvD;AAAA,IACA,MAAM,iBAAiB,MAAM,GAAG;AAAA,IAChC,UAAU;AAAA,IACV;AAAA,IACA,WAAW,OAAO,MAAM,gBAAgB;AAAA,IACxC,SAAS,OAAO,SAAS,OAAO;AAAA,IAChC,SAAS,WAAW;AAAA,IACpB,YAAY,OAAO,YAAY;AAAA,IAC/B,UAAU,UAAU;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,cAAc,OAAW,SAAQ,YAAY;AACjD,MAAI,cAAc,QAAW;AAC3B,YAAQ,MAAM;AACd,YAAQ,YAAY;AAAA,EACtB;AACA,MAAI,SAAS,OAAW,SAAQ,OAAO;AACvC,MAAI,YAAY,OAAW,SAAQ,UAAU;AAC7C,MAAI,UAAU,OAAW,SAAQ,QAAQ;AACzC,MAAI,WAAW,OAAW,SAAQ,SAAS;AAC3C,MAAI,gBAAgB,OAAW,SAAQ,cAAc;AAErD,SAAO;AACT;AAEO,SAAS,iBAAiB,KAAqC;AACpE,QAAM,aAAyB;AAAA,IAC7B,IAAI,IAAI,MAAM;AAAA,IACd,QAAQ,IAAI,aAAa;AAAA,IACzB,QAAQ,IAAI,UAAU;AAAA,EACxB;AACA,QAAM,gBAAgB,IAAI,eAAe,IAAI;AAE7C,MAAI,kBAAkB,QAAQ,kBAAkB,QAAW;AACzD,eAAW,gBAAgB;AAAA,EAC7B;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,SAGnB;AACA,QAAM,QAAqC;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,KAAK,CAAC,QAAQ,QAAQ,GAAG,MAAM,QAAQ,QAAQ,GAAG,MAAM,MAAS;AACpF,SAAO,EAAE,MAAM,MAAM,OAAO,QAAQ,IAAI,IAAI,OAAU;AACxD;AAEA,SAAS,eAAe,MAA4D;AAClF,UAAQ,OAAO,QAAQ,EAAE,GAAG;AAAA,IAC1B,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,QAAQ,SAA6C;AAC5D,SAAO,QAAQ,gBACV,QAAQ,qBAAqB,QAC7B,QAAQ,wBAAwB,uBAChC,QAAQ,qBAAqB,SAC7B,QAAQ,4BAA4B,uBACpC,QAAQ,qBAAqB,QAC7B,QAAQ,uBAAuB,QAC/B,QAAQ,uBAAuB,QAC/B,QAAQ,uBAAuB,QAC/B,yBAAyB,OAAO,KAChC;AACP;AAEA,SAAS,uBAAuB,SAA0D;AACxF,QAAM,UAAU,QAAQ;AAIxB,MAAI,SAAS,kBAAkB;AAC7B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,IAAI,QAAQ;AAAA,MACZ,GAAI,QAAQ,sBAAsB,EAAE,OAAO,QAAQ,oBAAoB,IAAI,CAAC;AAAA,IAC9E;AAAA,EACF;AAEA,QAAM,WAAW,QAAQ;AAIzB,MAAI,UAAU,YAAY;AACxB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,IAAI,SAAS;AAAA,MACb,GAAI,SAAS,sBAAsB,EAAE,OAAO,SAAS,oBAAoB,IAAI,CAAC;AAAA,IAChF;AAAA,EACF;AAEA,QAAM,OAAO,QAAQ;AAIrB,QAAM,QAAQ,MAAM,mBAAmB;AACvC,MAAI,OAAO;AACT,WAAO;AAAA,MACL,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,GAAI,MAAM,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,SAAS,iBAAiB,OAAO;AACvC,QAAM,WAAW,YAAY,QAAQ,CAAC,MAAM,eAAe,UAAU,WAAW,CAAC;AACjF,MAAI,UAAU;AACZ,UAAM,QAAQ,YAAY,QAAQ,CAAC,gBAAgB,OAAO,CAAC;AAC3D,UAAM,aAAa,eAAe,OAAO;AACzC,WAAO;AAAA,MACL,MAAM,eAAe,mBACf,WAAW,YAAY,UAAU,iBAAiB,UACpD,SACA;AAAA,MACJ,IAAI;AAAA,MACJ,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,eAAe,SAA6C;AACnE,QAAM,WAAW,QAAQ;AAKzB,SAAO,UAAU,2BAA2B,QAAQ;AACtD;AAEA,SAAS,yBAAyB,SAA6C;AAC7E,SAAO,YAAY,iBAAiB,OAAO,GAAG,CAAC,gBAAgB,OAAO,CAAC;AACzE;AAEA,SAAS,iBAAiB,SAA8D;AACtF,QAAM,WAAW,QAAQ;AAMzB,QAAM,OAAO,UAAU,2BAA2B;AAClD,MAAI,CAAC,KAAM,QAAO;AAElB,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,WAAO,OAAO,WAAW,YAAY,WAAW,OAC5C,SACA;AAAA,EACN,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YACP,OACA,MACoB;AACpB,MAAI,CAAC,MAAO,QAAO;AACnB,aAAW,OAAO,MAAM;AACtB,UAAM,QAAQ,MAAM,GAAG;AACvB,QAAI,OAAO,UAAU,YAAY,MAAM,SAAS,EAAG,QAAO;AAAA,EAC5D;AACA,SAAO;AACT;AAEA,SAAS,WAAW,SAA6C;AAC/D,SAAO,QAAQ,cAAc,WACxB,QAAQ,cAAc,WACtB,QAAQ,iBAAiB,WACzB;AACP;AAEA,SAAS,eAAe,MAA4C;AAClE,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,iBAAiB,OAAO;AACzE,WAAO;AAAA,EACT;AAEA,SAAQ,KAAkD,eAAe;AAC3E;AAEA,SAAS,SACP,MACA,MACA,iBAC0B;AAC1B,QAAM,UAA4D;AAAA,IAChE,cAAc;AAAA,IACd,cAAc;AAAA,IACd,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EAClB;AACA,QAAM,OAAO,OAAO,QAAQ,IAAI,IAAI;AAEpC,MAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,SAAS,MAAM;AACtD,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ;AAMd,QAAM,QAAsB;AAAA,IAC1B;AAAA,IACA,UAAU,mBAAmB,MAAM,aAAa;AAAA,EAClD;AAEA,MAAI,MAAM,SAAU,OAAM,WAAW,MAAM;AAC3C,MAAI,MAAM,SAAU,OAAM,WAAW,MAAM;AAE3C,QAAM,UAAU,SAAS,MAAM,OAAO;AACtC,MAAI,YAAY,OAAW,OAAM,UAAU;AAE3C,SAAO;AACT;AAEA,SAAS,UACP,SACA,QAC2B;AAC3B,MAAI,CAAC,SAAS,YAAY,CAAC,QAAQ,cAAe,QAAO;AAEzD,QAAM,UAAU,yBAAyB,QAAQ,aAAa;AAC9D,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,EAAE,MAAM,KAAK,IAAI,YAAY,OAAO;AAC1C,QAAM,QAAQ,SAAS,MAAM,MAAM,sBAAsB,QAAQ,aAAa,CAAC;AAC/E,QAAM,WAAW,QAAQ,eAAe;AACxC,QAAM,SAAwB;AAAA,IAC5B,KAAK;AAAA,MACH,IAAI,QAAQ;AAAA,MACZ,QAAQ,QAAQ,aAAa;AAAA,MAC7B,QAAQ;AAAA,MACR,GAAI,WAAW,EAAE,eAAe,SAAS,IAAI,CAAC;AAAA,IAChD;AAAA,IACA,UAAU,UAAU;AAAA,IACpB,YAAY,OAAO,YAAY;AAAA,IAC/B,aAAa,eAAe,IAAI;AAAA,EAClC;AACA,QAAM,OAAO,QAAQ,OAAO,KAAK,WAAW,OAAO;AAEnD,MAAI,SAAS,OAAW,QAAO,OAAO;AACtC,MAAI,aAAa,QAAW;AAC1B,WAAO,WAAW;AAClB,WAAO,SAAS,KAAK,eAAe,CAAC,QAAQ,CAAC;AAAA,EAChD;AACA,MAAI,UAAU,OAAW,QAAO,QAAQ;AAExC,SAAO;AACT;AAEA,SAAS,OAAO,OAAmD;AACjE,QAAM,UAAU,SAAS,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAC/D,SAAO,IAAI,KAAK,UAAU,GAAK;AACjC;AAEA,SAAS,SAAS,OAAiE;AACjF,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,SAAU,QAAO,MAAM,SAAS;AAC3C,MAAI,OAAO,OAAO,QAAQ,SAAU,QAAO,MAAM;AACjD,SAAO;AACT;;;ADtUO,IAAM,eAAN,MAA+C;AAAA,EAC3C;AAAA,EACA,UAAU,IAAI,kBAAkC;AAAA,EAChD;AAAA,EACA,gBAAgB,oBAAI,IAA+B;AAAA,EACnD,mBAAmB,oBAAI,QAAuC;AAAA,EAC9D;AAAA,EACT;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB,aAAa;AAAA,EACb,sBAAsB;AAAA,EACtB,gBAA+B,QAAQ,QAAQ;AAAA,EAC/C;AAAA,EAEA,YAAY,SAA8B;AACxC,SAAK,WAAW;AAChB,SAAK,UAAU,QAAQ,UAAU,IAAI,OAAO,QAAQ;AACpD,SAAK,oBAAoB,KAAK,IAAI,GAAG,QAAQ,oBAAoB,GAAK;AAAA,EACxE;AAAA,EAEA,GACE,OACA,UACA;AACA,WAAO,KAAK,QAAQ,GAAG,OAAO,QAAQ;AAAA,EACxC;AAAA,EAEA,MAAM,UAAyB;AAC7B,SAAK,oBAAoB;AACzB,UAAM,SAAS,MAAM,KAAK,cAAc;AAExC,QAAI,KAAK,cAAc,KAAK,iBAAiB;AAC3C;AAAA,IACF;AAEA,SAAK,oBAAoB;AACzB,UAAM,KAAK,QAAQ,KAAK,cAAc;AAAA,MACpC,OAAO,KAAK,oBAAoB,IAAI,iBAAiB;AAAA,MACrD,SAAS,KAAK;AAAA,IAChB,CAAC;AACD,SAAK,cAAc,MAAM;AAAA,EAC3B;AAAA,EAEA,MAAM,aAA4B;AAChC,SAAK,oBAAoB;AAEzB,QAAI,KAAK,iBAAiB;AACxB,mBAAa,KAAK,eAAe;AACjC,WAAK,kBAAkB;AAAA,IACzB;AAEA,UAAM,SAAS,KAAK;AACpB,SAAK,kBAAkB;AAEvB,QAAI,QAAQ;AACV,YAAM,OAAO,WAAW;AAAA,IAC1B,OAAO;AACL,YAAM,KAAK,QAAQ,KAAK,cAAc,EAAE,OAAO,SAAS,CAAC;AAAA,IAC3D;AAEA,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,oBAA8B;AAC5B,UAAM,cAAc,KAAK,SAAS,eAAe;AACjD,WAAO,iBAAiB;AAAA,MACtB,aAAa;AAAA,MACb,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAAmB,OAAgC;AACvD,UAAM,aAAa,MAAM,QAAQ,OAAO,EAAE;AAE1C,QAAI,WAAW,SAAS,IAAI;AAC1B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,cAAc;AAExC,QAAI,OAAO,eAAe,GAAG,OAAO;AAClC,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,KAAK,mBAAmB,CAAC,KAAK,YAAY;AAC7C,YAAM,KAAK,QAAQ;AAAA,IACrB;AAEA,QAAI;AACF,UAAI,CAAC,KAAK,kBAAkB;AAC1B,cAAM,KAAK;AAAA,UACT,KAAK;AAAA,UACL;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,aAAO,MAAM,OAAO,KAAK,mBAAmB,UAAU;AAAA,IACxD,SAAS,OAAO;AACd,UAAI,iBAAiB,aAAc,OAAM;AAEzC,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,OAAO,OAAO,aAAa,KAAK;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,YACJ,QACA,SACA,SACsB;AACtB,QAAI,aAAa,SAAS;AACxB,aAAO,KAAK,aAAa,QAAQ,SAAS,OAAO;AAAA,IACnD;AAEA,QAAI,UAAU,SAAS;AACrB,aAAO,KAAK,UAAU,QAAQ,SAAS,OAAO;AAAA,IAChD;AAEA,UAAM,SAAS,KAAK,eAAe;AACnC,UAAM,EAAE,OAAO,UAAU,SAAS,IAAI,MAAM,KAAK,WAAW,OAAO;AACnE,UAAM,SAAS,MAAM,OAAO,QAAQ,KAAK,QAAQ,OAAgB;AAAA,MAC/D,GAAI,UAAU,EAAE,OAAO,KAAK,WAAW,OAAO,EAAE,IAAI,CAAC;AAAA,MACrD,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;AAAA,MAC1C,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/C,CAAC;AAED,WAAO,KAAK,MAAM,QAAQ,MAAM;AAAA,EAClC;AAAA,EAEA,MAAM,cACJ,QACA,QACA,UAAgC,CAAC,GACX;AACtB,UAAM,WAAW,KAAK,mBAAmB,KAAK,WAAW,MAAM,CAAC;AAEhE,QAAI,CAAC,UAAU,SAAS;AACtB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,SAAS,EAAE,WAAW,OAAO,IAAI,QAAQ,OAAO,OAAO;AAAA,UACvD,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE,QAAQ;AAAA,MACjD;AAAA,MACA,SAAS;AAAA,MACT;AAAA,QACE,SAAS;AAAA,QACT,GAAI,QAAQ,YAAY,QAAQ,SAAS,SAAS,IAC9C,EAAE,UAAU,KAAK,UAAU,QAAQ,QAAQ,EAAE,IAC7C,CAAC;AAAA,MACP;AAAA,IACF;AAEA,WAAO,KAAK,MAAM,QAAQ,MAAM;AAAA,EAClC;AAAA,EAEA,MAAM,eAAe,KAAiB,OAAsC;AAC1E,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE,QAAQ,KAAK,IAAI,QAAQ;AAAA,MAClE,MAAM;AAAA,MACN,OAAO,SAAS;AAAA,MAChB,QAAQ,KAAK,WAAW,GAAG;AAAA,IAC7B,CAAC;AAED,WAAO,KAAK,MAAM,QAAQ,IAAI,MAAM;AAAA,EACtC;AAAA,EAEA,MAAM,cAAc,KAA2C;AAC7D,UAAM,UAAU,KAAK,iBAAiB,IAAI,GAAG,KACxC,KAAK,mBAAmB,KAAK,WAAW,GAAG,CAAC;AAEjD,QAAI,CAAC,SAAS,SAAS;AACrB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,aAAa,KAAK;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,aAAa,qBAAqB,OAAO;AAE/C,QAAI,CAAC,YAAY,OAAO;AACtB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,eAAe,yBAAyB,QAAQ,OAAO,KACxD,QAAQ;AACb,YAAM,QAAQ,MAAM,KAAK,eAAe,EAAE,QAAQ,cAAc,YAAY;AAE5E,aAAO;AAAA,QACL,MAAM,OAAO,KAAK,KAAK;AAAA,QACvB,MAAM,WAAW,MAAM;AAAA,QACvB,GAAI,WAAW,MAAM,WAAW,EAAE,UAAU,WAAW,MAAM,SAAS,IAAI,CAAC;AAAA,QAC3E,GAAI,WAAW,MAAM,WAAW,EAAE,UAAU,WAAW,MAAM,SAAS,IAAI,CAAC;AAAA,MAC7E;AAAA,IACF,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,OAAO,OAAO,aAAa,KAAK;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,KAAiB,SAAuC;AACxE,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE,QAAQ;AAAA,MACjD,IAAI;AAAA,MACJ;AAAA,MACA,EAAE,SAAS,KAAK,WAAW,GAAG,EAAE;AAAA,IAClC;AAEA,WAAO,KAAK,MAAM,QAAQ,IAAI,MAAM;AAAA,EACtC;AAAA,EAEA,MAAM,cAAc,KAAgC;AAClD,UAAM,KAAK,eAAe,EAAE,QAAQ,KAAK,IAAI,QAAQ;AAAA,MACnD,MAAM;AAAA,MACN,QAAQ,KAAK,WAAW,GAAG;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,SAAS,SAAyC;AACtD,UAAM,WAAW,MAAM,KAAK,eAAe,EAAE,MAAM,mBAAmB,OAAO;AAC7E,UAAM,eAAe,CAAC,GAAI,SAAS,gBAAgB,CAAC,CAAE;AACtD,UAAM,iBAAiB,SAAS,mBAAmB,SAC9C,aAAa,KAAK,CAAC,iBACnB,YAAY,OAAO,YAAY,MAAM,IAAI,SAAS,MAAM,CAAC,IAC1D,QACA;AAEJ,WAAO;AAAA,MACL,IAAI,SAAS,OAAO,SAAS,MAAM;AAAA,MACnC,SAAS,SAAS,WAAW;AAAA,MAC7B,QAAQ,SAAS,WAAW,WAAW;AAAA,MACvC;AAAA,MACA,WAAW,oBAAI,KAAK;AAAA,MACpB,cAAc,aAAa,IAAI,CAAC,gBAAgB;AAC9C,cAAM,KAAK,YAAY,OAAO,YAAY,MAAM,YAAY,OAAO,YAAY,eAAe;AAC9F,eAAO;AAAA,UACL;AAAA,UACA,GAAI,YAAY,MAAM,EAAE,KAAK,YAAY,IAAI,IAAI,CAAC;AAAA,UAClD,GAAI,YAAY,cAAc,EAAE,aAAa,YAAY,YAAY,IAAI,CAAC;AAAA,UAC1E,MAAM,YAAY,gBAAgB,YAAY,UAAU,eACpD,UACA,YAAY,WAAW,YAAY,UAAU,UAC3C,UACA;AAAA,QACR;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,SAAiB,QAAoC;AACxE,UAAM,KAAK,eAAe,EAAE,MAAM;AAAA,MAChC;AAAA,MACA;AAAA,MACA,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,SAAkC;AACzD,UAAM,OAAO,MAAM,KAAK,eAAe,EAAE,MAAM,gBAAgB,OAAO;AAEtE,QAAI,CAAC,MAAM;AACT,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,SAAkC;AACxD,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE,MAAM,aAAa,OAAO;AAErE,QAAI,CAAC,OAAO,MAAM;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,cACJ,SACA,KACA,QACe;AACf,UAAM,KAAK,eAAe,EAAE,QAAQ,KAAK,SAAS,SAC9C;AAAA,MACE,MAAM;AAAA,MACN,QAAQ,KAAK,WAAW,GAAG;AAAA,MAC3B,cAAc;AAAA,IAChB,IACA;AAAA,MACE,MAAM;AAAA,MACN,QAAQ,KAAK,WAAW,GAAG;AAAA,IAC7B,CAAC;AAAA,EACP;AAAA,EAEA,MAAM,kBACJ,SACA,UACA,QACkC;AAClC,UAAM,QAAQ,KAAK,eAAe,EAAE;AACpC,UAAM,UAAU,WAAW,WACvB,MAAM,MAAM,mBAAmB,SAAS,CAAC,QAAQ,CAAC,IAClD,WAAW,YACT,MAAM,MAAM,oBAAoB,SAAS,CAAC,QAAQ,CAAC,IACnD,MAAM,MAAM,mBAAmB,SAAS,CAAC,QAAQ,CAAC;AACxD,UAAM,SAAS,QAAQ,CAAC;AACxB,UAAM,UAAU,QAAQ,WAAW;AACnC,UAAM,SAAS,UAAU,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,UAAU,SAAS;AAEnF,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAI,QAAQ,MAAM,EAAE,UAAU,OAAO,IAAI,IAAI,CAAC;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,QAAgB,OAAqC;AACrE,UAAM,QAA4B,UAAU,WACxC,cACA,UAAU,cACR,cACA;AACN,UAAM,WAAW,KAAK,eAAe,EAAE;AAEvC,UAAM,SAAS,cAAc,QAAQ,EAAE,OAAO,MAAM,CAAC;AAAA,EACvD;AAAA,EAEA,MAAM,WAAW,QAAgB,OAA8B;AAC7D,SAAK,eAAe;AAEpB,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,aAAa,KAAK;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,KAAK,MAAM,WAAW,MAAM;AAAA,EACpC;AAAA,EAEA,MAAM,gBAAmC;AACvC,QAAI,KAAK,QAAS,QAAO,KAAK;AAE9B,UAAM,MAAM,KAAK,SAAS,MAAM,EAAE,WAAW,KAAK,CAAC;AACnD,UAAM,QAAQ,YAAY;AAAA,MACxB,UAAU;AAAA,QACR,QAAQ,kBAAkB;AAAA,UACxB,MAAM,KAAK,KAAK,SAAS,MAAM,cAAc;AAAA,UAC7C,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,MACA,WAAW;AAAA,QACT,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,QACV,WAAW;AAAA,QACX,UAAU;AAAA,QACV,cAAc;AAAA,QACd,UAAU;AAAA,QACV,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,MACA,gBAAgB;AAAA,QACd,eAAe;AAAA,MACjB;AAAA,IACF,CAAC;AACD,UAAM,UAA4B,CAAC;AAEnC,QAAI;AACF,YAAM,EAAE,WAAW,IAAI,MAAM,OAAO,eAAe;AACnD,cAAQ,KAAK,WAAW,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,IAC/C,SAAS,OAAO;AACd,WAAK,QAAQ,KAAK,6EAA6E;AAAA,QAC7F,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,IAAI,SAAS;AAAA,MAC1B;AAAA,MACA,WAAW,KAAK,SAAS,aAAa;AAAA,MACtC,qBAAqB;AAAA,MACrB,eAAe,KAAK,eAAe;AAAA,MACnC,qBAAqB,KAAK,qBAAqB;AAAA,MAC/C,SAAS,EAAE,SAAS,MAAM;AAAA,MAC1B,QAAQ;AAAA,QACN,aAAa;AAAA,QACb,mBAAmB;AAAA,MACrB;AAAA,MACA,OAAO,EAAE,WAAW,qBAAqB,EAAE;AAAA,MAC3C;AAAA,IACF,GAAG,IAAI,kBAAkB,KAAK,OAAO,CAAC;AAEtC,SAAK,UAAU;AACf,SAAK,QAAS,OAAyD;AACvE,SAAK,MAAM,MAAM;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAwB;AAC5B,WAAO,GAAG,yBAAyB,MAAM;AACvC,WAAK,kBAAkB;AAAA,IACzB,CAAC;AAED,WAAO,GAAG,WAAW,MAAM;AACzB,WAAK,kBAAkB;AAAA,IACzB,CAAC;AAED,WAAO,GAAG,eAAe,MAAM;AAC7B,WAAK,mBAAmB;AAAA,IAC1B,CAAC;AAED,WAAO,GAAG,WAAW,CAAC,UAAU;AAC9B,WAAK,eAAe,KAAK;AAAA,IAC3B,CAAC;AAED,WAAO,GAAG,gBAAgB,CAAC,UAAU;AACnC,UAAI,CAAC,MAAM,MAAM,CAAC,MAAM,QAAS;AAEjC,WAAK,UAAU;AAAA,QACb,KAAK;AAAA,UACH,IAAI,MAAM;AAAA,UACV,WAAW,MAAM;AAAA,UACjB,QAAQ;AAAA,QACV;AAAA,QACA,SAAS,MAAM;AAAA,QACf,kBAAkB,KAAK,MAAM,KAAK,IAAI,IAAI,GAAK;AAAA,MACjD,CAAC;AAAA,IACH,CAAC;AAED,WAAO,GAAG,oBAAoB,CAAC,UAAU;AACvC,WAAK,qBAAqB,KAAyC;AAAA,IACrE,CAAC;AAED,WAAO,GAAG,SAAS,CAAC,UAAU;AAC5B,WAAK,kBAAkB,KAAsC;AAAA,IAC/D,CAAC;AAED,QAAI,KAAK,OAAO;AACd,YAAM,aAAa;AAEnB,iBAAW,GAAG,sBAAsB,CAAC,UAAU;AAC7C,cAAM,OAAO,KAAK,mBAAmB,OAAO,OAAO;AACnD,YAAI,KAAM,MAAK,KAAK,QAAQ,KAAK,QAAQ,IAAI;AAAA,MAC/C,CAAC;AAED,iBAAW,GAAG,mBAAmB,CAAC,UAAU;AAC1C,YAAI,MAAM,WAAW,UAAU,QAAS;AAExC,cAAM,OAAO,KAAK,mBAAmB,KAAK;AAC1C,YAAI,QAAQ,KAAK,WAAW,QAAS,MAAK,KAAK,QAAQ,KAAK,QAAQ,IAAI;AAAA,MAC1E,CAAC;AAED,iBAAW,GAAG,mBAAmB,CAAC,UAAU;AAC1C,cAAM,OAAO,KAAK;AAAA,UAChB;AAAA,UACA,KAAK,eAAe,MAAM,WAAW,SAAS;AAAA,QAChD;AACA,YAAI,KAAM,MAAK,KAAK,QAAQ,KAAK,QAAQ,IAAI;AAAA,MAC/C,CAAC;AAAA,IACH;AAEA,WAAO,GAAG,cAAc,CAAC,UAAU;AACjC,WAAK,KAAK,uBAAuB,QAAQ,KAAK;AAAA,IAChD,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,OAAqC;AAClD,UAAM,SAAS;AAEf,QAAI,KAAK,kBAAkB,MAAM,GAAG;AAClC,WAAK,QAAQ,MAAM,yDAAyD;AAAA,QAC1E,WAAW,OAAO,IAAI,MAAM;AAAA,QAC5B,QAAQ,OAAO,IAAI,aAAa;AAAA,QAChC,kBAAkB,OAAO,oBAAoB;AAAA,MAC/C,CAAC;AACD;AAAA,IACF;AAEA,QAAI,OAAO,KAAK,MAAM,OAAO,QAAS,MAAK,UAAU,MAAM;AAE3D,UAAM,SAAS,yBAAyB,KAAK;AAC7C,QAAI,QAAQ,IAAI,MAAM,OAAO,SAAS;AACpC,WAAK,UAAU,MAAsC;AAAA,IACvD;AAEA,UAAM,UAAU,qBAAqB,KAAK;AAC1C,QAAI,CAAC,QAAS;AAEd,SAAK,iBAAiB,IAAI,QAAQ,MAAM,MAAM;AAC9C,QAAI,QAAQ,UAAU,QAAQ,SAAS;AACrC,WAAK,iBAAiB;AAAA,QACpB,QAAQ,OAAO;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAEA,SAAK,KAAK,QAAQ,KAAK,WAAW,OAAO;AAAA,EAC3C;AAAA,EAEA,qBAAqB,OAAoC;AACvD,UAAM,WAAW,MAAM,mBACjB,MAAM,SAAS;AACrB,QAAI,CAAC,SAAU;AAEf,UAAM,cAAc,SAAS;AAC7B,QAAI,CAAC,aAAa,GAAI;AAEtB,UAAM,YAAY,YAAY,aAAa,MAAM,IAAI;AACrD,UAAM,cAAc,YAAY,eAAe,MAAM,IAAI;AACzD,UAAM,iBAAiB,YAAY,kBAAkB,MAAM,IAAI;AAC/D,UAAM,SAA6B;AAAA,MACjC,GAAG;AAAA,MACH,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MAC/C,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,MACnD,GAAI,mBAAmB,SAAY,EAAE,eAAe,IAAI,CAAC;AAAA,IAC3D;AAEA,QAAI,CAAC,OAAO,UAAW;AAEvB,UAAM,SAAS,KAAK,mBAAmB,MAAM;AAC7C,UAAM,OAAO,UAAU;AAEvB,QAAI,SAAS,MAAM,QAAQ,gBAAgB,KAAK,QAAQ;AACtD,YAAMC,YAAW,SAAS,qBAAqB,MAAM,IAAI;AACzD,YAAM,cAAc,MAAM,IAAI,WAAW;AACzC,YAAM,cAAc,MAAM,IAAI,eACzB,MAAM,IAAI,mBACT,cAAc,KAAK,kBAAkB,EAAE,CAAC,IAAI,MAAM,IAAI,aAAa;AAEzE,WAAK,KAAK,QAAQ,KAAK,kBAAkB;AAAA,QACvC,KAAKA,WAAU,QAAQ,iBAAiB,MAAM;AAAA,QAC9C,GAAIA,YAAW,EAAE,SAASA,UAAS,IAAI,CAAC;AAAA,QACxC;AAAA,QACA,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,QACrC,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC;AACD;AAAA,IACF;AAEA,QAAI,SAAS,MAAM,QAAQ,gBAAgB,KAAK,gBAAgB,CAAC,SAAS,eAAe;AACvF;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,YAAY,QAAQ;AAC3C,UAAM,SAA4B;AAAA,MAChC,GAAI,UAAU,CAAC;AAAA,MACf,KAAK;AAAA,QACH,GAAI,QAAQ,OAAO,CAAC;AAAA,QACpB,GAAG;AAAA,MACL;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,kBAAkB,UAAU,SAAS,WAAW,KAC3C,MAAM,oBACN,QAAQ,oBACR,KAAK,MAAM,KAAK,IAAI,IAAI,GAAK;AAAA,MAClC,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/C;AACA,UAAM,UAAU,qBAAqB,MAAM;AAE3C,QAAI,CAAC,QAAS;AAEd,UAAM,WAAW,SAAS,qBAAqB,MAAM,IAAI;AACzD,SAAK,UAAU,MAAM;AACrB,UAAM,aAAa,MAAM,IAAI,WAAW;AACxC,UAAM,aAAa,MAAM,IAAI,eACxB,MAAM,IAAI,mBACT,aAAa,KAAK,kBAAkB,EAAE,CAAC,IAAI,MAAM,IAAI,aAAa;AAExE,SAAK,KAAK,QAAQ,KAAK,iBAAiB;AAAA,MACtC,KAAK,QAAQ;AAAA,MACb,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,MACnC,UAAU,QAAQ;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB,OAAiC;AACjD,UAAM,UAAU,MAAM;AACtB,QAAI,CAAC,QAAS;AAEd,UAAM,SAAS,KAAK,aAAa,MAAM,MAAM;AAC7C,UAAM,iBAAiB,KAAK,qBAAqB,KAAK;AAEtD,QAAI,UAAU,eAAe,SAAS,GAAG;AACvC,YAAM,WAAW,MAAM;AACvB,YAAM,SAAmC;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MACjC;AACA,WAAK,KAAK,QAAQ,KAAK,4BAA4B,MAAM;AAAA,IAC3D;AAEA,SAAK,KAAK,QAAQ,KAAK,gBAAgB,EAAE,QAAQ,CAAC;AAAA,EACpD;AAAA,EAEA,MAAM,uBACJ,QACA,OACe;AACf,QAAI,WAAW,KAAK,QAAS;AAE7B,QAAI,MAAM,WAAW,QAAQ;AAC3B,WAAK,kBAAkB;AACvB,WAAK,aAAa;AAClB,WAAK,sBAAsB,KAAK,MAAM,KAAK,IAAI,IAAI,GAAK;AACxD,WAAK,oBAAoB;AACzB,YAAM,KAAK,QAAQ,KAAK,cAAc,EAAE,OAAO,YAAY,CAAC;AAC5D;AAAA,IACF;AAEA,SAAK,kBAAkB;AACvB,SAAK,aAAa;AAClB,UAAM,QAAQ,MAAM,kBAAkB,QAClC,MAAM,SACN,MAAM,SACJ,IAAI,MAAM,OAAO,MAAM,MAAM,CAAC,IAC9B;AAEN,QAAI,KAAK,qBAAqB,MAAM,UAAU;AAC5C,YAAM,KAAK,QAAQ,KAAK,cAAc;AAAA,QACpC,OAAO;AAAA,QACP,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,MAC3B,CAAC;AACD;AAAA,IACF;AAEA,UAAM,KAAK,mBAAmB,KAAK;AAAA,EACrC;AAAA,EAEA,cAAc,QAAwB;AACpC,UAAM,UAAU,OAAO,QAAQ;AAC/B,SAAK,kBAAkB;AACvB,SAAK,QAAQ,MAAM,OAAO,UAAmB;AAC3C,UAAI,KAAK,oBAAoB,QAAS;AACtC,WAAK,kBAAkB;AAEvB,UAAI,KAAK,kBAAmB;AAE5B,YAAM,aAAa,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAC3E,WAAK,QAAQ,KAAK,uCAAuC,EAAE,OAAO,WAAW,CAAC;AAC9E,YAAM,KAAK,mBAAmB,UAAU;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAAmB,OAA8B;AACrD,QAAI,KAAK,gBAAiB;AAE1B,UAAM,UAAU,KAAK,SAAS;AAC9B,UAAM,cAAc,SAAS,eAAe;AAE5C,QAAI,SAAS,YAAY,SAAS,KAAK,qBAAqB,aAAa;AACvE,YAAM,KAAK,QAAQ,KAAK,cAAc;AAAA,QACpC,OAAO;AAAA,QACP,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,MAC3B,CAAC;AACD;AAAA,IACF;AAEA,SAAK,qBAAqB;AAC1B,UAAM,KAAK,QAAQ,KAAK,cAAc;AAAA,MACpC,OAAO;AAAA,MACP,SAAS,KAAK;AAAA,MACd,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IAC3B,CAAC;AAED,UAAM,UAAU,SAAS,kBAAkB;AAC3C,UAAM,UAAU,SAAS,cAAc;AACvC,UAAM,QAAQ,KAAK,IAAI,SAAS,UAAU,MAAM,KAAK,oBAAoB,EAAE;AAC3E,SAAK,kBAAkB,WAAW,MAAM;AACtC,WAAK,kBAAkB;AACvB,WAAK,KAAK,QAAQ;AAAA,IACpB,GAAG,QAAQ,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG,CAAC;AAAA,EAC5C;AAAA,EAEA,MAAM,aACJ,QACA,SACA,SACsB;AACtB,SAAK,iBAAiB,OAAO;AAC7B,UAAM,WAAW,QAAQ,WAAW,KAAK,UAAU,QAAQ,QAAQ,IAAI,CAAC;AACxE,UAAM,MAAsB;AAAA,MAC1B,oBAAoB;AAAA,QAClB,GAAI,QAAQ,UAAU,SAClB;AAAA,UACE,QAAQ;AAAA,YACN,OAAO,QAAQ;AAAA,YACf,oBAAoB;AAAA,UACtB;AAAA,QACF,IACA,CAAC;AAAA,QACL,MAAM,EAAE,MAAM,QAAQ,KAAK;AAAA,QAC3B,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,EAAE,MAAM,QAAQ,OAAO,EAAE,IAAI,CAAC;AAAA,QAC3E,GAAI,SAAS,SAAS,IAAI,EAAE,aAAa,EAAE,cAAc,SAAS,EAAE,IAAI,CAAC;AAAA,QACzE,mBAAmB;AAAA,UACjB,SAAS,QAAQ,QAAQ,IAAI,CAAC,WAAW;AACvC,gBAAI,OAAO,SAAS,QAAQ;AAC1B,qBAAO;AAAA,gBACL,MAAM;AAAA,gBACN,kBAAkB,KAAK,UAAU;AAAA,kBAC/B,cAAc,OAAO;AAAA,kBACrB,WAAW,OAAO;AAAA,gBACpB,CAAC;AAAA,cACH;AAAA,YACF;AAEA,gBAAI,OAAO,SAAS,SAAS;AAC3B,qBAAO;AAAA,gBACL,MAAM;AAAA,gBACN,kBAAkB,KAAK,UAAU;AAAA,kBAC/B,cAAc,OAAO;AAAA,kBACrB,IAAI,OAAO;AAAA,gBACb,CAAC;AAAA,cACH;AAAA,YACF;AAEA,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,kBAAkB,KAAK,UAAU;AAAA,gBAC/B,cAAc,OAAO;AAAA,gBACrB,KAAK,OAAO;AAAA,gBACZ,cAAc,OAAO;AAAA,cACvB,CAAC;AAAA,YACH;AAAA,UACF,CAAC;AAAA,UACD,mBAAmB;AAAA,UACnB,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE,QAAQ,KAAK,QAAQ,KAAK;AAAA,MACnE,GAAI,UAAU,EAAE,OAAO,KAAK,WAAW,OAAO,EAAE,IAAI,CAAC;AAAA,MACrD,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;AAAA,IAC5C,CAAC;AAED,WAAO,KAAK,MAAM,QAAQ,MAAM;AAAA,EAClC;AAAA,EAEA,MAAM,UACJ,QACA,SACA,SACsB;AACtB,SAAK,cAAc,OAAO;AAC1B,UAAM,WAAW,QAAQ,WAAW,KAAK,UAAU,QAAQ,QAAQ,IAAI,CAAC;AACxE,UAAM,MAAsB;AAAA,MAC1B,oBAAoB;AAAA,QAClB,GAAI,QAAQ,UAAU,SAClB;AAAA,UACE,QAAQ;AAAA,YACN,OAAO,QAAQ;AAAA,YACf,oBAAoB;AAAA,UACtB;AAAA,QACF,IACA,CAAC;AAAA,QACL,MAAM,EAAE,MAAM,QAAQ,KAAK;AAAA,QAC3B,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,EAAE,MAAM,QAAQ,OAAO,EAAE,IAAI,CAAC;AAAA,QAC3E,GAAI,SAAS,SAAS,IAAI,EAAE,aAAa,EAAE,cAAc,SAAS,EAAE,IAAI,CAAC;AAAA,QACzE,mBAAmB;AAAA,UACjB,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,kBAAkB,KAAK,UAAU;AAAA,gBAC/B,OAAO,QAAQ;AAAA,gBACf,UAAU,QAAQ,KAAK,IAAI,CAAC,aAAa;AAAA,kBACvC,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,kBAC9D,MAAM,QAAQ,KAAK,IAAI,CAAC,SAAS;AAAA,oBAC/B,IAAI,IAAI;AAAA,oBACR,OAAO,IAAI;AAAA,oBACX,GAAI,IAAI,gBAAgB,SAAY,EAAE,aAAa,IAAI,YAAY,IAAI,CAAC;AAAA,kBAC1E,EAAE;AAAA,gBACJ,EAAE;AAAA,cACJ,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,mBAAmB;AAAA,UACnB,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE,QAAQ,KAAK,QAAQ,KAAK;AAAA,MACnE,GAAI,UAAU,EAAE,OAAO,KAAK,WAAW,OAAO,EAAE,IAAI,CAAC;AAAA,MACrD,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;AAAA,IAC5C,CAAC;AAED,WAAO,KAAK,MAAM,QAAQ,MAAM;AAAA,EAClC;AAAA,EAEA,MAAM,WAAW,SAId;AACD,QAAI,UAAU,SAAS;AACrB,aAAO;AAAA,QACL,OAAO,EAAE,MAAM,QAAQ,MAAM,QAAQ,KAAK;AAAA,QAC1C,UAAU,QAAQ,WAAW,KAAK,UAAU,QAAQ,QAAQ,IAAI,CAAC;AAAA,MACnE;AAAA,IACF;AAEA,QAAI,UAAU,SAAS;AACrB,aAAO;AAAA,QACL,OAAO,KAAK,aAAa,OAAO;AAAA,QAChC,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAEA,QAAI,WAAW,SAAS;AACtB,aAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAK;AAAA,UACtC,GAAI,QAAQ,YAAY,SAAY,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,QACtE;AAAA,QACA,UAAU,QAAQ,WAAW,KAAK,UAAU,QAAQ,QAAQ,IAAI,CAAC;AAAA,QACjE,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MACzE;AAAA,IACF;AAEA,QAAI,WAAW,SAAS;AACtB,aAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAK;AAAA,UACtC,GAAI,QAAQ,YAAY,SAAY,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,UACpE,GAAI,QAAQ,QAAQ,SAAY,EAAE,aAAa,QAAQ,IAAI,IAAI,CAAC;AAAA,QAClE;AAAA,QACA,UAAU,QAAQ,WAAW,KAAK,UAAU,QAAQ,QAAQ,IAAI,CAAC;AAAA,QACjE,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MACzE;AAAA,IACF;AAEA,QAAI,aAAa,SAAS;AACxB,aAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,MAAM,KAAK,OAAO,QAAQ,OAAO;AAAA,UACxC,UAAU;AAAA,QACZ;AAAA,QACA,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAK;AAAA,QACtC,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,QACzD,GAAI,QAAQ,UAAU,SAAY,EAAE,KAAK,QAAQ,MAAM,IAAI,CAAC;AAAA,MAC9D;AAAA,MACA,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AAAA,EAEA,iBAAiB,SAA+B;AAC9C,QAAI,CAAC,QAAQ,KAAK,KAAK,KAAK,QAAQ,QAAQ,WAAW,GAAG;AACxD,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,eAAW,UAAU,QAAQ,SAAS;AACpC,UAAI,CAAC,OAAO,MAAM,KAAK,GAAG;AACxB,cAAM,IAAI,aAAa,oBAAoB,4CAA4C;AAAA,MACzF;AACA,UAAI,OAAO,SAAS,WAAW,CAAC,OAAO,GAAG,KAAK,GAAG;AAChD,cAAM,IAAI,aAAa,oBAAoB,mCAAmC;AAAA,MAChF;AACA,UAAI,OAAO,SAAS,UAAU,CAAC,OAAO,MAAM;AAC1C,cAAM,IAAI,aAAa,oBAAoB,wCAAwC;AAAA,MACrF;AACA,UAAI,OAAO,SAAS,UAAU,CAAC,OAAO,IAAI,KAAK,GAAG;AAChD,cAAM,IAAI,aAAa,oBAAoB,uCAAuC;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,SAA4B;AACxC,QAAI,CAAC,QAAQ,KAAK,KAAK,KAAK,CAAC,QAAQ,WAAW,KAAK,KAAK,QAAQ,KAAK,WAAW,GAAG;AACnF,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,WAAW;AACf,UAAM,MAAM,oBAAI,IAAY;AAC5B,eAAW,WAAW,QAAQ,MAAM;AAClC,iBAAW,OAAO,QAAQ,MAAM;AAC9B,oBAAY;AACZ,cAAM,KAAK,IAAI,GAAG,KAAK;AACvB,YAAI,CAAC,MAAM,CAAC,IAAI,MAAM,KAAK,GAAG;AAC5B,gBAAM,IAAI;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,YAAI,IAAI,IAAI,EAAE,GAAG;AACf,gBAAM,IAAI;AAAA,YACR;AAAA,YACA,0BAA0B,EAAE;AAAA,UAC9B;AAAA,QACF;AACA,YAAI,IAAI,EAAE;AAAA,MACZ;AAAA,IACF;AAEA,QAAI,aAAa,GAAG;AAClB,YAAM,IAAI,aAAa,oBAAoB,sCAAsC;AAAA,IACnF;AAAA,EACF;AAAA,EAEA,aAAa,SAA+B;AAC1C,UAAM,OAAO,QAAQ,KAAK,KAAK;AAC/B,UAAM,UAAU,QAAQ,QAAQ,IAAI,CAACC,YAAWA,QAAO,KAAK,CAAC,EAAE,OAAO,OAAO;AAC7E,UAAM,kBAAkB,QAAQ,mBAAmB;AAEnD,QAAI,CAAC,QAAQ,QAAQ,SAAS,GAAG;AAC/B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,UAAU,eAAe,KAAK,kBAAkB,KAAK,kBAAkB,QAAQ,QAAQ;AACjG,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,SAAS,EAAE,iBAAiB,SAAS,QAAQ,OAAO,EAAE;AAAA,MAC1D;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,QAAQ,mBAAmB,SAAY,EAAE,gBAAgB,QAAQ,eAAe,IAAI,CAAC;AAAA,IAC3F;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,QAAmD;AAC9D,QAAI,kBAAkB,WAAY,QAAO;AACzC,QAAI,UAAU,OAAQ,QAAO,OAAO;AAEpC,UAAM,WAAW,MAAM,MAAM,OAAO,GAAG;AAEvC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,SAAS,EAAE,QAAQ,SAAS,OAAO;AAAA,UACnC,aAAa,SAAS,UAAU;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAEA,WAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AAAA,EACpD;AAAA,EAEA,UAAU,UAA8C;AACtD,WAAO,SAAS,IAAI,CAAC,YACnB,OAAO,YAAY,WAAW,UAAU,QAAQ,SAAS;AAAA,EAC7D;AAAA,EAEA,WAAW,KAKT;AACA,WAAO;AAAA,MACL,IAAI,IAAI;AAAA,MACR,WAAW,IAAI;AAAA,MACf,QAAQ,IAAI;AAAA,MACZ,GAAI,IAAI,gBAAgB,EAAE,aAAa,IAAI,cAAc,IAAI,CAAC;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,MAAM,QAA+B,QAA6B;AAChE,QAAI,CAAC,OAAO,IAAI;AACd,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,MACX;AAAA,MACA,MAAM;AAAA,QACJ,IAAI,OAAO;AAAA,QACX;AAAA,QACA,QAAQ;AAAA,MACV;AAAA,MACA,WAAW,oBAAI,KAAK;AAAA,IACtB;AAAA,EACF;AAAA,EAGA,mBACE,OACA,cACuB;AACvB,UAAM,KAAK,MAAM;AACjB,UAAM,OAAO,MAAM,YAAY,MAAM,WAAW,MAAM;AACtD,UAAM,SAAS,MAAM,YAAY,MAAM,WAAW;AAElD,QAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAQ,QAAO;AAEpC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,gBAAgB,KAAK,YAAY,MAAM,WAAW,KAAK;AAAA,MAC/D,SAAS,MAAM,cAAc;AAAA,MAC7B,SAAS,QAAQ,MAAM,QAAQ;AAAA,MAC/B,MAAM,MAAM,aAAa,oBAAI,KAAK;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,YAAY,QAA+C;AACzD,YAAQ,QAAQ,YAAY,GAAG;AAAA,MAC7B,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA,EAEA,eAAe,QAA+C;AAC5D,WAAO,QAAQ,YAAY,MAAM,YAAY,YAAY;AAAA,EAC3D;AAAA,EAEA,aAAa,QAAuE;AAClF,UAAM,QAAQ,QAAQ,YAAY,KAAK;AACvC,QAAI,MAAM,SAAS,SAAS,EAAG,QAAO;AACtC,QAAI,MAAM,SAAS,QAAQ,EAAG,QAAO;AACrC,QAAI,MAAM,SAAS,QAAQ,KAAK,MAAM,SAAS,OAAO,EAAG,QAAO;AAChE,QAAI,MAAM,SAAS,KAAK,KAAK,MAAM,SAAS,MAAM,EAAG,QAAO;AAC5D,QAAI,MAAM,SAAS,aAAa,KAAK,MAAM,SAAS,QAAQ,EAAG,QAAO;AACtE,WAAO;AAAA,EACT;AAAA,EAEA,qBAAqB,OAAqC;AACxD,WAAO,kBAAkB,MAAM,gBAAgB,CAAC,GAAG,IAAI,CAAC,gBACtD,YAAY,OAAO,YAAY,UAAU,YAAY,QAAQ,CAAC;AAAA,EAClE;AAAA,EAEA,mBAAmB,KAAwD;AACzE,UAAM,SAAS,KAAK,cAAc,IAAI,KAAK,iBAAiB,GAAG,CAAC;AAChE,QAAI,OAAQ,QAAO;AACnB,QAAI,CAAC,IAAI,GAAI,QAAO;AAEpB,eAAW,WAAW,KAAK,cAAc,OAAO,GAAG;AACjD,UAAI,QAAQ,IAAI,OAAO,IAAI,MAAM,QAAQ,QAAS,QAAO;AAAA,IAC3D;AAEA,eAAW,WAAW,KAAK,cAAc,OAAO,GAAG;AACjD,YAAM,iBAAiB,yBAAyB,OAAiC;AACjF,UAAI,CAAC,gBAAgB,IAAI,MAAM,eAAe,IAAI,OAAO,IAAI,MAAM,CAAC,eAAe,SAAS;AAC1F;AAAA,MACF;AAEA,YAAM,eAAe;AACrB,WAAK,UAAU,YAAY;AAC3B,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,SAAkC;AAC1C,QAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,QAAS;AAEzC,UAAM,MAAM,KAAK,iBAAiB,QAAQ,GAAG;AAC7C,SAAK,cAAc,OAAO,GAAG;AAC7B,SAAK,cAAc,IAAI,KAAK,OAAO;AAEnC,WAAO,KAAK,cAAc,OAAO,KAAK,mBAAmB;AACvD,YAAM,SAAS,KAAK,cAAc,KAAK,EAAE,KAAK,EAAE;AAChD,UAAI,OAAQ,MAAK,cAAc,OAAO,MAAM;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,iBAAiB,KAAiC;AAChD,WAAO,GAAG,IAAI,aAAa,EAAE,IAAI,IAAI,MAAM,EAAE,IAAI,IAAI,eAAe,IAAI,kBAAkB,EAAE;AAAA,EAC9F;AAAA,EAEA,kBAAkB,SAAqC;AACrD,QAAI,KAAK,SAAS,2BAA2B,KAAM,QAAO;AAC1D,QAAI,QAAQ,YAAY,KAAM,QAAO;AACrC,QAAI,CAAC,KAAK,uBAAuB,QAAQ,oBAAoB,KAAM,QAAO;AAE1E,UAAM,YAAY,UAAU,QAAQ,gBAAgB;AACpD,QAAI,cAAc,OAAW,QAAO;AAEpC,WAAO,YAAY,KAAK,sBAAsB;AAAA,EAChD;AAAA,EAEA,oBAA0B;AACxB,SAAK,mBAAmB;AACxB,SAAK,uBAAuB;AAC5B,SAAK,uBAAuB;AAAA,EAC9B;AAAA,EAEA,sBAA4B;AAC1B,SAAK,mBAAmB;AACxB,SAAK,gBAAgB,IAAI,QAAc,CAACC,aAAY;AAClD,WAAK,uBAAuBA;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EAEA,iBAAyB;AACvB,WAAO,KAAK,SAAS,kCAA4B,WAAW;AAAA,EAC9D;AAAA,EAEA,uBAA+B;AAC7B,QAAI,KAAK,SAAS,gCAA2B,QAAO;AACpD,QAAI,KAAK,SAAS,kCAA4B,QAAO;AACrD,WAAO;AAAA,EACT;AAAA,EAEA,iBAA2B;AACzB,UAAM,SAAS,KAAK;AAEpB,QAAI,CAAC,UAAU,CAAC,KAAK,YAAY;AAC/B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,aAAa,KAAK;AAAA,MACtB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aACJ,SACA,WACA,SACY;AACZ,QAAI;AAEJ,QAAI;AACF,aAAO,MAAM,QAAQ,KAAK;AAAA,QACxB;AAAA,QACA,IAAI,QAAe,CAAC,GAAG,WAAW;AAChC,kBAAQ,WAAW,MAAM;AACvB,mBAAO,IAAI;AAAA,cACT;AAAA,cACA;AAAA,cACA,EAAE,aAAa,KAAK;AAAA,YACtB,CAAC;AAAA,UACH,GAAG,SAAS;AAAA,QACd,CAAC;AAAA,MACH,CAAC;AAAA,IACH,UAAE;AACA,UAAI,MAAO,cAAa,KAAK;AAAA,IAC/B;AAAA,EACF;AACF;AAGA,IAAM,oBAAN,MAAM,mBAAwC;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,QACA,UAA6C,CAAC,GAC9C;AACA,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,QAAQ,OAAO,UAAU,UAC1B,UACA,OAAO,UAAU,SACf,SACA,OAAO,UAAU,WAAW,OAAO,UAAU,WAC3C,UACA;AAAA,EACV;AAAA,EAEA,MAAM,SAAiB,SAAmD;AACxE,SAAK,QAAQ,MAAM,SAAS,KAAK,OAAO,OAAO,CAAC;AAAA,EAClD;AAAA,EAEA,MAAM,SAAiB,SAAmD;AACxE,SAAK,QAAQ,MAAM,SAAS,KAAK,OAAO,OAAO,CAAC;AAAA,EAClD;AAAA,EAEA,KAAK,SAAiB,SAAmD;AACvE,SAAK,QAAQ,KAAK,SAAS,KAAK,OAAO,OAAO,CAAC;AAAA,EACjD;AAAA,EAEA,KAAK,SAAiB,SAAmD;AACvE,SAAK,QAAQ,KAAK,SAAS,KAAK,OAAO,OAAO,CAAC;AAAA,EACjD;AAAA,EAEA,MAAM,SAAiB,SAAmD;AACxE,SAAK,QAAQ,MAAM,SAAS,KAAK,OAAO,OAAO,CAAC;AAAA,EAClD;AAAA,EAEA,MAAM,UAAyD;AAC7D,WAAO,IAAI,mBAAkB,KAAK,SAAS;AAAA,MACzC,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,OACE,SACmC;AACnC,WAAO,UACH,EAAE,GAAG,KAAK,UAAU,GAAG,QAAQ,IAC/B,KAAK;AAAA,EACX;AACF;AAEA,SAAS,UAAU,OAAiE;AAClF,QAAM,MAAM,OAAO,UAAU,WACzB,QACA,OAAO,WACL,MAAM,SAAS,IACf,OAAO;AAEb,MAAI,QAAQ,OAAW,QAAO;AAC9B,SAAO,MAAM,OAAiB,KAAK,MAAM,MAAM,GAAK,IAAI;AAC1D;;;AEr4CA,eAAsB,OAAO,UAAyB,CAAC,GAAwB;AAC7E,QAAM,SAAS,IAAI,OAAO,QAAQ,MAAM;AACxC,QAAM,WAAW,QAAQ,YAAY,IAAI,aAAa;AAAA,IACpD,MAAM,QAAQ,QAAQ;AAAA,IACtB,SAAS,QAAQ;AAAA,IACjB,QAAQ,OAAO,MAAM,UAAU;AAAA,IAC/B,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,IAC5D,GAAI,QAAQ,qBAAqB,SAC7B,EAAE,kBAAkB,QAAQ,iBAAiB,IAC7C,CAAC;AAAA,IACL,GAAI,QAAQ,2BAA2B,SACnC,EAAE,wBAAwB,QAAQ,uBAAuB,IACzD,CAAC;AAAA,IACL,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,EAC9D,CAAC;AAED,SAAO,IAAI,WAAW,UAAU;AAAA,IAC9B,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,IAC5D,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,IAChD,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IACjE,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,IAChD,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IACnD,GAAI,QAAQ,OAAO,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,IAC7C,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,EACrD,GAAG,MAAM;AACX;;;AC5DA;AAAA,EACE,QAAAC;AAAA,EACA,WAAAC;AAAA,OACK;AAoDA,IAAM,qBAAN,MAAyB;AAAA,EACrB;AAAA,EAET,YAAY,MAAuC;AACjD,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,QAAQ,YAAqC;AAC3C,eAAW,OAAO,KAAK,MAAM,OAAO,GAAG;AACrC,UAAI,SAAS,QAAQ,UAAU;AAAA,IACjC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,YAAqC;AACvC,eAAW,OAAO,KAAK,MAAM,OAAO,GAAG;AACrC,UAAI,SAAS,IAAI,UAAU;AAAA,IAC7B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,SAA0C;AAChD,UAAM,cAAc,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS,QAAQ,OAAO,CAAC;AACvF,WAAO,MAAM;AACX,iBAAW,UAAU,YAAa,QAAO;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,MAAM,KACJ,SACA,UAA+B,CAAC,GACa;AAC7C,WAAO,QAAQ,IAAI,CAAC,GAAG,KAAK,KAAK,EAAE,IAAI,OAAO,CAAC,WAAW,GAAG,OAAO;AAAA,MAClE;AAAA,MACA,QAAQ,MAAM,IAAI,SAAS,KAAK,SAAS,OAAO;AAAA,IAClD,EAAE,CAAC;AAAA,EACL;AACF;AAEO,IAAM,kBAAN,MAAsB;AAAA,EAClB;AAAA,EACA;AAAA,EAET,YAAY,MAAuC;AACjD,SAAK,QAAQ;AACb,SAAK,WAAW,IAAI,mBAAmB,IAAI;AAAA,EAC7C;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,KAAK,MAAM,OAAO,KAAK,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,EAAE,MAAM,CAAC,QAAQ,IAAI,OAAO;AAAA,EACnF;AAAA,EAEA,MAAyB;AACvB,WAAO,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC;AAAA,EAC9B;AAAA,EAEA,IAAI,WAA4B;AAC9B,WAAO,KAAK,MAAM,IAAI,SAAS;AAAA,EACjC;AAAA,EAEA,IAAI,WAA2C;AAC7C,WAAO,KAAK,MAAM,IAAI,SAAS;AAAA,EACjC;AAAA,EAEA,SAAgC;AAC9B,WAAO,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC;AAAA,EAChC;AAAA,EAEA,SAA6B;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,GACE,OACA,UACY;AACZ,UAAM,cAAc,CAAC,GAAG,KAAK,KAAK,EAAE,IAAI,CAAC,CAAC,WAAW,GAAG,MACtD,IAAI,GAAG,OAAO,CAAC,YAAY,SAAS,EAAE,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC;AAEnE,WAAO,MAAM;AACX,iBAAW,UAAU,YAAa,QAAO;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,SAAoC;AAClC,WAAO,CAAC,GAAG,KAAK,KAAK,EAAE,IAAI,CAAC,CAAC,WAAW,GAAG,OAAO;AAAA,MAChD;AAAA,MACA,GAAG,IAAI,OAAO;AAAA,IAChB,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,MAAM,UAA6B,CAAC,GAAkB;AAC1D,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,CAAC,GAAG,KAAK,KAAK,EAAE,IAAI,OAAO,CAAC,WAAW,GAAG,MAAM;AAC9C,cAAM,IAAI,MAAM;AAAA,UACd,GAAI,QAAQ,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,UAC1E,GAAI,QAAQ,SACR,EAAE,QAAQ,CAAC,SAAiB,QAAQ,SAAS,WAAW,IAAI,EAAE,IAC9D,CAAC;AAAA,QACP,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AACA,UAAM,WAAW,QACd,IAAI,CAAC,QAAQ,WAAW,EAAE,QAAQ,WAAW,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE,EACjE,OAAO,CAAC,UAGJ,MAAM,OAAO,WAAW,cAAc,MAAM,cAAc,MAAS;AAE1E,QAAI,SAAS,WAAW,GAAG;AACzB;AAAA,IACF;AAEA,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAO,IAAI;AAAA,UACT,SAAS,IAAI,CAAC,EAAE,OAAO,MAAM,OAAO,MAAM;AAAA,UAC1C;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,UAAU,SAAS,IAAI,CAAC,EAAE,UAAU,MAAM,SAAS;AAAA,QACrD;AAAA,QACA,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,IAAI,WAAW,CAAC;AAAA,IACxD;AACA,UAAM,WAAW,QAAQ,OAAO,CAAC,WAC/B,OAAO,WAAW,UAAU;AAE9B,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,OAAO,IAAI;AAAA,YACT,SAAS,IAAI,CAAC,WAAW,OAAO,MAAM;AAAA,YACtC;AAAA,UACF;AAAA,UACA,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,YAAY,SAAuD;AACvF,MAAI,QAAQ,SAAS,WAAW,GAAG;AACjC,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,gBAAgB,oBAAI,IAAY;AACtC,QAAM,YAAY,oBAAI,IAAY;AAElC,aAAW,WAAW,UAAU;AAC9B,sBAAkB,QAAQ,EAAE;AAC5B,UAAM,eAAe,QAAQ,GAAG,YAAY;AAE5C,QAAI,cAAc,IAAI,YAAY,GAAG;AACnC,YAAM,IAAI;AAAA,QACR;AAAA,QACA,yBAAyB,QAAQ,EAAE;AAAA,MACrC;AAAA,IACF;AAEA,kBAAc,IAAI,YAAY;AAE9B,QAAI,QAAQ,aAAa,QAAW;AAClC,YAAM,WAAWC,SAAQ,QAAQ,QAAQC,MAAK,UAAU,QAAQ,EAAE,CAAC;AAEnE,UAAI,UAAU,IAAI,QAAQ,GAAG;AAC3B,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,UACA,EAAE,SAAS,EAAE,MAAM,SAAS,EAAE;AAAA,QAChC;AAAA,MACF;AAEA,gBAAU,IAAI,QAAQ;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,OAAO,oBAAI,IAAwB;AAEzC,aAAW,WAAW,UAAU;AAC9B,UAAM;AAAA,MACJ;AAAA,MACA,GAAG;AAAA,IACL,IAAI;AACJ,UAAM,SAAS,mBAAmB,QAAQ,SAAS;AAEnD,QACE,OAAO,MAAM,YAAY,QACtB,OAAO,KAAK,UAAU,UACtB,OAAO,KAAK,aAAa,QAC5B;AACA,aAAO,OAAO;AAAA,QACZ,GAAG,OAAO;AAAA,QACV,UAAUA,MAAK,UAAU,WAAW,EAAE,SAAS;AAAA,MACjD;AAAA,IACF;AAEA,UAAM,MAAM,MAAM,OAAO;AAAA,MACvB,GAAG;AAAA,MACH,WAAW;AAAA,MACX,MAAM,UAAU,QAAQA,MAAK,UAAU,EAAE;AAAA,IAC3C,CAAC;AACD,SAAK,IAAI,IAAI,GAAG;AAAA,EAClB;AAEA,SAAO,IAAI,gBAAgB,IAAI;AACjC;AAEA,SAAS,kBAAkB,WAAyB;AAClD,MAAI,CAAC,6BAA6B,KAAK,SAAS,GAAG;AACjD,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA,EAAE,SAAS,EAAE,UAAU,EAAE;AAAA,IAC3B;AAAA,EACF;AACF;AAEA,SAAS,mBACP,QACA,SACe;AACf,QAAM,SAAwB;AAAA,IAC5B,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAEA,MAAI,OAAO,SAAS,QAAQ,OAAO;AACjC,WAAO,QAAQ;AAAA,MACb,GAAG,OAAO;AAAA,MACV,GAAG,QAAQ;AAAA,IACb;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,QAAQ,MAAM;AAC/B,WAAO,OAAO;AAAA,MACZ,GAAG,OAAO;AAAA,MACV,GAAG,QAAQ;AAAA,IACb;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,QAAQ,QAAQ;AACnC,WAAO,SAAS;AAAA,MACd,GAAG,OAAO;AAAA,MACV,GAAG,QAAQ;AAAA,IACb;AAAA,EACF;AAEA,MAAI,OAAO,aAAa,QAAQ,WAAW;AACzC,WAAO,YAAY;AAAA,MACjB,GAAG,OAAO;AAAA,MACV,GAAG,QAAQ;AAAA,IACb;AAAA,EACF;AAEA,MACE,OAAO,UACJ,QAAQ,UACR,OAAO,OAAO,WAAW,YACzB,OAAO,QAAQ,WAAW,UAC7B;AACA,WAAO,SAAS;AAAA,MACd,GAAG,OAAO;AAAA,MACV,GAAG,QAAQ;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AACT;;;AC7UO,IAAM,SAAS;AAAA,EACpB,QAAsB;AACpB,WAAO,CAAC,YAAY,QAAQ,WAAY;AAAA,MACtC,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,QAAsB;AACpB,WAAO,CAAC,YAAY,QAAQ,WAAY;AAAA,MACtC,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,UAAwB;AACtB,WAAO,CAAC,YAAY,CAAC,QAAQ,WAAY;AAAA,MACvC,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,YAA0B;AACxB,WAAO,OAAO,YACZ,QAAQ,WACL,MAAM,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,KAC7D;AAAA,MACJ,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,WAAyB;AACvB,WAAO,OAAO,YACZ,QAAQ,WACL,MAAM,QAAQ,OAAO,mBAAmB,QAAQ,MAAM,KACrD;AAAA,MACJ,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,WACE,OACc;AACd,WAAO,OAAO,YAAY,MAAM,MAAM,OAAO,KAAM;AAAA,MACjD,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,OAAO,OAAmC;AACxC,WAAO;AAAA,EACT;AACF;","names":["controller","resolve","path","context","option","path","require","resolve","Browser","previous","option","resolve","join","resolve","resolve","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/cache/memory-cache.ts","../src/errors/error.ts","../src/models/identity.ts","../src/models/user.ts","../src/commands/args-parser.ts","../src/commands/command.ts","../src/commands/concurrency.ts","../src/commands/context.ts","../src/commands/load-commands.ts","../src/commands/options.ts","../src/services/user-service.ts","../src/commands/router.ts","../src/logger/logger.ts","../src/mute/mute-service.ts","../src/mute/sqlite-mute-store.ts","../src/provider/event-emitter.ts","../src/services/account-service.ts","../src/services/chat-service.ts","../src/services/group-service.ts","../src/services/media-service.ts","../src/services/member-service.ts","../src/services/message-service.ts","../src/app/whanext-app.ts","../src/auth/browser.ts","../src/provider/zapo/zapo-provider.ts","../src/provider/zapo/normalize-message.ts","../src/app/create.ts","../src/app/multi-app.ts","../src/commands/guards.ts"],"sourcesContent":["import type { CacheStore } from '@/cache/cache-store.js';\n\ninterface CacheEntry {\n value: unknown;\n expiresAt?: number;\n}\n\nexport interface MemoryCacheStats {\n size: number;\n maxEntries: number;\n hits: number;\n misses: number;\n sets: number;\n evictions: number;\n expirations: number;\n}\n\nexport class MemoryCache implements CacheStore {\n readonly #entries = new Map<string, CacheEntry>();\n readonly #maxEntries: number;\n #hits = 0;\n #misses = 0;\n #sets = 0;\n #evictions = 0;\n #expirations = 0;\n\n constructor(options: { maxEntries?: number } = {}) {\n this.#maxEntries = Math.max(1, options.maxEntries ?? 1_000);\n }\n\n async get<T>(key: string): Promise<T | undefined> {\n const entry = this.#entries.get(key);\n\n if (!entry) {\n this.#misses += 1;\n return undefined;\n }\n\n if (entry.expiresAt !== undefined && entry.expiresAt <= Date.now()) {\n this.#entries.delete(key);\n this.#misses += 1;\n this.#expirations += 1;\n return undefined;\n }\n\n this.#hits += 1;\n this.#entries.delete(key);\n this.#entries.set(key, entry);\n return entry.value as T;\n }\n\n async set<T>(key: string, value: T, ttlMs?: number): Promise<void> {\n const entry: CacheEntry = { value };\n\n if (ttlMs !== undefined) {\n entry.expiresAt = Date.now() + ttlMs;\n }\n\n this.#sets += 1;\n this.#entries.delete(key);\n this.#entries.set(key, entry);\n\n while (this.#entries.size > this.#maxEntries) {\n const oldest = this.#entries.keys().next().value as string | undefined;\n if (oldest === undefined) return;\n this.#entries.delete(oldest);\n this.#evictions += 1;\n }\n }\n\n async delete(key: string): Promise<void> {\n this.#entries.delete(key);\n }\n\n async clear(): Promise<void> {\n this.#entries.clear();\n }\n\n prune(now = Date.now()): number {\n let removed = 0;\n\n for (const [key, entry] of this.#entries) {\n if (entry.expiresAt !== undefined && entry.expiresAt <= now) {\n this.#entries.delete(key);\n removed += 1;\n }\n }\n\n this.#expirations += removed;\n return removed;\n }\n\n stats(): Readonly<MemoryCacheStats> {\n return {\n size: this.#entries.size,\n maxEntries: this.#maxEntries,\n hits: this.#hits,\n misses: this.#misses,\n sets: this.#sets,\n evictions: this.#evictions,\n expirations: this.#expirations,\n };\n }\n}\n","export type WhaNextErrorCode =\n | 'AUTH_INVALID_PHONE'\n | 'AUTH_EXPIRED'\n | 'CONNECTION_CLOSED'\n | 'CONNECTION_FAILED'\n | 'GROUP_NOT_FOUND'\n | 'MEMBER_NOT_FOUND'\n | 'BOT_NOT_ADMIN'\n | 'MESSAGE_NOT_FOUND'\n | 'MEDIA_NOT_AVAILABLE'\n | 'MUTE_DISABLED'\n | 'STORAGE_ERROR'\n | 'ARGUMENT_MISSING'\n | 'ARGUMENT_INVALID'\n | 'COMMAND_NOT_ALLOWED'\n | 'COMMAND_COOLDOWN'\n | 'COMMAND_BUSY'\n | 'COMMAND_LOAD_FAILED'\n | 'PROVIDER_ERROR'\n | 'UNKNOWN_ERROR';\n\nexport interface WhaNextErrorOptions {\n cause?: unknown;\n context?: Readonly<Record<string, unknown>>;\n recoverable?: boolean;\n}\n\nexport class WhaNextError extends Error {\n readonly code: WhaNextErrorCode;\n readonly context: Readonly<Record<string, unknown>>;\n readonly recoverable: boolean;\n\n constructor(\n code: WhaNextErrorCode,\n message: string,\n options: WhaNextErrorOptions = {},\n ) {\n super(message, { cause: options.cause });\n this.name = 'WhaNextError';\n this.code = code;\n this.context = options.context ?? {};\n this.recoverable = options.recoverable ?? false;\n }\n}\n\nexport function toWhaNextError(\n error: unknown,\n context?: Readonly<Record<string, unknown>>,\n): WhaNextError {\n if (error instanceof WhaNextError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : 'An unknown error occurred.';\n return new WhaNextError('UNKNOWN_ERROR', message, {\n cause: error,\n ...(context ? { context } : {}),\n });\n}\n","export function normalizeIdentity(identity: string): string {\n const value = identity.trim().toLowerCase();\n const separator = value.lastIndexOf('@');\n\n if (separator === -1) {\n return value.replace(/\\D/g, '');\n }\n\n const user = value.slice(0, separator).replace(/:\\d+$/, '');\n const rawServer = value.slice(separator + 1);\n const server = rawServer === 'c.us' ? 's.whatsapp.net' : rawServer;\n return `${user}@${server}`;\n}\n\nexport function identityUsername(identity: string): string {\n const normalized = normalizeIdentity(identity);\n const separator = normalized.lastIndexOf('@');\n return separator === -1 ? normalized : normalized.slice(0, separator);\n}\n\nexport function identityPhoneNumber(identity: string): string | undefined {\n const normalized = normalizeIdentity(identity);\n\n if (normalized.endsWith('@lid')) {\n return undefined;\n }\n\n const username = identityUsername(normalized);\n return /^\\d+$/.test(username) ? username : undefined;\n}\n\nexport function identitiesMatch(left: string, right: string): boolean {\n return normalizeIdentity(left) === normalizeIdentity(right);\n}\n\nexport function uniqueIdentities(identities: ReadonlyArray<string | null | undefined>): string[] {\n const values = identities.filter((identity): identity is string => Boolean(identity));\n return [...new Map(values.map((identity) => [normalizeIdentity(identity), identity])).values()];\n}\n","import {\n identityPhoneNumber,\n identityUsername,\n identitiesMatch,\n uniqueIdentities,\n} from '@/models/identity.js';\n\nexport interface UserData {\n id: string;\n identities?: readonly string[];\n jid?: string;\n lid?: string;\n phoneNumber?: string;\n name?: string;\n}\n\nexport class User {\n readonly id: string;\n readonly identities: string[];\n readonly jid: string | undefined;\n readonly lid: string | undefined;\n readonly phoneNumber: string | undefined;\n readonly name: string | undefined;\n\n constructor(data: UserData) {\n const identities = uniqueIdentities([\n data.id,\n data.jid,\n data.lid,\n data.phoneNumber,\n ...(data.identities ?? []),\n ]);\n\n this.jid = data.jid ?? identities.find((identity) =>\n identity.endsWith('@s.whatsapp.net') || identity.endsWith('@c.us'));\n this.lid = data.lid ?? identities.find((identity) => identity.endsWith('@lid'));\n this.phoneNumber = data.phoneNumber ?? this.jid;\n this.name = data.name;\n this.id = this.jid ?? this.phoneNumber ?? this.lid ?? data.id;\n this.identities = identities;\n }\n\n get mentionId(): string {\n return this.jid ?? this.phoneNumber ?? this.lid ?? this.id;\n }\n\n get mention(): string {\n return `@${this.username}`;\n }\n\n get phone(): string | undefined {\n return this.phoneNumber ? identityPhoneNumber(this.phoneNumber) : undefined;\n }\n\n get username(): string {\n return identityUsername(this.mentionId);\n }\n\n get displayName(): string {\n return this.name ?? this.mention;\n }\n\n matches(identity: string | User): boolean {\n const candidates = typeof identity === 'string' ? [identity] : identity.identities;\n return this.identities.some((ownIdentity) =>\n candidates.some((candidate) => identitiesMatch(ownIdentity, candidate)));\n }\n\n toJSON(): UserData {\n return {\n id: this.id,\n identities: this.identities,\n ...(this.jid ? { jid: this.jid } : {}),\n ...(this.lid ? { lid: this.lid } : {}),\n ...(this.phoneNumber ? { phoneNumber: this.phoneNumber } : {}),\n ...(this.name ? { name: this.name } : {}),\n };\n }\n\n static fromIdentities(identities: readonly string[]): User {\n const [id] = identities;\n\n if (!id) {\n throw new TypeError('A user requires at least one identity.');\n }\n\n return new User({ id, identities });\n }\n\n static fromPhoneNumber(phoneNumber: string): User {\n const normalized = phoneNumber.replace(/\\D/g, '');\n\n if (normalized.length < 8) {\n throw new TypeError('A user phone number must include country and area codes.');\n }\n\n return User.fromIdentities([`${normalized}@s.whatsapp.net`]);\n }\n}\n","import { WhaNextError } from '@/errors/error.js';\nimport { User } from '@/models/user.js';\n\nexport interface ArgumentOptions {\n optional?: boolean;\n}\n\nexport class ArgsParser {\n readonly #values: string[];\n #cursor = 0;\n\n constructor(values: readonly string[]) {\n this.#values = [...values];\n }\n\n get remaining(): number {\n return this.#values.length - this.#cursor;\n }\n\n peek(): string | undefined {\n return this.#values[this.#cursor];\n }\n\n skip(count = 1): this {\n this.#cursor = Math.min(this.#values.length, this.#cursor + Math.max(0, count));\n return this;\n }\n\n string(name = 'argument', options: ArgumentOptions = {}): string | undefined {\n return this.#consume(name, options);\n }\n\n number(name = 'number', options: ArgumentOptions = {}): number | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n const value = Number(raw);\n\n if (!Number.isFinite(value)) {\n throw new WhaNextError('ARGUMENT_INVALID', `The argument \"${name}\" must be a number.`, {\n context: { name, received: raw },\n });\n }\n\n return value;\n }\n\n boolean(name = 'boolean', options: ArgumentOptions = {}): boolean | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n const normalized = raw.toLowerCase();\n const truthy = new Set(['true', 'on', 'yes', 'sim', '1']);\n const falsy = new Set(['false', 'off', 'no', 'não', 'nao', '0']);\n\n if (truthy.has(normalized)) {\n return true;\n }\n\n if (falsy.has(normalized)) {\n return false;\n }\n\n throw new WhaNextError('ARGUMENT_INVALID', `The argument \"${name}\" must be a boolean.`, {\n context: { name, received: raw },\n });\n }\n\n enum<const Values extends readonly string[]>(\n values: Values,\n name = 'option',\n options: ArgumentOptions = {},\n ): Values[number] | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n if (!values.includes(raw)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The argument \"${name}\" must be one of: ${values.join(', ')}.`,\n {\n context: { name, received: raw, expected: values },\n },\n );\n }\n\n return raw as Values[number];\n }\n\n user(name?: string): User;\n user(name: string, options: { optional: true }): User | undefined;\n user(name = 'user', options: ArgumentOptions = {}): User | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n const normalized = raw.replace(/^@/, '').replace(/\\D/g, '');\n\n if (normalized.length < 8) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The argument \"${name}\" must be a mention or phone number.`,\n {\n context: { name, received: raw },\n },\n );\n }\n\n return User.fromPhoneNumber(normalized);\n }\n\n duration(name = 'duration', options: ArgumentOptions = {}): number | undefined {\n const raw = this.#consume(name, options);\n\n if (raw === undefined) {\n return undefined;\n }\n\n const normalized = raw.toLowerCase();\n const permanent = new Set([\n 'forever',\n 'indefinido',\n 'permanent',\n 'permanente',\n 'sempre',\n ]);\n\n if (permanent.has(normalized)) {\n return undefined;\n }\n\n const match = /^(\\d+)(ms|s|m|h|d)$/.exec(normalized);\n\n if (!match) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The argument \"${name}\" must be a duration such as 30s or 5m.`,\n {\n context: { name, received: raw },\n },\n );\n }\n\n const amount = Number(match[1]);\n const unit = match[2] as 'ms' | 's' | 'm' | 'h' | 'd';\n const multiplier = { ms: 1, s: 1_000, m: 60_000, h: 3_600_000, d: 86_400_000 }[unit];\n return amount * multiplier;\n }\n\n rest(): string {\n const value = this.#values.slice(this.#cursor).join(' ');\n this.#cursor = this.#values.length;\n return value;\n }\n\n #consume(name: string, options: ArgumentOptions): string | undefined {\n const value = this.#values[this.#cursor];\n\n if (value === undefined) {\n if (options.optional) {\n return undefined;\n }\n\n throw new WhaNextError('ARGUMENT_MISSING', `The argument \"${name}\" is required.`, {\n context: { name, position: this.#cursor },\n });\n }\n\n this.#cursor += 1;\n return value;\n }\n}\n","import type { ArgsParser } from '@/commands/args-parser.js';\nimport type { CommandContext } from '@/commands/context.js';\nimport type { CommandGuard } from '@/commands/guards.js';\nimport type { CommandOptionSchema } from '@/commands/options.js';\n\nexport type CommandScope = 'global' | 'user' | 'chat' | 'user-chat' | 'user-group';\nexport type ConcurrencyStrategy = 'parallel' | 'reject' | 'queue' | 'replace';\n\nexport interface CommandCooldown {\n durationMs: number;\n scope?: CommandScope;\n}\n\nexport interface CommandConcurrency {\n max?: number;\n scope?: CommandScope;\n strategy?: ConcurrencyStrategy;\n}\n\nexport interface CommandLocalization {\n name?: string;\n aliases?: readonly string[];\n description?: string;\n}\n\nexport type CommandMiddleware = (\n context: CommandContext,\n next: () => Promise<void>,\n) => void | Promise<void>;\n\nexport interface CommandHooks {\n beforeExecute?: (context: CommandContext) => void | Promise<void>;\n afterExecute?: (context: CommandContext) => void | Promise<void>;\n onError?: (context: CommandContext, error: Error) => void | Promise<void>;\n}\n\nexport interface CommandMetadata {\n name: string;\n description: string;\n aliases?: readonly string[];\n prefixless?: boolean | readonly string[];\n category?: string;\n usage?: string;\n examples?: readonly string[];\n hidden?: boolean;\n localizations?: Readonly<Record<string, CommandLocalization>>;\n guards?: readonly CommandGuard[];\n middleware?: readonly CommandMiddleware[];\n cooldown?: CommandCooldown;\n concurrency?: CommandConcurrency;\n hooks?: CommandHooks;\n onlyGroup?: boolean;\n onlyPrivate?: boolean;\n onlyAdmin?: boolean;\n botMustBeAdmin?: boolean;\n onlyOwner?: boolean;\n}\n\nexport interface ExecutableCommandDefinition<\n Schema extends CommandOptionSchema = CommandOptionSchema,\n> extends CommandMetadata {\n options?: Schema;\n execute(\n context: CommandContext<Schema>,\n args: ArgsParser,\n ): void | Promise<void>;\n}\n\nexport interface CommandGroupDefinition extends CommandMetadata {\n subcommands: readonly CommandDefinition[];\n}\n\nexport type CommandDefinition<Schema extends CommandOptionSchema = CommandOptionSchema> =\n | ExecutableCommandDefinition<Schema>\n | CommandGroupDefinition;\n\nexport interface RegisteredCommand {\n definition: ExecutableCommandDefinition;\n root: CommandDefinition;\n path: readonly string[];\n aliases: readonly string[];\n category: string;\n}\n\nexport function defineCommand<const Schema extends CommandOptionSchema = CommandOptionSchema>(\n command: ExecutableCommandDefinition<Schema>,\n): ExecutableCommandDefinition<Schema> {\n return command;\n}\n\nexport function defineSubcommand<const Schema extends CommandOptionSchema = CommandOptionSchema>(\n command: ExecutableCommandDefinition<Schema>,\n): ExecutableCommandDefinition<Schema> {\n return command;\n}\n\nexport function defineCommandGroup<const Group extends CommandGroupDefinition>(group: Group): Group {\n return group;\n}\n\nexport function defineCommands<const Commands extends readonly CommandDefinition[]>(\n ...commands: Commands\n): Commands {\n return commands;\n}\n\nexport function isCommandGroup(\n definition: CommandDefinition,\n): definition is CommandGroupDefinition {\n return 'subcommands' in definition;\n}\n","import type {\n CommandConcurrency,\n ConcurrencyStrategy,\n} from '@/commands/command.js';\nimport { WhaNextError } from '@/errors/error.js';\n\ninterface ExecutionState {\n active: number;\n queue: Array<() => void>;\n controllers: Set<AbortController>;\n}\n\nexport class CommandConcurrencyController {\n readonly #states = new Map<string, ExecutionState>();\n\n async run(\n key: string,\n options: CommandConcurrency | undefined,\n execute: (signal: AbortSignal) => Promise<void>,\n ): Promise<void> {\n const strategy = options?.strategy ?? 'parallel';\n if (strategy === 'parallel') {\n await execute(new AbortController().signal);\n return;\n }\n\n const max = Math.max(1, options?.max ?? 1);\n const state = this.#states.get(key) ?? { active: 0, queue: [], controllers: new Set() };\n this.#states.set(key, state);\n\n if (strategy === 'replace') {\n for (const controller of state.controllers) controller.abort();\n state.controllers.clear();\n } else if (strategy === 'reject' && state.active >= max) {\n throw new WhaNextError('COMMAND_BUSY', 'This command is already running.', {\n context: { key, max },\n recoverable: true,\n });\n } else if (strategy === 'queue' && state.active >= max) {\n await new Promise<void>((resolve) => state.queue.push(resolve));\n }\n\n const controller = new AbortController();\n state.controllers.add(controller);\n state.active += 1;\n\n try {\n await execute(controller.signal);\n } finally {\n state.controllers.delete(controller);\n state.active -= 1;\n state.queue.shift()?.();\n\n if (state.active === 0 && state.queue.length === 0) {\n this.#states.delete(key);\n }\n }\n }\n}\n\nexport function normalizeConcurrencyStrategy(\n strategy: ConcurrencyStrategy | undefined,\n): ConcurrencyStrategy {\n return strategy ?? 'parallel';\n}\n","import type {\n CommandOptionSchema,\n ParsedCommandOptions,\n} from '@/commands/options.js';\nimport type { ArgsParser } from '@/commands/args-parser.js';\nimport type { RegisteredCommand } from '@/commands/command.js';\nimport { WhaNextError } from '@/errors/error.js';\nimport type {\n Message,\n MessageContent,\n SentMessage,\n} from '@/models/message.js';\nimport type { User } from '@/models/user.js';\nimport type { MuteService } from '@/mute/mute-service.js';\nimport type { ChatService } from '@/services/chat-service.js';\nimport type { GroupService } from '@/services/group-service.js';\nimport type { MediaService } from '@/services/media-service.js';\nimport type { MemberService } from '@/services/member-service.js';\nimport type { MessageService } from '@/services/message-service.js';\nimport type { UserService } from '@/services/user-service.js';\n\nexport interface CommandCatalogView {\n readonly prefix: string;\n readonly prefixes: readonly string[];\n readonly size: number;\n catalog(options?: { category?: string; includeHidden?: boolean }): readonly RegisteredCommand[];\n categories(): readonly string[];\n has(path: string): boolean;\n find(path: string): RegisteredCommand | undefined;\n}\n\nexport interface CommandAccountContext {\n readonly id: string | undefined;\n readonly ids: readonly string[];\n isOwner(message: Pick<Message, 'keys' | 'senderIds'>): boolean;\n}\n\nexport interface CommandRuntimeServices {\n account: CommandAccountContext;\n messages: MessageService;\n media: MediaService;\n groups: GroupService;\n members: MemberService;\n chats: ChatService;\n users: UserService;\n mute: MuteService;\n}\n\nexport interface CommandChatContext {\n id: string;\n isGroup: boolean;\n}\n\nexport interface CommandGroupContext {\n id: string;\n metadata(refresh?: boolean): ReturnType<GroupService['metadata']>;\n isUserAdmin(): Promise<boolean>;\n isBotAdmin(): Promise<boolean>;\n}\n\nexport interface ReplyOptions {\n deleteAfterMs?: number;\n}\n\nexport interface CommandContext<Schema extends CommandOptionSchema = CommandOptionSchema>\n extends Message {\n readonly message: Message;\n readonly user: User;\n readonly account: CommandAccountContext;\n readonly isOwner: boolean;\n readonly chat: CommandChatContext;\n readonly group: CommandGroupContext | undefined;\n readonly command: RegisteredCommand;\n readonly commands: CommandCatalogView;\n readonly prefix: string;\n readonly options: ParsedCommandOptions<Schema>;\n readonly args: ArgsParser;\n readonly locale: string | undefined;\n readonly signal: AbortSignal;\n readonly client: CommandRuntimeServices;\n readonly messages: MessageService;\n readonly mediaService: MediaService;\n readonly groups: GroupService;\n readonly members: MemberService;\n readonly chats: ChatService;\n readonly users: UserService;\n readonly muteService: MuteService;\n\n reply(content: string | MessageContent, options?: ReplyOptions): Promise<SentMessage>;\n defer(content?: string | MessageContent): Promise<DeferredReply>;\n edit(content: string): Promise<SentMessage>;\n react(emoji: string): Promise<SentMessage>;\n unreact(): Promise<SentMessage>;\n delete(): Promise<void>;\n deleteReply(options?: ReplyOptions): Promise<void>;\n}\n\ninterface CreateCommandContextOptions<Schema extends CommandOptionSchema> {\n message: Message;\n command: RegisteredCommand;\n options: ParsedCommandOptions<Schema>;\n args: ArgsParser;\n services: CommandRuntimeServices;\n commands: CommandCatalogView;\n signal: AbortSignal;\n prefix?: string;\n locale?: string;\n}\n\nclass CommandContextImplementation<Schema extends CommandOptionSchema> {\n readonly message: Message;\n readonly user: User;\n readonly account: CommandAccountContext;\n readonly isOwner: boolean;\n readonly chat: CommandChatContext;\n readonly group: CommandGroupContext | undefined;\n readonly command: RegisteredCommand;\n readonly commands: CommandCatalogView;\n readonly prefix: string;\n readonly options: ParsedCommandOptions<Schema>;\n readonly args: ArgsParser;\n readonly locale: string | undefined;\n readonly signal: AbortSignal;\n readonly client: CommandRuntimeServices;\n readonly messages: MessageService;\n readonly mediaService: MediaService;\n readonly groups: GroupService;\n readonly members: MemberService;\n readonly chats: ChatService;\n readonly users: UserService;\n readonly muteService: MuteService;\n #lastReply: SentMessage | undefined;\n\n constructor(options: CreateCommandContextOptions<Schema>) {\n this.message = options.message;\n this.user = options.message.sender;\n this.account = options.services.account;\n this.isOwner = this.account.isOwner(options.message);\n this.chat = { id: options.message.chatId, isGroup: options.message.isGroup };\n this.command = options.command;\n this.commands = options.commands;\n this.prefix = options.prefix ?? options.commands.prefix;\n this.options = options.options;\n this.args = options.args;\n this.locale = options.locale;\n this.signal = options.signal;\n this.client = options.services;\n this.messages = options.services.messages;\n this.mediaService = options.services.media;\n this.groups = options.services.groups;\n this.members = options.services.members;\n this.chats = options.services.chats;\n this.users = options.services.users;\n this.muteService = options.services.mute;\n this.group = options.message.isGroup\n ? this.#createGroupContext(options.message)\n : undefined;\n Object.assign(this, options.message);\n }\n\n async reply(content: string | MessageContent, options: ReplyOptions = {}): Promise<SentMessage> {\n const sent = await this.messages.reply(this.message, normalizeContent(content));\n this.#lastReply = sent;\n this.#scheduleDeletion(sent, options.deleteAfterMs);\n return sent;\n }\n\n async defer(\n content: string | MessageContent = '⏳ _Processando..._',\n ): Promise<DeferredReply> {\n const sent = await this.reply(content);\n return new DeferredReply(this.messages, sent, (message) => {\n this.#lastReply = message;\n });\n }\n\n async edit(content: string): Promise<SentMessage> {\n if (!this.#lastReply) {\n throw new WhaNextError(\n 'MESSAGE_NOT_FOUND',\n 'There is no command reply to edit. Call reply() or defer() first.',\n );\n }\n\n const edited = await this.messages.edit(this.#lastReply, content);\n this.#lastReply = edited;\n return edited;\n }\n\n react(emoji: string): Promise<SentMessage> {\n return this.messages.react(this.message, emoji);\n }\n\n unreact(): Promise<SentMessage> {\n return this.messages.unreact(this.message);\n }\n\n delete(): Promise<void> {\n return this.messages.delete(this.message);\n }\n\n async deleteReply(options: ReplyOptions = {}): Promise<void> {\n if (!this.#lastReply) return;\n\n if (options.deleteAfterMs !== undefined && options.deleteAfterMs > 0) {\n this.#scheduleDeletion(this.#lastReply, options.deleteAfterMs);\n return;\n }\n\n await this.messages.delete(this.#lastReply);\n this.#lastReply = undefined;\n }\n\n #createGroupContext(message: Message): CommandGroupContext {\n return {\n id: message.chatId,\n metadata: (refresh) => this.groups.metadata(message.chatId, refresh),\n isUserAdmin: () => this.groups.isAdmin(message.chatId, message.senderIds),\n isBotAdmin: () => this.groups.isCurrentUserAdmin(message.chatId),\n };\n }\n\n #scheduleDeletion(message: SentMessage, delayMs?: number): void {\n if (delayMs === undefined || delayMs <= 0) return;\n\n const timer = setTimeout(() => {\n void this.messages.delete(message).catch(() => undefined);\n }, delayMs);\n timer.unref?.();\n }\n}\n\nexport class DeferredReply {\n readonly #messages: MessageService;\n #message: SentMessage;\n readonly #onEdit: (message: SentMessage) => void;\n\n constructor(\n messages: MessageService,\n message: SentMessage,\n onEdit: (message: SentMessage) => void,\n ) {\n this.#messages = messages;\n this.#message = message;\n this.#onEdit = onEdit;\n }\n\n async edit(content: string): Promise<SentMessage> {\n this.#message = await this.#messages.edit(this.#message, content);\n this.#onEdit(this.#message);\n return this.#message;\n }\n\n delete(): Promise<void> {\n return this.#messages.delete(this.#message);\n }\n}\n\nexport function createCommandContext<Schema extends CommandOptionSchema>(\n options: CreateCommandContextOptions<Schema>,\n): CommandContext<Schema> {\n return new CommandContextImplementation(options) as unknown as CommandContext<Schema>;\n}\n\nfunction normalizeContent(content: string | MessageContent): MessageContent {\n return typeof content === 'string' ? { text: content } : content;\n}\n","import type { Dirent } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nimport type { CommandDefinition } from '@/commands/command.js';\nimport { WhaNextError } from '@/errors/error.js';\n\nexport interface CommandRegistrar {\n command(definition: CommandDefinition): unknown;\n}\n\nexport interface LoadCommandsOptions {\n extensions?: readonly string[];\n recursive?: boolean;\n}\n\nexport interface LoadCommandsResult {\n loaded: readonly string[];\n skipped: readonly string[];\n commands: readonly LoadedCommand[];\n}\n\nexport interface LoadedCommand {\n name: string;\n filePath: string;\n}\n\nconst DEFAULT_EXTENSIONS = ['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts'] as const;\n\nexport async function loadCommands(\n registrar: CommandRegistrar,\n dirPath: string | URL,\n options: LoadCommandsOptions = {},\n): Promise<LoadCommandsResult> {\n const extensions = options.extensions ?? DEFAULT_EXTENSIONS;\n const recursive = options.recursive ?? true;\n const resolvedDirPath = dirPath instanceof URL ? fileURLToPath(dirPath) : dirPath;\n\n const entries = await readEntries(resolvedDirPath, recursive);\n const loaded: string[] = [];\n const skipped: string[] = [];\n const commands: LoadedCommand[] = [];\n\n for (const filePath of entries) {\n if (isDeclarationFile(filePath) || !extensions.includes(path.extname(filePath))) {\n skipped.push(filePath);\n continue;\n }\n\n const definitions = await importCommands(filePath);\n\n for (const definition of definitions) {\n registrar.command(definition);\n commands.push({ name: definition.name, filePath });\n }\n\n loaded.push(filePath);\n }\n\n return { loaded, skipped, commands };\n}\n\nasync function readEntries(dirPath: string, recursive: boolean): Promise<string[]> {\n let dirents: Dirent[];\n\n try {\n dirents = await readdir(dirPath, { recursive, withFileTypes: true });\n } catch (error) {\n throw new WhaNextError('COMMAND_LOAD_FAILED', `Could not read the commands directory \"${dirPath}\".`, {\n cause: error,\n context: { dirPath },\n });\n }\n\n return dirents\n .filter((dirent) => dirent.isFile())\n .map((dirent) => path.join(dirent.parentPath, dirent.name))\n .sort((left, right) => left.localeCompare(right));\n}\n\nasync function importCommands(filePath: string): Promise<CommandDefinition[]> {\n let module: Record<string, unknown>;\n\n try {\n module = await import(pathToFileURL(filePath).href);\n } catch (error) {\n throw new WhaNextError('COMMAND_LOAD_FAILED', `Could not import the command file \"${filePath}\".`, {\n cause: error,\n context: { filePath },\n });\n }\n\n const definitions: CommandDefinition[] = [];\n const seen = new Set<CommandDefinition>();\n const exports = [\n module.default,\n ...Object.entries(module)\n .filter(([name]) => name !== 'default')\n .map(([, value]) => value),\n ];\n\n for (const value of exports) {\n const candidates = Array.isArray(value) ? value : [value];\n\n for (const candidate of candidates) {\n if (isCommandDefinition(candidate) && !seen.has(candidate)) {\n seen.add(candidate);\n definitions.push(candidate);\n }\n }\n }\n\n if (definitions.length === 0) {\n throw new WhaNextError('COMMAND_LOAD_FAILED', `The file \"${filePath}\" does not export any valid commands.`, {\n context: { filePath },\n });\n }\n\n return definitions;\n}\n\nfunction isCommandDefinition(value: unknown): value is CommandDefinition {\n const candidate = value as Partial<CommandDefinition> & { subcommands?: unknown };\n return (\n typeof value === 'object'\n && value !== null\n && typeof candidate.name === 'string'\n && (\n typeof (candidate as { execute?: unknown }).execute === 'function'\n || Array.isArray(candidate.subcommands)\n )\n );\n}\n\nfunction isDeclarationFile(filePath: string): boolean {\n return /\\.d\\.(?:ts|mts|cts)$/.test(filePath);\n}\n","import { ArgsParser } from '@/commands/args-parser.js';\nimport { WhaNextError } from '@/errors/error.js';\nimport type { Message } from '@/models/message.js';\nimport type { User } from '@/models/user.js';\nimport type { UserService } from '@/services/user-service.js';\n\ninterface BaseOption<TKind extends string> {\n kind: TKind;\n description: string;\n required?: boolean;\n}\n\nexport interface StringOption extends BaseOption<'string'> {\n rest?: boolean;\n minLength?: number;\n maxLength?: number;\n}\n\nexport interface NumberOption extends BaseOption<'number'> {\n min?: number;\n max?: number;\n}\n\nexport interface BooleanOption extends BaseOption<'boolean'> {}\nexport interface UserOption extends BaseOption<'user'> {}\nexport interface DurationOption extends BaseOption<'duration'> {}\n\nexport interface EnumOption<Values extends readonly string[] = readonly string[]>\n extends BaseOption<'enum'> {\n values: Values;\n}\n\nexport type CommandOptionDefinition =\n | StringOption\n | NumberOption\n | BooleanOption\n | UserOption\n | DurationOption\n | EnumOption;\n\nexport type CommandOptionSchema = Readonly<Record<string, CommandOptionDefinition>>;\n\ntype RawOptionValue<Definition extends CommandOptionDefinition> =\n Definition extends StringOption ? string\n : Definition extends NumberOption ? number\n : Definition extends BooleanOption ? boolean\n : Definition extends UserOption ? User\n : Definition extends DurationOption ? number | undefined\n : Definition extends EnumOption<infer Values> ? Values[number]\n : never;\n\nexport type CommandOptionValue<Definition extends CommandOptionDefinition> =\n Definition['required'] extends true\n ? RawOptionValue<Definition>\n : RawOptionValue<Definition> | undefined;\n\nexport type CommandOptionValues<Schema extends CommandOptionSchema> = {\n readonly [Name in keyof Schema]: CommandOptionValue<Schema[Name]>;\n};\n\nexport const option = {\n string<const Definition extends Omit<StringOption, 'kind'>>(definition: Definition) {\n return { kind: 'string' as const, ...definition };\n },\n number<const Definition extends Omit<NumberOption, 'kind'>>(definition: Definition) {\n return { kind: 'number' as const, ...definition };\n },\n boolean<const Definition extends Omit<BooleanOption, 'kind'>>(definition: Definition) {\n return { kind: 'boolean' as const, ...definition };\n },\n user<const Definition extends Omit<UserOption, 'kind'>>(definition: Definition) {\n return { kind: 'user' as const, ...definition };\n },\n duration<const Definition extends Omit<DurationOption, 'kind'>>(definition: Definition) {\n return { kind: 'duration' as const, ...definition };\n },\n enum<\n const Values extends readonly string[],\n const Definition extends Omit<EnumOption<Values>, 'kind' | 'values'>,\n >(values: Values, definition: Definition) {\n return { kind: 'enum' as const, values, ...definition };\n },\n};\n\nexport class ParsedCommandOptions<Schema extends CommandOptionSchema = CommandOptionSchema> {\n readonly #values: CommandOptionValues<Schema>;\n\n constructor(values: CommandOptionValues<Schema>) {\n this.#values = values;\n }\n\n get<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.#values[name];\n }\n\n string<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n number<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n boolean<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n user<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n duration<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n enum<Name extends keyof Schema>(name: Name): CommandOptionValue<Schema[Name]> {\n return this.get(name);\n }\n\n toJSON(): CommandOptionValues<Schema> {\n return { ...this.#values };\n }\n}\n\nexport async function parseCommandOptions<Schema extends CommandOptionSchema>(\n schema: Schema | undefined,\n tokens: readonly string[],\n message: Message,\n users: UserService,\n): Promise<ParsedCommandOptions<Schema>> {\n const args = new ArgsParser(tokens);\n const values: Record<string, unknown> = {};\n\n for (const [name, definition] of Object.entries(schema ?? {})) {\n const optional = definition.required !== true;\n\n if (definition.kind === 'user') {\n const hasImplicitUser = message.mentionedUsers.length > 0 || message.quoted?.sender !== undefined;\n if (optional && !hasImplicitUser && args.remaining === 0) {\n values[name] = undefined;\n } else {\n values[name] = await users.resolve(message, args);\n }\n continue;\n }\n\n const argumentOptions = optional ? { optional: true as const } : undefined;\n\n if (definition.kind === 'string') {\n const value = definition.rest ? args.rest() : args.string(name, argumentOptions);\n if (definition.required && !value) {\n throw missing(name);\n }\n if (value !== undefined && definition.minLength !== undefined && value.length < definition.minLength) {\n throw invalid(name, value, `at least ${definition.minLength} characters`);\n }\n if (value !== undefined && definition.maxLength !== undefined && value.length > definition.maxLength) {\n throw invalid(name, value, `at most ${definition.maxLength} characters`);\n }\n values[name] = value || undefined;\n } else if (definition.kind === 'number') {\n const value = args.number(name, argumentOptions);\n if (value !== undefined && definition.min !== undefined && value < definition.min) {\n throw invalid(name, value, `at least ${definition.min}`);\n }\n if (value !== undefined && definition.max !== undefined && value > definition.max) {\n throw invalid(name, value, `at most ${definition.max}`);\n }\n values[name] = value;\n } else if (definition.kind === 'boolean') {\n values[name] = args.boolean(name, argumentOptions);\n } else if (definition.kind === 'duration') {\n values[name] = args.duration(name, argumentOptions);\n } else {\n values[name] = args.enum(definition.values, name, argumentOptions);\n }\n }\n\n if (schema !== undefined && args.remaining > 0) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Too many arguments were provided.', {\n context: { remaining: args.remaining },\n });\n }\n\n return new ParsedCommandOptions(values as CommandOptionValues<Schema>);\n}\n\nfunction missing(name: string): WhaNextError {\n return new WhaNextError('ARGUMENT_MISSING', `The argument \"${name}\" is required.`, {\n context: { name },\n });\n}\n\nfunction invalid(name: string, received: unknown, expected: string): WhaNextError {\n return new WhaNextError('ARGUMENT_INVALID', `The argument \"${name}\" must be ${expected}.`, {\n context: { name, received, expected },\n });\n}\n","import type { ArgsParser } from '@/commands/args-parser.js';\nimport type { Message } from '@/models/message.js';\nimport { User } from '@/models/user.js';\nimport type { GroupService } from '@/services/group-service.js';\n\nexport class UserService {\n readonly #group: GroupService;\n\n constructor(group: GroupService) {\n this.#group = group;\n }\n\n async resolve(message: Message, args: ArgsParser): Promise<User> {\n const mentioned = message.mentionedUsers[0];\n let user: User;\n\n if (mentioned) {\n if (args.peek()?.startsWith('@')) {\n args.skip();\n }\n\n user = mentioned;\n } else if (message.quoted?.sender) {\n user = message.quoted.sender;\n } else {\n user = args.user('membro');\n }\n\n return this.#group.resolveUser(message.chatId, user);\n }\n\n from(identity: string): User {\n if (!identity.includes('@')) {\n return User.fromPhoneNumber(identity);\n }\n\n return User.fromIdentities([identity]);\n }\n}\n","import { ArgsParser } from '@/commands/args-parser.js';\nimport {\n type CommandDefinition,\n type CommandHooks,\n type CommandMiddleware,\n type CommandScope,\n type ExecutableCommandDefinition,\n isCommandGroup,\n type RegisteredCommand,\n} from '@/commands/command.js';\nimport { CommandConcurrencyController } from '@/commands/concurrency.js';\nimport {\n createCommandContext,\n type CommandContext,\n type CommandRuntimeServices,\n} from '@/commands/context.js';\nimport { loadCommands, type LoadCommandsOptions, type LoadCommandsResult } from '@/commands/load-commands.js';\nimport type { CommandGuard, GuardResult } from '@/commands/guards.js';\nimport {\n ParsedCommandOptions,\n parseCommandOptions,\n} from '@/commands/options.js';\nimport {\n WhaNextError,\n toWhaNextError,\n} from '@/errors/error.js';\nimport type { Message, SentMessage } from '@/models/message.js';\nimport type { GroupService } from '@/services/group-service.js';\nimport { UserService } from '@/services/user-service.js';\n\nexport interface RouterOptions {\n prefix?: string | readonly string[];\n onError?: (error: WhaNextError, message: Message) => void | Promise<void>;\n onCommandError?: CommandErrorHandler;\n beforeExecute?: (context: CommandContext) => void | Promise<void>;\n afterExecute?: (context: CommandContext) => void | Promise<void>;\n}\n\nexport interface CommandCatalogOptions {\n category?: string;\n includeHidden?: boolean;\n}\n\nexport interface CommandHelpOptions extends CommandCatalogOptions {\n title?: string;\n}\n\nexport type CommandErrorHandler = (\n context: CommandContext,\n error: WhaNextError,\n) => void | Promise<void>;\n\ninterface ResolvedCommand {\n registered: RegisteredCommand;\n layers: readonly CommandDefinition[];\n tokens: readonly string[];\n locale?: string;\n}\n\ninterface RegisteredRoot {\n definition: CommandDefinition;\n locale?: string;\n}\n\nexport class CommandRouter {\n readonly #roots = new Map<string, RegisteredRoot>();\n readonly #prefixlessRoots = new Map<string, RegisteredRoot>();\n readonly #definitions = new Set<CommandDefinition>();\n #prefix = '!';\n #prefixes: readonly string[] = ['!'];\n #matchingPrefixes: readonly string[] = ['!'];\n readonly #services: CommandRuntimeServices;\n readonly #legacyOnError?: RouterOptions['onError'];\n readonly #globalMiddleware: CommandMiddleware[] = [];\n readonly #errorHandlers: CommandErrorHandler[] = [];\n readonly #cooldowns = new Map<string, number>();\n readonly #concurrency = new CommandConcurrencyController();\n readonly #beforeExecute?: RouterOptions['beforeExecute'];\n readonly #afterExecute?: RouterOptions['afterExecute'];\n #cooldownOperations = 0;\n\n constructor(services: CommandRuntimeServices, options?: RouterOptions);\n constructor(group: GroupService, options?: RouterOptions);\n constructor(\n servicesOrGroup: CommandRuntimeServices | GroupService,\n options: RouterOptions = {},\n ) {\n this.#services = isRuntimeServices(servicesOrGroup)\n ? servicesOrGroup\n : createLegacyServices(servicesOrGroup);\n this.setPrefixes(options.prefix ?? '!');\n this.#legacyOnError = options.onError;\n this.#beforeExecute = options.beforeExecute;\n this.#afterExecute = options.afterExecute;\n if (options.onCommandError) this.#errorHandlers.push(options.onCommandError);\n }\n\n get prefix(): string {\n return this.#prefix;\n }\n\n get prefixes(): readonly string[] {\n return this.#prefixes;\n }\n\n setPrefixes(prefixes: string | readonly string[]): this {\n const normalized = normalizePrefixes(prefixes);\n this.#prefixes = normalized;\n this.#matchingPrefixes = [...normalized].sort((left, right) => right.length - left.length);\n this.#prefix = normalized[0]!;\n return this;\n }\n\n get size(): number {\n return this.catalog({ includeHidden: true }).length;\n }\n\n command(definition: CommandDefinition): this {\n this.#validateTree(definition, []);\n\n for (const name of commandNames(definition)) {\n const normalized = name.value.toLowerCase();\n\n if (this.#roots.has(normalized)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The command \"${normalized}\" is already registered.`,\n );\n }\n\n this.#roots.set(normalized, {\n definition,\n ...(name.locale ? { locale: name.locale } : {}),\n });\n }\n\n for (const name of prefixlessCommandNames(definition)) {\n const normalized = name.value.toLowerCase();\n\n if (this.#prefixlessRoots.has(normalized)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The prefixless command trigger \"${normalized}\" is already registered.`,\n );\n }\n\n this.#prefixlessRoots.set(normalized, {\n definition,\n ...(name.locale ? { locale: name.locale } : {}),\n });\n }\n\n this.#definitions.add(definition);\n return this;\n }\n\n load(dirPath: string | URL, options: LoadCommandsOptions = {}): Promise<LoadCommandsResult> {\n return loadCommands(this, dirPath, options);\n }\n\n use(middleware: CommandMiddleware): this {\n this.#globalMiddleware.push(middleware);\n return this;\n }\n\n onError(handler: CommandErrorHandler): () => void {\n this.#errorHandlers.push(handler);\n return () => {\n const index = this.#errorHandlers.indexOf(handler);\n if (index >= 0) this.#errorHandlers.splice(index, 1);\n };\n }\n\n catalog(options: CommandCatalogOptions = {}): readonly RegisteredCommand[] {\n const commands = [...this.#definitions].flatMap((definition) =>\n flattenCommands(definition));\n return commands.filter((command) => (\n (options.includeHidden || !command.definition.hidden)\n && (!options.category || command.category === options.category)\n ));\n }\n\n categories(): readonly string[] {\n return [...new Set(this.catalog().map((command) => command.category))].sort();\n }\n\n has(path: string): boolean {\n return this.find(path) !== undefined;\n }\n\n values(): readonly RegisteredCommand[] {\n return this.catalog({ includeHidden: true });\n }\n\n find(path: string): RegisteredCommand | undefined {\n const normalized = path.trim().toLowerCase().split(/\\s+/);\n return this.catalog({ includeHidden: true }).find((command) =>\n command.path.join(' ').toLowerCase() === normalized.join(' ')\n || command.aliases.some((alias) => alias.toLowerCase() === normalized.at(-1)));\n }\n\n async help(\n context: CommandContext,\n options: CommandHelpOptions = {},\n ): Promise<SentMessage> {\n const commands = this.catalog(options);\n const title = options.title ?? (options.category\n ? `📚 *${options.category}*`\n : '📚 *Comandos*');\n const lines = commands.map((command) => {\n const usage = command.definition.usage\n ?? `${this.#prefix}${command.path.join(' ')}${formatOptions(command.definition)}`;\n const description = context.locale\n ? command.definition.localizations?.[context.locale]?.description\n ?? command.definition.description\n : command.definition.description;\n return `• *${usage}*\\n ${description}`;\n });\n const text = lines.length > 0\n ? `${title}\\n\\n${lines.join('\\n\\n')}`\n : `${title}\\n\\n_Nenhum comando disponível._`;\n return context.reply(text);\n }\n\n async dispatch(message: Message): Promise<boolean> {\n const text = (message.interactive?.id ?? message.text)?.trim();\n if (!text) return false;\n\n const matchedPrefix = this.#matchPrefix(text);\n const tokens = tokenize(matchedPrefix === undefined ? text : text.slice(matchedPrefix.length));\n const rootName = tokens.shift()?.toLowerCase();\n if (!rootName) return false;\n\n const root = matchedPrefix === undefined\n ? this.#prefixlessRoots.get(rootName)\n : this.#roots.get(rootName);\n if (!root) return false;\n const invocationPrefix = matchedPrefix ?? '';\n\n let resolved: ResolvedCommand;\n\n try {\n resolved = this.#resolve(root, tokens);\n } catch (error) {\n const normalized = toWhaNextError(error, { command: root.definition.name, messageId: message.id });\n const fallbackDefinition: ExecutableCommandDefinition = {\n ...root.definition,\n execute: () => undefined,\n };\n const context = createCommandContext({\n message,\n command: {\n definition: fallbackDefinition,\n root: root.definition,\n path: [root.definition.name],\n aliases: root.definition.aliases ?? [],\n category: root.definition.category ?? 'general',\n },\n options: new ParsedCommandOptions({}),\n args: new ArgsParser(tokens),\n services: this.#services,\n commands: this,\n prefix: invocationPrefix,\n signal: new AbortController().signal,\n ...(root.locale ? { locale: root.locale } : {}),\n });\n if (root.definition.hooks?.onError) {\n await root.definition.hooks.onError(context, normalized);\n return true;\n }\n if (this.#errorHandlers.length > 0) {\n for (const handler of this.#errorHandlers) await handler(context, normalized);\n return true;\n }\n if (this.#legacyOnError) {\n await this.#legacyOnError(normalized, message);\n return true;\n }\n throw normalized;\n }\n\n const legacyArgs = new ArgsParser(resolved.tokens);\n let context: CommandContext | undefined;\n\n try {\n const parsedOptions = await parseCommandOptions(\n resolved.registered.definition.options,\n resolved.tokens,\n message,\n this.#services.users,\n );\n const concurrency = [...resolved.layers]\n .reverse()\n .find((layer) => layer.concurrency)?.concurrency;\n const concurrencyKey = this.#executionKey(\n resolved,\n message,\n concurrency?.scope ?? 'user-chat',\n );\n\n await this.#concurrency.run(\n concurrencyKey,\n concurrency,\n async (signal) => {\n context = createCommandContext({\n message,\n command: resolved.registered,\n options: parsedOptions,\n args: legacyArgs,\n services: this.#services,\n commands: this,\n prefix: invocationPrefix,\n signal,\n ...(resolved.locale ? { locale: resolved.locale } : {}),\n });\n\n await this.#authorize(resolved.layers, context);\n this.#consumeCooldown(resolved, context);\n await this.#execute(resolved, context);\n },\n );\n return true;\n } catch (error) {\n const normalized = toWhaNextError(error, {\n command: resolved.registered.path.join(' '),\n messageId: message.id,\n });\n context ??= createCommandContext({\n message,\n command: resolved.registered,\n options: new ParsedCommandOptions({}),\n args: legacyArgs,\n services: this.#services,\n commands: this,\n prefix: invocationPrefix,\n signal: new AbortController().signal,\n ...(resolved.locale ? { locale: resolved.locale } : {}),\n });\n\n if (await this.#handleError(resolved, context, normalized)) return true;\n throw normalized;\n }\n }\n\n #matchPrefix(text: string): string | undefined {\n return this.#matchingPrefixes.find((prefix) => text.startsWith(prefix));\n }\n\n #resolve(root: RegisteredRoot, inputTokens: readonly string[]): ResolvedCommand {\n const tokens = [...inputTokens];\n const layers: CommandDefinition[] = [root.definition];\n let current = root.definition;\n let locale = root.locale;\n\n while (isCommandGroup(current)) {\n const name = tokens.shift()?.toLowerCase();\n if (!name) {\n throw new WhaNextError('ARGUMENT_MISSING', `Choose a subcommand for \"${current.name}\".`, {\n context: { command: current.name },\n });\n }\n\n const found = findChild(current.subcommands, name);\n if (!found) {\n throw new WhaNextError('ARGUMENT_INVALID', `The subcommand \"${name}\" does not exist.`, {\n context: { command: current.name, subcommand: name },\n });\n }\n\n current = found.definition;\n locale ??= found.locale;\n layers.push(current);\n }\n\n const path = layers.map((definition) => definition.name);\n return {\n registered: {\n definition: current,\n root: root.definition,\n path,\n aliases: current.aliases ?? [],\n category: current.category ?? root.definition.category ?? 'general',\n },\n layers,\n tokens,\n ...(locale ? { locale } : {}),\n };\n }\n\n async #authorize(layers: readonly CommandDefinition[], context: CommandContext): Promise<void> {\n for (const command of layers) {\n await this.#authorizeLegacy(command, context);\n for (const guard of command.guards ?? []) await runGuard(guard, context);\n }\n }\n\n async #authorizeLegacy(command: CommandDefinition, context: CommandContext): Promise<void> {\n if (command.onlyOwner && !context.isOwner) {\n throw new WhaNextError(\n 'COMMAND_NOT_ALLOWED',\n 'This command can only be used by the connected WhatsApp account.',\n );\n }\n if (command.onlyGroup && !context.isGroup) {\n throw new WhaNextError('COMMAND_NOT_ALLOWED', 'This command can only be used in groups.');\n }\n if (command.onlyPrivate && context.isGroup) {\n throw new WhaNextError('COMMAND_NOT_ALLOWED', 'This command can only be used in private chats.');\n }\n if (command.onlyAdmin && !(await this.#services.groups.isAdmin(context.chatId, context.senderIds))) {\n throw new WhaNextError('COMMAND_NOT_ALLOWED', 'This command can only be used by group administrators.');\n }\n if (command.botMustBeAdmin && !(await this.#services.groups.isCurrentUserAdmin(context.chatId))) {\n throw new WhaNextError('BOT_NOT_ADMIN', 'The connected WhatsApp account must be a group administrator.');\n }\n }\n\n async #execute(resolved: ResolvedCommand, context: CommandContext): Promise<void> {\n const hooks = resolved.layers.map((layer) => layer.hooks).filter(Boolean) as CommandHooks[];\n if (this.#beforeExecute) await this.#beforeExecute(context);\n for (const hook of hooks) await hook.beforeExecute?.(context);\n\n const middleware = [\n ...this.#globalMiddleware,\n ...resolved.layers.flatMap((layer) => layer.middleware ?? []),\n ];\n await composeMiddleware(middleware, context, async () => {\n await resolved.registered.definition.execute(context, context.args);\n });\n\n for (const hook of [...hooks].reverse()) await hook.afterExecute?.(context);\n if (this.#afterExecute) await this.#afterExecute(context);\n }\n\n #consumeCooldown(resolved: ResolvedCommand, context: CommandContext): void {\n const config = [...resolved.layers].reverse().find((layer) => layer.cooldown)?.cooldown;\n if (!config || config.durationMs <= 0) return;\n\n const key = this.#executionKey(resolved, context, config.scope ?? 'user');\n const now = Date.now();\n this.#cooldownOperations += 1;\n if (this.#cooldownOperations % 256 === 0) this.#pruneCooldowns(now);\n const expiresAt = this.#cooldowns.get(key) ?? 0;\n\n if (expiresAt > now) {\n throw new WhaNextError('COMMAND_COOLDOWN', 'This command is on cooldown.', {\n context: { retryAfterMs: expiresAt - now, key },\n recoverable: true,\n });\n }\n\n this.#cooldowns.set(key, now + config.durationMs);\n }\n\n #pruneCooldowns(now: number): void {\n for (const [key, expiresAt] of this.#cooldowns) {\n if (expiresAt <= now) this.#cooldowns.delete(key);\n }\n }\n\n #executionKey(\n resolved: ResolvedCommand,\n message: Pick<Message, 'chatId' | 'senderId' | 'isGroup'>,\n scope: CommandScope,\n ): string {\n const command = resolved.registered.path.join('/').toLowerCase();\n if (scope === 'global') return command;\n if (scope === 'user') return `${command}:user:${message.senderId}`;\n if (scope === 'chat') return `${command}:chat:${message.chatId}`;\n return `${command}:user-chat:${message.senderId}:${message.chatId}`;\n }\n\n async #handleError(\n resolved: ResolvedCommand,\n context: CommandContext,\n error: WhaNextError,\n ): Promise<boolean> {\n for (const layer of [...resolved.layers].reverse()) {\n if (layer.hooks?.onError) {\n await layer.hooks.onError(context, error);\n return true;\n }\n }\n\n if (this.#errorHandlers.length > 0) {\n for (const handler of this.#errorHandlers) await handler(context, error);\n return true;\n }\n\n if (this.#legacyOnError) {\n await this.#legacyOnError(error, context.message);\n return true;\n }\n\n return false;\n }\n\n #validateTree(definition: CommandDefinition, parents: readonly string[]): void {\n if (!definition.name.trim() || /\\s/.test(definition.name)) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Command names cannot be empty or contain whitespace.', {\n context: { name: definition.name },\n });\n }\n\n for (const name of commandNames(definition)) {\n if (!name.value.trim() || /\\s/.test(name.value)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Command names and aliases cannot be empty or contain whitespace.',\n { context: { name: name.value } },\n );\n }\n }\n\n if (definition.prefixless && parents.length > 0) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Prefixless triggers are only supported on root commands and command groups.',\n { context: { command: definition.name } },\n );\n }\n\n if (Array.isArray(definition.prefixless)) {\n const available = new Set(commandNames(definition).map((name) => name.value.toLowerCase()));\n for (const trigger of definition.prefixless) {\n const normalized = trigger.trim().toLowerCase();\n if (!normalized || /\\s/.test(trigger) || !available.has(normalized)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Every prefixless trigger must match the command name or one of its aliases.',\n { context: { command: definition.name, trigger } },\n );\n }\n }\n }\n\n if (!isCommandGroup(definition)) return;\n if (definition.subcommands.length === 0) {\n throw new WhaNextError('ARGUMENT_INVALID', `The command group \"${definition.name}\" is empty.`);\n }\n\n const names = new Set<string>();\n for (const child of definition.subcommands) {\n for (const name of commandNames(child)) {\n const normalized = name.value.toLowerCase();\n if (names.has(normalized)) {\n throw new WhaNextError('ARGUMENT_INVALID', `Duplicate subcommand \"${normalized}\".`, {\n context: { path: [...parents, definition.name].join(' ') },\n });\n }\n names.add(normalized);\n }\n this.#validateTree(child, [...parents, definition.name]);\n }\n }\n}\n\nasync function runGuard(guard: CommandGuard, context: CommandContext): Promise<void> {\n const result = await guard(context);\n if (result === undefined || result === true) return;\n\n const normalized: GuardResult = result === false ? { allowed: false } : result;\n if (normalized.allowed) return;\n throw new WhaNextError(\n normalized.code ?? 'COMMAND_NOT_ALLOWED',\n normalized.message ?? 'This command is not allowed in the current context.',\n );\n}\n\nasync function composeMiddleware(\n middleware: readonly CommandMiddleware[],\n context: CommandContext,\n execute: () => Promise<void>,\n): Promise<void> {\n let index = -1;\n const dispatch = async (position: number): Promise<void> => {\n if (position <= index) throw new Error('next() was called more than once.');\n index = position;\n const current = middleware[position];\n if (!current) return execute();\n await current(context, () => dispatch(position + 1));\n };\n await dispatch(0);\n}\n\nfunction normalizePrefixes(input: string | readonly string[]): readonly string[] {\n const values = typeof input === 'string' ? [input] : [...input];\n const prefixes = [...new Set(values)];\n\n if (prefixes.length === 0) {\n throw new WhaNextError('ARGUMENT_INVALID', 'At least one command prefix is required.');\n }\n\n for (const prefix of prefixes) {\n if (prefix.length === 0 || /\\s/.test(prefix)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Command prefixes cannot be empty or contain whitespace.',\n { context: { prefix } },\n );\n }\n }\n\n return prefixes;\n}\n\nfunction prefixlessCommandNames(\n definition: CommandDefinition,\n): Array<{ value: string; locale?: string }> {\n if (!definition.prefixless) return [];\n\n const names = commandNames(definition);\n if (definition.prefixless === true) return names;\n\n const enabled = new Set(definition.prefixless.map((name) => name.toLowerCase()));\n return names.filter((name) => enabled.has(name.value.toLowerCase()));\n}\n\nfunction commandNames(definition: CommandDefinition): Array<{ value: string; locale?: string }> {\n const names: Array<{ value: string; locale?: string }> = [\n definition.name,\n ...(definition.aliases ?? []),\n ].map((value) => ({ value }));\n for (const [locale, localization] of Object.entries(definition.localizations ?? {})) {\n if (localization.name) names.push({ value: localization.name, locale });\n for (const alias of localization.aliases ?? []) names.push({ value: alias, locale });\n }\n return names;\n}\n\nfunction findChild(\n definitions: readonly CommandDefinition[],\n name: string,\n): { definition: CommandDefinition; locale?: string } | undefined {\n for (const definition of definitions) {\n const found = commandNames(definition).find((candidate) => candidate.value.toLowerCase() === name);\n if (found) return { definition, ...(found.locale ? { locale: found.locale } : {}) };\n }\n return undefined;\n}\n\nfunction flattenCommands(\n root: CommandDefinition,\n parents: readonly CommandDefinition[] = [],\n): RegisteredCommand[] {\n if (isCommandGroup(root)) {\n return root.subcommands.flatMap((child) => flattenCommands(child, [...parents, root]));\n }\n\n const pathDefinitions = [...parents, root];\n return [{\n definition: root,\n root: pathDefinitions[0] ?? root,\n path: pathDefinitions.map((definition) => definition.name),\n aliases: root.aliases ?? [],\n category: root.category\n ?? [...parents].reverse().find((parent) => parent.category)?.category\n ?? 'general',\n }];\n}\n\nfunction formatOptions(definition: ExecutableCommandDefinition): string {\n return Object.entries(definition.options ?? {}).map(([name, option]) =>\n option.required ? ` <${name}>` : ` [${name}]`).join('');\n}\n\nfunction tokenize(input: string): string[] {\n return input\n .match(/(?:[^\\s\"']+|\"[^\"]*\"|'[^']*')+/g)\n ?.map((token) => token.replace(/^([\"'])(.*)\\1$/, '$2'))\n ?? [];\n}\n\nfunction isRuntimeServices(value: CommandRuntimeServices | GroupService): value is CommandRuntimeServices {\n return 'groups' in value && 'messages' in value;\n}\n\nfunction createLegacyServices(group: GroupService): CommandRuntimeServices {\n const unavailable = new Proxy({}, {\n get() {\n return () => {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'This CommandRouter was created without the full application services.',\n );\n };\n },\n });\n return {\n account: {\n id: undefined,\n get ids() {\n return [];\n },\n isOwner(message) {\n return message.keys.fromMe;\n },\n },\n groups: group,\n users: new UserService(group),\n messages: unavailable as CommandRuntimeServices['messages'],\n media: unavailable as CommandRuntimeServices['media'],\n members: unavailable as CommandRuntimeServices['members'],\n chats: unavailable as CommandRuntimeServices['chats'],\n mute: unavailable as CommandRuntimeServices['mute'],\n };\n}\n","import { WhaNextError } from '@/errors/error.js';\n\nexport type LogLevel = \n | 'debug'\n | 'info'\n | 'warn'\n | 'error'\n | 'silent';\n \nexport type LogFormat = \n | 'pretty'\n | 'json';\n \nexport type LogContext = Readonly<Record<string, unknown>>;\n\nexport interface LogEntry {\n timestamp: string;\n level: Exclude<LogLevel, 'silent'>;\n scope: string;\n message: string;\n context: LogContext;\n}\n\nexport type LogWriter = (entry: LogEntry) => unknown;\n\nexport interface LoggerOptions {\n level?: LogLevel;\n format?: LogFormat;\n writer?: LogWriter;\n scope?: string;\n redact?: readonly string[];\n}\n\nexport type LoggerConfig = LogLevel | LoggerOptions;\n\nconst priorities: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n silent: Number.POSITIVE_INFINITY,\n};\n\nconst defaultRedactions = [\n 'auth',\n 'pairingcode',\n 'password',\n 'phone',\n 'secret',\n 'session',\n 'token',\n];\n\ninterface LoggerState {\n level: LogLevel;\n}\n\nexport class Logger {\n #state: LoggerState;\n readonly #scope: string;\n readonly #writer: LogWriter;\n readonly #redactions: Set<string>;\n\n constructor(config: LoggerConfig = 'info') {\n const options = typeof config === 'string' ? { level: config } : config;\n const level = options.level ?? 'info';\n assertLevel(level);\n\n if (options.writer !== undefined && typeof options.writer !== 'function') {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Logger writer must be a function.',\n );\n }\n\n if (options.format !== undefined && !['pretty', 'json'].includes(options.format)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Logger format must be \"pretty\" or \"json\".',\n { context: { format: options.format } },\n );\n }\n\n this.#state = { level };\n this.#scope = options.scope ?? 'whanext';\n this.#redactions = new Set(\n [...defaultRedactions, ...(options.redact ?? [])]\n .map((key) => key.toLowerCase()),\n );\n this.#writer = options.writer ?? consoleWriter(options.format ?? 'pretty');\n }\n\n get level(): LogLevel {\n return this.#state.level;\n }\n\n setLevel(level: LogLevel): this {\n assertLevel(level);\n this.#state.level = level;\n return this;\n }\n\n isEnabled(level: Exclude<LogLevel, 'silent'>): boolean {\n return priorities[level] >= priorities[this.#state.level];\n }\n\n child(scope: string): Logger {\n const childScope = this.#scope ? `${this.#scope}:${scope}` : scope;\n const child = new Logger({\n level: this.#state.level,\n scope: childScope,\n writer: this.#writer,\n redact: [...this.#redactions],\n });\n child.#state = this.#state;\n return child;\n }\n\n debug(message: string, context: LogContext = {}): void {\n this.#write('debug', message, context);\n }\n\n info(message: string, context: LogContext = {}): void {\n this.#write('info', message, context);\n }\n\n warn(message: string, context: LogContext = {}): void {\n this.#write('warn', message, context);\n }\n\n error(message: string, context: LogContext = {}): void {\n this.#write('error', message, context);\n }\n\n #write(\n level: Exclude<LogLevel, 'silent'>,\n message: string,\n context: LogContext,\n ): void {\n if (!this.isEnabled(level)) {\n return;\n }\n\n try {\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level,\n scope: this.#scope,\n message,\n context: normalizeContext(context, this.#redactions),\n };\n const result = this.#writer(entry);\n\n if (result instanceof Promise) {\n void result.catch(() => undefined);\n }\n } catch {\n return;\n }\n }\n}\n\nfunction assertLevel(level: LogLevel): void {\n if (!(level in priorities)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Logger level must be debug, info, warn, error or silent.',\n { context: { level } },\n );\n }\n}\n\nfunction consoleWriter(format: LogFormat): LogWriter {\n return (entry) => {\n const method = entry.level === 'debug'\n ? console.debug\n : entry.level === 'info'\n ? console.info\n : entry.level === 'warn'\n ? console.warn\n : console.error;\n\n if (format === 'json') {\n method(JSON.stringify(entry));\n return;\n }\n\n const details = Object.keys(entry.context).length > 0\n ? ` ${JSON.stringify(entry.context)}`\n : '';\n method(\n `[${entry.timestamp}] ${entry.level.toUpperCase()} ${entry.scope} ${entry.message}${details}`,\n );\n };\n}\n\nfunction normalizeContext(\n context: LogContext,\n redactions: ReadonlySet<string>,\n): LogContext {\n const seen = new WeakSet<object>();\n return Object.fromEntries(\n Object.entries(context).map(([key, value]) => [\n key,\n normalizeValue(value, key, redactions, seen),\n ]),\n );\n}\n\nfunction normalizeValue(\n value: unknown,\n key: string,\n redactions: ReadonlySet<string>,\n seen: WeakSet<object>,\n): unknown {\n if (isRedactedKey(key, redactions)) {\n return '[REDACTED]';\n }\n\n if (\n value === null\n || typeof value === 'string'\n || typeof value === 'number'\n || typeof value === 'boolean'\n || value === undefined\n ) {\n return value;\n }\n\n if (typeof value === 'bigint') {\n return value.toString();\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n ...('code' in value ? { code: value.code } : {}),\n };\n }\n\n if (typeof value !== 'object') {\n return String(value);\n }\n\n if (seen.has(value)) {\n return '[Circular]';\n }\n\n seen.add(value);\n\n if (Array.isArray(value)) {\n return value.map((item) =>\n normalizeValue(item, '', redactions, seen));\n }\n\n return Object.fromEntries(\n Object.entries(value).map(([nestedKey, nestedValue]) => [\n nestedKey,\n normalizeValue(nestedValue, nestedKey, redactions, seen),\n ]),\n );\n}\n\nfunction isRedactedKey(\n key: string,\n redactions: ReadonlySet<string>,\n): boolean {\n const normalized = key.toLowerCase();\n return [...redactions].some((redaction) =>\n normalized === redaction\n || normalized.startsWith(redaction)\n || normalized.endsWith(redaction));\n}\n","import { WhaNextError } from '@/errors/error.js';\nimport { normalizeIdentity } from '@/models/identity.js';\nimport type { Message } from '@/models/message.js';\nimport { User } from '@/models/user.js';\nimport type {\n MuteStore,\n StoredMute,\n} from '@/mute/mute-store.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport interface AddMuteOptions {\n durationMs?: number;\n}\n\nexport interface MuteRecord {\n groupId: string;\n user: User;\n createdAt: Date;\n expiresAt: Date | null;\n}\n\nexport type AddMuteResult =\n | {\n ok: true;\n changed: true;\n state: 'muted' | 'updated';\n record: MuteRecord;\n }\n | {\n ok: true;\n changed: false;\n state: 'already_muted';\n record: MuteRecord;\n };\n\nexport type RemoveMuteResult =\n | {\n ok: true;\n changed: true;\n state: 'unmuted';\n }\n | {\n ok: true;\n changed: false;\n state: 'already_unmuted';\n };\n\nexport type MuteChangeResult = AddMuteResult | RemoveMuteResult;\n\nexport interface MuteEnforcement {\n message: Message;\n record: MuteRecord;\n}\n\nexport class MuteService {\n readonly #provider: WhatsAppProvider;\n readonly #store: MuteStore | undefined;\n\n constructor(provider: WhatsAppProvider, store?: MuteStore) {\n this.#provider = provider;\n this.#store = store;\n }\n\n get enabled(): boolean {\n return this.#store !== undefined;\n }\n\n async add(\n groupId: string,\n user: User,\n options: AddMuteOptions = {},\n ): Promise<AddMuteResult> {\n const store = this.#requireStore();\n const now = Date.now();\n\n if (options.durationMs !== undefined && options.durationMs <= 0) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Mute duration must be greater than zero.');\n }\n\n const current = await this.#findActive(groupId, user.identities);\n\n if (current && current.expiresAt === null && options.durationMs === undefined) {\n return {\n ok: true,\n changed: false,\n state: 'already_muted',\n record: this.#record(current),\n };\n }\n\n const stored: StoredMute = {\n key: normalizeIdentity(user.id),\n groupId,\n user: user.toJSON(),\n identities: user.identities,\n createdAt: now,\n expiresAt: options.durationMs === undefined ? null : now + options.durationMs,\n };\n await this.#storage(\n 'upsert',\n () => store.upsert(stored),\n { groupId, userId: user.id },\n );\n return {\n ok: true,\n changed: true,\n state: current ? 'updated' : 'muted',\n record: this.#record(stored),\n };\n }\n\n async remove(groupId: string, user: User): Promise<RemoveMuteResult> {\n const store = this.#requireStore();\n const changed = await this.#storage(\n 'delete',\n () => store.delete(groupId, user.identities),\n { groupId, userId: user.id },\n );\n\n if (changed) {\n return {\n ok: true,\n changed: true,\n state: 'unmuted',\n };\n }\n\n return {\n ok: true,\n changed: false,\n state: 'already_unmuted',\n };\n }\n\n async get(groupId: string, user: User): Promise<MuteRecord | undefined> {\n this.#requireStore();\n const stored = await this.#findActive(groupId, user.identities);\n return stored ? this.#record(stored) : undefined;\n }\n\n async isMuted(groupId: string, user: User): Promise<boolean> {\n return (await this.get(groupId, user)) !== undefined;\n }\n\n async enforce(message: Message): Promise<MuteEnforcement | undefined> {\n if (!this.#store || !message.isGroup || message.keys.fromMe) {\n return undefined;\n }\n\n const stored = await this.#findActive(message.chatId, message.sender.identities);\n\n if (!stored) {\n return undefined;\n }\n\n try {\n await this.#provider.deleteMessage(message.keys);\n } catch (error) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'Could not delete a message sent by a muted member.',\n {\n cause: error,\n context: {\n groupId: message.chatId,\n messageId: message.id,\n userId: message.sender.id,\n },\n recoverable: true,\n },\n );\n }\n\n return {\n message,\n record: this.#record(stored),\n };\n }\n\n async purgeExpired(): Promise<number> {\n const store = this.#requireStore();\n return this.#storage(\n 'purge',\n () => store.purgeExpired(Date.now()),\n );\n }\n\n async close(): Promise<void> {\n if (this.#store?.close) {\n await this.#storage('close', () => this.#store?.close?.());\n }\n }\n\n #record(stored: StoredMute): MuteRecord {\n return {\n groupId: stored.groupId,\n user: new User(stored.user),\n createdAt: new Date(stored.createdAt),\n expiresAt: stored.expiresAt === null ? null : new Date(stored.expiresAt),\n };\n }\n\n async #findActive(\n groupId: string,\n identities: readonly string[],\n ): Promise<StoredMute | undefined> {\n const stored = await this.#storage(\n 'find',\n () => this.#store?.find(groupId, identities),\n { groupId },\n );\n\n if (!stored) {\n return undefined;\n }\n\n if (stored.expiresAt !== null && stored.expiresAt <= Date.now()) {\n await this.#storage(\n 'delete_expired',\n () => this.#store?.delete(groupId, stored.identities),\n { groupId },\n );\n return undefined;\n }\n\n return stored;\n }\n\n #requireStore(): MuteStore {\n if (!this.#store) {\n throw new WhaNextError(\n 'MUTE_DISABLED',\n 'Mute is disabled. Enable it in create({ mute: { enabled: true } }).',\n );\n }\n\n return this.#store;\n }\n\n async #storage<Result>(\n action: string,\n operation: () => Result | Promise<Result>,\n context: Readonly<Record<string, unknown>> = {},\n ): Promise<Result> {\n try {\n return await operation();\n } catch (error) {\n throw new WhaNextError(\n 'STORAGE_ERROR',\n `Mute storage operation \"${action}\" failed.`,\n {\n cause: error,\n context: { action, ...context },\n recoverable: true,\n },\n );\n }\n }\n}\n","import { mkdirSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport {\n dirname,\n resolve,\n} from 'node:path';\nimport type { DatabaseSync as NodeDatabaseSync } from 'node:sqlite';\nimport { WhaNextError } from '@/errors/error.js';\nimport { normalizeIdentity } from '@/models/identity.js';\nimport type {\n MuteStore,\n StoredMute,\n} from '@/mute/mute-store.js';\n\ninterface MuteRow {\n mute_key: string;\n group_id: string;\n user_json: string;\n created_at: number;\n expires_at: number | null;\n}\n\nexport class SqliteMuteStore implements MuteStore {\n readonly #database: NodeDatabaseSync;\n\n constructor(path = './data/whanext.sqlite') {\n const databasePath = path === ':memory:' ? path : resolve(path);\n\n if (databasePath !== ':memory:') {\n mkdirSync(dirname(databasePath), { recursive: true });\n }\n\n let database: NodeDatabaseSync | undefined;\n\n try {\n const require = createRequire(import.meta.url);\n const sqlite = require('node:sqlite') as typeof import('node:sqlite');\n database = new sqlite.DatabaseSync(databasePath);\n database.exec('PRAGMA journal_mode = WAL');\n database.exec('PRAGMA busy_timeout = 5000');\n database.exec(`\n CREATE TABLE IF NOT EXISTS whanext_mutes (\n group_id TEXT NOT NULL,\n identity TEXT NOT NULL,\n mute_key TEXT NOT NULL,\n user_json TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n expires_at INTEGER,\n PRIMARY KEY (group_id, identity)\n ) STRICT;\n CREATE INDEX IF NOT EXISTS whanext_mutes_expiration\n ON whanext_mutes (expires_at);\n CREATE INDEX IF NOT EXISTS whanext_mutes_key\n ON whanext_mutes (group_id, mute_key);\n `);\n } catch (error) {\n database?.close();\n throw new WhaNextError(\n 'STORAGE_ERROR',\n 'Could not initialize the SQLite mute store.',\n {\n cause: error,\n context: { database: databasePath },\n },\n );\n }\n\n this.#database = database;\n }\n\n upsert(mute: StoredMute): void {\n const identities = this.#identities(mute.identities);\n const existingKeys = this.#matchingKeys(mute.groupId, identities);\n\n this.#transaction(() => {\n for (const key of existingKeys) {\n this.#database.prepare(\n 'DELETE FROM whanext_mutes WHERE group_id = ? AND mute_key = ?',\n ).run(mute.groupId, key);\n }\n\n const insert = this.#database.prepare(`\n INSERT OR REPLACE INTO whanext_mutes (\n group_id,\n identity,\n mute_key,\n user_json,\n created_at,\n expires_at\n ) VALUES (?, ?, ?, ?, ?, ?)\n `);\n\n for (const identity of identities) {\n insert.run(\n mute.groupId,\n identity,\n mute.key,\n JSON.stringify(mute.user),\n mute.createdAt,\n mute.expiresAt,\n );\n }\n });\n }\n\n find(groupId: string, identities: readonly string[]): StoredMute | undefined {\n const normalized = this.#identities(identities);\n\n if (normalized.length === 0) {\n return undefined;\n }\n\n const placeholders = normalized.map(() => '?').join(', ');\n const row = this.#database.prepare(`\n SELECT mute_key, group_id, user_json, created_at, expires_at\n FROM whanext_mutes\n WHERE group_id = ? AND identity IN (${placeholders})\n LIMIT 1\n `).get(groupId, ...normalized) as unknown as MuteRow | undefined;\n\n if (!row) {\n return undefined;\n }\n\n if (row.expires_at !== null && row.expires_at <= Date.now()) {\n this.#database.prepare(\n 'DELETE FROM whanext_mutes WHERE group_id = ? AND mute_key = ?',\n ).run(groupId, row.mute_key);\n return undefined;\n }\n\n const identityRows = this.#database.prepare(`\n SELECT identity\n FROM whanext_mutes\n WHERE group_id = ? AND mute_key = ?\n `).all(groupId, row.mute_key) as unknown as Array<{ identity: string }>;\n\n return {\n key: row.mute_key,\n groupId: row.group_id,\n user: JSON.parse(row.user_json) as StoredMute['user'],\n identities: identityRows.map(({ identity }) => identity),\n createdAt: row.created_at,\n expiresAt: row.expires_at,\n };\n }\n\n delete(groupId: string, identities: readonly string[]): boolean {\n const keys = this.#matchingKeys(groupId, this.#identities(identities));\n\n if (keys.length === 0) {\n return false;\n }\n\n this.#transaction(() => {\n const statement = this.#database.prepare(\n 'DELETE FROM whanext_mutes WHERE group_id = ? AND mute_key = ?',\n );\n\n for (const key of keys) {\n statement.run(groupId, key);\n }\n });\n return true;\n }\n\n purgeExpired(now: number): number {\n const result = this.#database.prepare(`\n DELETE FROM whanext_mutes\n WHERE expires_at IS NOT NULL AND expires_at <= ?\n `).run(now);\n return Number(result.changes);\n }\n\n close(): void {\n this.#database.close();\n }\n\n #matchingKeys(groupId: string, identities: readonly string[]): string[] {\n if (identities.length === 0) {\n return [];\n }\n\n const placeholders = identities.map(() => '?').join(', ');\n const rows = this.#database.prepare(`\n SELECT DISTINCT mute_key\n FROM whanext_mutes\n WHERE group_id = ? AND identity IN (${placeholders})\n `).all(groupId, ...identities) as unknown as Array<{ mute_key: string }>;\n return rows.map(({ mute_key }) => mute_key);\n }\n\n #identities(identities: readonly string[]): string[] {\n return [...new Set(identities.map(normalizeIdentity).filter(Boolean))];\n }\n\n #transaction(operation: () => void): void {\n this.#database.exec('BEGIN IMMEDIATE');\n\n try {\n operation();\n this.#database.exec('COMMIT');\n } catch (error) {\n this.#database.exec('ROLLBACK');\n throw error;\n }\n }\n}\n","export class TypedEventEmitter<Events extends object> {\n readonly #listeners = new Map<keyof Events, Set<(payload: never) => void | Promise<void>>>();\n\n on<Event extends keyof Events>(\n event: Event,\n listener: (payload: Events[Event]) => void | Promise<void>,\n ): () => void {\n const listeners = this.#listeners.get(event) ?? new Set();\n listeners.add(listener as (payload: never) => void | Promise<void>);\n this.#listeners.set(event, listeners);\n\n return () => listeners.delete(listener as (payload: never) => void | Promise<void>);\n }\n\n async emit<Event extends keyof Events>(event: Event, payload: Events[Event]): Promise<void> {\n const listeners = this.#listeners.get(event);\n\n if (!listeners) {\n return;\n }\n\n await Promise.all([...listeners].map((listener) => listener(payload as never)));\n }\n}\n","import {\n identitiesMatch,\n identityPhoneNumber,\n normalizeIdentity,\n uniqueIdentities,\n} from '@/models/identity.js';\nimport type { Message } from '@/models/message.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class AccountService {\n readonly id: string | undefined;\n readonly #provider: WhatsAppProvider;\n\n constructor(provider: WhatsAppProvider, id?: string) {\n this.#provider = provider;\n this.id = id;\n }\n\n get ids(): readonly string[] {\n return uniqueIdentities(this.#provider.getCurrentUserIds());\n }\n\n get jid(): string | undefined {\n const identity = this.ids.find((candidate) =>\n candidate.endsWith('@s.whatsapp.net') || candidate.endsWith('@c.us'));\n\n if (identity) {\n return normalizeIdentity(identity);\n }\n\n const phone = this.ids\n .map((candidate) => identityPhoneNumber(candidate))\n .find((candidate): candidate is string => candidate !== undefined);\n\n return phone ? `${phone}@s.whatsapp.net` : undefined;\n }\n\n get lid(): string | undefined {\n const identity = this.ids.find((candidate) => candidate.endsWith('@lid'));\n return identity ? normalizeIdentity(identity) : undefined;\n }\n\n get phoneNumber(): string | undefined {\n const jid = this.jid;\n return jid ? identityPhoneNumber(jid) : undefined;\n }\n\n get selfChatId(): string | undefined {\n return this.jid ?? this.lid ?? this.ids[0];\n }\n\n isOwner(message: Pick<Message, 'keys' | 'senderIds'>): boolean {\n if (message.keys.fromMe) {\n return true;\n }\n\n const currentIds = this.ids;\n return message.senderIds.some((senderId) =>\n currentIds.some((currentId) => identitiesMatch(senderId, currentId)));\n }\n}\n","import type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class ChatService {\n readonly #provider: WhatsAppProvider;\n\n constructor(provider: WhatsAppProvider) {\n this.#provider = provider;\n }\n\n typing(chatId: string): Promise<void> {\n return this.#provider.setPresence(chatId, 'typing');\n }\n\n recording(chatId: string): Promise<void> {\n return this.#provider.setPresence(chatId, 'recording');\n }\n\n stop(chatId: string): Promise<void> {\n return this.#provider.setPresence(chatId, 'paused');\n }\n\n stopTyping(chatId: string): Promise<void> {\n return this.stop(chatId);\n }\n\n rejectCall(callId: string, from: string): Promise<void> {\n return this.#provider.rejectCall(callId, from);\n }\n}\n","import type { CacheStore } from '@/cache/cache-store.js';\nimport type {\n ChangeResult,\n GroupAccess,\n GroupSnapshot,\n InviteResult,\n} from '@/models/group.js';\nimport { identitiesMatch } from '@/models/identity.js';\nimport type { MessageKey } from '@/models/message.js';\nimport { User } from '@/models/user.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class GroupService {\n readonly #provider: WhatsAppProvider;\n readonly #cache: CacheStore;\n readonly #ttlMs: number;\n readonly #requests = new Map<string, Promise<GroupSnapshot>>();\n\n constructor(provider: WhatsAppProvider, cache: CacheStore, ttlMs = 300_000) {\n this.#provider = provider;\n this.#cache = cache;\n this.#ttlMs = ttlMs;\n }\n\n async open(groupId: string): Promise<ChangeResult<'open' | 'already_open'>> {\n const group = await this.metadata(groupId);\n\n if (group.access === 'open') {\n return { ok: true, changed: false, state: 'already_open' };\n }\n\n await this.#provider.setGroupAccess(groupId, 'open');\n await this.invalidate(groupId);\n return { ok: true, changed: true, state: 'open' };\n }\n\n async close(groupId: string): Promise<ChangeResult<'closed' | 'already_closed'>> {\n const group = await this.metadata(groupId);\n\n if (group.access === 'closed') {\n return { ok: true, changed: false, state: 'already_closed' };\n }\n\n await this.#provider.setGroupAccess(groupId, 'closed');\n await this.invalidate(groupId);\n return { ok: true, changed: true, state: 'closed' };\n }\n\n async invite(groupId: string): Promise<InviteResult> {\n const code = await this.#provider.getGroupInviteCode(groupId);\n return { ok: true, code, url: `https://chat.whatsapp.com/${code}` };\n }\n\n async revokeInvite(groupId: string): Promise<InviteResult> {\n const code = await this.#provider.revokeGroupInvite(groupId);\n return { ok: true, code, url: `https://chat.whatsapp.com/${code}` };\n }\n\n async pin(groupId: string, key: MessageKey): Promise<ChangeResult<'pinned'>> {\n await this.#provider.setMessagePin(groupId, key, true);\n return { ok: true, changed: true, state: 'pinned' };\n }\n\n async unpin(groupId: string, key: MessageKey): Promise<ChangeResult<'unpinned'>> {\n await this.#provider.setMessagePin(groupId, key, false);\n return { ok: true, changed: true, state: 'unpinned' };\n }\n\n async metadata(groupId: string, refresh = false): Promise<GroupSnapshot> {\n const key = this.#key(groupId);\n\n if (!refresh) {\n const cached = await this.#cache.get<GroupSnapshot>(key);\n\n if (cached) {\n return cached;\n }\n }\n\n const pending = this.#requests.get(key);\n\n if (pending) {\n return pending;\n }\n\n const request = this.#loadMetadata(key, groupId);\n this.#requests.set(key, request);\n\n try {\n return await request;\n } finally {\n this.#requests.delete(key);\n }\n }\n\n async isAdmin(\n groupId: string,\n memberIds: string | readonly string[],\n ): Promise<boolean> {\n if (!groupId.endsWith('@g.us')) {\n return false;\n }\n\n const group = await this.metadata(groupId);\n const identities = typeof memberIds === 'string' ? [memberIds] : memberIds;\n const participant = group.participants.find((item) =>\n this.#matchesParticipant(item, identities));\n return participant?.role === 'admin' || participant?.role === 'owner';\n }\n\n async isCurrentUserAdmin(groupId: string): Promise<boolean> {\n const ids = this.#provider.getCurrentUserIds();\n\n if (ids.length === 0 || !groupId.endsWith('@g.us')) {\n return false;\n }\n\n const group = await this.metadata(groupId);\n return group.participants.some((participant) =>\n this.#matchesParticipant(participant, ids)\n && (participant.role === 'admin' || participant.role === 'owner'));\n }\n\n async resolveUser(groupId: string, user: User): Promise<User> {\n if (!groupId.endsWith('@g.us')) {\n return user;\n }\n\n const group = await this.metadata(groupId);\n const participant = group.participants.find((item) =>\n this.#matchesParticipant(item, user.identities));\n\n if (!participant) {\n return user;\n }\n\n return new User({\n id: participant.id,\n identities: [\n participant.id,\n ...(participant.lid ? [participant.lid] : []),\n ...(participant.phoneNumber ? [participant.phoneNumber] : []),\n ],\n ...(participant.lid ? { lid: participant.lid } : {}),\n ...(participant.phoneNumber ? {\n jid: participant.phoneNumber,\n phoneNumber: participant.phoneNumber,\n } : {}),\n ...(user.name ? { name: user.name } : {}),\n });\n }\n\n invalidate(groupId: string): Promise<void> {\n return this.#cache.delete(this.#key(groupId));\n }\n\n #key(groupId: string): string {\n return `group:${groupId}`;\n }\n\n async #loadMetadata(key: string, groupId: string): Promise<GroupSnapshot> {\n const group = await this.#provider.getGroup(groupId);\n await this.#cache.set(key, group, this.#ttlMs);\n return group;\n }\n\n #matchesParticipant(\n participant: GroupSnapshot['participants'][number],\n identities: readonly string[],\n ): boolean {\n const participantIds = [participant.id, participant.lid, participant.phoneNumber]\n .filter((identity): identity is string => identity !== undefined);\n return identities.some((identity) =>\n participantIds.some((participantId) =>\n identitiesMatch(identity, participantId)));\n }\n}\n","import type {\n AudioContent,\n DownloadedMedia,\n ImageContent,\n Message,\n MessageKey,\n QuotedMessage,\n SentMessage,\n StickerContent,\n VideoContent,\n} from '@/models/message.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class MediaService {\n readonly #provider: WhatsAppProvider;\n\n constructor(provider: WhatsAppProvider) {\n this.#provider = provider;\n }\n\n image(chatId: string, content: ImageContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n video(chatId: string, content: VideoContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n audio(chatId: string, content: AudioContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n sticker(chatId: string, content: StickerContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n download(message: Message | QuotedMessage | MessageKey): Promise<DownloadedMedia> {\n const key = 'keys' in message\n ? message.keys\n : 'key' in message\n ? message.key\n : message;\n\n return this.#provider.downloadMedia(key);\n }\n}\n","import { WhaNextError } from '@/errors/error.js';\nimport type {\n ChangeResult,\n GroupParticipant,\n GroupSnapshot,\n MemberActionState,\n} from '@/models/group.js';\nimport { identitiesMatch } from '@/models/identity.js';\nimport type { User } from '@/models/user.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\nimport type { GroupService } from '@/services/group-service.js';\n\nexport class MemberService {\n readonly #provider: WhatsAppProvider;\n readonly #group: GroupService;\n\n constructor(provider: WhatsAppProvider, group: GroupService) {\n this.#provider = provider;\n this.#group = group;\n }\n\n async remove(groupId: string, member: string | User): Promise<ChangeResult<MemberActionState>> {\n const { group, participant } = await this.#participant(groupId, member);\n\n if (!participant) {\n return { ok: true, changed: false, state: 'already_removed' };\n }\n\n await this.#update(groupId, this.#actionId(group, participant), 'remove');\n await this.#group.invalidate(groupId);\n return { ok: true, changed: true, state: 'removed' };\n }\n\n async promote(groupId: string, member: string | User): Promise<ChangeResult<MemberActionState>> {\n const { group, participant } = await this.#participant(groupId, member);\n\n if (!participant) {\n return { ok: true, changed: false, state: 'not_in_group' };\n }\n\n if (participant.role === 'admin' || participant.role === 'owner') {\n return { ok: true, changed: false, state: 'already_admin' };\n }\n\n await this.#update(groupId, this.#actionId(group, participant), 'promote');\n await this.#group.invalidate(groupId);\n return { ok: true, changed: true, state: 'promoted' };\n }\n\n async demote(groupId: string, member: string | User): Promise<ChangeResult<MemberActionState>> {\n const { group, participant } = await this.#participant(groupId, member);\n\n if (!participant) {\n return { ok: true, changed: false, state: 'not_in_group' };\n }\n\n if (participant.role === 'member') {\n return { ok: true, changed: false, state: 'not_admin' };\n }\n\n await this.#update(groupId, this.#actionId(group, participant), 'demote');\n await this.#group.invalidate(groupId);\n return { ok: true, changed: true, state: 'demoted' };\n }\n\n async #participant(groupId: string, member: string | User): Promise<{\n group: GroupSnapshot;\n participant: GroupParticipant | undefined;\n }> {\n const group = await this.#group.metadata(groupId);\n const memberIds = typeof member === 'string' ? [member] : member.identities;\n const participant = group.participants.find((item) =>\n [item.id, item.lid, item.phoneNumber]\n .filter((identity): identity is string => identity !== undefined)\n .some((identity) =>\n memberIds.some((memberId) => identitiesMatch(identity, memberId))));\n return { group, participant };\n }\n\n #actionId(group: GroupSnapshot, participant: GroupParticipant): string {\n if (group.addressingMode === 'lid') {\n return participant.lid\n ?? (participant.id.endsWith('@lid')\n ? participant.id\n : participant.phoneNumber ?? participant.id);\n }\n\n return participant.phoneNumber\n ?? (participant.id.endsWith('@s.whatsapp.net')\n ? participant.id\n : participant.lid ?? participant.id);\n }\n\n async #update(\n groupId: string,\n memberId: string,\n action: 'remove' | 'promote' | 'demote',\n ): Promise<void> {\n const result = await this.#provider.updateParticipant(groupId, memberId, action);\n\n if (!result.success) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n `WhatsApp rejected the member action with status ${result.status}.`,\n {\n context: { groupId, memberId, action, status: result.status },\n recoverable: true,\n },\n );\n }\n }\n}\n","import type {\n ButtonsContent,\n ListContent,\n MentionTarget,\n Message,\n MessageContent,\n MessageKey,\n PollContent,\n RepostMessageOptions,\n SentMessage,\n TextContent,\n} from '@/models/message.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport class MessageService {\n readonly #provider: WhatsAppProvider;\n\n constructor(provider: WhatsAppProvider) {\n this.#provider = provider;\n }\n\n send(chatId: string, content: MessageContent): Promise<SentMessage> {\n return this.#provider.sendMessage(chatId, content);\n }\n\n reply(message: Message, content: MessageContent): Promise<SentMessage> {\n return this.#provider.sendMessage(message.chatId, content, message.keys);\n }\n\n /**\n * Reposts a cached received message into a chat without creating a reply.\n * The original payload is preserved by the provider, so this works for\n * media and structured WhatsApp messages as well as text.\n */\n repost(\n source: Message | MessageKey,\n chatId: string,\n options: RepostMessageOptions = {},\n ): Promise<SentMessage> {\n const key = 'keys' in source ? source.keys : source;\n return this.#provider.repostMessage(key, chatId, options);\n }\n\n edit(message: Message | SentMessage | MessageKey, text: string): Promise<SentMessage> {\n const key = 'keys' in message ? message.keys : message;\n return this.#provider.editMessage(key, text);\n }\n\n delete(message: Message | SentMessage | MessageKey): Promise<void> {\n const key = 'keys' in message ? message.keys : message;\n return this.#provider.deleteMessage(key);\n }\n\n react(message: Message | SentMessage | MessageKey, emoji: string): Promise<SentMessage> {\n const key = 'keys' in message ? message.keys : message;\n return this.#provider.reactToMessage(key, emoji);\n }\n\n unreact(message: Message | SentMessage | MessageKey): Promise<SentMessage> {\n const key = 'keys' in message ? message.keys : message;\n return this.#provider.reactToMessage(key);\n }\n\n text(chatId: string, text: string, mentions?: MentionTarget[]): Promise<SentMessage> {\n const content: TextContent = { text };\n\n if (mentions !== undefined) {\n content.mentions = mentions;\n }\n\n return this.send(chatId, content);\n }\n\n buttons(chatId: string, content: ButtonsContent): Promise<SentMessage> {\n return this.send(chatId, content);\n }\n\n list(chatId: string, content: ListContent): Promise<SentMessage> {\n return this.send(chatId, content);\n }\n\n poll(chatId: string, content: PollContent): Promise<SentMessage> {\n return this.send(chatId, content);\n }\n}\n","import type { CacheOptions } from '@/cache/cache-store.js';\nimport { MemoryCache } from '@/cache/memory-cache.js';\nimport {\n CommandRouter,\n type RouterOptions,\n} from '@/commands/router.js';\nimport {\n WhaNextError,\n toWhaNextError,\n} from '@/errors/error.js';\nimport {\n Logger,\n type LogLevel,\n type LoggerConfig,\n} from '@/logger/logger.js';\nimport type { CallEvent } from '@/models/call.js';\nimport type { GroupParticipantsChanged } from '@/models/group.js';\nimport type {\n Message,\n MessageDeleted,\n MessageEdited,\n} from '@/models/message.js';\nimport type { MuteOptions } from '@/mute/mute-store.js';\nimport {\n MuteService,\n type MuteEnforcement,\n} from '@/mute/mute-service.js';\nimport { SqliteMuteStore } from '@/mute/sqlite-mute-store.js';\nimport { TypedEventEmitter } from '@/provider/event-emitter.js';\nimport type {\n ConnectionUpdate,\n WhatsAppProvider,\n} from '@/provider/provider.js';\nimport { AccountService } from '@/services/account-service.js';\nimport { ChatService } from '@/services/chat-service.js';\nimport { GroupService } from '@/services/group-service.js';\nimport { MediaService } from '@/services/media-service.js';\nimport { MemberService } from '@/services/member-service.js';\nimport { MessageService } from '@/services/message-service.js';\nimport { UserService } from '@/services/user-service.js';\n\nexport interface AppEvents {\n message: Message;\n messageDeleted: MessageDeleted;\n messageEdited: MessageEdited;\n connection: ConnectionUpdate;\n error: WhaNextError;\n mute: MuteEnforcement;\n call: CallEvent;\n groupParticipantsChanged: GroupParticipantsChanged;\n}\n\nexport interface LoginOptions {\n onCode?: (code: string) => void | Promise<void>;\n timeoutMs?: number;\n}\n\nexport type AppHealthStatus = 'idle' | 'starting' | 'ready' | 'stopped';\n\nexport interface AppHealth {\n status: AppHealthStatus;\n state: ConnectionUpdate['state'];\n ready: boolean;\n uptimeMs: number;\n timestamp: Date;\n muteEnabled: boolean;\n logLevel: LogLevel;\n}\n\nexport interface WhaNextAppOptions {\n phone?: string;\n prefix?: string | readonly string[];\n cache?: CacheOptions;\n logger?: LoggerConfig;\n mute?: MuteOptions;\n router?: Omit<RouterOptions, 'prefix'>;\n accountId?: string;\n}\n\nexport class WhaNextApp {\n readonly account: AccountService;\n readonly message: MessageService;\n readonly media: MediaService;\n readonly group: GroupService;\n readonly member: MemberService;\n readonly chat: ChatService;\n readonly user: UserService;\n readonly mute: MuteService;\n readonly logger: Logger;\n readonly commands: CommandRouter;\n readonly #provider: WhatsAppProvider;\n readonly #phone: string | undefined;\n readonly #events = new TypedEventEmitter<AppEvents>();\n readonly #router: CommandRouter;\n readonly #startedAt = Date.now();\n #state: ConnectionUpdate['state'] = 'idle';\n\n constructor(\n provider: WhatsAppProvider,\n options: WhaNextAppOptions = {},\n logger = new Logger(options.logger),\n ) {\n this.#provider = provider;\n this.#phone = options.phone;\n this.account = new AccountService(provider, options.accountId);\n this.logger = logger;\n const cache = options.cache?.store ?? new MemoryCache(\n options.cache?.memoryMaxEntries === undefined\n ? undefined\n : { maxEntries: options.cache.memoryMaxEntries },\n );\n this.group = new GroupService(provider, cache, options.cache?.groupTtlMs);\n this.member = new MemberService(provider, this.group);\n this.message = new MessageService(provider);\n this.media = new MediaService(provider);\n this.chat = new ChatService(provider);\n this.user = new UserService(this.group);\n const muteEnabled = options.mute?.enabled === true || options.mute?.store !== undefined;\n const muteStore = muteEnabled\n ? options.mute?.store ?? new SqliteMuteStore(options.mute?.database)\n : undefined;\n this.mute = new MuteService(provider, muteStore);\n this.commands = new CommandRouter({\n account: this.account,\n messages: this.message,\n media: this.media,\n groups: this.group,\n members: this.member,\n chats: this.chat,\n users: this.user,\n mute: this.mute,\n }, {\n ...options.router,\n ...(options.prefix !== undefined ? { prefix: options.prefix } : {}),\n });\n this.#router = this.commands;\n this.#bind();\n this.logger.debug('Application initialized', {\n muteEnabled: this.mute.enabled,\n prefix: options.prefix ?? '!',\n });\n }\n\n get state(): ConnectionUpdate['state'] {\n return this.#state;\n }\n\n get isReady(): boolean {\n return this.#state === 'connected';\n }\n\n health(): AppHealth {\n return {\n status: this.#healthStatus(),\n state: this.#state,\n ready: this.isReady,\n uptimeMs: Date.now() - this.#startedAt,\n timestamp: new Date(),\n muteEnabled: this.mute.enabled,\n logLevel: this.logger.level,\n };\n }\n\n router(): CommandRouter {\n return this.#router;\n }\n\n on<Event extends keyof AppEvents>(\n event: Event,\n listener: (payload: AppEvents[Event]) => void | Promise<void>,\n ) {\n return this.#events.on(event, listener);\n }\n\n async login(options: LoginOptions = {}): Promise<void> {\n if (this.#state === 'connected') {\n return;\n }\n\n this.logger.info('Login started');\n\n let unsubscribe: () => void = () => undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const connected = new Promise<void>((resolve, reject) => {\n unsubscribe = this.#provider.on('connection', (update) => {\n if (update.state === 'connected') resolve();\n if (update.state === 'closed') {\n reject(\n new WhaNextError(\n 'CONNECTION_FAILED',\n 'WhatsApp closed the connection before login completed.',\n {\n cause: update.error,\n recoverable: true,\n },\n ),\n );\n }\n });\n\n timer = setTimeout(() => {\n reject(\n new WhaNextError(\n 'CONNECTION_FAILED',\n 'WhatsApp login timed out.',\n { recoverable: true },\n ),\n );\n }, options.timeoutMs ?? 300_000);\n });\n\n void connected.catch(() => undefined);\n\n try {\n await this.#provider.connect();\n\n if (this.#phone) {\n const code = await this.#provider.requestPairingCode(this.#phone);\n\n if (code) {\n this.logger.info('Pairing code generated');\n\n if (options.onCode) {\n await options.onCode(code);\n }\n }\n }\n\n await connected;\n } finally {\n unsubscribe();\n if (timer) clearTimeout(timer);\n }\n }\n\n async disconnect(): Promise<void> {\n this.logger.info('Disconnecting application');\n\n try {\n await this.#provider.disconnect();\n } finally {\n await this.mute.close();\n }\n }\n\n #bind(): void {\n this.#provider.on('connection', async (update) => {\n this.#state = update.state;\n this.#logConnection(update);\n await this.#events.emit('connection', update);\n });\n\n this.#provider.on('groupChanged', ({ groupId }) => this.group.invalidate(groupId));\n\n this.#provider.on('groupParticipantsChanged', async (change) => {\n await this.group.invalidate(change.groupId);\n await this.#events.emit('groupParticipantsChanged', change);\n });\n\n this.#provider.on('call', async (call) => {\n this.logger.debug('Call received', {\n callId: call.id,\n from: call.from,\n status: call.status,\n });\n await this.#events.emit('call', call);\n });\n\n this.#provider.on('messageDeleted', async (deletion) => {\n this.logger.debug('Message deleted', {\n chatId: deletion.key.chatId,\n messageId: deletion.key.id,\n deletedByMe: deletion.deletedByMe,\n cached: deletion.message !== undefined,\n });\n await this.#events.emit('messageDeleted', deletion);\n });\n\n this.#provider.on('messageEdited', async (edit) => {\n this.logger.debug('Message edited', {\n chatId: edit.key.chatId,\n messageId: edit.key.id,\n editedByMe: edit.editedByMe,\n cached: edit.previous !== undefined,\n });\n await this.#events.emit('messageEdited', edit);\n });\n\n this.#provider.on('message', async (message) => {\n try {\n const enforcement = await this.mute.enforce(message);\n\n if (enforcement) {\n this.logger.info('Muted message deleted', {\n groupId: message.chatId,\n messageId: message.id,\n userId: message.sender.id,\n });\n await this.#events.emit('mute', enforcement);\n return;\n }\n } catch (error) {\n await this.#reportError(error, { messageId: message.id });\n return;\n }\n\n try {\n this.logger.debug('Message received', {\n chatId: message.chatId,\n messageId: message.id,\n senderId: message.sender.id,\n });\n await this.#events.emit('message', message);\n const dispatched = await this.#router.dispatch(message);\n\n if (dispatched) {\n this.logger.debug('Command dispatched', {\n chatId: message.chatId,\n messageId: message.id,\n });\n }\n } catch (error) {\n await this.#reportError(error, { messageId: message.id });\n }\n });\n }\n\n #healthStatus(): AppHealthStatus {\n if (this.#state === 'connected') {\n return 'ready';\n }\n\n if (this.#state === 'closed') {\n return 'stopped';\n }\n\n if (this.#state === 'connecting' || this.#state === 'reconnecting') {\n return 'starting';\n }\n\n return 'idle';\n }\n\n #logConnection(update: ConnectionUpdate): void {\n const context = {\n ...(update.attempt !== undefined ? { attempt: update.attempt } : {}),\n ...(update.error ? { error: update.error } : {}),\n };\n\n if (update.state === 'connected') {\n this.logger.info('WhatsApp connected');\n } else if (update.state === 'reconnecting') {\n this.logger.warn('WhatsApp reconnecting', context);\n } else if (update.state === 'closed' && update.error) {\n this.logger.warn('WhatsApp connection closed', context);\n } else if (update.state === 'closed') {\n this.logger.info('WhatsApp connection closed');\n } else {\n this.logger.debug('WhatsApp connecting', context);\n }\n }\n\n async #reportError(\n error: unknown,\n context: Readonly<Record<string, unknown>>,\n ): Promise<void> {\n const normalized = toWhaNextError(error, context);\n this.logger.error(normalized.message, {\n code: normalized.code,\n ...normalized.context,\n });\n await this.#events.emit('error', normalized);\n }\n}\n","export enum Browser {\n Windows = 'windows',\n MacOS = 'macos',\n Ubuntu = 'ubuntu',\n}","import { mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { createMediaProcessor } from '@zapo-js/media-utils';\nimport { createSqliteStore } from '@zapo-js/store-sqlite';\nimport {\n WaClient,\n createStore,\n proto,\n type Logger as ZapoLogger,\n type LogLevel as ZapoLogLevel,\n type Proto,\n type WaIncomingMessageEvent,\n} from 'zapo-js';\nimport { Browser } from '@/auth/browser.js';\nimport { WhaNextError } from '@/errors/error.js';\nimport { Logger } from '@/logger/logger.js';\nimport type { CallEvent, CallStatus } from '@/models/call.js';\nimport type {\n GroupAccess,\n GroupParticipantAction,\n GroupParticipantsChanged,\n GroupSnapshot,\n} from '@/models/group.js';\nimport { uniqueIdentities } from '@/models/identity.js';\nimport type {\n ButtonsContent,\n DownloadedMedia,\n ListContent,\n MediaSource,\n MentionTarget,\n MessageContent,\n MessageKey,\n PollContent,\n RepostMessageOptions,\n SentMessage,\n} from '@/models/message.js';\nimport { TypedEventEmitter } from '@/provider/event-emitter.js';\nimport type {\n ParticipantAction,\n ParticipantUpdateResult,\n PresenceState,\n ProviderEvents,\n WhatsAppProvider,\n} from '@/provider/provider.js';\nimport {\n extractQuotedZapoMessage,\n unwrapZapoMessageContent,\n normalizeZapoKey,\n normalizeZapoMessage,\n type ZapoMessageKeyLike,\n} from '@/provider/zapo/normalize-message.js';\n\nexport interface ZapoProviderOptions {\n auth: string;\n browser: Browser;\n logger?: Logger;\n messageCacheSize?: number;\n sessionId?: string;\n processOfflineMessages?: boolean;\n reconnect?: {\n enabled?: boolean;\n maxAttempts?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n };\n}\n\ninterface StoredZapoMessage {\n key: ZapoMessageKeyLike;\n message?: Proto.IMessage | null;\n timestampSeconds?: number | null;\n pushName?: string | null;\n offline?: boolean | null;\n}\n\ninterface ZapoPublishResultLike {\n id?: string | null;\n}\n\ninterface ZapoCredentialsLike {\n meJid?: string | null;\n meLid?: string | null;\n}\n\ninterface ZapoProtocolEventLike extends StoredZapoMessage {\n protocolMessage?: {\n type?: number | null;\n key?: ZapoMessageKeyLike | null;\n editedMessage?: Proto.IMessage | null;\n timestampMs?: number | LongLike | null;\n } | null;\n}\n\ninterface ZapoAddonEventLike {\n key: ZapoMessageKeyLike;\n kind?: string | null;\n targetMessageId?: string | null;\n decrypted?: unknown;\n raw?: Proto.IMessage | null;\n offline?: boolean | null;\n}\n\ninterface ZapoGroupEventParticipantLike {\n jid?: string | null;\n lidJid?: string | null;\n phoneJid?: string | null;\n}\n\ninterface ZapoGroupEventLike {\n groupJid?: string | null;\n action?: string | null;\n authorJid?: string | null;\n participants?: readonly ZapoGroupEventParticipantLike[] | null;\n}\n\n\ninterface ZapoCallEventLike {\n type?: string | null;\n callId?: string | null;\n callCreatorJid?: string | null;\n callerPnJid?: string | null;\n groupJid?: string | null;\n isVideo?: boolean | null;\n callerPushName?: string | null;\n timestampMs?: number | LongLike | null;\n}\n\ninterface ZapoBinaryNodeLike {\n tag: string;\n attrs: Record<string, string>;\n content?: ZapoBinaryNodeLike[];\n}\n\ninterface ZapoLowLevelLike {\n sendNode(node: ZapoBinaryNodeLike): Promise<void>;\n}\n\ninterface ZapoGroupMetadataLike {\n jid?: string | null;\n id?: string | null;\n subject?: string | null;\n announce?: boolean | null;\n addressingMode?: string | null;\n participants?: readonly ZapoGroupParticipantLike[] | null;\n}\n\ninterface ZapoGroupParticipantLike {\n jid?: string | null;\n id?: string | null;\n lid?: string | null;\n phoneNumber?: string | null;\n isAdmin?: boolean | null;\n isSuperAdmin?: boolean | null;\n admin?: string | null;\n}\n\ninterface LongLike {\n toNumber?: () => number;\n low?: number;\n}\n\ntype ZapoChatstateState = 'composing' | 'recording' | 'paused';\n\ninterface ZapoPresenceLike {\n sendChatstate(jid: string, value: { state: ZapoChatstateState }): Promise<void>;\n}\n\nexport class ZapoProvider implements WhatsAppProvider {\n readonly #options: ZapoProviderOptions;\n readonly #events = new TypedEventEmitter<ProviderEvents>();\n readonly #logger: Logger;\n readonly #messageStore = new Map<string, StoredZapoMessage>();\n readonly #messageKeyStore = new WeakMap<MessageKey, StoredZapoMessage>();\n readonly #deliveredMessageStore = new Set<string>();\n readonly #handledProtocolStore = new Set<string>();\n readonly #callCreatorStore = new Map<string, string>();\n readonly #messageCacheSize: number;\n #client: WaClient | undefined;\n #intentionalClose = false;\n #reconnectAttempt = 0;\n #reconnectTimer: ReturnType<typeof setTimeout> | undefined;\n #connectPromise: Promise<void> | undefined;\n #pairingRequired = false;\n #connected = false;\n #connectedAtSeconds = 0;\n #pairingReady: Promise<void> = Promise.resolve();\n #resolvePairingReady: (() => void) | undefined;\n\n constructor(options: ZapoProviderOptions) {\n this.#options = options;\n this.#logger = options.logger ?? new Logger('silent');\n this.#messageCacheSize = Math.max(1, options.messageCacheSize ?? 1_000);\n }\n\n on<Event extends keyof ProviderEvents>(\n event: Event,\n listener: (payload: ProviderEvents[Event]) => void | Promise<void>,\n ) {\n return this.#events.on(event, listener);\n }\n\n async connect(): Promise<void> {\n this.#intentionalClose = false;\n const client = await this.#ensureClient();\n\n if (this.#connected || this.#connectPromise) {\n return;\n }\n\n this.#preparePairingGate();\n await this.#events.emit('connection', {\n state: this.#reconnectAttempt > 0 ? 'reconnecting' : 'connecting',\n attempt: this.#reconnectAttempt,\n });\n this.#startConnect(client);\n }\n\n async disconnect(): Promise<void> {\n this.#intentionalClose = true;\n\n if (this.#reconnectTimer) {\n clearTimeout(this.#reconnectTimer);\n this.#reconnectTimer = undefined;\n }\n\n const client = this.#client;\n this.#connectPromise = undefined;\n\n if (client) {\n await client.disconnect();\n } else {\n await this.#events.emit('connection', { state: 'closed' });\n }\n\n this.#connected = false;\n }\n\n getCurrentUserIds(): string[] {\n const credentials = this.#client?.getCredentials() as ZapoCredentialsLike | null | undefined;\n return uniqueIdentities([\n credentials?.meJid,\n credentials?.meLid,\n ]);\n }\n\n async requestPairingCode(phone: string): Promise<string> {\n const normalized = phone.replace(/\\D/g, '');\n\n if (normalized.length < 10) {\n throw new WhaNextError(\n 'AUTH_INVALID_PHONE',\n 'The phone number must include its country code.',\n );\n }\n\n const client = await this.#ensureClient();\n\n if (client.getCredentials()?.meJid) {\n return '';\n }\n\n if (!this.#connectPromise && !this.#connected) {\n await this.connect();\n }\n\n try {\n if (!this.#pairingRequired) {\n await this.#withTimeout(\n this.#pairingReady,\n 60_000,\n 'The WhatsApp pairing challenge was not received in time.',\n );\n }\n\n return await client.auth.requestPairingCode(normalized);\n } catch (error) {\n if (error instanceof WhaNextError) throw error;\n\n throw new WhaNextError(\n 'CONNECTION_FAILED',\n 'Could not request the pairing code after the authentication challenge.',\n { cause: error, recoverable: true },\n );\n }\n }\n\n async sendMessage(\n chatId: string,\n content: MessageContent,\n replyTo?: MessageKey,\n ): Promise<SentMessage> {\n if ('buttons' in content) {\n return this.#sendButtons(chatId, content, replyTo);\n }\n\n if ('list' in content) {\n return this.#sendList(chatId, content, replyTo);\n }\n\n const client = this.#requireClient();\n const { value, mentions, viewOnce } = await this.#toContent(content);\n const result = await client.message.send(chatId, value as never, {\n ...(replyTo ? { quote: this.#toZapoKey(replyTo) } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n ...(viewOnce !== undefined ? { viewOnce } : {}),\n });\n\n return this.#sent(result, chatId);\n }\n\n async repostMessage(\n source: MessageKey,\n chatId: string,\n options: RepostMessageOptions = {},\n ): Promise<SentMessage> {\n const original = this.#findStoredMessage(this.#toZapoKey(source));\n\n if (!original?.message) {\n throw new WhaNextError(\n 'MESSAGE_NOT_FOUND',\n 'The source message is no longer available in the recent-message cache.',\n {\n context: { messageId: source.id, chatId: source.chatId },\n recoverable: true,\n },\n );\n }\n\n const result = await this.#requireClient().message.send(\n chatId,\n original.message,\n {\n forward: true,\n ...(options.mentions && options.mentions.length > 0\n ? { mentions: this.#mentions(options.mentions) }\n : {}),\n },\n );\n\n return this.#sent(result, chatId);\n }\n\n async reactToMessage(key: MessageKey, emoji?: string): Promise<SentMessage> {\n const result = await this.#requireClient().message.send(key.chatId, {\n type: 'reaction',\n emoji: emoji ?? '',\n target: this.#toZapoKey(key),\n });\n\n return this.#sent(result, key.chatId);\n }\n\n async downloadMedia(key: MessageKey): Promise<DownloadedMedia> {\n const message = this.#messageKeyStore.get(key)\n ?? this.#findStoredMessage(this.#toZapoKey(key));\n\n if (!message?.message) {\n throw new WhaNextError(\n 'MEDIA_NOT_AVAILABLE',\n 'The media is unavailable. Download it from the received message event while it is cached.',\n { recoverable: true },\n );\n }\n\n const normalized = normalizeZapoMessage(message);\n\n if (!normalized?.media) {\n throw new WhaNextError(\n 'MEDIA_NOT_AVAILABLE',\n 'The selected message does not contain media.',\n );\n }\n\n try {\n const mediaMessage = unwrapZapoMessageContent(message.message)\n ?? message.message;\n const bytes = await this.#requireClient().message.downloadBytes(mediaMessage);\n\n return {\n data: Buffer.from(bytes),\n kind: normalized.media.kind,\n ...(normalized.media.mimetype ? { mimetype: normalized.media.mimetype } : {}),\n ...(normalized.media.fileName ? { fileName: normalized.media.fileName } : {}),\n };\n } catch (error) {\n throw new WhaNextError(\n 'MEDIA_NOT_AVAILABLE',\n 'WhatsApp could not download the selected media.',\n { cause: error, recoverable: true },\n );\n }\n }\n\n async editMessage(key: MessageKey, content: string): Promise<SentMessage> {\n const result = await this.#requireClient().message.send(\n key.chatId,\n content,\n { editKey: this.#toZapoKey(key) },\n );\n\n return this.#sent(result, key.chatId);\n }\n\n async deleteMessage(key: MessageKey): Promise<void> {\n await this.#requireClient().message.send(key.chatId, {\n type: 'revoke',\n target: this.#toZapoKey(key),\n });\n }\n\n async getGroup(groupId: string): Promise<GroupSnapshot> {\n const metadata = await this.#requireClient().group.queryGroupMetadata(groupId) as ZapoGroupMetadataLike;\n const participants = [...(metadata.participants ?? [])];\n const addressingMode = metadata.addressingMode === 'lid'\n || participants.some((participant) =>\n (participant.jid ?? participant.id ?? '').endsWith('@lid'))\n ? 'lid'\n : 'pn';\n\n return {\n id: metadata.jid ?? metadata.id ?? groupId,\n subject: metadata.subject ?? '',\n access: metadata.announce ? 'closed' : 'open',\n addressingMode,\n fetchedAt: new Date(),\n participants: participants.map((participant) => {\n const id = participant.jid ?? participant.id ?? participant.lid ?? participant.phoneNumber ?? '';\n return {\n id,\n ...(participant.lid ? { lid: participant.lid } : {}),\n ...(participant.phoneNumber ? { phoneNumber: participant.phoneNumber } : {}),\n role: participant.isSuperAdmin || participant.admin === 'superadmin'\n ? 'owner'\n : participant.isAdmin || participant.admin === 'admin'\n ? 'admin'\n : 'member',\n };\n }),\n };\n }\n\n async setGroupAccess(groupId: string, access: GroupAccess): Promise<void> {\n await this.#requireClient().group.setSetting(\n groupId,\n 'announcement',\n access === 'closed',\n );\n }\n\n async getGroupInviteCode(groupId: string): Promise<string> {\n const code = await this.#requireClient().group.queryInviteCode(groupId);\n\n if (!code) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'WhatsApp did not return a group invite code.',\n );\n }\n\n return code;\n }\n\n async revokeGroupInvite(groupId: string): Promise<string> {\n const result = await this.#requireClient().group.revokeInvite(groupId);\n\n if (!result.code) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'WhatsApp did not return a new group invite code.',\n );\n }\n\n return result.code;\n }\n\n async setMessagePin(\n groupId: string,\n key: MessageKey,\n pinned: boolean,\n ): Promise<void> {\n await this.#requireClient().message.send(groupId, pinned\n ? {\n type: 'pin',\n target: this.#toZapoKey(key),\n durationSecs: 604_800,\n }\n : {\n type: 'unpin',\n target: this.#toZapoKey(key),\n });\n }\n\n async updateParticipant(\n groupId: string,\n memberId: string,\n action: ParticipantAction,\n ): Promise<ParticipantUpdateResult> {\n const group = this.#requireClient().group;\n const results = action === 'remove'\n ? await group.removeParticipants(groupId, [memberId])\n : action === 'promote'\n ? await group.promoteParticipants(groupId, [memberId])\n : await group.demoteParticipants(groupId, [memberId]);\n const result = results[0];\n const success = result?.status === 'ok';\n const status = success ? '200' : String(result?.code ?? result?.status ?? 'unknown');\n\n return {\n success,\n status,\n ...(result?.jid ? { memberId: result.jid } : {}),\n };\n }\n\n async setPresence(chatId: string, state: PresenceState): Promise<void> {\n const value: ZapoChatstateState = state === 'typing'\n ? 'composing'\n : state === 'recording'\n ? 'recording'\n : 'paused';\n const presence = this.#requireClient().presence as unknown as ZapoPresenceLike;\n\n await presence.sendChatstate(chatId, { state: value });\n }\n\n async rejectCall(callId: string, from: string): Promise<void> {\n const client = this.#requireClient();\n const creator = this.#callCreatorStore.get(callId) ?? from;\n if (!creator) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Call creator is required to reject a call.');\n }\n\n const lowlevel = client.lowlevel as unknown as ZapoLowLevelLike;\n await lowlevel.sendNode({\n tag: 'call',\n attrs: { to: creator },\n content: [\n {\n tag: 'reject',\n attrs: {\n 'call-id': callId,\n 'call-creator': creator,\n },\n },\n ],\n });\n }\n\n async #ensureClient(): Promise<WaClient> {\n if (this.#client) return this.#client;\n\n await mkdir(this.#options.auth, { recursive: true });\n const store = createStore({\n backends: {\n sqlite: createSqliteStore({\n path: join(this.#options.auth, 'state.sqlite'),\n driver: 'auto',\n }),\n },\n providers: {\n auth: 'sqlite',\n signal: 'sqlite',\n preKey: 'sqlite',\n session: 'sqlite',\n identity: 'sqlite',\n senderKey: 'sqlite',\n appState: 'sqlite',\n privacyToken: 'sqlite',\n messages: 'none',\n threads: 'none',\n contacts: 'none',\n },\n cacheProviders: {\n messageSecret: 'sqlite',\n },\n });\n const client = new WaClient({\n store,\n sessionId: this.#options.sessionId ?? 'default',\n markOnlineOnConnect: false,\n deviceBrowser: this.#deviceBrowser(),\n deviceOsDisplayName: this.#deviceOsDisplayName(),\n history: { enabled: false },\n addons: {\n autoDecrypt: true,\n persistAllSecrets: true,\n },\n media: { processor: createMediaProcessor() },\n }, new WhaNextZapoLogger(this.#logger));\n\n this.#client = client;\n this.#bind(client);\n return client;\n }\n\n #bind(client: WaClient): void {\n client.on('auth_pairing_required', () => {\n this.#markPairingReady();\n });\n\n client.on('auth_qr', () => {\n this.#markPairingReady();\n });\n\n client.on('auth_paired', () => {\n this.#pairingRequired = false;\n });\n\n client.on('message', (event) => {\n this.#handleMessage(event);\n });\n\n client.on('message_send', (event) => {\n if (!event.id || !event.message) return;\n\n this.#remember({\n key: {\n id: event.id,\n remoteJid: event.to,\n fromMe: true,\n },\n message: event.message,\n timestampSeconds: Math.floor(Date.now() / 1_000),\n });\n });\n\n client.on('message_protocol', (event) => {\n this.#handleProtocolEvent(event as unknown as ZapoProtocolEventLike);\n });\n\n client.on('message_addon', (event) => {\n this.#handleAddonEvent(event as unknown as ZapoAddonEventLike);\n });\n\n client.on('group', (event) => {\n this.#handleGroupEvent(event as unknown as ZapoGroupEventLike);\n });\n\n client.on('call', (event) => {\n const call = this.#normalizeCall(event as unknown as ZapoCallEventLike);\n if (call) void this.#events.emit('call', call);\n });\n\n client.on('connection', (event) => {\n void this.#handleConnectionEvent(client, event);\n });\n }\n\n #handleMessage(event: WaIncomingMessageEvent): void {\n const stored = event as unknown as StoredZapoMessage;\n\n if (stored.key?.id && stored.message) this.#remember(stored);\n\n const quoted = extractQuotedZapoMessage(event);\n if (quoted?.key.id && quoted.message) {\n this.#remember(quoted as unknown as StoredZapoMessage);\n }\n\n if (this.#isOfflineMessage(stored)) {\n this.#logger.debug('Ignored message queued before the current live connection.', {\n messageId: stored.key.id ?? undefined,\n chatId: stored.key.remoteJid ?? undefined,\n timestampSeconds: stored.timestampSeconds ?? undefined,\n });\n return;\n }\n\n const deliveryKey = this.#messageDeliveryKey(stored.key);\n if (stored.key.id && this.#deliveredMessageStore.has(deliveryKey)) {\n this.#logger.debug('Ignored duplicate Zapo message event.', {\n messageId: stored.key.id,\n chatId: stored.key.remoteJid ?? undefined,\n });\n return;\n }\n\n const message = normalizeZapoMessage(event);\n if (!message) return;\n\n if (stored.key.id) this.#rememberDeliveredMessage(deliveryKey);\n this.#messageKeyStore.set(message.keys, stored);\n if (message.quoted && quoted?.message) {\n this.#messageKeyStore.set(\n message.quoted.key,\n quoted as unknown as StoredZapoMessage,\n );\n }\n\n void this.#events.emit('message', message);\n }\n\n #handleAddonEvent(event: ZapoAddonEventLike): void {\n if (event.kind !== 'message_edit' || !event.targetMessageId) return;\n\n const editedMessage = this.#addonEditedMessage(event.decrypted);\n if (!editedMessage) return;\n\n const target: ZapoMessageKeyLike = {\n id: event.targetMessageId,\n ...(event.key.remoteJid !== undefined ? { remoteJid: event.key.remoteJid } : {}),\n ...(event.key.fromMe !== undefined ? { fromMe: event.key.fromMe } : {}),\n ...(event.key.participant !== undefined ? { participant: event.key.participant } : {}),\n ...(event.key.participantAlt !== undefined ? { participantAlt: event.key.participantAlt } : {}),\n };\n\n this.#handleProtocolEvent({\n key: event.key,\n ...(event.offline !== undefined ? { offline: event.offline } : {}),\n protocolMessage: {\n type: proto.Message.ProtocolMessage.Type.MESSAGE_EDIT,\n key: target,\n editedMessage,\n },\n });\n }\n\n #addonEditedMessage(value: unknown): Proto.IMessage | undefined {\n if (!value || typeof value !== 'object') return undefined;\n\n const record = value as Record<string, unknown>;\n const protocol = record.protocolMessage;\n if (protocol && typeof protocol === 'object') {\n const edited = (protocol as Record<string, unknown>).editedMessage;\n if (edited && typeof edited === 'object') return edited as Proto.IMessage;\n }\n\n const edited = record.editedMessage;\n if (edited && typeof edited === 'object') return edited as Proto.IMessage;\n\n const message = record.message;\n if (message && typeof message === 'object') return message as Proto.IMessage;\n\n return value as Proto.IMessage;\n }\n\n #handleProtocolEvent(event: ZapoProtocolEventLike): void {\n if (this.#isOfflineMessage(event)) {\n this.#logger.debug('Ignored protocol event queued before the current live connection.', {\n messageId: event.key.id ?? undefined,\n chatId: event.key.remoteJid ?? undefined,\n timestampSeconds: event.timestampSeconds ?? undefined,\n });\n return;\n }\n\n const protocol = event.protocolMessage\n ?? (event.message?.protocolMessage as ZapoProtocolEventLike['protocolMessage']);\n if (!protocol) return;\n\n const protocolKey = protocol.key;\n if (!protocolKey?.id) return;\n\n const remoteJid = protocolKey.remoteJid ?? event.key.remoteJid;\n const participant = protocolKey.participant ?? event.key.participant;\n const participantAlt = protocolKey.participantAlt ?? event.key.participantAlt;\n const target: ZapoMessageKeyLike = {\n ...protocolKey,\n ...(remoteJid !== undefined ? { remoteJid } : {}),\n ...(participant !== undefined ? { participant } : {}),\n ...(participantAlt !== undefined ? { participantAlt } : {}),\n };\n\n if (!target.remoteJid) return;\n\n const stored = this.#findStoredMessage(target);\n const type = protocol?.type;\n const mutationKey = this.#protocolDeliveryKey(event, target, type);\n\n if (mutationKey && this.#handledProtocolStore.has(mutationKey)) {\n this.#logger.debug('Ignored duplicate Zapo protocol event.', {\n messageId: event.key.id ?? undefined,\n targetMessageId: target.id ?? undefined,\n });\n return;\n }\n\n if (type === proto.Message.ProtocolMessage.Type.REVOKE) {\n if (mutationKey) this.#rememberHandledProtocol(mutationKey);\n const previous = stored ? normalizeZapoMessage(stored) : undefined;\n const deletedByMe = event.key.fromMe === true;\n const deletedById = event.key.participant\n ?? event.key.participantAlt\n ?? (deletedByMe ? this.getCurrentUserIds()[0] : event.key.remoteJid ?? undefined);\n\n void this.#events.emit('messageDeleted', {\n key: previous?.keys ?? normalizeZapoKey(target),\n ...(previous ? { message: previous } : {}),\n deletedByMe,\n ...(deletedById ? { deletedById } : {}),\n deletedAt: new Date(),\n });\n return;\n }\n\n if (type !== proto.Message.ProtocolMessage.Type.MESSAGE_EDIT || !protocol.editedMessage) {\n return;\n }\n\n const pushName = event.pushName ?? stored?.pushName;\n const edited: StoredZapoMessage = {\n ...(stored ?? {}),\n key: {\n ...(stored?.key ?? {}),\n ...target,\n },\n message: protocol.editedMessage,\n timestampSeconds: toSeconds(protocol.timestampMs)\n ?? event.timestampSeconds\n ?? stored?.timestampSeconds\n ?? Math.floor(Date.now() / 1_000),\n ...(pushName !== undefined ? { pushName } : {}),\n };\n const message = normalizeZapoMessage(edited);\n\n if (!message) return;\n\n const previous = stored ? normalizeZapoMessage(stored) : undefined;\n if (mutationKey) this.#rememberHandledProtocol(mutationKey);\n this.#remember(edited);\n const editedByMe = event.key.fromMe === true;\n const editedById = event.key.participant\n ?? event.key.participantAlt\n ?? (editedByMe ? this.getCurrentUserIds()[0] : event.key.remoteJid ?? undefined);\n\n void this.#events.emit('messageEdited', {\n key: message.keys,\n ...(previous ? { previous } : {}),\n message,\n editedByMe,\n ...(editedById ? { editedById } : {}),\n editedAt: message.timestamp,\n });\n }\n\n #handleGroupEvent(event: ZapoGroupEventLike): void {\n const groupId = event.groupJid;\n if (!groupId) return;\n\n const action = this.#groupAction(event.action);\n const participantIds = this.#groupParticipantIds(event);\n\n if (action && participantIds.length > 0) {\n const authorId = event.authorJid;\n const change: GroupParticipantsChanged = {\n groupId,\n action,\n participantIds,\n ...(authorId ? { authorId } : {}),\n };\n void this.#events.emit('groupParticipantsChanged', change);\n }\n\n void this.#events.emit('groupChanged', { groupId });\n }\n\n async #handleConnectionEvent(\n client: WaClient,\n event: { status: 'open' | 'close'; reason?: unknown; isLogout?: boolean },\n ): Promise<void> {\n if (client !== this.#client) return;\n\n if (event.status === 'open') {\n this.#connectPromise = undefined;\n this.#connected = true;\n this.#connectedAtSeconds = Math.floor(Date.now() / 1_000);\n this.#reconnectAttempt = 0;\n await this.#events.emit('connection', { state: 'connected' });\n return;\n }\n\n this.#connectPromise = undefined;\n this.#connected = false;\n const error = event.reason instanceof Error\n ? event.reason\n : event.reason\n ? new Error(String(event.reason))\n : undefined;\n\n if (this.#intentionalClose || event.isLogout) {\n await this.#events.emit('connection', {\n state: 'closed',\n ...(error ? { error } : {}),\n });\n return;\n }\n\n await this.#scheduleReconnect(error);\n }\n\n #startConnect(client: WaClient): void {\n const promise = client.connect();\n this.#connectPromise = promise;\n void promise.catch(async (error: unknown) => {\n if (this.#connectPromise !== promise) return;\n this.#connectPromise = undefined;\n\n if (this.#intentionalClose) return;\n\n const normalized = error instanceof Error ? error : new Error(String(error));\n this.#logger.warn('WhatsApp connection attempt failed.', { error: normalized });\n await this.#scheduleReconnect(normalized);\n });\n }\n\n async #scheduleReconnect(error?: Error): Promise<void> {\n if (this.#reconnectTimer) return;\n\n const options = this.#options.reconnect;\n const maxAttempts = options?.maxAttempts ?? 10;\n\n if (options?.enabled === false || this.#reconnectAttempt >= maxAttempts) {\n await this.#events.emit('connection', {\n state: 'closed',\n ...(error ? { error } : {}),\n });\n return;\n }\n\n this.#reconnectAttempt += 1;\n await this.#events.emit('connection', {\n state: 'reconnecting',\n attempt: this.#reconnectAttempt,\n ...(error ? { error } : {}),\n });\n\n const initial = options?.initialDelayMs ?? 1_000;\n const maximum = options?.maxDelayMs ?? 30_000;\n const delay = Math.min(maximum, initial * 2 ** (this.#reconnectAttempt - 1));\n this.#reconnectTimer = setTimeout(() => {\n this.#reconnectTimer = undefined;\n void this.connect();\n }, delay + Math.floor(Math.random() * 250));\n }\n\n async #sendButtons(\n chatId: string,\n content: ButtonsContent,\n replyTo?: MessageKey,\n ): Promise<SentMessage> {\n this.#validateButtons(content);\n const mentions = content.mentions ? this.#mentions(content.mentions) : [];\n const raw: Proto.IMessage = {\n interactiveMessage: {\n ...(content.title !== undefined\n ? {\n header: {\n title: content.title,\n hasMediaAttachment: false,\n },\n }\n : {}),\n body: { text: content.text },\n ...(content.footer !== undefined ? { footer: { text: content.footer } } : {}),\n ...(mentions.length > 0 ? { contextInfo: { mentionedJid: mentions } } : {}),\n nativeFlowMessage: {\n buttons: content.buttons.map((button) => {\n if (button.type === 'copy') {\n return {\n name: 'cta_copy',\n buttonParamsJson: JSON.stringify({\n display_text: button.label,\n copy_code: button.code,\n }),\n };\n }\n\n if (button.type === 'reply') {\n return {\n name: 'quick_reply',\n buttonParamsJson: JSON.stringify({\n display_text: button.label,\n id: button.id,\n }),\n };\n }\n\n return {\n name: 'cta_url',\n buttonParamsJson: JSON.stringify({\n display_text: button.label,\n url: button.url,\n merchant_url: button.url,\n }),\n };\n }),\n messageParamsJson: '{}',\n messageVersion: 1,\n },\n },\n };\n const result = await this.#requireClient().message.send(chatId, raw, {\n ...(replyTo ? { quote: this.#toZapoKey(replyTo) } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n });\n\n return this.#sent(result, chatId);\n }\n\n async #sendList(\n chatId: string,\n content: ListContent,\n replyTo?: MessageKey,\n ): Promise<SentMessage> {\n this.#validateList(content);\n const mentions = content.mentions ? this.#mentions(content.mentions) : [];\n const raw: Proto.IMessage = {\n interactiveMessage: {\n ...(content.title !== undefined\n ? {\n header: {\n title: content.title,\n hasMediaAttachment: false,\n },\n }\n : {}),\n body: { text: content.text },\n ...(content.footer !== undefined ? { footer: { text: content.footer } } : {}),\n ...(mentions.length > 0 ? { contextInfo: { mentionedJid: mentions } } : {}),\n nativeFlowMessage: {\n buttons: [\n {\n name: 'single_select',\n buttonParamsJson: JSON.stringify({\n title: content.buttonText,\n sections: content.list.map((section) => ({\n ...(section.title !== undefined ? { title: section.title } : {}),\n rows: section.rows.map((row) => ({\n id: row.id,\n title: row.title,\n ...(row.description !== undefined ? { description: row.description } : {}),\n })),\n })),\n }),\n },\n ],\n messageParamsJson: '{}',\n messageVersion: 1,\n },\n },\n };\n const result = await this.#requireClient().message.send(chatId, raw, {\n ...(replyTo ? { quote: this.#toZapoKey(replyTo) } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n });\n\n return this.#sent(result, chatId);\n }\n\n async #toContent(content: MessageContent): Promise<{\n value: unknown;\n mentions: string[];\n viewOnce?: boolean;\n }> {\n if ('text' in content) {\n return {\n value: { type: 'text', text: content.text },\n mentions: content.mentions ? this.#mentions(content.mentions) : [],\n };\n }\n\n if ('poll' in content) {\n return {\n value: this.#pollContent(content),\n mentions: [],\n };\n }\n\n if ('image' in content) {\n return {\n value: {\n type: 'image',\n media: await this.#media(content.image),\n ...(content.caption !== undefined ? { caption: content.caption } : {}),\n },\n mentions: content.mentions ? this.#mentions(content.mentions) : [],\n ...(content.viewOnce !== undefined ? { viewOnce: content.viewOnce } : {}),\n };\n }\n\n if ('video' in content) {\n return {\n value: {\n type: 'video',\n media: await this.#media(content.video),\n ...(content.caption !== undefined ? { caption: content.caption } : {}),\n ...(content.gif !== undefined ? { gifPlayback: content.gif } : {}),\n },\n mentions: content.mentions ? this.#mentions(content.mentions) : [],\n ...(content.viewOnce !== undefined ? { viewOnce: content.viewOnce } : {}),\n };\n }\n\n if ('sticker' in content) {\n return {\n value: {\n type: 'sticker',\n media: await this.#media(content.sticker),\n mimetype: 'image/webp',\n },\n mentions: [],\n };\n }\n\n return {\n value: {\n type: 'audio',\n media: await this.#media(content.audio),\n ...(content.mimetype ? { mimetype: content.mimetype } : {}),\n ...(content.voice !== undefined ? { ptt: content.voice } : {}),\n },\n mentions: [],\n };\n }\n\n #validateButtons(content: ButtonsContent): void {\n if (!content.text.trim() || content.buttons.length === 0) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Interactive buttons require body text and at least one button.',\n );\n }\n\n for (const button of content.buttons) {\n if (!button.label.trim()) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Interactive button labels cannot be empty.');\n }\n if (button.type === 'reply' && !button.id.trim()) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Reply button IDs cannot be empty.');\n }\n if (button.type === 'copy' && !button.code) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Copy buttons require a non-empty code.');\n }\n if (button.type === 'link' && !button.url.trim()) {\n throw new WhaNextError('ARGUMENT_INVALID', 'Link buttons require a non-empty URL.');\n }\n }\n }\n\n #validateList(content: ListContent): void {\n if (!content.text.trim() || !content.buttonText.trim() || content.list.length === 0) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'List menus require body text, button text and at least one section.',\n );\n }\n\n let rowCount = 0;\n const ids = new Set<string>();\n for (const section of content.list) {\n for (const row of section.rows) {\n rowCount += 1;\n const id = row.id.trim();\n if (!id || !row.title.trim()) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Every list row requires a non-empty id and title.',\n );\n }\n if (ids.has(id)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `Duplicate list row id \"${id}\".`,\n );\n }\n ids.add(id);\n }\n }\n\n if (rowCount === 0) {\n throw new WhaNextError('ARGUMENT_INVALID', 'List menus require at least one row.');\n }\n }\n\n #pollContent(content: PollContent): unknown {\n const name = content.poll.trim();\n const options = content.options.map((option) => option.trim()).filter(Boolean);\n const selectableCount = content.selectableCount ?? 1;\n\n if (!name || options.length < 2) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Polls require a question and at least two non-empty options.',\n );\n }\n\n if (!Number.isInteger(selectableCount) || selectableCount < 1 || selectableCount > options.length) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'selectableCount must be an integer between 1 and the number of poll options.',\n { context: { selectableCount, options: options.length } },\n );\n }\n\n return {\n type: 'poll',\n name,\n options,\n selectableCount,\n ...(content.allowAddOption !== undefined ? { allowAddOption: content.allowAddOption } : {}),\n };\n }\n\n async #media(source: MediaSource): Promise<string | Uint8Array> {\n if (source instanceof Uint8Array) return source;\n if ('path' in source) return source.path;\n\n const response = await fetch(source.url);\n\n if (!response.ok) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'Could not download the remote media source.',\n {\n context: { status: response.status },\n recoverable: response.status >= 500,\n },\n );\n }\n\n return new Uint8Array(await response.arrayBuffer());\n }\n\n #mentions(mentions: readonly MentionTarget[]): string[] {\n return mentions.map((mention) =>\n typeof mention === 'string' ? mention : mention.mentionId);\n }\n\n #toZapoKey(key: MessageKey): {\n id: string;\n remoteJid: string;\n fromMe: boolean;\n participant?: string;\n } {\n return {\n id: key.id,\n remoteJid: key.chatId,\n fromMe: key.fromMe,\n ...(key.participantId ? { participant: key.participantId } : {}),\n };\n }\n\n #sent(result: ZapoPublishResultLike, chatId: string): SentMessage {\n if (!result.id) {\n throw new WhaNextError(\n 'PROVIDER_ERROR',\n 'WhatsApp did not confirm the sent message.',\n );\n }\n\n return {\n id: result.id,\n chatId,\n keys: {\n id: result.id,\n chatId,\n fromMe: true,\n },\n timestamp: new Date(),\n };\n }\n\n\n #normalizeCall(event: ZapoCallEventLike): CallEvent | undefined {\n const id = event.callId;\n const creator = event.callCreatorJid ?? undefined;\n const from = event.callerPnJid ?? creator;\n const chatId = event.groupJid ?? from;\n\n if (!id || !from || !chatId) return undefined;\n\n if (creator) {\n this.#callCreatorStore.delete(id);\n this.#callCreatorStore.set(id, creator);\n while (this.#callCreatorStore.size > 256) {\n const oldest = this.#callCreatorStore.keys().next().value as string | undefined;\n if (!oldest) break;\n this.#callCreatorStore.delete(oldest);\n }\n }\n\n const timestampMs = toNumber(event.timestampMs);\n return {\n id,\n chatId,\n from,\n status: this.#callStatus(event.type),\n isVideo: event.isVideo === true,\n isGroup: Boolean(event.groupJid),\n date: timestampMs && timestampMs > 0 ? new Date(timestampMs) : new Date(),\n };\n }\n\n #callStatus(status: string | null | undefined): CallStatus {\n switch (status?.toLowerCase()) {\n case 'offer':\n return 'offer';\n case 'ringing':\n return 'ringing';\n case 'preaccept':\n return 'preaccept';\n case 'accept':\n return 'accept';\n case 'reject':\n case 'terminate':\n return 'reject';\n default:\n return 'timeout';\n }\n }\n\n #groupAction(action: string | null | undefined): GroupParticipantAction | undefined {\n const value = action?.toLowerCase() ?? '';\n if (value.includes('promote')) return 'promote';\n if (value.includes('demote')) return 'demote';\n if (value.includes('remove') || value.includes('leave')) return 'remove';\n if (value.includes('add') || value.includes('join')) return 'add';\n if (value.includes('participant') || value.includes('modify')) return 'modify';\n return undefined;\n }\n\n #groupParticipantIds(event: ZapoGroupEventLike): string[] {\n return uniqueIdentities((event.participants ?? []).map((participant) =>\n participant.jid ?? participant.lidJid ?? participant.phoneJid));\n }\n\n #findStoredMessage(key: ZapoMessageKeyLike): StoredZapoMessage | undefined {\n const direct = this.#messageStore.get(this.#messageStoreKey(key));\n if (direct) return direct;\n if (!key.id) return undefined;\n\n for (const message of this.#messageStore.values()) {\n if (message.key.id === key.id && message.message) return message;\n }\n\n for (const message of this.#messageStore.values()) {\n const embeddedQuoted = extractQuotedZapoMessage(message as WaIncomingMessageEvent);\n if (!embeddedQuoted?.key.id || embeddedQuoted.key.id !== key.id || !embeddedQuoted.message) {\n continue;\n }\n\n const storedQuoted = embeddedQuoted as unknown as StoredZapoMessage;\n this.#remember(storedQuoted);\n return storedQuoted;\n }\n\n return undefined;\n }\n\n #remember(message: StoredZapoMessage): void {\n if (!message.key.id || !message.message) return;\n\n const key = this.#messageStoreKey(message.key);\n this.#messageStore.delete(key);\n this.#messageStore.set(key, message);\n\n while (this.#messageStore.size > this.#messageCacheSize) {\n const oldest = this.#messageStore.keys().next().value as string | undefined;\n if (oldest) this.#messageStore.delete(oldest);\n }\n }\n\n #messageStoreKey(key: ZapoMessageKeyLike): string {\n return `${key.remoteJid ?? ''}:${key.id ?? ''}:${key.participant ?? key.participantAlt ?? ''}`;\n }\n\n #messageDeliveryKey(key: ZapoMessageKeyLike): string {\n return `${key.remoteJid ?? ''}:${key.id ?? ''}`;\n }\n\n #protocolDeliveryKey(\n event: ZapoProtocolEventLike,\n target: ZapoMessageKeyLike,\n type: number | null | undefined,\n ): string | undefined {\n if (type == null || !event.key.id || !target.id) return undefined;\n return `${type}:${event.key.remoteJid ?? target.remoteJid ?? ''}:${event.key.id}:${target.id}`;\n }\n\n #rememberHandledProtocol(key: string): void {\n this.#handledProtocolStore.delete(key);\n this.#handledProtocolStore.add(key);\n\n while (this.#handledProtocolStore.size > this.#messageCacheSize) {\n const oldest = this.#handledProtocolStore.values().next().value as string | undefined;\n if (oldest) this.#handledProtocolStore.delete(oldest);\n }\n }\n\n #rememberDeliveredMessage(key: string): void {\n this.#deliveredMessageStore.delete(key);\n this.#deliveredMessageStore.add(key);\n\n while (this.#deliveredMessageStore.size > this.#messageCacheSize) {\n const oldest = this.#deliveredMessageStore.values().next().value as string | undefined;\n if (oldest) this.#deliveredMessageStore.delete(oldest);\n }\n }\n\n #isOfflineMessage(message: StoredZapoMessage): boolean {\n if (this.#options.processOfflineMessages === true) return false;\n if (message.offline === true) return true;\n\n if (!this.#connected) return true;\n\n if (!this.#connectedAtSeconds || message.timestampSeconds == null) return false;\n const timestamp = toSeconds(message.timestampSeconds);\n if (timestamp === undefined) return false;\n\n return timestamp < this.#connectedAtSeconds - 3;\n }\n\n #markPairingReady(): void {\n this.#pairingRequired = true;\n this.#resolvePairingReady?.();\n this.#resolvePairingReady = undefined;\n }\n\n #preparePairingGate(): void {\n this.#pairingRequired = false;\n this.#pairingReady = new Promise<void>((resolve) => {\n this.#resolvePairingReady = resolve;\n });\n }\n\n #deviceBrowser(): string {\n return this.#options.browser === Browser.MacOS ? 'safari' : 'chrome';\n }\n\n #deviceOsDisplayName(): string {\n if (this.#options.browser === Browser.MacOS) return 'macOS';\n if (this.#options.browser === Browser.Ubuntu) return 'Ubuntu';\n return 'Windows';\n }\n\n #requireClient(): WaClient {\n const client = this.#client;\n\n if (!client || !this.#connected) {\n throw new WhaNextError(\n 'CONNECTION_CLOSED',\n 'WhatsApp is not connected.',\n { recoverable: true },\n );\n }\n\n return client;\n }\n\n async #withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message: string,\n ): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n reject(new WhaNextError(\n 'CONNECTION_FAILED',\n message,\n { recoverable: true },\n ));\n }, timeoutMs);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n}\n\n\nclass WhaNextZapoLogger implements ZapoLogger {\n readonly level: ZapoLogLevel;\n readonly #logger: Logger;\n readonly #context: Readonly<Record<string, unknown>>;\n\n constructor(\n logger: Logger,\n context: Readonly<Record<string, unknown>> = {},\n ) {\n this.#logger = logger;\n this.#context = context;\n this.level = logger.level === 'debug'\n ? 'debug'\n : logger.level === 'warn'\n ? 'warn'\n : logger.level === 'error' || logger.level === 'silent'\n ? 'error'\n : 'info';\n }\n\n trace(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.debug(message, this.#merge(context));\n }\n\n debug(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.debug(message, this.#merge(context));\n }\n\n info(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.info(message, this.#merge(context));\n }\n\n warn(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.warn(message, this.#merge(context));\n }\n\n error(message: string, context?: Readonly<Record<string, unknown>>): void {\n this.#logger.error(message, this.#merge(context));\n }\n\n child(bindings: Readonly<Record<string, unknown>>): ZapoLogger {\n return new WhaNextZapoLogger(this.#logger, {\n ...this.#context,\n ...bindings,\n });\n }\n\n #merge(\n context?: Readonly<Record<string, unknown>>,\n ): Readonly<Record<string, unknown>> {\n return context\n ? { ...this.#context, ...context }\n : this.#context;\n }\n}\n\nfunction toNumber(value: number | LongLike | null | undefined): number | undefined {\n if (typeof value === 'number') return value;\n if (value?.toNumber) return value.toNumber();\n if (typeof value?.low === 'number') return value.low;\n return undefined;\n}\n\nfunction toSeconds(value: number | LongLike | null | undefined): number | undefined {\n const raw = typeof value === 'number'\n ? value\n : value?.toNumber\n ? value.toNumber()\n : value?.low;\n\n if (raw === undefined) return undefined;\n return raw > 10_000_000_000 ? Math.floor(raw / 1_000) : raw;\n}\n","import type { Proto, WaIncomingMessageEvent } from 'zapo-js';\nimport { uniqueIdentities } from '@/models/identity.js';\nimport type {\n InteractiveResponse,\n MediaKind,\n Message,\n MessageContentKind,\n MessageKey,\n MessageMedia,\n QuotedMessage,\n} from '@/models/message.js';\nimport { User } from '@/models/user.js';\n\nexport interface ZapoMessageKeyLike {\n remoteJid?: string | null;\n remoteJidAlt?: string | null;\n id?: string | null;\n fromMe?: boolean | null;\n participant?: string | null;\n participantAlt?: string | null;\n senderUsername?: string | null;\n}\n\ninterface EventLike {\n key: ZapoMessageKeyLike;\n message?: Proto.IMessage | null;\n timestampSeconds?: number | null;\n pushName?: string | null;\n}\n\ninterface ContextInfoLike {\n stanzaId?: string | null;\n remoteJid?: string | null;\n participant?: string | null;\n quotedMessage?: Proto.IMessage | null;\n mentionedJid?: string[] | null;\n}\n\ninterface LongLike {\n toNumber?: () => number;\n low?: number;\n}\n\nexport function unwrapZapoMessageContent(\n input: Proto.IMessage | null | undefined,\n): Proto.IMessage | undefined {\n if (!input) return undefined;\n\n const nested = input.ephemeralMessage?.message\n ?? input.viewOnceMessage?.message\n ?? input.viewOnceMessageV2?.message\n ?? viewOnceV2ExtensionMessage(input)\n ?? input.deviceSentMessage?.message\n ?? input.documentWithCaptionMessage?.message;\n\n return nested ? unwrapZapoMessageContent(nested) : input;\n}\n\nfunction viewOnceV2ExtensionMessage(\n input: Proto.IMessage,\n): Proto.IMessage | undefined {\n const extension = (input as Proto.IMessage & {\n viewOnceMessageV2Extension?: {\n message?: Proto.IMessage | null;\n } | null;\n }).viewOnceMessageV2Extension;\n\n return extension?.message ?? undefined;\n}\n\nexport function isZapoViewOnceContent(\n input: Proto.IMessage | null | undefined,\n): boolean {\n if (!input) return false;\n\n if (\n input.viewOnceMessage?.message\n || input.viewOnceMessageV2?.message\n || viewOnceV2ExtensionMessage(input)\n ) {\n return true;\n }\n\n return isZapoViewOnceContent(input.ephemeralMessage?.message);\n}\n\nexport function extractQuotedZapoMessage(\n input: WaIncomingMessageEvent | EventLike,\n): WaIncomingMessageEvent | undefined {\n const event = input as EventLike;\n const chatId = event.key.remoteJid;\n const content = unwrapZapoMessageContent(event.message);\n\n if (!chatId || !content) return undefined;\n\n const { node } = contentNode(content);\n const context = getContextInfo(node);\n\n if (!context?.stanzaId || !context.quotedMessage) return undefined;\n\n return {\n key: {\n id: context.stanzaId,\n remoteJid: context.remoteJid ?? chatId,\n fromMe: false,\n ...(context.participant ? { participant: context.participant } : {}),\n },\n message: context.quotedMessage,\n } as WaIncomingMessageEvent;\n}\n\nexport function normalizeZapoMessage(\n input: WaIncomingMessageEvent | EventLike,\n): Message | undefined {\n const event = input as EventLike;\n const chatId = event.key.remoteJid;\n const id = event.key.id;\n\n if (!chatId || !id || !event.message) {\n return undefined;\n }\n\n const content = unwrapZapoMessageContent(event.message);\n\n if (!content) {\n return undefined;\n }\n\n const { type, node } = contentNode(content);\n const context = getContextInfo(node);\n const isPrivateIncoming = !chatId.endsWith('@g.us') && event.key.fromMe !== true;\n const senderIds = uniqueIdentities([\n event.key.participant,\n event.key.participantAlt,\n event.key.senderUsername?.includes('@')\n ? event.key.senderUsername\n : undefined,\n isPrivateIncoming ? event.key.remoteJidAlt : undefined,\n isPrivateIncoming ? chatId : undefined,\n ]);\n const senderJid = senderIds.find((identity) =>\n identity.endsWith('@s.whatsapp.net') || identity.endsWith('@c.us'));\n const senderLid = senderIds.find((identity) => identity.endsWith('@lid'));\n const senderId = senderJid ?? senderLid ?? senderIds[0] ?? chatId;\n const sender = new User({\n id: senderId,\n identities: senderIds.length > 0 ? senderIds : [senderId],\n ...(event.pushName ? { name: event.pushName } : {}),\n });\n const mentionedIds = [...(context?.mentionedJid ?? [])];\n const mentionedUsers = mentionedIds.map((identity) => User.fromIdentities([identity]));\n const viewOnce = isZapoViewOnceContent(event.message);\n const media = getMedia(type, node, viewOnce);\n const contentKind = getContentKind(type);\n const text = getText(content);\n const caption = getCaption(content);\n const quoted = getQuoted(context, chatId);\n const interactive = getInteractiveResponse(content);\n\n const message: Message = {\n id,\n jid: chatId,\n chatId,\n senderId,\n senderIds: senderIds.length > 0 ? senderIds : [senderId],\n sender,\n keys: normalizeZapoKey(event.key),\n mentions: mentionedIds,\n mentionedUsers,\n timestamp: toDate(event.timestampSeconds),\n isGroup: chatId.endsWith('@g.us'),\n isReply: quoted !== undefined,\n isViewOnce: media?.viewOnce ?? false,\n hasMedia: media !== undefined,\n contentKind,\n };\n\n if (senderJid !== undefined) message.senderJid = senderJid;\n if (senderLid !== undefined) {\n message.lid = senderLid;\n message.senderLid = senderLid;\n }\n if (text !== undefined) message.text = text;\n if (caption !== undefined) message.caption = caption;\n if (media !== undefined) message.media = media;\n if (quoted !== undefined) message.quoted = quoted;\n if (interactive !== undefined) message.interactive = interactive;\n\n return message;\n}\n\nexport function normalizeZapoKey(key: ZapoMessageKeyLike): MessageKey {\n const normalized: MessageKey = {\n id: key.id ?? '',\n chatId: key.remoteJid ?? '',\n fromMe: key.fromMe ?? false,\n };\n const participantId = key.participant ?? key.participantAlt;\n\n if (participantId !== null && participantId !== undefined) {\n normalized.participantId = participantId;\n }\n\n return normalized;\n}\n\nfunction contentNode(content: Proto.IMessage): {\n type: keyof Proto.IMessage | undefined;\n node: unknown;\n} {\n const order: Array<keyof Proto.IMessage> = [\n 'conversation',\n 'extendedTextMessage',\n 'imageMessage',\n 'videoMessage',\n 'audioMessage',\n 'documentMessage',\n 'stickerMessage',\n 'locationMessage',\n 'liveLocationMessage',\n 'contactMessage',\n 'contactsArrayMessage',\n 'buttonsResponseMessage',\n 'listResponseMessage',\n 'templateButtonReplyMessage',\n 'pollCreationMessage',\n 'pollCreationMessageV2',\n 'pollCreationMessageV3',\n 'pollCreationMessageV5',\n 'productMessage',\n 'orderMessage',\n 'interactiveResponseMessage',\n ];\n\n const type = order.find((key) => content[key] !== null && content[key] !== undefined);\n return { type, node: type ? content[type] : undefined };\n}\n\nfunction getContentKind(type: keyof Proto.IMessage | undefined): MessageContentKind {\n switch (String(type ?? '')) {\n case 'conversation':\n case 'extendedTextMessage':\n case 'buttonsResponseMessage':\n case 'listResponseMessage':\n case 'templateButtonReplyMessage':\n case 'interactiveResponseMessage':\n return 'text';\n case 'imageMessage':\n return 'image';\n case 'videoMessage':\n return 'video';\n case 'audioMessage':\n return 'audio';\n case 'documentMessage':\n return 'document';\n case 'stickerMessage':\n return 'sticker';\n case 'locationMessage':\n case 'liveLocationMessage':\n return 'location';\n case 'contactMessage':\n case 'contactsArrayMessage':\n return 'contact';\n case 'pollCreationMessage':\n case 'pollCreationMessageV2':\n case 'pollCreationMessageV3':\n case 'pollCreationMessageV5':\n return 'poll';\n case 'productMessage':\n case 'orderMessage':\n return 'catalog';\n default:\n return 'unknown';\n }\n}\n\nfunction getText(content: Proto.IMessage): string | undefined {\n return content.conversation\n ?? content.extendedTextMessage?.text\n ?? content.buttonsResponseMessage?.selectedDisplayText\n ?? content.listResponseMessage?.title\n ?? content.templateButtonReplyMessage?.selectedDisplayText\n ?? content.pollCreationMessage?.name\n ?? content.pollCreationMessageV2?.name\n ?? content.pollCreationMessageV3?.name\n ?? content.pollCreationMessageV5?.name\n ?? getNativeFlowDisplayText(content)\n ?? undefined;\n}\n\nfunction getInteractiveResponse(content: Proto.IMessage): InteractiveResponse | undefined {\n const buttons = content.buttonsResponseMessage as {\n selectedButtonId?: string | null;\n selectedDisplayText?: string | null;\n } | null | undefined;\n if (buttons?.selectedButtonId) {\n return {\n kind: 'button',\n id: buttons.selectedButtonId,\n ...(buttons.selectedDisplayText ? { title: buttons.selectedDisplayText } : {}),\n };\n }\n\n const template = content.templateButtonReplyMessage as {\n selectedId?: string | null;\n selectedDisplayText?: string | null;\n } | null | undefined;\n if (template?.selectedId) {\n return {\n kind: 'button',\n id: template.selectedId,\n ...(template.selectedDisplayText ? { title: template.selectedDisplayText } : {}),\n };\n }\n\n const list = content.listResponseMessage as {\n title?: string | null;\n singleSelectReply?: { selectedRowId?: string | null } | null;\n } | null | undefined;\n const rowId = list?.singleSelectReply?.selectedRowId;\n if (rowId) {\n return {\n kind: 'list',\n id: rowId,\n ...(list?.title ? { title: list.title } : {}),\n };\n }\n\n const native = nativeFlowParams(content);\n const nativeId = stringField(native, ['id', 'selected_id', 'row_id', 'button_id']);\n if (nativeId) {\n const title = stringField(native, ['display_text', 'title']);\n const nativeName = nativeFlowName(content);\n return {\n kind: nativeName === 'single_select'\n || (native && ('row_id' in native || 'selected_id' in native))\n ? 'list'\n : 'button',\n id: nativeId,\n ...(title ? { title } : {}),\n };\n }\n\n return undefined;\n}\n\n\nfunction nativeFlowName(content: Proto.IMessage): string | undefined {\n const response = content.interactiveResponseMessage as {\n nativeFlowResponseMessage?: {\n name?: string | null;\n } | null;\n } | null | undefined;\n return response?.nativeFlowResponseMessage?.name ?? undefined;\n}\n\nfunction getNativeFlowDisplayText(content: Proto.IMessage): string | undefined {\n return stringField(nativeFlowParams(content), ['display_text', 'title']);\n}\n\nfunction nativeFlowParams(content: Proto.IMessage): Record<string, unknown> | undefined {\n const response = content.interactiveResponseMessage as {\n nativeFlowResponseMessage?: {\n name?: string | null;\n paramsJson?: string | null;\n } | null;\n } | null | undefined;\n const json = response?.nativeFlowResponseMessage?.paramsJson;\n if (!json) return undefined;\n\n try {\n const parsed = JSON.parse(json) as unknown;\n return typeof parsed === 'object' && parsed !== null\n ? parsed as Record<string, unknown>\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction stringField(\n value: Record<string, unknown> | undefined,\n keys: readonly string[],\n): string | undefined {\n if (!value) return undefined;\n for (const key of keys) {\n const field = value[key];\n if (typeof field === 'string' && field.length > 0) return field;\n }\n return undefined;\n}\n\nfunction getCaption(content: Proto.IMessage): string | undefined {\n return content.imageMessage?.caption\n ?? content.videoMessage?.caption\n ?? content.documentMessage?.caption\n ?? undefined;\n}\n\nfunction getContextInfo(node: unknown): ContextInfoLike | undefined {\n if (typeof node !== 'object' || node === null || !('contextInfo' in node)) {\n return undefined;\n }\n\n return (node as { contextInfo?: ContextInfoLike | null }).contextInfo ?? undefined;\n}\n\nfunction getMedia(\n type: keyof Proto.IMessage | undefined,\n node: unknown,\n wrapperViewOnce: boolean,\n): MessageMedia | undefined {\n const mapping: Partial<Record<keyof Proto.IMessage, MediaKind>> = {\n imageMessage: 'image',\n videoMessage: 'video',\n audioMessage: 'audio',\n documentMessage: 'document',\n stickerMessage: 'sticker',\n };\n const kind = type ? mapping[type] : undefined;\n\n if (!kind || typeof node !== 'object' || node === null) {\n return undefined;\n }\n\n const value = node as {\n mimetype?: string | null;\n fileName?: string | null;\n seconds?: number | LongLike | null;\n viewOnce?: boolean | null;\n };\n const media: MessageMedia = {\n kind,\n viewOnce: wrapperViewOnce || value.viewOnce === true,\n };\n\n if (value.mimetype) media.mimetype = value.mimetype;\n if (value.fileName) media.fileName = value.fileName;\n\n const seconds = toNumber(value.seconds);\n if (seconds !== undefined) media.seconds = seconds;\n\n return media;\n}\n\nfunction getQuoted(\n context: ContextInfoLike | undefined,\n chatId: string,\n): QuotedMessage | undefined {\n if (!context?.stanzaId || !context.quotedMessage) return undefined;\n\n const content = unwrapZapoMessageContent(context.quotedMessage);\n if (!content) return undefined;\n\n const { type, node } = contentNode(content);\n const media = getMedia(type, node, isZapoViewOnceContent(context.quotedMessage));\n const senderId = context.participant ?? undefined;\n const quoted: QuotedMessage = {\n key: {\n id: context.stanzaId,\n chatId: context.remoteJid ?? chatId,\n fromMe: false,\n ...(senderId ? { participantId: senderId } : {}),\n },\n hasMedia: media !== undefined,\n isViewOnce: media?.viewOnce ?? false,\n contentKind: getContentKind(type),\n };\n const text = getText(content) ?? getCaption(content);\n\n if (text !== undefined) quoted.text = text;\n if (senderId !== undefined) {\n quoted.senderId = senderId;\n quoted.sender = User.fromIdentities([senderId]);\n }\n if (media !== undefined) quoted.media = media;\n\n return quoted;\n}\n\nfunction toDate(value: number | LongLike | null | undefined): Date {\n const seconds = toNumber(value) ?? Math.floor(Date.now() / 1000);\n return new Date(seconds * 1_000);\n}\n\nfunction toNumber(value: number | LongLike | null | undefined): number | undefined {\n if (typeof value === 'number') return value;\n if (value?.toNumber) return value.toNumber();\n if (typeof value?.low === 'number') return value.low;\n return undefined;\n}\n","import { WhaNextApp } from '@/app/whanext-app.js';\nimport { Browser } from '@/auth/browser.js';\nimport type { CacheOptions } from '@/cache/cache-store.js';\nimport type { RouterOptions } from '@/commands/router.js';\nimport {\n Logger,\n type LoggerConfig,\n} from '@/logger/logger.js';\nimport type { MuteOptions } from '@/mute/mute-store.js';\nimport { ZapoProvider } from '@/provider/zapo/zapo-provider.js';\nimport type { WhatsAppProvider } from '@/provider/provider.js';\n\nexport interface ReconnectOptions {\n enabled?: boolean;\n maxAttempts?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n}\n\nexport interface CreateOptions {\n phone?: string;\n browser?: Browser;\n auth?: string;\n prefix?: string | readonly string[];\n cache?: CacheOptions;\n logger?: LoggerConfig;\n mute?: MuteOptions;\n router?: Omit<RouterOptions, 'prefix'>;\n reconnect?: ReconnectOptions;\n messageCacheSize?: number;\n processOfflineMessages?: boolean;\n provider?: WhatsAppProvider;\n accountId?: string;\n}\n\nexport async function create(options: CreateOptions = {}): Promise<WhaNextApp> {\n const logger = new Logger(options.logger);\n const provider = options.provider ?? new ZapoProvider({\n auth: options.auth ?? './session',\n browser: options.browser ?? Browser.Windows,\n logger: logger.child('provider'),\n ...(options.accountId ? { sessionId: options.accountId } : {}),\n ...(options.messageCacheSize !== undefined\n ? { messageCacheSize: options.messageCacheSize }\n : {}),\n ...(options.processOfflineMessages !== undefined\n ? { processOfflineMessages: options.processOfflineMessages }\n : {}),\n ...(options.reconnect ? { reconnect: options.reconnect } : {}),\n });\n\n return new WhaNextApp(provider, {\n ...(options.accountId ? { accountId: options.accountId } : {}),\n ...(options.phone ? { phone: options.phone } : {}),\n ...(options.prefix !== undefined ? { prefix: options.prefix } : {}),\n ...(options.cache ? { cache: options.cache } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n ...(options.mute ? { mute: options.mute } : {}),\n ...(options.router ? { router: options.router } : {}),\n }, logger);\n}\n","import {\n join,\n resolve,\n} from 'node:path';\nimport {\n create,\n type CreateOptions,\n} from '@/app/create.js';\nimport {\n type AppEvents,\n type AppHealth,\n type LoginOptions,\n WhaNextApp,\n} from '@/app/whanext-app.js';\nimport type {\n CommandDefinition,\n CommandMiddleware,\n} from '@/commands/command.js';\nimport type {\n CommandErrorHandler,\n} from '@/commands/router.js';\nimport type {\n LoadCommandsOptions,\n LoadCommandsResult,\n} from '@/commands/load-commands.js';\nimport { WhaNextError } from '@/errors/error.js';\n\nexport interface MultiAccountOptions extends Omit<CreateOptions, 'accountId'> {\n id: string;\n}\n\nexport interface CreateMultiOptions extends Omit<CreateOptions, 'accountId' | 'auth' | 'phone' | 'provider'> {\n accounts: readonly MultiAccountOptions[];\n authRoot?: string;\n}\n\nexport interface MultiLoginOptions extends Omit<LoginOptions, 'onCode'> {\n onCode?: (accountId: string, code: string) => void | Promise<void>;\n}\n\nexport interface MultiAppHealth extends AppHealth {\n accountId: string;\n}\n\nexport interface MultiAppEvent<Event extends keyof AppEvents> {\n accountId: string;\n app: WhaNextApp;\n payload: AppEvents[Event];\n}\n\nexport interface MultiLoadCommandsResult {\n accountId: string;\n result: LoadCommandsResult;\n}\n\nexport class MultiCommandRouter {\n readonly #apps: ReadonlyMap<string, WhaNextApp>;\n\n constructor(apps: ReadonlyMap<string, WhaNextApp>) {\n this.#apps = apps;\n }\n\n command(definition: CommandDefinition): this {\n for (const app of this.#apps.values()) {\n app.commands.command(definition);\n }\n return this;\n }\n\n use(middleware: CommandMiddleware): this {\n for (const app of this.#apps.values()) {\n app.commands.use(middleware);\n }\n return this;\n }\n\n onError(handler: CommandErrorHandler): () => void {\n const unsubscribe = [...this.#apps.values()].map((app) => app.commands.onError(handler));\n return () => {\n for (const remove of unsubscribe) remove();\n };\n }\n\n async load(\n dirPath: string | URL,\n options: LoadCommandsOptions = {},\n ): Promise<readonly MultiLoadCommandsResult[]> {\n return Promise.all([...this.#apps].map(async ([accountId, app]) => ({\n accountId,\n result: await app.commands.load(dirPath, options),\n })));\n }\n}\n\nexport class WhaNextMultiApp {\n readonly commands: MultiCommandRouter;\n readonly #apps: ReadonlyMap<string, WhaNextApp>;\n\n constructor(apps: ReadonlyMap<string, WhaNextApp>) {\n this.#apps = apps;\n this.commands = new MultiCommandRouter(apps);\n }\n\n get size(): number {\n return this.#apps.size;\n }\n\n get isReady(): boolean {\n return this.#apps.size > 0 && [...this.#apps.values()].every((app) => app.isReady);\n }\n\n ids(): readonly string[] {\n return [...this.#apps.keys()];\n }\n\n has(accountId: string): boolean {\n return this.#apps.has(accountId);\n }\n\n get(accountId: string): WhaNextApp | undefined {\n return this.#apps.get(accountId);\n }\n\n values(): readonly WhaNextApp[] {\n return [...this.#apps.values()];\n }\n\n router(): MultiCommandRouter {\n return this.commands;\n }\n\n on<Event extends keyof AppEvents>(\n event: Event,\n listener: (entry: MultiAppEvent<Event>) => void | Promise<void>,\n ): () => void {\n const unsubscribe = [...this.#apps].map(([accountId, app]) =>\n app.on(event, (payload) => listener({ accountId, app, payload })));\n\n return () => {\n for (const remove of unsubscribe) remove();\n };\n }\n\n health(): readonly MultiAppHealth[] {\n return [...this.#apps].map(([accountId, app]) => ({\n accountId,\n ...app.health(),\n }));\n }\n\n async login(options: MultiLoginOptions = {}): Promise<void> {\n const results = await Promise.allSettled(\n [...this.#apps].map(async ([accountId, app]) => {\n await app.login({\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n ...(options.onCode\n ? { onCode: (code: string) => options.onCode?.(accountId, code) }\n : {}),\n });\n }),\n );\n const failures = results\n .map((result, index) => ({ result, accountId: this.ids()[index] }))\n .filter((entry): entry is {\n result: PromiseRejectedResult;\n accountId: string;\n } => entry.result.status === 'rejected' && entry.accountId !== undefined);\n\n if (failures.length === 0) {\n return;\n }\n\n throw new WhaNextError(\n 'CONNECTION_FAILED',\n 'One or more WhatsApp accounts could not complete login.',\n {\n cause: new AggregateError(\n failures.map(({ result }) => result.reason),\n 'Multi-account login failed.',\n ),\n context: {\n accounts: failures.map(({ accountId }) => accountId),\n },\n recoverable: true,\n },\n );\n }\n\n async disconnect(): Promise<void> {\n const results = await Promise.allSettled(\n [...this.#apps.values()].map((app) => app.disconnect()),\n );\n const failures = results.filter((result): result is PromiseRejectedResult =>\n result.status === 'rejected');\n\n if (failures.length > 0) {\n throw new WhaNextError(\n 'CONNECTION_FAILED',\n 'One or more WhatsApp accounts could not disconnect cleanly.',\n {\n cause: new AggregateError(\n failures.map((result) => result.reason),\n 'Multi-account disconnect failed.',\n ),\n recoverable: true,\n },\n );\n }\n }\n}\n\nexport async function createMulti(options: CreateMultiOptions): Promise<WhaNextMultiApp> {\n if (options.accounts.length === 0) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'At least one WhatsApp account is required.',\n );\n }\n\n const {\n accounts,\n authRoot = './sessions',\n ...shared\n } = options;\n const normalizedIds = new Set<string>();\n const authPaths = new Set<string>();\n\n for (const account of accounts) {\n validateAccountId(account.id);\n const normalizedId = account.id.toLowerCase();\n\n if (normalizedIds.has(normalizedId)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n `The multi-account id \"${account.id}\" is duplicated.`,\n );\n }\n\n normalizedIds.add(normalizedId);\n\n if (account.provider === undefined) {\n const authPath = resolve(account.auth ?? join(authRoot, account.id));\n\n if (authPaths.has(authPath)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Each WhatsApp account must use a different auth directory.',\n { context: { auth: authPath } },\n );\n }\n\n authPaths.add(authPath);\n }\n }\n\n const apps = new Map<string, WhaNextApp>();\n\n for (const account of accounts) {\n const {\n id,\n ...overrides\n } = account;\n const merged = mergeCreateOptions(shared, overrides);\n\n if (\n merged.mute?.enabled === true\n && merged.mute.store === undefined\n && merged.mute.database === undefined\n ) {\n merged.mute = {\n ...merged.mute,\n database: join('./data', `whanext-${id}.sqlite`),\n };\n }\n\n const app = await create({\n ...merged,\n accountId: id,\n auth: overrides.auth ?? join(authRoot, id),\n });\n apps.set(id, app);\n }\n\n return new WhaNextMultiApp(apps);\n}\n\nfunction validateAccountId(accountId: string): void {\n if (!/^[a-z0-9][a-z0-9_-]{0,63}$/.test(accountId)) {\n throw new WhaNextError(\n 'ARGUMENT_INVALID',\n 'Multi-account ids must use lowercase letters, numbers, underscores or hyphens.',\n { context: { accountId } },\n );\n }\n}\n\nfunction mergeCreateOptions(\n shared: Omit<CreateMultiOptions, 'accounts' | 'authRoot'>,\n account: Omit<MultiAccountOptions, 'id'>,\n): CreateOptions {\n const merged: CreateOptions = {\n ...shared,\n ...account,\n };\n\n if (shared.cache || account.cache) {\n merged.cache = {\n ...shared.cache,\n ...account.cache,\n };\n }\n\n if (shared.mute || account.mute) {\n merged.mute = {\n ...shared.mute,\n ...account.mute,\n };\n }\n\n if (shared.router || account.router) {\n merged.router = {\n ...shared.router,\n ...account.router,\n };\n }\n\n if (shared.reconnect || account.reconnect) {\n merged.reconnect = {\n ...shared.reconnect,\n ...account.reconnect,\n };\n }\n\n if (\n shared.logger\n && account.logger\n && typeof shared.logger === 'object'\n && typeof account.logger === 'object'\n ) {\n merged.logger = {\n ...shared.logger,\n ...account.logger,\n };\n }\n\n return merged;\n}\n","import type { CommandContext } from '@/commands/context.js';\nimport type { WhaNextErrorCode } from '@/errors/error.js';\n\nexport interface GuardResult {\n allowed: boolean;\n code?: WhaNextErrorCode;\n message?: string;\n}\n\nexport type CommandGuard = (\n context: CommandContext,\n) => boolean | void | GuardResult | Promise<boolean | void | GuardResult>;\n\nexport const guards = {\n owner(): CommandGuard {\n return (context) => context.isOwner || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'This command can only be used by the connected WhatsApp account.',\n });\n },\n\n group(): CommandGuard {\n return (context) => context.isGroup || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'This command can only be used in groups.',\n });\n },\n\n private(): CommandGuard {\n return (context) => !context.isGroup || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'This command can only be used in private chats.',\n });\n },\n\n userAdmin(): CommandGuard {\n return async (context) => (\n context.isGroup\n && await context.groups.isAdmin(context.chatId, context.senderIds)\n ) || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'This command can only be used by group administrators.',\n });\n },\n\n botAdmin(): CommandGuard {\n return async (context) => (\n context.isGroup\n && await context.groups.isCurrentUserAdmin(context.chatId)\n ) || ({\n allowed: false,\n code: 'BOT_NOT_ADMIN',\n message: 'The connected WhatsApp account must be a group administrator.',\n });\n },\n\n botEnabled(\n check: (context: CommandContext) => boolean | Promise<boolean>,\n ): CommandGuard {\n return async (context) => await check(context) || ({\n allowed: false,\n code: 'COMMAND_NOT_ALLOWED',\n message: 'Commands are disabled in this chat.',\n });\n },\n\n custom(guard: CommandGuard): CommandGuard {\n return guard;\n },\n};\n"],"mappings":"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","names":["controller","resolve","path","context","option","path","require","resolve","Browser","edited","previous","option","toNumber","resolve","join","resolve","resolve","join"]}
|