@baseportal/chat-widget 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/index.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/platform.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/util/logger.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/util/utils.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/types/errorinfo.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/package.json","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/util/defaults.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/util/multicaster.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/constants/HttpMethods.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/constants/HttpStatusCodes.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/auth.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/types/http.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/baseclient.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/types/devicedetails.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/resource.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/paginatedresource.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/types/pushchannelsubscription.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/push.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/types/message.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/types/presencemessage.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/restpresence.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/restchannel.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/types/stats.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/restchannelmixin.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/restpresencemixin.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/rest.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/baserest.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/modularplugins.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/types/defaultmessage.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/types/defaultpresencemessage.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/defaultrest.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/util/eventemitter.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/types/protocolmessage.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/transport/messagequeue.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/transport/protocol.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/connectionstatechange.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/transport/connectionerrors.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/transport/transport.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/constants/TransportName.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/transport/connectionmanager.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/connection.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/channelstatechange.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/realtimechannel.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/baserealtime.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/presencemap.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/realtimepresence.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/transport/websockettransport.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/filteredsubscriptions.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/client/defaultrealtime.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/util/hmac-sha256.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/util/bufferutils.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/util/crypto.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/constants/XHRStates.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/http/http.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/util/webstorage.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/config.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/common/lib/transport/comettransport.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/http/request/xhrrequest.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/transport/xhrpollingtransport.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/transport/index.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/util/defaults.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/util/msgpack.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/http/request/fetchrequest.ts","../node_modules/.pnpm/ably@2.6.0/node_modules/ably/src/platform/web/lib/http/request/index.ts","../src/index.ts","../src/api/client.ts","../src/realtime/ably-client.ts","../src/ui/i18n.ts","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/constants.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/util.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/options.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/create-element.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/component.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/diff/props.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/create-context.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/diff/children.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/diff/index.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/render.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/clone-element.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/diff/catch-error.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/hooks/src/index.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/jsx-runtime/src/utils.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/src/constants.js","../node_modules/.pnpm/preact@10.25.0/node_modules/preact/jsx-runtime/src/index.js","../src/ui/icons.tsx","../src/ui/components/ChatBubble.tsx","../src/ui/components/ConversationList.tsx","../src/ui/components/MessageInput.tsx","../src/ui/components/ImageLightbox.tsx","../src/ui/components/MessageMedia.tsx","../src/ui/components/MessageList.tsx","../src/ui/components/PreChatForm.tsx","../src/ui/components/ChatWindow.tsx","../src/ui/App.tsx","../src/ui/styles/widget-css.ts","../src/ui/mount.ts","../src/utils/events.ts","../src/utils/storage.ts","../src/widget.ts"],"sourcesContent":["// Common\r\nimport { DefaultRest } from '../../common/lib/client/defaultrest';\r\nimport { DefaultRealtime } from '../../common/lib/client/defaultrealtime';\r\nimport Platform from '../../common/platform';\r\nimport ErrorInfo from '../../common/lib/types/errorinfo';\r\nimport { fromDeserializedIncludingDependencies as protocolMessageFromDeserialized } from '../../common/lib/types/protocolmessage';\r\n\r\n// Platform Specific\r\nimport BufferUtils from './lib/util/bufferutils';\r\n// @ts-ignore\r\nimport { createCryptoClass } from './lib/util/crypto';\r\nimport Http from './lib/http/http';\r\nimport Config from './config';\r\n// @ts-ignore\r\nimport Transports from './lib/transport';\r\nimport Logger from '../../common/lib/util/logger';\r\nimport { getDefaults } from '../../common/lib/util/defaults';\r\nimport WebStorage from './lib/util/webstorage';\r\nimport PlatformDefaults from './lib/util/defaults';\r\nimport msgpack from './lib/util/msgpack';\r\nimport { defaultBundledRequestImplementations } from './lib/http/request';\r\n\r\nconst Crypto = createCryptoClass(Config, BufferUtils);\r\n\r\nPlatform.Crypto = Crypto;\r\nPlatform.BufferUtils = BufferUtils;\r\nPlatform.Http = Http;\r\nPlatform.Config = Config;\r\nPlatform.Transports = Transports;\r\nPlatform.WebStorage = WebStorage;\r\n\r\nfor (const clientClass of [DefaultRest, DefaultRealtime]) {\r\n clientClass.Crypto = Crypto;\r\n clientClass._MsgPack = msgpack;\r\n}\r\n\r\nHttp.bundledRequestImplementations = defaultBundledRequestImplementations;\r\n\r\nLogger.initLogHandlers();\r\n\r\nPlatform.Defaults = getDefaults(PlatformDefaults);\r\n\r\nif (Platform.Config.agent) {\r\n // @ts-ignore\r\n Platform.Defaults.agent += ' ' + Platform.Config.agent;\r\n}\r\n\r\nexport { DefaultRest as Rest, DefaultRealtime as Realtime, msgpack, protocolMessageFromDeserialized, ErrorInfo };\r\n\r\nexport default {\r\n ErrorInfo,\r\n Rest: DefaultRest,\r\n Realtime: DefaultRealtime,\r\n msgpack,\r\n};\r\n","import { IPlatformConfig } from './types/IPlatformConfig';\nimport { IPlatformHttpStatic } from './types/http';\nimport IDefaults from './types/IDefaults';\nimport IWebStorage from './types/IWebStorage';\nimport IBufferUtils from './types/IBufferUtils';\nimport * as WebBufferUtils from '../platform/web/lib/util/bufferutils';\nimport * as NodeBufferUtils from '../platform/nodejs/lib/util/bufferutils';\nimport { IUntypedCryptoStatic } from '../common/types/ICryptoStatic';\nimport TransportName from './constants/TransportName';\nimport { TransportCtor } from './lib/transport/transport';\n\nexport type Bufferlike = WebBufferUtils.Bufferlike | NodeBufferUtils.Bufferlike;\ntype BufferUtilsOutput = WebBufferUtils.Output | NodeBufferUtils.Output;\ntype ToBufferOutput = WebBufferUtils.ToBufferOutput | NodeBufferUtils.ToBufferOutput;\n\nexport type TransportImplementations = Partial<Record<TransportName, TransportCtor>>;\n\nexport default class Platform {\n static Config: IPlatformConfig;\n /*\n What we actually _want_ is for Platform to be a generic class\n parameterised by Bufferlike etc, but that requires far-reaching changes to\n components that make use of Platform. So instead we have to advertise a\n BufferUtils object that accepts a broader range of data types than it\n can in reality handle.\n */\n static BufferUtils: IBufferUtils<Bufferlike, BufferUtilsOutput, ToBufferOutput>;\n /*\n We’d like this to be ICryptoStatic with the correct generic arguments,\n but Platform doesn’t currently allow that, as described in the BufferUtils\n comment above.\n */\n static Crypto: IUntypedCryptoStatic | null;\n static Http: IPlatformHttpStatic;\n static Transports: {\n order: TransportName[];\n // Transport implementations that always come with this platform\n bundledImplementations: TransportImplementations;\n };\n static Defaults: IDefaults;\n static WebStorage: IWebStorage | null;\n}\n","import Platform from 'common/platform';\n\nexport type LoggerOptions = {\n handler: LoggerFunction;\n level: LogLevels;\n};\ntype LoggerFunction = (...args: string[]) => void;\n\n// Workaround for salesforce lightning locker compatibility\n// This is a shorthand version of Utils.getGlobalObject (which we can't use here without creating a circular import)\nlet globalObject = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : self;\n\nenum LogLevels {\n None = 0,\n Error = 1,\n Major = 2,\n Minor = 3,\n Micro = 4,\n}\n\nfunction pad(timeSegment: number, three?: number) {\n return `${timeSegment}`.padStart(three ? 3 : 2, '0');\n}\n\nfunction getHandler(logger: Function): Function {\n return Platform.Config.logTimestamps\n ? function (msg: unknown) {\n const time = new Date();\n logger(\n pad(time.getHours()) +\n ':' +\n pad(time.getMinutes()) +\n ':' +\n pad(time.getSeconds()) +\n '.' +\n pad(time.getMilliseconds(), 1) +\n ' ' +\n msg,\n );\n }\n : function (msg: string) {\n logger(msg);\n };\n}\n\nconst getDefaultLoggers = (): [Function, Function] => {\n let consoleLogger;\n let errorLogger;\n\n // we expect ably-js to be run in environments which have `console` object available with its `log` function\n if (typeof globalObject?.console?.log === 'function') {\n consoleLogger = function (...args: unknown[]) {\n console.log.apply(console, args);\n };\n\n errorLogger = console.warn\n ? function (...args: unknown[]) {\n console.warn.apply(console, args);\n }\n : consoleLogger;\n } else {\n // otherwise we should fallback to noop for log functions\n consoleLogger = errorLogger = function () {};\n }\n\n return [consoleLogger, errorLogger].map(getHandler) as [Function, Function];\n};\n\nclass Logger {\n private static defaultLogLevel: LogLevels = LogLevels.Error;\n private static defaultLogHandler: Function;\n private static defaultLogErrorHandler: Function;\n\n private logLevel: LogLevels;\n private logHandler: Function;\n private logErrorHandler: Function;\n\n // public constants\n static readonly LOG_NONE: LogLevels = LogLevels.None;\n static readonly LOG_ERROR: LogLevels = LogLevels.Error;\n static readonly LOG_MAJOR: LogLevels = LogLevels.Major;\n static readonly LOG_MINOR: LogLevels = LogLevels.Minor;\n static readonly LOG_MICRO: LogLevels = LogLevels.Micro;\n\n /**\n * This logger instance should only be used when there is no more appropriate logger to use, for example when implementing a public static method or function whose API doesn’t accept any logging configuration.\n */\n static defaultLogger: Logger;\n\n static initLogHandlers() {\n const [logHandler, logErrorHandler] = getDefaultLoggers();\n this.defaultLogHandler = logHandler;\n this.defaultLogErrorHandler = logErrorHandler;\n this.defaultLogger = new Logger();\n }\n\n constructor() {\n this.logLevel = Logger.defaultLogLevel;\n this.logHandler = Logger.defaultLogHandler;\n this.logErrorHandler = Logger.defaultLogErrorHandler;\n }\n\n /* public static functions */\n /**\n * In the modular variant of the SDK, the `stripLogs` esbuild plugin strips out all calls to this method (when invoked as `Logger.logAction(...)`) except when called with level `Logger.LOG_ERROR`. If you wish for a log statement to never be stripped, use the {@link logActionNoStrip} method instead.\n *\n * The aforementioned plugin expects `level` to be an expression of the form `Logger.LOG_*`; that is, you can’t dynamically specify the log level.\n */\n static logAction = (logger: Logger, level: LogLevels, action: string, message?: string) => {\n this.logActionNoStrip(logger, level, action, message);\n };\n\n /**\n * Calls to this method are never stripped by the `stripLogs` esbuild plugin. Use it for log statements that you wish to always be included in the modular variant of the SDK.\n */\n static logActionNoStrip(logger: Logger, level: LogLevels, action: string, message?: string) {\n logger.logAction(level, action, message);\n }\n\n private logAction(level: LogLevels, action: string, message?: string) {\n if (this.shouldLog(level)) {\n (level === LogLevels.Error ? this.logErrorHandler : this.logHandler)('Ably: ' + action + ': ' + message, level);\n }\n }\n\n deprecated = (description: string, msg: string) => {\n this.deprecationWarning(`${description} is deprecated and will be removed in a future version. ${msg}`);\n };\n\n renamedClientOption(oldName: string, newName: string) {\n this.deprecationWarning(\n `The \\`${oldName}\\` client option has been renamed to \\`${newName}\\`. Please update your code to use \\`${newName}\\` instead. \\`${oldName}\\` will be removed in a future version.`,\n );\n }\n\n renamedMethod(className: string, oldName: string, newName: string) {\n this.deprecationWarning(\n `\\`${className}\\`’s \\`${oldName}\\` method has been renamed to \\`${newName}\\`. Please update your code to use \\`${newName}\\` instead. \\`${oldName}\\` will be removed in a future version.`,\n );\n }\n\n deprecationWarning(message: string) {\n if (this.shouldLog(LogLevels.Error)) {\n this.logErrorHandler(`Ably: Deprecation warning - ${message}`, LogLevels.Error);\n }\n }\n\n /* Where a logging operation is expensive, such as serialisation of data, use shouldLog will prevent\n\t the object being serialised if the log level will not output the message */\n shouldLog = (level: LogLevels) => {\n return level <= this.logLevel;\n };\n\n setLog = (level: LogLevels | undefined, handler: Function | undefined) => {\n if (level !== undefined) this.logLevel = level;\n if (handler !== undefined) this.logHandler = this.logErrorHandler = handler;\n };\n}\n\nexport default Logger;\n","import Platform from 'common/platform';\r\nimport ErrorInfo, { PartialErrorInfo } from 'common/lib/types/errorinfo';\r\nimport { ModularPlugins } from '../client/modularplugins';\r\nimport { MsgPack } from 'common/types/msgpack';\r\n\r\nfunction randomPosn(arrOrStr: Array<unknown> | string) {\r\n return Math.floor(Math.random() * arrOrStr.length);\r\n}\r\n\r\n/**\r\n * Add a set of properties to a target object\r\n *\r\n * @param target the target object\r\n * @param args objects, which enumerable properties are added to target, by reference only\r\n * @returns target object with added properties\r\n */\r\nexport function mixin(\r\n target: Record<string, unknown>,\r\n ...args: Array<object | undefined | null>\r\n): Record<string, unknown> {\r\n for (let i = 0; i < args.length; i++) {\r\n const source = args[i];\r\n if (!source) {\r\n break;\r\n }\r\n\r\n for (const key in source) {\r\n if (Object.prototype.hasOwnProperty.call(source, key)) {\r\n target[key] = (source as Record<string, unknown>)[key];\r\n }\r\n }\r\n }\r\n return target;\r\n}\r\n\r\n/**\r\n * Creates a copy of enumerable properties of the source object\r\n *\r\n * @param src object to copy\r\n * @returns copy of src\r\n */\r\nexport function copy<T = Record<string, unknown>>(src: T | Record<string, unknown> | null | undefined): T {\r\n return mixin({}, src as Record<string, unknown>) as T;\r\n}\r\n\r\n/*\r\n * Ensures that an Array object is always returned\r\n * returning the original Array of obj is an Array\r\n * else wrapping the obj in a single element Array\r\n */\r\nexport function ensureArray(obj: Record<string, unknown>): unknown[] {\r\n if (isNil(obj)) {\r\n return [];\r\n }\r\n if (Array.isArray(obj)) {\r\n return obj;\r\n }\r\n return [obj];\r\n}\r\n\r\nexport function isObject(ob: unknown): ob is Record<string, unknown> {\r\n return Object.prototype.toString.call(ob) == '[object Object]';\r\n}\r\n\r\n/*\r\n * Determine whether or not an object contains\r\n * any enumerable properties.\r\n * ob: the object\r\n */\r\nexport function isEmpty(ob: Record<string, unknown> | unknown[]): boolean {\r\n for (const prop in ob) return false;\r\n return true;\r\n}\r\n\r\n/**\r\n * Checks if `value` is `null` or `undefined`.\r\n *\r\n * Source: https://github.com/lodash/lodash/blob/main/src/isNil.ts\r\n */\r\nexport function isNil(arg: unknown): arg is null | undefined {\r\n return arg == null;\r\n}\r\n\r\n/*\r\n * Perform a simple shallow clone of an object.\r\n * Result is an object irrespective of whether\r\n * the input is an object or array. All\r\n * enumerable properties are copied.\r\n * ob: the object\r\n */\r\nexport function shallowClone(ob: Record<string, unknown>): Record<string, unknown> {\r\n const result = new Object() as Record<string, unknown>;\r\n for (const prop in ob) result[prop] = ob[prop];\r\n return result;\r\n}\r\n\r\n/*\r\n * Clone an object by creating a new object with the\r\n * given object as its prototype. Optionally\r\n * a set of additional own properties can be\r\n * supplied to be added to the newly created clone.\r\n * ob: the object to be cloned\r\n * ownProperties: optional object with additional\r\n * properties to add\r\n */\r\nexport function prototypicalClone(\r\n ob: Record<string, unknown>,\r\n ownProperties: Record<string, unknown>,\r\n): Record<string, unknown> {\r\n class F {}\r\n F.prototype = ob;\r\n const result = new F() as Record<string, unknown>;\r\n if (ownProperties) mixin(result, ownProperties);\r\n return result;\r\n}\r\n\r\n/*\r\n * Declare a constructor to represent a subclass\r\n * of another constructor\r\n * If platform has a built-in version we use that from Platform, else we\r\n * define here (so can make use of other Utils fns)\r\n * See node.js util.inherits\r\n */\r\nexport const inherits = function (ctor: any, superCtor: Function) {\r\n if (Platform.Config.inherits) {\r\n Platform.Config.inherits(ctor, superCtor);\r\n return;\r\n }\r\n ctor.super_ = superCtor;\r\n ctor.prototype = prototypicalClone(superCtor.prototype, { constructor: ctor });\r\n};\r\n\r\n/*\r\n * Determine whether or not an object has an enumerable\r\n * property whose value equals a given value.\r\n * ob: the object\r\n * val: the value to find\r\n */\r\nexport function containsValue(ob: Record<string, unknown>, val: unknown): boolean {\r\n for (const i in ob) {\r\n if (ob[i] == val) return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport function intersect<K extends string, T>(arr: Array<K>, ob: K[] | Partial<Record<K, T>>): K[] {\r\n return Array.isArray(ob) ? arrIntersect(arr, ob) : arrIntersectOb(arr, ob);\r\n}\r\n\r\nexport function arrIntersect<T>(arr1: Array<T>, arr2: Array<T>): Array<T> {\r\n const result = [];\r\n for (let i = 0; i < arr1.length; i++) {\r\n const member = arr1[i];\r\n if (arr2.indexOf(member) != -1) result.push(member);\r\n }\r\n return result;\r\n}\r\n\r\nexport function arrIntersectOb<K extends string>(arr: Array<K>, ob: Partial<Record<K, unknown>>): K[] {\r\n const result = [];\r\n for (let i = 0; i < arr.length; i++) {\r\n const member = arr[i];\r\n if (member in ob) result.push(member);\r\n }\r\n return result;\r\n}\r\n\r\nexport function arrSubtract<T>(arr1: Array<T>, arr2: Array<T>): Array<T> {\r\n const result = [];\r\n for (let i = 0; i < arr1.length; i++) {\r\n const element = arr1[i];\r\n if (arr2.indexOf(element) == -1) result.push(element);\r\n }\r\n return result;\r\n}\r\n\r\nexport function arrDeleteValue<T>(arr: Array<T>, val: T): boolean {\r\n const idx = arr.indexOf(val);\r\n const res = idx != -1;\r\n if (res) arr.splice(idx, 1);\r\n return res;\r\n}\r\n\r\nexport function arrWithoutValue<T>(arr: Array<T>, val: T): Array<T> {\r\n const newArr = arr.slice();\r\n arrDeleteValue(newArr, val);\r\n return newArr;\r\n}\r\n\r\n/*\r\n * Construct an array of the keys of the enumerable\r\n * properties of a given object, optionally limited\r\n * to only the own properties.\r\n * ob: the object\r\n * ownOnly: boolean, get own properties only\r\n */\r\nexport function keysArray(ob: Record<string, unknown>, ownOnly?: boolean): Array<string> {\r\n const result = [];\r\n for (const prop in ob) {\r\n if (ownOnly && !Object.prototype.hasOwnProperty.call(ob, prop)) continue;\r\n result.push(prop);\r\n }\r\n return result;\r\n}\r\n\r\n/*\r\n * Construct an array of the values of the enumerable\r\n * properties of a given object, optionally limited\r\n * to only the own properties.\r\n * ob: the object\r\n * ownOnly: boolean, get own properties only\r\n */\r\nexport function valuesArray<T>(ob: Record<string, T>, ownOnly?: boolean): T[] {\r\n const result = [];\r\n for (const prop in ob) {\r\n if (ownOnly && !Object.prototype.hasOwnProperty.call(ob, prop)) continue;\r\n result.push(ob[prop]);\r\n }\r\n return result;\r\n}\r\n\r\nexport function forInOwnNonNullProperties(ob: Record<string, unknown>, fn: (prop: string) => void): void {\r\n for (const prop in ob) {\r\n if (Object.prototype.hasOwnProperty.call(ob, prop) && ob[prop]) {\r\n fn(prop);\r\n }\r\n }\r\n}\r\n\r\nexport function allSame(arr: Array<Record<string, unknown>>, prop: string): boolean {\r\n if (arr.length === 0) {\r\n return true;\r\n }\r\n const first = arr[0][prop];\r\n return arr.every(function (item) {\r\n return item[prop] === first;\r\n });\r\n}\r\n\r\nexport enum Format {\r\n msgpack = 'msgpack',\r\n json = 'json',\r\n}\r\n\r\nexport function arrPopRandomElement<T>(arr: Array<T>): T {\r\n return arr.splice(randomPosn(arr), 1)[0];\r\n}\r\n\r\nexport function toQueryString(params?: Record<string, string> | null): string {\r\n const parts = [];\r\n if (params) {\r\n for (const key in params) parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));\r\n }\r\n return parts.length ? '?' + parts.join('&') : '';\r\n}\r\n\r\nexport function parseQueryString(query: string): Record<string, string> {\r\n let match;\r\n const search = /([^?&=]+)=?([^&]*)/g;\r\n const result: Record<string, string> = {};\r\n\r\n while ((match = search.exec(query))) result[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);\r\n\r\n return result;\r\n}\r\n\r\nexport function isErrorInfoOrPartialErrorInfo(err: unknown): err is ErrorInfo | PartialErrorInfo {\r\n return typeof err == 'object' && err !== null && (err instanceof ErrorInfo || err instanceof PartialErrorInfo);\r\n}\r\n\r\nexport function inspectError(err: unknown): string {\r\n if (\r\n err instanceof Error ||\r\n (err as ErrorInfo)?.constructor?.name === 'ErrorInfo' ||\r\n (err as PartialErrorInfo)?.constructor?.name === 'PartialErrorInfo'\r\n )\r\n return (err as Error).toString();\r\n return Platform.Config.inspect(err);\r\n}\r\n\r\nexport function inspectBody(body: unknown): string {\r\n if (Platform.BufferUtils.isBuffer(body)) {\r\n return (body as any).toString();\r\n } else if (typeof body === 'string') {\r\n return body;\r\n } else {\r\n return Platform.Config.inspect(body);\r\n }\r\n}\r\n\r\n/* Data is assumed to be either a string or a buffer. */\r\nexport function dataSizeBytes(data: string | Buffer): number {\r\n if (Platform.BufferUtils.isBuffer(data)) {\r\n return Platform.BufferUtils.byteLength(data);\r\n }\r\n if (typeof data === 'string') {\r\n return Platform.Config.stringByteSize(data);\r\n }\r\n throw new Error('Expected input of Utils.dataSizeBytes to be a buffer or string, but was: ' + typeof data);\r\n}\r\n\r\nexport function cheapRandStr(): string {\r\n return String(Math.random()).substr(2);\r\n}\r\n\r\n/* Takes param the minimum number of bytes of entropy the string must\r\n * include, not the length of the string. String length produced is not\r\n * guaranteed. */\r\nexport const randomString = async (numBytes: number): Promise<string> => {\r\n const buffer = await Platform.Config.getRandomArrayBuffer(numBytes);\r\n return Platform.BufferUtils.base64Encode(buffer);\r\n};\r\n\r\n/* Pick n elements at random without replacement from an array */\r\nexport function arrChooseN<T>(arr: Array<T>, n: number): Array<T> {\r\n const numItems = Math.min(n, arr.length),\r\n mutableArr = arr.slice(),\r\n result: Array<T> = [];\r\n for (let i = 0; i < numItems; i++) {\r\n result.push(arrPopRandomElement(mutableArr));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Uses a callback to communicate the result of a `Promise`. The first argument passed to the callback will be either an error (when the promise is rejected) or `null` (when the promise is fulfilled). In the case where the promise is fulfilled, the resulting value will be passed to the callback as a second argument.\r\n */\r\nexport function whenPromiseSettles<T, E = unknown>(\r\n promise: Promise<T>,\r\n callback?: (err: E | null, result?: T) => void,\r\n) {\r\n promise\r\n .then((result) => {\r\n callback?.(null, result);\r\n })\r\n .catch((err: unknown) => {\r\n // We make no guarantees about the type of the error that gets passed to the callback. Issue https://github.com/ably/ably-js/issues/1617 will think about how to correctly handle error types.\r\n callback?.(err as E);\r\n });\r\n}\r\n\r\nexport function decodeBody<T>(body: unknown, MsgPack: MsgPack | null, format?: Format | null): T {\r\n if (format == 'msgpack') {\r\n if (!MsgPack) {\r\n throwMissingPluginError('MsgPack');\r\n }\r\n return MsgPack.decode(body as Buffer);\r\n }\r\n\r\n return JSON.parse(String(body));\r\n}\r\n\r\nexport function encodeBody(body: unknown, MsgPack: MsgPack | null, format?: Format): string | Buffer {\r\n if (format == 'msgpack') {\r\n if (!MsgPack) {\r\n throwMissingPluginError('MsgPack');\r\n }\r\n return MsgPack.encode(body, true) as Buffer;\r\n }\r\n\r\n return JSON.stringify(body);\r\n}\r\n\r\nexport function allToLowerCase(arr: Array<string>): Array<string> {\r\n return arr.map(function (element) {\r\n return element && element.toLowerCase();\r\n });\r\n}\r\n\r\nexport function allToUpperCase(arr: Array<string>): Array<string> {\r\n return arr.map(function (element) {\r\n return element && element.toUpperCase();\r\n });\r\n}\r\n\r\nexport function getBackoffCoefficient(count: number) {\r\n return Math.min((count + 2) / 3, 2);\r\n}\r\n\r\nexport function getJitterCoefficient() {\r\n return 1 - Math.random() * 0.2;\r\n}\r\n\r\n/**\r\n *\r\n * @param initialTimeout initial timeout value\r\n * @param retryAttempt integer indicating retryAttempt\r\n * @returns RetryTimeout value for given timeout and retryAttempt.\r\n * If x is the value generated then,\r\n * Upper bound = min((retryAttempt + 2) / 3, 2) * initialTimeout,\r\n * Lower bound = 0.8 * Upper bound,\r\n * Lower bound < x < Upper bound\r\n */\r\nexport function getRetryTime(initialTimeout: number, retryAttempt: number) {\r\n return initialTimeout * getBackoffCoefficient(retryAttempt) * getJitterCoefficient();\r\n}\r\n\r\nexport function getGlobalObject() {\r\n if (typeof global !== 'undefined') {\r\n return global;\r\n }\r\n\r\n if (typeof window !== 'undefined') {\r\n return window;\r\n }\r\n\r\n return self;\r\n}\r\n\r\nexport function shallowEquals(source: Record<string, unknown>, target: Record<string, unknown>) {\r\n return (\r\n Object.keys(source).every((key) => source[key] === target[key]) &&\r\n Object.keys(target).every((key) => target[key] === source[key])\r\n );\r\n}\r\n\r\nexport function matchDerivedChannel(name: string) {\r\n /**\r\n * This regex check is to retain existing channel params if any e.g [?rewind=1]foo to\r\n * [filter=xyz?rewind=1]foo. This is to keep channel compatibility around use of\r\n * channel params that work with derived channels.\r\n *\r\n * This eslint unsafe regex warning is triggered because the RegExp uses nested quantifiers,\r\n * but it does not create any situation where the regex engine has to\r\n * explore a large number of possible matches so it’s safe to ignore\r\n */\r\n const regex = /^(\\[([^?]*)(?:(.*))\\])?(.+)$/; // eslint-disable-line\r\n const match = name.match(regex);\r\n if (!match || !match.length || match.length < 5) {\r\n throw new ErrorInfo('regex match failed', 400, 40010);\r\n }\r\n // Fail if there is already a channel qualifier, eg [meta]foo should fail instead of just overriding with [filter=xyz]foo\r\n if (match![2]) {\r\n throw new ErrorInfo(`cannot use a derived option with a ${match[2]} channel`, 400, 40010);\r\n }\r\n // Return match values to be added to derive channel quantifier.\r\n return {\r\n qualifierParam: match[3] || '',\r\n channelName: match[4],\r\n };\r\n}\r\n\r\nexport function toBase64(str: string) {\r\n const bufferUtils = Platform.BufferUtils;\r\n const textBuffer = bufferUtils.utf8Encode(str);\r\n return bufferUtils.base64Encode(textBuffer);\r\n}\r\n\r\nexport function arrEquals(a: any[], b: any[]) {\r\n return (\r\n a.length === b.length &&\r\n a.every(function (val, i) {\r\n return val === b[i];\r\n })\r\n );\r\n}\r\n\r\nexport function createMissingPluginError(pluginName: keyof ModularPlugins): ErrorInfo {\r\n return new ErrorInfo(`${pluginName} plugin not provided`, 40019, 400);\r\n}\r\n\r\nexport function throwMissingPluginError(pluginName: keyof ModularPlugins): never {\r\n throw createMissingPluginError(pluginName);\r\n}\r\n\r\nexport async function withTimeoutAsync<A>(promise: Promise<A>, timeout = 5000, err = 'Timeout expired'): Promise<A> {\r\n const e = new ErrorInfo(err, 50000, 500);\r\n return Promise.race([promise, new Promise<A>((_resolve, reject) => setTimeout(() => reject(e), timeout))]);\r\n}\r\n\r\ntype NonFunctionKeyNames<A> = { [P in keyof A]: A[P] extends Function ? never : P }[keyof A];\r\nexport type Properties<A> = Pick<A, NonFunctionKeyNames<A>>;\r\n","import Platform from 'common/platform';\nimport * as Utils from '../util/utils';\nimport * as API from '../../../../ably';\n\nexport interface IPartialErrorInfo extends Error {\n code: number | null;\n statusCode?: number;\n cause?: string | Error | ErrorInfo;\n href?: string;\n}\n\nfunction toString(err: ErrorInfo | PartialErrorInfo) {\n let result = '[' + err.constructor.name;\n if (err.message) result += ': ' + err.message;\n if (err.statusCode) result += '; statusCode=' + err.statusCode;\n if (err.code) result += '; code=' + err.code;\n if (err.cause) result += '; cause=' + Utils.inspectError(err.cause);\n if (err.href && !(err.message && err.message.indexOf('help.ably.io') > -1)) result += '; see ' + err.href + ' ';\n result += ']';\n return result;\n}\n\nexport interface IConvertibleToErrorInfo {\n message: string;\n code: number;\n statusCode: number;\n}\n\nexport interface IConvertibleToPartialErrorInfo {\n message: string;\n code: number | null;\n statusCode?: number;\n}\n\nexport default class ErrorInfo extends Error implements IPartialErrorInfo, API.ErrorInfo {\n code: number;\n statusCode: number;\n cause?: string | Error | ErrorInfo;\n href?: string;\n\n constructor(message: string, code: number, statusCode: number, cause?: string | Error | ErrorInfo) {\n super(message);\n if (typeof Object.setPrototypeOf !== 'undefined') {\n Object.setPrototypeOf(this, ErrorInfo.prototype);\n }\n this.code = code;\n this.statusCode = statusCode;\n this.cause = cause;\n }\n\n toString(): string {\n return toString(this);\n }\n\n static fromValues(values: IConvertibleToErrorInfo): ErrorInfo {\n const { message, code, statusCode } = values;\n if (typeof message !== 'string' || typeof code !== 'number' || typeof statusCode !== 'number') {\n throw new Error('ErrorInfo.fromValues(): invalid values: ' + Platform.Config.inspect(values));\n }\n const result = Object.assign(new ErrorInfo(message, code, statusCode), values);\n if (result.code && !result.href) {\n result.href = 'https://help.ably.io/error/' + result.code;\n }\n return result;\n }\n}\n\nexport class PartialErrorInfo extends Error implements IPartialErrorInfo {\n code: number | null;\n statusCode?: number;\n cause?: string | Error | ErrorInfo;\n href?: string;\n\n constructor(message: string, code: number | null, statusCode?: number, cause?: string | Error | ErrorInfo) {\n super(message);\n if (typeof Object.setPrototypeOf !== 'undefined') {\n Object.setPrototypeOf(this, PartialErrorInfo.prototype);\n }\n this.code = code;\n this.statusCode = statusCode;\n this.cause = cause;\n }\n\n toString(): string {\n return toString(this);\n }\n\n static fromValues(values: IConvertibleToPartialErrorInfo): PartialErrorInfo {\n const { message, code, statusCode } = values;\n if (\n typeof message !== 'string' ||\n (!Utils.isNil(code) && typeof code !== 'number') ||\n (!Utils.isNil(statusCode) && typeof statusCode !== 'number')\n ) {\n throw new Error('PartialErrorInfo.fromValues(): invalid values: ' + Platform.Config.inspect(values));\n }\n const result = Object.assign(new PartialErrorInfo(message, code, statusCode), values);\n if (result.code && !result.href) {\n result.href = 'https://help.ably.io/error/' + result.code;\n }\n return result;\n }\n}\n","{\r\n \"name\": \"ably\",\r\n \"description\": \"Realtime client library for Ably, the realtime messaging service\",\r\n \"version\": \"2.6.0\",\r\n \"license\": \"Apache-2.0\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/ably/ably-js/issues\",\r\n \"email\": \"support@ably.com\"\r\n },\r\n \"main\": \"./build/ably-node.js\",\r\n \"browser\": \"./build/ably.js\",\r\n \"react-native\": \"./build/ably-reactnative.js\",\r\n \"typings\": \"./ably.d.ts\",\r\n \"exports\": {\r\n \".\": {\r\n \"types\": \"./ably.d.ts\",\r\n \"node\": \"./build/ably-node.js\",\r\n \"react-native\": \"./build/ably-reactnative.js\",\r\n \"default\": \"./build/ably.js\"\r\n },\r\n \"./modular\": {\r\n \"types\": \"./modular.d.ts\",\r\n \"import\": \"./build/modular/index.mjs\"\r\n },\r\n \"./react\": {\r\n \"require\": \"./react/cjs/index.js\",\r\n \"import\": \"./react/mjs/index.js\"\r\n },\r\n \"./push\": {\r\n \"types\": \"./push.d.ts\",\r\n \"import\": \"./build/push.js\"\r\n }\r\n },\r\n \"files\": [\r\n \"build/**\",\r\n \"ably.d.ts\",\r\n \"push.d.ts\",\r\n \"modular.d.ts\",\r\n \"resources/**\",\r\n \"src/**\",\r\n \"react/**\"\r\n ],\r\n \"dependencies\": {\r\n \"@ably/msgpack-js\": \"^0.4.0\",\r\n \"fastestsmallesttextencoderdecoder\": \"^1.0.22\",\r\n \"got\": \"^11.8.5\",\r\n \"ulid\": \"^2.3.0\",\r\n \"ws\": \"^8.17.1\"\r\n },\r\n \"peerDependencies\": {\r\n \"react\": \">=16.8.0\",\r\n \"react-dom\": \">=16.8.0\"\r\n },\r\n \"peerDependenciesMeta\": {\r\n \"react\": {\r\n \"optional\": true\r\n },\r\n \"react-dom\": {\r\n \"optional\": true\r\n }\r\n },\r\n \"devDependencies\": {\r\n \"@ably/vcdiff-decoder\": \"1.0.6\",\r\n \"@arethetypeswrong/cli\": \"^0.13.1\",\r\n \"@babel/generator\": \"^7.23.6\",\r\n \"@babel/parser\": \"^7.23.6\",\r\n \"@babel/traverse\": \"^7.23.7\",\r\n \"@testing-library/react\": \"^13.3.0\",\r\n \"@types/cli-table\": \"^0.3.4\",\r\n \"@types/jmespath\": \"^0.15.2\",\r\n \"@types/node\": \"^18.0.0\",\r\n \"@types/request\": \"^2.48.7\",\r\n \"@types/ws\": \"^8.2.0\",\r\n \"@typescript-eslint/eslint-plugin\": \"^5.59.6\",\r\n \"@typescript-eslint/parser\": \"^5.59.6\",\r\n \"@vitejs/plugin-react\": \"^1.3.2\",\r\n \"async\": \"ably-forks/async#requirejs\",\r\n \"aws-sdk\": \"^2.1413.0\",\r\n \"chai\": \"^4.2.0\",\r\n \"cli-table\": \"^0.3.11\",\r\n \"cors\": \"^2.8.5\",\r\n \"csv\": \"^6.3.9\",\r\n \"dox\": \"^1.0.0\",\r\n \"esbuild\": \"^0.18.10\",\r\n \"esbuild-plugin-umd-wrapper\": \"ably-forks/esbuild-plugin-umd-wrapper#1.0.7-optional-amd-named-module\",\r\n \"esbuild-runner\": \"^2.2.2\",\r\n \"eslint\": \"^7.13.0\",\r\n \"eslint-plugin-import\": \"^2.28.0\",\r\n \"eslint-plugin-jsdoc\": \"^40.0.0\",\r\n \"eslint-plugin-react\": \"^7.32.2\",\r\n \"eslint-plugin-react-hooks\": \"^4.6.0\",\r\n \"eslint-plugin-security\": \"^1.4.0\",\r\n \"express\": \"^4.17.1\",\r\n \"glob\": \"^10.4.2\",\r\n \"grunt\": \"^1.6.1\",\r\n \"grunt-cli\": \"~1.2.0\",\r\n \"grunt-shell\": \"~1.1\",\r\n \"grunt-webpack\": \"^5.0.0\",\r\n \"hexy\": \"~0.2\",\r\n \"jmespath\": \"^0.16.0\",\r\n \"jsdom\": \"^20.0.0\",\r\n \"minimist\": \"^1.2.5\",\r\n \"mocha\": \"^8.1.3\",\r\n \"mocha-junit-reporter\": \"^2.2.1\",\r\n \"path-browserify\": \"^1.0.1\",\r\n \"playwright\": \"^1.39.0\",\r\n \"prettier\": \"^3.3.3\",\r\n \"process\": \"^0.11.10\",\r\n \"react\": \">=18.1.0\",\r\n \"react-dom\": \">=18.1.0\",\r\n \"requirejs\": \"~2.1\",\r\n \"shelljs\": \"~0.8\",\r\n \"source-map-explorer\": \"^2.5.2\",\r\n \"source-map-support\": \"^0.5.21\",\r\n \"stream-browserify\": \"^3.0.0\",\r\n \"ts-loader\": \"^9.4.2\",\r\n \"tsconfig-paths-webpack-plugin\": \"^4.0.1\",\r\n \"tslib\": \"^2.3.1\",\r\n \"typedoc\": \"^0.24.7\",\r\n \"typescript\": \"^4.9.5\",\r\n \"vite\": \"^4.4.9\",\r\n \"vitest\": \"^0.18.0\",\r\n \"webpack\": \"^5.79.0\",\r\n \"webpack-cli\": \"^5.0.1\"\r\n },\r\n \"engines\": {\r\n \"node\": \">=16\"\r\n },\r\n \"repository\": \"ably/ably-js\",\r\n \"jspm\": {\r\n \"registry\": \"npm\",\r\n \"directories\": {\r\n \"lib\": \"build\"\r\n },\r\n \"main\": \"ably\"\r\n },\r\n \"scripts\": {\r\n \"start:react\": \"npx vite serve\",\r\n \"grunt\": \"grunt\",\r\n \"test\": \"npm run test:node\",\r\n \"test:node\": \"npm run build:node && npm run build:push && mocha\",\r\n \"test:grep\": \"npm run build:node && npm run build:push && mocha --grep\",\r\n \"test:node:skip-build\": \"mocha\",\r\n \"test:webserver\": \"grunt test:webserver\",\r\n \"test:playwright\": \"node test/support/runPlaywrightTests.js\",\r\n \"test:react\": \"vitest run\",\r\n \"test:package\": \"grunt test:package\",\r\n \"concat\": \"grunt concat\",\r\n \"build\": \"grunt build:all && npm run build:react\",\r\n \"build:node\": \"grunt build:node\",\r\n \"build:browser\": \"grunt build:browser\",\r\n \"build:react\": \"npm run build:react:mjs && npm run build:react:cjs && cp src/platform/react-hooks/res/package.react.json react/package.json\",\r\n \"build:react:mjs\": \"tsc --project src/platform/react-hooks/tsconfig.mjs.json && cp src/platform/react-hooks/res/package.mjs.json react/mjs/package.json\",\r\n \"build:react:cjs\": \"tsc --project src/platform/react-hooks/tsconfig.cjs.json && cp src/platform/react-hooks/res/package.cjs.json react/cjs/package.json\",\r\n \"build:push\": \"grunt build:push\",\r\n \"requirejs\": \"grunt requirejs\",\r\n \"lint\": \"eslint .\",\r\n \"lint:fix\": \"eslint --fix .\",\r\n \"prepare\": \"npm run build\",\r\n \"format\": \"prettier --write .\",\r\n \"format:check\": \"prettier --check .\",\r\n \"sourcemap\": \"source-map-explorer build/ably.min.js\",\r\n \"modulereport\": \"tsc --noEmit --esModuleInterop scripts/moduleReport.ts && esr scripts/moduleReport.ts\",\r\n \"speccoveragereport\": \"tsc --noEmit --esModuleInterop --target ES2017 --moduleResolution node scripts/specCoverageReport.ts && esr scripts/specCoverageReport.ts\",\r\n \"process-private-api-data\": \"tsc --noEmit --esModuleInterop --strictNullChecks scripts/processPrivateApiData/run.ts && esr scripts/processPrivateApiData/run.ts\",\r\n \"docs\": \"typedoc\"\r\n }\r\n}\r\n","import Platform from 'common/platform';\nimport * as Utils from './utils';\nimport Logger from './logger';\nimport ErrorInfo from 'common/lib/types/errorinfo';\nimport { version } from '../../../../package.json';\nimport ClientOptions, { NormalisedClientOptions } from 'common/types/ClientOptions';\nimport IDefaults from '../../types/IDefaults';\nimport { MsgPack } from 'common/types/msgpack';\nimport { IUntypedCryptoStatic } from 'common/types/ICryptoStatic';\nimport { ChannelOptions } from 'common/types/channel';\nimport { ModularPlugins } from '../client/modularplugins';\n\nlet agent = 'ably-js/' + version;\n\ntype CompleteDefaults = IDefaults & {\n ENVIRONMENT: string;\n REST_HOST: string;\n REALTIME_HOST: string;\n FALLBACK_HOSTS: string[];\n PORT: number;\n TLS_PORT: number;\n TIMEOUTS: {\n disconnectedRetryTimeout: number;\n suspendedRetryTimeout: number;\n httpRequestTimeout: number;\n httpMaxRetryDuration: number;\n channelRetryTimeout: number;\n fallbackRetryTimeout: number;\n connectionStateTtl: number;\n realtimeRequestTimeout: number;\n recvTimeout: number;\n webSocketConnectTimeout: number;\n webSocketSlowTimeout: number;\n };\n httpMaxRetryCount: number;\n maxMessageSize: number;\n version: string;\n protocolVersion: number;\n agent: string;\n getHost(options: ClientOptions, host?: string | null, ws?: boolean): string;\n getPort(options: ClientOptions, tls?: boolean): number | undefined;\n getHttpScheme(options: ClientOptions): string;\n environmentFallbackHosts(environment: string): string[];\n getFallbackHosts(options: NormalisedClientOptions): string[];\n getHosts(options: NormalisedClientOptions, ws?: boolean): string[];\n checkHost(host: string): void;\n objectifyOptions(\n options: undefined | ClientOptions | string,\n allowKeyOrToken: boolean,\n sourceForErrorMessage: string,\n logger: Logger,\n modularPluginsToInclude?: ModularPlugins,\n ): ClientOptions;\n normaliseOptions(options: ClientOptions, MsgPack: MsgPack | null, logger: Logger | null): NormalisedClientOptions;\n defaultGetHeaders(options: NormalisedClientOptions, headersOptions?: HeadersOptions): Record<string, string>;\n defaultPostHeaders(options: NormalisedClientOptions, headersOptions?: HeadersOptions): Record<string, string>;\n};\n\nconst Defaults = {\n ENVIRONMENT: '',\n REST_HOST: 'rest.ably.io',\n REALTIME_HOST: 'realtime.ably.io',\n FALLBACK_HOSTS: [\n 'A.ably-realtime.com',\n 'B.ably-realtime.com',\n 'C.ably-realtime.com',\n 'D.ably-realtime.com',\n 'E.ably-realtime.com',\n ],\n PORT: 80,\n TLS_PORT: 443,\n TIMEOUTS: {\n /* Documented as options params: */\n disconnectedRetryTimeout: 15000,\n suspendedRetryTimeout: 30000,\n /* Undocumented, but part of the api and can be used by customers: */\n httpRequestTimeout: 10000,\n httpMaxRetryDuration: 15000,\n channelRetryTimeout: 15000,\n fallbackRetryTimeout: 600000,\n /* For internal / test use only: */\n connectionStateTtl: 120000,\n realtimeRequestTimeout: 10000,\n recvTimeout: 90000,\n webSocketConnectTimeout: 10000,\n webSocketSlowTimeout: 4000,\n },\n httpMaxRetryCount: 3,\n maxMessageSize: 65536,\n\n version,\n protocolVersion: 3,\n agent,\n getHost,\n getPort,\n getHttpScheme,\n environmentFallbackHosts,\n getFallbackHosts,\n getHosts,\n checkHost,\n objectifyOptions,\n normaliseOptions,\n defaultGetHeaders,\n defaultPostHeaders,\n};\n\nexport function getHost(options: ClientOptions, host?: string | null, ws?: boolean): string {\n if (ws) host = (host == options.restHost && options.realtimeHost) || host || options.realtimeHost;\n else host = host || options.restHost;\n\n return host as string;\n}\n\nexport function getPort(options: ClientOptions, tls?: boolean): number | undefined {\n return tls || options.tls ? options.tlsPort : options.port;\n}\n\nexport function getHttpScheme(options: ClientOptions): string {\n return options.tls ? 'https://' : 'http://';\n}\n\n// construct environment fallback hosts as per RSC15i\nexport function environmentFallbackHosts(environment: string): string[] {\n return [\n environment + '-a-fallback.ably-realtime.com',\n environment + '-b-fallback.ably-realtime.com',\n environment + '-c-fallback.ably-realtime.com',\n environment + '-d-fallback.ably-realtime.com',\n environment + '-e-fallback.ably-realtime.com',\n ];\n}\n\nexport function getFallbackHosts(options: NormalisedClientOptions): string[] {\n const fallbackHosts = options.fallbackHosts,\n httpMaxRetryCount =\n typeof options.httpMaxRetryCount !== 'undefined' ? options.httpMaxRetryCount : Defaults.httpMaxRetryCount;\n\n return fallbackHosts ? Utils.arrChooseN(fallbackHosts, httpMaxRetryCount) : [];\n}\n\nexport function getHosts(options: NormalisedClientOptions, ws?: boolean): string[] {\n const hosts = [options.restHost].concat(getFallbackHosts(options));\n return ws ? hosts.map((host) => getHost(options, host, true)) : hosts;\n}\n\nfunction checkHost(host: string): void {\n if (typeof host !== 'string') {\n throw new ErrorInfo('host must be a string; was a ' + typeof host, 40000, 400);\n }\n if (!host.length) {\n throw new ErrorInfo('host must not be zero-length', 40000, 400);\n }\n}\n\nfunction getRealtimeHost(options: ClientOptions, production: boolean, environment: string, logger: Logger): string {\n if (options.realtimeHost) return options.realtimeHost;\n /* prefer setting realtimeHost to restHost as a custom restHost typically indicates\n * a development environment is being used that can't be inferred by the library */\n if (options.restHost) {\n Logger.logAction(\n logger,\n Logger.LOG_MINOR,\n 'Defaults.normaliseOptions',\n 'restHost is set to \"' +\n options.restHost +\n '\" but realtimeHost is not set, so setting realtimeHost to \"' +\n options.restHost +\n '\" too. If this is not what you want, please set realtimeHost explicitly.',\n );\n return options.restHost;\n }\n return production ? Defaults.REALTIME_HOST : environment + '-' + Defaults.REALTIME_HOST;\n}\n\nfunction getTimeouts(options: ClientOptions) {\n /* Allow values passed in options to override default timeouts */\n const timeouts: Record<string, number> = {};\n for (const prop in Defaults.TIMEOUTS) {\n timeouts[prop] = (options as Record<string, number>)[prop] || (Defaults.TIMEOUTS as Record<string, number>)[prop];\n }\n return timeouts;\n}\n\nexport function getAgentString(options: ClientOptions): string {\n let agentStr = Defaults.agent;\n if (options.agents) {\n for (var agent in options.agents) {\n agentStr += ' ' + agent + '/' + options.agents[agent];\n }\n }\n return agentStr;\n}\n\nexport function objectifyOptions(\n options: undefined | ClientOptions | string,\n allowKeyOrToken: boolean,\n sourceForErrorMessage: string,\n logger: Logger,\n modularPluginsToInclude?: ModularPlugins,\n): ClientOptions {\n if (options === undefined) {\n const msg = allowKeyOrToken\n ? `${sourceForErrorMessage} must be initialized with either a client options object, an Ably API key, or an Ably Token`\n : `${sourceForErrorMessage} must be initialized with a client options object`;\n Logger.logAction(logger, Logger.LOG_ERROR, `${sourceForErrorMessage}()`, msg);\n throw new Error(msg);\n }\n\n let optionsObj: ClientOptions;\n\n if (typeof options === 'string') {\n if (options.indexOf(':') == -1) {\n if (!allowKeyOrToken) {\n const msg = `${sourceForErrorMessage} cannot be initialized with just an Ably Token; you must provide a client options object with a \\`plugins\\` property. (Set this Ably Token as the object’s \\`token\\` property.)`;\n Logger.logAction(logger, Logger.LOG_ERROR, `${sourceForErrorMessage}()`, msg);\n throw new Error(msg);\n }\n\n optionsObj = { token: options };\n } else {\n if (!allowKeyOrToken) {\n const msg = `${sourceForErrorMessage} cannot be initialized with just an Ably API key; you must provide a client options object with a \\`plugins\\` property. (Set this Ably API key as the object’s \\`key\\` property.)`;\n Logger.logAction(logger, Logger.LOG_ERROR, `${sourceForErrorMessage}()`, msg);\n throw new Error(msg);\n }\n\n optionsObj = { key: options };\n }\n } else {\n optionsObj = options;\n }\n\n if (modularPluginsToInclude) {\n optionsObj = { ...optionsObj, plugins: { ...modularPluginsToInclude, ...optionsObj.plugins } };\n }\n\n return optionsObj;\n}\n\nexport function normaliseOptions(\n options: ClientOptions,\n MsgPack: MsgPack | null,\n logger: Logger | null, // should only be omitted by tests\n): NormalisedClientOptions {\n const loggerToUse = logger ?? Logger.defaultLogger;\n\n if (typeof options.recover === 'function' && options.closeOnUnload === true) {\n Logger.logAction(\n loggerToUse,\n Logger.LOG_ERROR,\n 'Defaults.normaliseOptions',\n 'closeOnUnload was true and a session recovery function was set - these are mutually exclusive, so unsetting the latter',\n );\n options.recover = undefined;\n }\n\n if (!('closeOnUnload' in options)) {\n /* Have closeOnUnload default to true unless we have any indication that\n * the user may want to recover the connection */\n options.closeOnUnload = !options.recover;\n }\n\n if (!('queueMessages' in options)) options.queueMessages = true;\n\n /* infer hosts and fallbacks based on the configured environment */\n const environment = (options.environment && String(options.environment).toLowerCase()) || Defaults.ENVIRONMENT;\n const production = !environment || environment === 'production';\n\n if (!options.fallbackHosts && !options.restHost && !options.realtimeHost && !options.port && !options.tlsPort) {\n options.fallbackHosts = production ? Defaults.FALLBACK_HOSTS : environmentFallbackHosts(environment);\n }\n\n const restHost = options.restHost || (production ? Defaults.REST_HOST : environment + '-' + Defaults.REST_HOST);\n const realtimeHost = getRealtimeHost(options, production, environment, loggerToUse);\n\n (options.fallbackHosts || []).concat(restHost, realtimeHost).forEach(checkHost);\n\n options.port = options.port || Defaults.PORT;\n options.tlsPort = options.tlsPort || Defaults.TLS_PORT;\n if (!('tls' in options)) options.tls = true;\n\n const timeouts = getTimeouts(options);\n\n if (MsgPack) {\n if ('useBinaryProtocol' in options) {\n options.useBinaryProtocol = Platform.Config.supportsBinary && options.useBinaryProtocol;\n } else {\n options.useBinaryProtocol = Platform.Config.preferBinary;\n }\n } else {\n options.useBinaryProtocol = false;\n }\n\n const headers: Record<string, string> = {};\n if (options.clientId) {\n headers['X-Ably-ClientId'] = Platform.BufferUtils.base64Encode(Platform.BufferUtils.utf8Encode(options.clientId));\n }\n\n if (!('idempotentRestPublishing' in options)) {\n options.idempotentRestPublishing = true;\n }\n\n let connectivityCheckParams = null;\n let connectivityCheckUrl = options.connectivityCheckUrl;\n if (options.connectivityCheckUrl) {\n let [uri, qs] = options.connectivityCheckUrl.split('?');\n connectivityCheckParams = qs ? Utils.parseQueryString(qs) : {};\n if (uri.indexOf('://') === -1) {\n uri = 'https://' + uri;\n }\n connectivityCheckUrl = uri;\n }\n\n let wsConnectivityCheckUrl = options.wsConnectivityCheckUrl;\n if (wsConnectivityCheckUrl && wsConnectivityCheckUrl.indexOf('://') === -1) {\n wsConnectivityCheckUrl = 'wss://' + wsConnectivityCheckUrl;\n }\n\n return {\n ...options,\n realtimeHost,\n restHost,\n maxMessageSize: options.maxMessageSize || Defaults.maxMessageSize,\n timeouts,\n connectivityCheckParams,\n connectivityCheckUrl,\n wsConnectivityCheckUrl,\n headers,\n };\n}\n\nexport function normaliseChannelOptions(Crypto: IUntypedCryptoStatic | null, logger: Logger, options?: ChannelOptions) {\n const channelOptions = options || {};\n if (channelOptions.cipher) {\n if (!Crypto) Utils.throwMissingPluginError('Crypto');\n const cipher = Crypto.getCipher(channelOptions.cipher, logger);\n channelOptions.cipher = cipher.cipherParams;\n channelOptions.channelCipher = cipher.cipher;\n } else if ('cipher' in channelOptions) {\n /* Don't deactivate an existing cipher unless options\n * has a 'cipher' key that's falsey */\n channelOptions.cipher = undefined;\n channelOptions.channelCipher = null;\n }\n return channelOptions;\n}\n\nconst contentTypes = {\n json: 'application/json',\n xml: 'application/xml',\n html: 'text/html',\n msgpack: 'application/x-msgpack',\n text: 'text/plain',\n};\n\nexport interface HeadersOptions {\n format?: Utils.Format | 'xml' | 'html' | 'text';\n protocolVersion?: number;\n}\n\nconst defaultHeadersOptions: Required<HeadersOptions> = {\n format: Utils.Format.json,\n protocolVersion: Defaults.protocolVersion,\n};\n\nexport function defaultGetHeaders(\n options: NormalisedClientOptions,\n {\n format = defaultHeadersOptions.format,\n protocolVersion = defaultHeadersOptions.protocolVersion,\n }: HeadersOptions = {},\n): Record<string, string> {\n const accept = contentTypes[format];\n return {\n accept: accept,\n 'X-Ably-Version': protocolVersion.toString(),\n 'Ably-Agent': getAgentString(options),\n };\n}\n\nexport function defaultPostHeaders(\n options: NormalisedClientOptions,\n {\n format = defaultHeadersOptions.format,\n protocolVersion = defaultHeadersOptions.protocolVersion,\n }: HeadersOptions = {},\n): Record<string, string> {\n let contentType;\n const accept = (contentType = contentTypes[format]);\n\n return {\n accept: accept,\n 'content-type': contentType,\n 'X-Ably-Version': protocolVersion.toString(),\n 'Ably-Agent': getAgentString(options),\n };\n}\n\nexport default Defaults as CompleteDefaults;\n\nexport function getDefaults(platformDefaults: IDefaults) {\n return Object.assign(Defaults, platformDefaults);\n}\n","import { StandardCallback } from 'common/types/utils';\nimport ErrorInfo from 'common/lib/types/errorinfo';\nimport Logger from './logger';\n\nexport interface MulticasterInstance<T> extends Function {\n (err?: ErrorInfo | null, result?: T): void;\n push: (fn: StandardCallback<T>) => void;\n /**\n * Creates a promise that will be resolved or rejected when this instance is called.\n */\n createPromise: () => Promise<T>;\n /**\n * Syntatic sugar for when working in a context that uses promises; equivalent to calling as a function with arguments (null, result).\n */\n resolveAll(result: T): void;\n /**\n * Syntatic sugar for when working in a context that uses promises; equivalent to calling as a function with arguments (err).\n */\n rejectAll(err: ErrorInfo): void;\n}\n\nclass Multicaster<T> {\n members: Array<StandardCallback<T>>;\n\n // Private constructor; use static Multicaster.create instead\n private constructor(\n private readonly logger: Logger,\n members?: Array<StandardCallback<T> | undefined>,\n ) {\n this.members = (members as Array<StandardCallback<T>>) || [];\n }\n\n private call(err?: ErrorInfo | null, result?: T): void {\n for (const member of this.members) {\n if (member) {\n try {\n member(err, result);\n } catch (e) {\n Logger.logAction(\n this.logger,\n Logger.LOG_ERROR,\n 'Multicaster multiple callback handler',\n 'Unexpected exception: ' + e + '; stack = ' + (e as Error).stack,\n );\n }\n }\n }\n }\n\n push(...args: Array<StandardCallback<T>>): void {\n this.members.push(...args);\n }\n\n createPromise(): Promise<T> {\n return new Promise((resolve, reject) => {\n this.push((err, result) => {\n err ? reject(err) : resolve(result!);\n });\n });\n }\n\n resolveAll(result: T) {\n this.call(null, result);\n }\n\n rejectAll(err: ErrorInfo) {\n this.call(err);\n }\n\n static create<T>(logger: Logger, members?: Array<StandardCallback<T> | undefined>): MulticasterInstance<T> {\n const instance = new Multicaster(logger, members);\n return Object.assign((err?: ErrorInfo | null, result?: T) => instance.call(err, result), {\n push: (fn: StandardCallback<T>) => instance.push(fn),\n createPromise: () => instance.createPromise(),\n resolveAll: (result: T) => instance.resolveAll(result),\n rejectAll: (err: ErrorInfo) => instance.rejectAll(err),\n });\n }\n}\n\nexport default Multicaster;\n","enum HttpMethods {\n Get = 'get',\n Delete = 'delete',\n Post = 'post',\n Put = 'put',\n Patch = 'patch',\n}\n\nexport default HttpMethods;\n","enum HttpStatusCodes {\n Success = 200,\n NoContent = 204,\n BadRequest = 400,\n Unauthorized = 401,\n Forbidden = 403,\n RequestTimeout = 408,\n InternalServerError = 500,\n}\n\nexport function isSuccessCode(statusCode: number) {\n return statusCode >= HttpStatusCodes.Success && statusCode < HttpStatusCodes.BadRequest;\n}\n\nexport default HttpStatusCodes;\n","import Logger from '../util/logger';\nimport * as Utils from '../util/utils';\nimport Multicaster, { MulticasterInstance } from '../util/multicaster';\nimport ErrorInfo, { IPartialErrorInfo } from '../types/errorinfo';\nimport { RequestResultError, RequestParams, RequestResult } from '../../types/http';\nimport * as API from '../../../../ably';\nimport BaseClient from './baseclient';\nimport BaseRealtime from './baserealtime';\nimport ClientOptions from '../../types/ClientOptions';\nimport HttpMethods from '../../constants/HttpMethods';\nimport HttpStatusCodes from 'common/constants/HttpStatusCodes';\nimport Platform, { Bufferlike } from '../../platform';\nimport Defaults from '../util/defaults';\n\ntype BatchResult<T> = API.BatchResult<T>;\ntype TokenRevocationTargetSpecifier = API.TokenRevocationTargetSpecifier;\ntype TokenRevocationOptions = API.TokenRevocationOptions;\ntype TokenRevocationSuccessResult = API.TokenRevocationSuccessResult;\ntype TokenRevocationFailureResult = API.TokenRevocationFailureResult;\ntype TokenRevocationResult = BatchResult<TokenRevocationSuccessResult | TokenRevocationFailureResult>;\n\nconst MAX_TOKEN_LENGTH = Math.pow(2, 17);\nfunction random() {\n return ('000000' + Math.floor(Math.random() * 1e16)).slice(-16);\n}\n\nfunction isRealtime(client: BaseClient): client is BaseRealtime {\n return !!(client as BaseRealtime).connection;\n}\n\n/* A client auth callback may give errors in any number of formats; normalise to an ErrorInfo or PartialErrorInfo */\nfunction normaliseAuthcallbackError(err: any) {\n if (!Utils.isErrorInfoOrPartialErrorInfo(err)) {\n return new ErrorInfo(Utils.inspectError(err), err.code || 40170, err.statusCode || 401);\n }\n /* network errors will not have an inherent error code */\n if (!err.code) {\n if (err.statusCode === 403) {\n err.code = 40300;\n } else {\n err.code = 40170;\n /* normalise statusCode to 401 per RSA4e */\n err.statusCode = 401;\n }\n }\n return err;\n}\n\nlet hmac = (text: string, key: string): string => {\n const bufferUtils = Platform.BufferUtils;\n\n const textBuffer = bufferUtils.utf8Encode(text);\n const keyBuffer = bufferUtils.utf8Encode(key);\n\n const digest = bufferUtils.hmacSha256(textBuffer, keyBuffer);\n\n return bufferUtils.base64Encode(digest);\n};\n\nfunction c14n(capability?: string | Record<string, Array<string>>) {\n if (!capability) return '';\n\n if (typeof capability == 'string') capability = JSON.parse(capability);\n\n const c14nCapability: Record<string, Array<string>> = Object.create(null);\n const keys = Utils.keysArray(capability as Record<string, Array<string>>, true);\n if (!keys) return '';\n keys.sort();\n for (let i = 0; i < keys.length; i++) {\n c14nCapability[keys[i]] = (capability as Record<string, Array<string>>)[keys[i]].sort();\n }\n return JSON.stringify(c14nCapability);\n}\n\nfunction logAndValidateTokenAuthMethod(authOptions: AuthOptions, logger: Logger) {\n if (authOptions.authCallback) {\n Logger.logAction(logger, Logger.LOG_MINOR, 'Auth()', 'using token auth with authCallback');\n } else if (authOptions.authUrl) {\n Logger.logAction(logger, Logger.LOG_MINOR, 'Auth()', 'using token auth with authUrl');\n } else if (authOptions.key) {\n Logger.logAction(logger, Logger.LOG_MINOR, 'Auth()', 'using token auth with client-side signing');\n } else if (authOptions.tokenDetails) {\n Logger.logAction(logger, Logger.LOG_MINOR, 'Auth()', 'using token auth with supplied token only');\n } else {\n const msg = 'authOptions must include valid authentication parameters';\n Logger.logAction(logger, Logger.LOG_ERROR, 'Auth()', msg);\n throw new Error(msg);\n }\n}\n\nfunction basicAuthForced(options: ClientOptions) {\n return 'useTokenAuth' in options && !options.useTokenAuth;\n}\n\n/* RSA4 */\nexport function useTokenAuth(options: ClientOptions) {\n return (\n options.useTokenAuth ||\n (!basicAuthForced(options) && (options.authCallback || options.authUrl || options.token || options.tokenDetails))\n );\n}\n\n/* RSA4a */\nfunction noWayToRenew(options: ClientOptions) {\n return !options.key && !options.authCallback && !options.authUrl;\n}\n\nlet trId = 0;\nfunction getTokenRequestId() {\n return trId++;\n}\n\n/**\n * Auth options used only for testing.\n */\ntype PrivateAuthOptions = {\n requestHeaders?: Record<string, string>;\n suppressMaxLengthCheck?: boolean;\n};\n\ntype AuthOptions = API.AuthOptions & PrivateAuthOptions;\n\nclass Auth {\n client: BaseClient;\n tokenParams: API.TokenParams;\n currentTokenRequestId: number | null;\n waitingForTokenRequest: MulticasterInstance<API.TokenDetails> | null;\n // This initialization is always overwritten and only used to prevent a TypeScript compiler error\n authOptions: AuthOptions = {} as AuthOptions;\n tokenDetails?: API.TokenDetails | null;\n method?: string;\n key?: string;\n basicKey?: string;\n clientId?: string | null;\n\n constructor(client: BaseClient, options: ClientOptions) {\n this.client = client;\n this.tokenParams = options.defaultTokenParams || {};\n /* The id of the current token request if one is in progress, else null */\n this.currentTokenRequestId = null;\n this.waitingForTokenRequest = null;\n\n if (useTokenAuth(options)) {\n /* Token auth */\n if (noWayToRenew(options)) {\n Logger.logAction(\n this.logger,\n Logger.LOG_ERROR,\n 'Auth()',\n 'Warning: library initialized with a token literal without any way to renew the token when it expires (no authUrl, authCallback, or key). See https://help.ably.io/error/40171 for help',\n );\n }\n this._saveTokenOptions(options.defaultTokenParams as API.TokenDetails, options);\n logAndValidateTokenAuthMethod(this.authOptions, this.logger);\n } else {\n /* Basic auth */\n if (!options.key) {\n const msg =\n 'No authentication options provided; need one of: key, authUrl, or authCallback (or for testing only, token or tokenDetails)';\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'Auth()', msg);\n throw new ErrorInfo(msg, 40160, 401);\n }\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Auth()', 'anonymous, using basic auth');\n this._saveBasicOptions(options);\n }\n }\n\n get logger(): Logger {\n return this.client.logger;\n }\n\n /**\n * Instructs the library to get a token immediately and ensures Token Auth\n * is used for all future requests, storing the tokenParams and authOptions\n * given as the new defaults for subsequent use.\n */\n async authorize(): Promise<API.TokenDetails>;\n\n /**\n * Instructs the library to get a token immediately and ensures Token Auth\n * is used for all future requests, storing the tokenParams and authOptions\n * given as the new defaults for subsequent use.\n *\n * @param tokenParams\n * an object containing the parameters for the requested token:\n *\n * - ttl: (optional) the requested life of any new token in ms. If none\n * is specified a default of 1 hour is provided. The maximum lifetime\n * is 24hours; any request exceeding that lifetime will be rejected\n * with an error.\n *\n * - capability: (optional) the capability to associate with the access token.\n * If none is specified, a token will be requested with all of the\n * capabilities of the specified key.\n *\n * - clientId: (optional) a client ID to associate with the token\n *\n * - timestamp: (optional) the time in ms since the epoch. If none is specified,\n * the system will be queried for a time value to use.\n */\n async authorize(tokenParams: API.TokenParams | null): Promise<API.TokenDetails>;\n\n /**\n * Instructs the library to get a token immediately and ensures Token Auth\n * is used for all future requests, storing the tokenParams and authOptions\n * given as the new defaults for subsequent use.\n *\n * @param tokenParams\n * an object containing the parameters for the requested token:\n *\n * - ttl: (optional) the requested life of any new token in ms. If none\n * is specified a default of 1 hour is provided. The maximum lifetime\n * is 24hours; any request exceeding that lifetime will be rejected\n * with an error.\n *\n * - capability: (optional) the capability to associate with the access token.\n * If none is specified, a token will be requested with all of the\n * capabilities of the specified key.\n *\n * - clientId: (optional) a client ID to associate with the token\n *\n * - timestamp: (optional) the time in ms since the epoch. If none is specified,\n * the system will be queried for a time value to use.\n *\n * @param authOptions\n * an object containing auth options relevant to token auth:\n *\n * - queryTime (optional) boolean indicating that the Ably system should be\n * queried for the current time when none is specified explicitly.\n *\n * - tokenDetails: (optional) object: An authenticated TokenDetails object.\n *\n * - token: (optional) string: the `token` property of a tokenDetails object\n *\n * - authCallback: (optional) a JavaScript callback to be called to get auth information.\n * authCallback should be a function of (tokenParams, callback) that calls\n * the callback with (err, result), where result is any of:\n * - a tokenRequest object (ie the result of a rest.auth.createTokenRequest call),\n * - a tokenDetails object (ie the result of a rest.auth.requestToken call),\n * - a token string\n *\n * - authUrl: (optional) a URL to be used to GET or POST a set of token request\n * params, to obtain a signed token request.\n *\n * - authHeaders: (optional) a set of application-specific headers to be added to any request\n * made to the authUrl.\n *\n * - authParams: (optional) a set of application-specific query params to be added to any\n * request made to the authUrl.\n *\n *\n * - requestHeaders (optional, unsupported, for testing only) extra headers to add to the\n * requestToken request\n */\n async authorize(tokenParams: API.TokenParams | null, authOptions: AuthOptions | null): Promise<API.TokenDetails>;\n\n async authorize(\n tokenParams?: Record<string, any> | null,\n authOptions?: AuthOptions | null,\n ): Promise<API.TokenDetails> {\n /* RSA10a: authorize() call implies token auth. If a key is passed it, we\n * just check if it doesn't clash and assume we're generating a token from it */\n if (authOptions && authOptions.key && this.authOptions.key !== authOptions.key) {\n throw new ErrorInfo('Unable to update auth options with incompatible key', 40102, 401);\n }\n\n try {\n let tokenDetails = await this._forceNewToken(tokenParams ?? null, authOptions ?? null);\n\n /* RTC8\n * - When authorize called by an end user and have a realtime connection,\n * don't call back till new token has taken effect.\n * - Use this.client.connection as a proxy for (this.client instanceof BaseRealtime),\n * which doesn't work in node as BaseRealtime isn't part of the vm context for Rest clients */\n if (isRealtime(this.client)) {\n return new Promise((resolve, reject) => {\n (this.client as BaseRealtime).connection.connectionManager.onAuthUpdated(\n tokenDetails,\n (err: unknown, tokenDetails?: API.TokenDetails) => (err ? reject(err) : resolve(tokenDetails!)),\n );\n });\n } else {\n return tokenDetails;\n }\n } catch (err) {\n if ((this.client as BaseRealtime).connection && (err as ErrorInfo).statusCode === HttpStatusCodes.Forbidden) {\n /* Per RSA4d & RSA4d1, if the auth server explicitly repudiates our right to\n * stay connecticed by returning a 403, we actively disconnect the connection\n * even though we may well still have time left in the old token. */\n (this.client as BaseRealtime).connection.connectionManager.actOnErrorFromAuthorize(err as ErrorInfo);\n }\n throw err;\n }\n }\n\n /* For internal use, eg by connectionManager - useful when want to call back\n * as soon as we have the new token, rather than waiting for it to take\n * effect on the connection as #authorize does */\n async _forceNewToken(\n tokenParams: API.TokenParams | null,\n authOptions: AuthOptions | null,\n ): Promise<API.TokenDetails> {\n /* get rid of current token even if still valid */\n this.tokenDetails = null;\n\n /* _save normalises the tokenParams and authOptions and updates the auth\n * object. All subsequent operations should use the values on `this`,\n * not the passed in ones. */\n this._saveTokenOptions(tokenParams, authOptions);\n\n logAndValidateTokenAuthMethod(this.authOptions, this.logger);\n\n try {\n return this._ensureValidAuthCredentials(true);\n } finally {\n /* RSA10g */\n delete this.tokenParams.timestamp;\n delete this.authOptions.queryTime;\n }\n }\n\n /**\n * Request an access token\n */\n async requestToken(): Promise<API.TokenDetails>;\n\n /**\n * Request an access token\n * @param tokenParams\n * an object containing the parameters for the requested token:\n * - ttl: (optional) the requested life of the token in milliseconds. If none is specified\n * a default of 1 hour is provided. The maximum lifetime is 24hours; any request\n * exceeding that lifetime will be rejected with an error.\n *\n * - capability: (optional) the capability to associate with the access token.\n * If none is specified, a token will be requested with all of the\n * capabilities of the specified key.\n *\n * - clientId: (optional) a client ID to associate with the token; if not\n * specified, a clientId passed in constructing the Rest interface will be used\n *\n * - timestamp: (optional) the time in ms since the epoch. If none is specified,\n * the system will be queried for a time value to use.\n */\n async requestToken(tokenParams: API.TokenParams | null): Promise<API.TokenDetails>;\n\n /**\n * Request an access token\n * @param tokenParams\n * an object containing the parameters for the requested token:\n * - ttl: (optional) the requested life of the token in milliseconds. If none is specified\n * a default of 1 hour is provided. The maximum lifetime is 24hours; any request\n * exceeding that lifetime will be rejected with an error.\n *\n * - capability: (optional) the capability to associate with the access token.\n * If none is specified, a token will be requested with all of the\n * capabilities of the specified key.\n *\n * - clientId: (optional) a client ID to associate with the token; if not\n * specified, a clientId passed in constructing the Rest interface will be used\n *\n * - timestamp: (optional) the time in ms since the epoch. If none is specified,\n * the system will be queried for a time value to use.\n *\n * @param authOptions\n * an object containing the request options:\n * - key: the key to use.\n *\n * - authCallback: (optional) a JavaScript callback to be called to get auth information.\n * authCallback should be a function of (tokenParams, callback) that calls\n * the callback with (err, result), where result is any of:\n * - a tokenRequest object (ie the result of a rest.auth.createTokenRequest call),\n * - a tokenDetails object (ie the result of a rest.auth.requestToken call),\n * - a token string\n *\n * - authUrl: (optional) a URL to be used to GET or POST a set of token request\n * params, to obtain a signed token request.\n *\n * - authHeaders: (optional) a set of application-specific headers to be added to any request\n * made to the authUrl.\n *\n * - authParams: (optional) a set of application-specific query params to be added to any\n * request made to the authUrl.\n *\n * - queryTime (optional) boolean indicating that the ably system should be\n * queried for the current time when none is specified explicitly\n *\n * - requestHeaders (optional, unsupported, for testing only) extra headers to add to the\n * requestToken request\n */\n async requestToken(tokenParams: API.TokenParams | null, authOptions: AuthOptions): Promise<API.TokenDetails>;\n\n async requestToken(tokenParams?: API.TokenParams | null, authOptions?: AuthOptions): Promise<API.TokenDetails> {\n /* RSA8e: if authOptions passed in, they're used instead of stored, don't merge them */\n const resolvedAuthOptions = authOptions || this.authOptions;\n const resolvedTokenParams = tokenParams || Utils.copy(this.tokenParams);\n\n /* first set up whatever callback will be used to get signed\n * token requests */\n let tokenRequestCallback: (\n data: API.TokenParams,\n callback: (\n error: API.ErrorInfo | RequestResultError | string | null,\n tokenRequestOrDetails: API.TokenDetails | API.TokenRequest | string | null,\n contentType?: string,\n ) => void,\n ) => void,\n client = this.client;\n\n if (resolvedAuthOptions.authCallback) {\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Auth.requestToken()', 'using token auth with authCallback');\n tokenRequestCallback = resolvedAuthOptions.authCallback;\n } else if (resolvedAuthOptions.authUrl) {\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Auth.requestToken()', 'using token auth with authUrl');\n tokenRequestCallback = (params, cb) => {\n const authHeaders = Utils.mixin(\n { accept: 'application/json, text/plain' },\n resolvedAuthOptions.authHeaders,\n ) as Record<string, string>;\n const usePost = resolvedAuthOptions.authMethod && resolvedAuthOptions.authMethod.toLowerCase() === 'post';\n let providedQsParams;\n /* Combine authParams with any qs params given in the authUrl */\n const queryIdx = resolvedAuthOptions.authUrl!.indexOf('?');\n if (queryIdx > -1) {\n providedQsParams = Utils.parseQueryString(resolvedAuthOptions.authUrl!.slice(queryIdx));\n resolvedAuthOptions.authUrl = resolvedAuthOptions.authUrl!.slice(0, queryIdx);\n if (!usePost) {\n /* In case of conflict, authParams take precedence over qs params in the authUrl */\n resolvedAuthOptions.authParams = Utils.mixin(\n providedQsParams,\n resolvedAuthOptions.authParams,\n ) as typeof resolvedAuthOptions.authParams;\n }\n }\n /* RSA8c2 */\n const authParams = Utils.mixin({}, resolvedAuthOptions.authParams || {}, params) as RequestParams;\n const authUrlRequestCallback = (result: RequestResult) => {\n let body = (result.body ?? null) as string | Bufferlike | API.TokenDetails | API.TokenRequest | null;\n\n let contentType: string | null = null;\n if (result.error) {\n Logger.logAction(\n this.logger,\n Logger.LOG_MICRO,\n 'Auth.requestToken().tokenRequestCallback',\n 'Received Error: ' + Utils.inspectError(result.error),\n );\n } else {\n const contentTypeHeaderOrHeaders = result.headers!['content-type'] ?? null;\n if (Array.isArray(contentTypeHeaderOrHeaders)) {\n // Combine multiple header values into a comma-separated list per https://datatracker.ietf.org/doc/html/rfc9110#section-5.2; see https://github.com/ably/ably-js/issues/1616 for doing this consistently across the codebase.\n contentType = contentTypeHeaderOrHeaders.join(', ');\n } else {\n contentType = contentTypeHeaderOrHeaders;\n }\n Logger.logAction(\n this.logger,\n Logger.LOG_MICRO,\n 'Auth.requestToken().tokenRequestCallback',\n 'Received; content-type: ' + contentType + '; body: ' + Utils.inspectBody(body),\n );\n }\n if (result.error) {\n cb(result.error, null);\n return;\n }\n if (result.unpacked) {\n cb(null, body as Exclude<typeof body, Bufferlike>);\n return;\n }\n if (Platform.BufferUtils.isBuffer(body)) body = body.toString();\n if (!contentType) {\n cb(new ErrorInfo('authUrl response is missing a content-type header', 40170, 401), null);\n return;\n }\n const json = contentType.indexOf('application/json') > -1,\n text = contentType.indexOf('text/plain') > -1 || contentType.indexOf('application/jwt') > -1;\n if (!json && !text) {\n cb(\n new ErrorInfo(\n 'authUrl responded with unacceptable content-type ' +\n contentType +\n ', should be either text/plain, application/jwt or application/json',\n 40170,\n 401,\n ),\n null,\n );\n return;\n }\n if (json) {\n if ((body as string).length > MAX_TOKEN_LENGTH) {\n cb(new ErrorInfo('authUrl response exceeded max permitted length', 40170, 401), null);\n return;\n }\n try {\n body = JSON.parse(body as string);\n } catch (e) {\n cb(\n new ErrorInfo(\n 'Unexpected error processing authURL response; err = ' + (e as Error).message,\n 40170,\n 401,\n ),\n null,\n );\n return;\n }\n }\n cb(null, body as Exclude<typeof body, Bufferlike>, contentType);\n };\n Logger.logAction(\n this.logger,\n Logger.LOG_MICRO,\n 'Auth.requestToken().tokenRequestCallback',\n 'Requesting token from ' +\n resolvedAuthOptions.authUrl +\n '; Params: ' +\n JSON.stringify(authParams) +\n '; method: ' +\n (usePost ? 'POST' : 'GET'),\n );\n if (usePost) {\n /* send body form-encoded */\n const headers = authHeaders || {};\n headers['content-type'] = 'application/x-www-form-urlencoded';\n const body = Utils.toQueryString(authParams).slice(1); /* slice is to remove the initial '?' */\n Utils.whenPromiseSettles(\n this.client.http.doUri(\n HttpMethods.Post,\n resolvedAuthOptions.authUrl!,\n headers,\n body,\n providedQsParams as Record<string, string>,\n ),\n (err: any, result) =>\n err\n ? authUrlRequestCallback(err) // doUri isn’t meant to throw an error, but handle any just in case\n : authUrlRequestCallback(result!),\n );\n } else {\n Utils.whenPromiseSettles(\n this.client.http.doUri(HttpMethods.Get, resolvedAuthOptions.authUrl!, authHeaders || {}, null, authParams),\n (err: any, result) =>\n err\n ? authUrlRequestCallback(err) // doUri isn’t meant to throw an error, but handle any just in case\n : authUrlRequestCallback(result!),\n );\n }\n };\n } else if (resolvedAuthOptions.key) {\n Logger.logAction(\n this.logger,\n Logger.LOG_MINOR,\n 'Auth.requestToken()',\n 'using token auth with client-side signing',\n );\n tokenRequestCallback = (params, cb) => {\n Utils.whenPromiseSettles(this.createTokenRequest(params, resolvedAuthOptions), (err, result) =>\n cb(err as string | ErrorInfo | null, result ?? null),\n );\n };\n } else {\n const msg =\n 'Need a new token, but authOptions does not include any way to request one (no authUrl, authCallback, or key)';\n Logger.logAction(\n this.logger,\n Logger.LOG_ERROR,\n 'Auth()',\n 'library initialized with a token literal without any way to renew the token when it expires (no authUrl, authCallback, or key). See https://help.ably.io/error/40171 for help',\n );\n throw new ErrorInfo(msg, 40171, 403);\n }\n\n /* normalise token params */\n if ('capability' in (resolvedTokenParams as Record<string, any>))\n (resolvedTokenParams as Record<string, any>).capability = c14n(\n (resolvedTokenParams as Record<string, any>).capability,\n );\n\n const tokenRequest = (\n signedTokenParams: Record<string, any>,\n tokenCb: (err: RequestResultError | null, tokenResponse?: API.TokenDetails | string, unpacked?: boolean) => void,\n ) => {\n const keyName = signedTokenParams.keyName,\n path = '/keys/' + keyName + '/requestToken',\n tokenUri = function (host: string) {\n return client.baseUri(host) + path;\n };\n\n const requestHeaders = Defaults.defaultPostHeaders(this.client.options);\n if (resolvedAuthOptions.requestHeaders) Utils.mixin(requestHeaders, resolvedAuthOptions.requestHeaders);\n Logger.logAction(\n this.logger,\n Logger.LOG_MICRO,\n 'Auth.requestToken().requestToken',\n 'Sending POST to ' + path + '; Token params: ' + JSON.stringify(signedTokenParams),\n );\n Utils.whenPromiseSettles(\n this.client.http.do(HttpMethods.Post, tokenUri, requestHeaders, JSON.stringify(signedTokenParams), null),\n (err: any, result) =>\n err\n ? tokenCb(err) // doUri isn’t meant to throw an error, but handle any just in case\n : tokenCb(result!.error, result!.body as API.TokenDetails | string | undefined, result!.unpacked),\n );\n };\n\n return new Promise((resolve, reject) => {\n let tokenRequestCallbackTimeoutExpired = false,\n timeoutLength = this.client.options.timeouts.realtimeRequestTimeout,\n tokenRequestCallbackTimeout = setTimeout(() => {\n tokenRequestCallbackTimeoutExpired = true;\n const msg = 'Token request callback timed out after ' + timeoutLength / 1000 + ' seconds';\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'Auth.requestToken()', msg);\n reject(new ErrorInfo(msg, 40170, 401));\n }, timeoutLength);\n\n tokenRequestCallback!(resolvedTokenParams, (err, tokenRequestOrDetails, contentType) => {\n if (tokenRequestCallbackTimeoutExpired) return;\n clearTimeout(tokenRequestCallbackTimeout);\n\n if (err) {\n Logger.logAction(\n this.logger,\n Logger.LOG_ERROR,\n 'Auth.requestToken()',\n 'token request signing call returned error; err = ' + Utils.inspectError(err),\n );\n reject(normaliseAuthcallbackError(err));\n return;\n }\n /* the response from the callback might be a token string, a signed request or a token details */\n if (typeof tokenRequestOrDetails === 'string') {\n if (tokenRequestOrDetails.length === 0) {\n reject(new ErrorInfo('Token string is empty', 40170, 401));\n } else if (tokenRequestOrDetails.length > MAX_TOKEN_LENGTH) {\n reject(\n new ErrorInfo(\n 'Token string exceeded max permitted length (was ' + tokenRequestOrDetails.length + ' bytes)',\n 40170,\n 401,\n ),\n );\n } else if (tokenRequestOrDetails === 'undefined' || tokenRequestOrDetails === 'null') {\n /* common failure mode with poorly-implemented authCallbacks */\n reject(new ErrorInfo('Token string was literal null/undefined', 40170, 401));\n } else if (\n tokenRequestOrDetails[0] === '{' &&\n !(contentType && contentType.indexOf('application/jwt') > -1)\n ) {\n reject(\n new ErrorInfo(\n \"Token was double-encoded; make sure you're not JSON-encoding an already encoded token request or details\",\n 40170,\n 401,\n ),\n );\n } else {\n resolve({ token: tokenRequestOrDetails } as API.TokenDetails);\n }\n return;\n }\n if (typeof tokenRequestOrDetails !== 'object' || tokenRequestOrDetails === null) {\n const msg =\n 'Expected token request callback to call back with a token string or token request/details object, but got a ' +\n typeof tokenRequestOrDetails;\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'Auth.requestToken()', msg);\n reject(new ErrorInfo(msg, 40170, 401));\n return;\n }\n const objectSize = JSON.stringify(tokenRequestOrDetails).length;\n if (objectSize > MAX_TOKEN_LENGTH && !resolvedAuthOptions.suppressMaxLengthCheck) {\n reject(\n new ErrorInfo(\n 'Token request/details object exceeded max permitted stringified size (was ' + objectSize + ' bytes)',\n 40170,\n 401,\n ),\n );\n return;\n }\n if ('issued' in tokenRequestOrDetails) {\n /* a tokenDetails object */\n resolve(tokenRequestOrDetails);\n return;\n }\n if (!('keyName' in tokenRequestOrDetails)) {\n const msg =\n 'Expected token request callback to call back with a token string, token request object, or token details object';\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'Auth.requestToken()', msg);\n reject(new ErrorInfo(msg, 40170, 401));\n return;\n }\n /* it's a token request, so make the request */\n tokenRequest(tokenRequestOrDetails, (err, tokenResponse, unpacked) => {\n if (err) {\n Logger.logAction(\n this.logger,\n Logger.LOG_ERROR,\n 'Auth.requestToken()',\n 'token request API call returned error; err = ' + Utils.inspectError(err),\n );\n reject(normaliseAuthcallbackError(err));\n return;\n }\n if (!unpacked) tokenResponse = JSON.parse(tokenResponse as string);\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Auth.getToken()', 'token received');\n resolve(tokenResponse as API.TokenDetails);\n });\n });\n });\n }\n\n /**\n * Create and sign a token request based on the given options.\n * NOTE this can only be used when the key value is available locally.\n * Otherwise, signed token requests must be obtained from the key\n * owner (either using the token request callback or url).\n *\n * @param authOptions\n * an object containing the request options:\n * - key: the key to use. If not specified, a key passed in constructing\n * the Rest interface will be used\n *\n * - queryTime (optional) boolean indicating that the ably system should be\n * queried for the current time when none is specified explicitly\n *\n * - requestHeaders (optional, unsupported, for testing only) extra headers to add to the\n * requestToken request\n *\n * @param tokenParams\n * an object containing the parameters for the requested token:\n * - ttl: (optional) the requested life of the token in ms. If none is specified\n * a default of 1 hour is provided. The maximum lifetime is 24hours; any request\n * exceeding that lifetime will be rejected with an error.\n *\n * - capability: (optional) the capability to associate with the access token.\n * If none is specified, a token will be requested with all of the\n * capabilities of the specified key.\n *\n * - clientId: (optional) a client ID to associate with the token; if not\n * specified, a clientId passed in constructing the Rest interface will be used\n *\n * - timestamp: (optional) the time in ms since the epoch. If none is specified,\n * the system will be queried for a time value to use.\n */\n async createTokenRequest(tokenParams: API.TokenParams | null, authOptions: any): Promise<API.TokenRequest> {\n /* RSA9h: if authOptions passed in, they're used instead of stored, don't merge them */\n authOptions = authOptions || this.authOptions;\n tokenParams = tokenParams || Utils.copy<API.TokenParams>(this.tokenParams);\n\n const key = authOptions.key;\n if (!key) {\n throw new ErrorInfo('No key specified', 40101, 403);\n }\n const keyParts = key.split(':'),\n keyName = keyParts[0],\n keySecret = keyParts[1];\n\n if (!keySecret) {\n throw new ErrorInfo('Invalid key specified', 40101, 403);\n }\n\n if (tokenParams.clientId === '') {\n throw new ErrorInfo('clientId can’t be an empty string', 40012, 400);\n }\n\n if ('capability' in tokenParams) {\n tokenParams.capability = c14n(tokenParams.capability);\n }\n\n const request: Partial<API.TokenRequest> = Utils.mixin({ keyName: keyName }, tokenParams),\n clientId = tokenParams.clientId || '',\n ttl = tokenParams.ttl || '',\n capability = tokenParams.capability || '';\n\n if (!request.timestamp) {\n request.timestamp = await this.getTimestamp(authOptions && authOptions.queryTime);\n }\n\n /* nonce */\n /* NOTE: there is no expectation that the client\n * specifies the nonce; this is done by the library\n * However, this can be overridden by the client\n * simply for testing purposes. */\n const nonce = request.nonce || (request.nonce = random()),\n timestamp = request.timestamp;\n\n const signText =\n request.keyName + '\\n' + ttl + '\\n' + capability + '\\n' + clientId + '\\n' + timestamp + '\\n' + nonce + '\\n';\n\n /* mac */\n /* NOTE: there is no expectation that the client\n * specifies the mac; this is done by the library\n * However, this can be overridden by the client\n * simply for testing purposes. */\n request.mac = request.mac || hmac(signText, keySecret);\n\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Auth.getTokenRequest()', 'generated signed request');\n\n return request as API.TokenRequest;\n }\n\n /**\n * Get the auth query params to use for a websocket connection,\n * based on the current auth parameters\n */\n async getAuthParams(): Promise<Record<string, string>> {\n if (this.method == 'basic') return { key: this.key! };\n else {\n let tokenDetails = await this._ensureValidAuthCredentials(false);\n if (!tokenDetails) {\n throw new Error('Auth.getAuthParams(): _ensureValidAuthCredentials returned no error or tokenDetails');\n }\n return { access_token: tokenDetails.token };\n }\n }\n\n /**\n * Get the authorization header to use for a REST or comet request,\n * based on the current auth parameters\n */\n async getAuthHeaders(): Promise<Record<string, string>> {\n if (this.method == 'basic') {\n return { authorization: 'Basic ' + this.basicKey };\n } else {\n const tokenDetails = await this._ensureValidAuthCredentials(false);\n if (!tokenDetails) {\n throw new Error('Auth.getAuthParams(): _ensureValidAuthCredentials returned no error or tokenDetails');\n }\n return { authorization: 'Bearer ' + Utils.toBase64(tokenDetails.token) };\n }\n }\n\n /**\n * Get the current time based on the local clock,\n * or if the option queryTime is true, return the server time.\n * The server time offset from the local time is stored so that\n * only one request to the server to get the time is ever needed\n */\n async getTimestamp(queryTime: boolean): Promise<number> {\n if (!this.isTimeOffsetSet() && (queryTime || this.authOptions.queryTime)) {\n return this.client.time();\n } else {\n return this.getTimestampUsingOffset();\n }\n }\n\n getTimestampUsingOffset() {\n return Date.now() + (this.client.serverTimeOffset || 0);\n }\n\n isTimeOffsetSet() {\n return this.client.serverTimeOffset !== null;\n }\n\n _saveBasicOptions(authOptions: AuthOptions) {\n this.method = 'basic';\n this.key = authOptions.key;\n this.basicKey = Utils.toBase64(authOptions.key as string);\n this.authOptions = authOptions || {};\n if ('clientId' in authOptions) {\n this._userSetClientId(authOptions.clientId);\n }\n }\n\n _saveTokenOptions(tokenParams: API.TokenParams | null, authOptions: AuthOptions | null) {\n this.method = 'token';\n\n if (tokenParams) {\n /* We temporarily persist tokenParams.timestamp in case a new token needs\n * to be requested, then null it out in the callback of\n * _ensureValidAuthCredentials for RSA10g compliance */\n this.tokenParams = tokenParams;\n }\n\n if (authOptions) {\n /* normalise */\n if (authOptions.token) {\n /* options.token may contain a token string or, for convenience, a TokenDetails */\n authOptions.tokenDetails =\n typeof authOptions.token === 'string'\n ? ({ token: authOptions.token } as API.TokenDetails)\n : authOptions.token;\n }\n\n if (authOptions.tokenDetails) {\n this.tokenDetails = authOptions.tokenDetails;\n }\n\n if ('clientId' in authOptions) {\n this._userSetClientId(authOptions.clientId);\n }\n\n this.authOptions = authOptions;\n }\n }\n\n /* @param forceSupersede: force a new token request even if there's one in\n * progress, making all pending callbacks wait for the new one */\n async _ensureValidAuthCredentials(forceSupersede: boolean): Promise<API.TokenDetails> {\n const token = this.tokenDetails;\n\n if (token) {\n if (this._tokenClientIdMismatch(token.clientId)) {\n /* 403 to trigger a permanently failed client - RSA15c */\n throw new ErrorInfo(\n 'Mismatch between clientId in token (' + token.clientId + ') and current clientId (' + this.clientId + ')',\n 40102,\n 403,\n );\n }\n /* RSA4b1 -- if we have a server time offset set already, we can\n * automatically remove expired tokens. Else just use the cached token. If it is\n * expired Ably will tell us and we'll discard it then. */\n if (!this.isTimeOffsetSet() || !token.expires || token.expires >= this.getTimestampUsingOffset()) {\n Logger.logAction(\n this.logger,\n Logger.LOG_MINOR,\n 'Auth.getToken()',\n 'using cached token; expires = ' + token.expires,\n );\n return token;\n }\n /* expired, so remove and fallthrough to getting a new one */\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Auth.getToken()', 'deleting expired token');\n this.tokenDetails = null;\n }\n\n const promise = (\n this.waitingForTokenRequest || (this.waitingForTokenRequest = Multicaster.create(this.logger))\n ).createPromise();\n if (this.currentTokenRequestId !== null && !forceSupersede) {\n return promise;\n }\n\n /* Request a new token */\n const tokenRequestId = (this.currentTokenRequestId = getTokenRequestId());\n\n let tokenResponse: API.TokenDetails,\n caughtError: ErrorInfo | null = null;\n try {\n tokenResponse = await this.requestToken(this.tokenParams, this.authOptions);\n } catch (err) {\n caughtError = err as ErrorInfo;\n }\n\n if ((this.currentTokenRequestId as number) > tokenRequestId) {\n Logger.logAction(\n this.logger,\n Logger.LOG_MINOR,\n 'Auth._ensureValidAuthCredentials()',\n 'Discarding token request response; overtaken by newer one',\n );\n return promise;\n }\n\n this.currentTokenRequestId = null;\n const multicaster = this.waitingForTokenRequest;\n this.waitingForTokenRequest = null;\n if (caughtError) {\n multicaster?.rejectAll(caughtError);\n return promise;\n }\n multicaster?.resolveAll((this.tokenDetails = tokenResponse!));\n\n return promise;\n }\n\n /* User-set: check types, '*' is disallowed, throw any errors */\n _userSetClientId(clientId: string | undefined) {\n if (!(typeof clientId === 'string' || clientId === null)) {\n throw new ErrorInfo('clientId must be either a string or null', 40012, 400);\n } else if (clientId === '*') {\n throw new ErrorInfo(\n 'Can’t use \"*\" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, instantiate the library with {defaultTokenParams: {clientId: \"*\"}}), or if calling authorize(), pass it in as a tokenParam: authorize({clientId: \"*\"}, authOptions)',\n 40012,\n 400,\n );\n } else {\n const err = this._uncheckedSetClientId(clientId);\n if (err) throw err;\n }\n }\n\n /* Ably-set: no typechecking, '*' is allowed but not set on this.clientId), return errors to the caller */\n _uncheckedSetClientId(clientId: string | undefined) {\n if (this._tokenClientIdMismatch(clientId)) {\n /* Should never happen in normal circumstances as realtime should\n * recognise mismatch and return an error */\n const msg = 'Unexpected clientId mismatch: client has ' + this.clientId + ', requested ' + clientId;\n const err = new ErrorInfo(msg, 40102, 401);\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'Auth._uncheckedSetClientId()', msg);\n return err;\n } else {\n /* RSA7a4: if options.clientId is provided and is not\n * null, it overrides defaultTokenParams.clientId */\n this.clientId = this.tokenParams.clientId = clientId;\n return null;\n }\n }\n\n _tokenClientIdMismatch(tokenClientId?: string | null): boolean {\n return !!(\n this.clientId &&\n this.clientId !== '*' &&\n tokenClientId &&\n tokenClientId !== '*' &&\n this.clientId !== tokenClientId\n );\n }\n\n static isTokenErr(error: IPartialErrorInfo) {\n return error.code && error.code >= 40140 && error.code < 40150;\n }\n\n revokeTokens(\n specifiers: TokenRevocationTargetSpecifier[],\n options?: TokenRevocationOptions,\n ): Promise<TokenRevocationResult> {\n return this.client.rest.revokeTokens(specifiers, options);\n }\n}\n\nexport default Auth;\n","import Defaults from 'common/lib/util/defaults';\r\nimport Platform from 'common/platform';\r\nimport BaseRealtime from 'common/lib/client/baserealtime';\r\nimport HttpMethods from '../constants/HttpMethods';\r\nimport BaseClient from '../lib/client/baseclient';\r\nimport ErrorInfo, { IPartialErrorInfo } from '../lib/types/errorinfo';\r\nimport Logger from 'common/lib/util/logger';\r\nimport * as Utils from 'common/lib/util/utils';\r\n\r\nexport type PathParameter = string | ((host: string) => string);\r\nexport type ResponseHeaders = Partial<Record<string, string | string[]>>;\r\nexport type RequestResultError = ErrnoException | IPartialErrorInfo;\r\n\r\n/**\r\n * The `body`, `headers`, `unpacked`, and `statusCode` properties of a `RequestResult` may be populated even if its `error` property is non-null.\r\n */\r\nexport type RequestResult = {\r\n error: RequestResultError | null;\r\n body?: unknown;\r\n headers?: ResponseHeaders;\r\n unpacked?: boolean;\r\n statusCode?: number;\r\n};\r\n\r\nexport type RequestParams = Record<string, string> | null;\r\nexport type RequestBody =\r\n | Buffer // only on Node\r\n | ArrayBuffer // only on web\r\n | string;\r\n\r\nexport interface IPlatformHttpStatic {\r\n new (client?: BaseClient): IPlatformHttp;\r\n methods: Array<HttpMethods>;\r\n methodsWithBody: Array<HttpMethods>;\r\n methodsWithoutBody: Array<HttpMethods>;\r\n}\r\n\r\nexport interface IPlatformHttp {\r\n supportsAuthHeaders: boolean;\r\n supportsLinkHeaders: boolean;\r\n\r\n /**\r\n * This method should not throw any errors; rather, it should communicate any error by populating the {@link RequestResult.error} property of the returned {@link RequestResult}.\r\n */\r\n doUri(\r\n method: HttpMethods,\r\n uri: string,\r\n headers: Record<string, string> | null,\r\n body: RequestBody | null,\r\n params: RequestParams,\r\n ): Promise<RequestResult>;\r\n\r\n checkConnectivity?: () => Promise<boolean>;\r\n\r\n /**\r\n * @param error An error from the {@link RequestResult.error} property of a result returned by {@link doUri}.\r\n */\r\n shouldFallback(error: RequestResultError): boolean;\r\n}\r\n\r\nexport function paramString(params: Record<string, any> | null) {\r\n const paramPairs = [];\r\n if (params) {\r\n for (const needle in params) {\r\n paramPairs.push(needle + '=' + params[needle]);\r\n }\r\n }\r\n return paramPairs.join('&');\r\n}\r\n\r\nexport function appendingParams(uri: string, params: Record<string, any> | null) {\r\n return uri + (params ? '?' : '') + paramString(params);\r\n}\r\n\r\nfunction logResult(\r\n result: RequestResult,\r\n method: HttpMethods,\r\n uri: string,\r\n params: Record<string, string> | null,\r\n logger: Logger,\r\n) {\r\n if (result.error) {\r\n Logger.logActionNoStrip(\r\n logger,\r\n Logger.LOG_MICRO,\r\n 'Http.' + method + '()',\r\n 'Received Error; ' + appendingParams(uri, params) + '; Error: ' + Utils.inspectError(result.error),\r\n );\r\n } else {\r\n Logger.logActionNoStrip(\r\n logger,\r\n Logger.LOG_MICRO,\r\n 'Http.' + method + '()',\r\n 'Received; ' +\r\n appendingParams(uri, params) +\r\n '; Headers: ' +\r\n paramString(result.headers as Record<string, any>) +\r\n '; StatusCode: ' +\r\n result.statusCode +\r\n '; Body' +\r\n (Platform.BufferUtils.isBuffer(result.body)\r\n ? ' (Base64): ' + Platform.BufferUtils.base64Encode(result.body)\r\n : ': ' + result.body),\r\n );\r\n }\r\n}\r\n\r\nfunction logRequest(method: HttpMethods, uri: string, body: RequestBody | null, params: RequestParams, logger: Logger) {\r\n if (logger.shouldLog(Logger.LOG_MICRO)) {\r\n Logger.logActionNoStrip(\r\n logger,\r\n Logger.LOG_MICRO,\r\n 'Http.' + method + '()',\r\n 'Sending; ' +\r\n appendingParams(uri, params) +\r\n '; Body' +\r\n (Platform.BufferUtils.isBuffer(body) ? ' (Base64): ' + Platform.BufferUtils.base64Encode(body) : ': ' + body),\r\n );\r\n }\r\n}\r\n\r\nexport class Http {\r\n private readonly platformHttp: IPlatformHttp;\r\n checkConnectivity?: () => Promise<boolean>;\r\n\r\n constructor(private readonly client?: BaseClient) {\r\n this.platformHttp = new Platform.Http(client);\r\n\r\n this.checkConnectivity = this.platformHttp.checkConnectivity\r\n ? () => this.platformHttp.checkConnectivity!()\r\n : undefined;\r\n }\r\n\r\n get logger(): Logger {\r\n return this.client?.logger ?? Logger.defaultLogger;\r\n }\r\n\r\n get supportsAuthHeaders() {\r\n return this.platformHttp.supportsAuthHeaders;\r\n }\r\n\r\n get supportsLinkHeaders() {\r\n return this.platformHttp.supportsLinkHeaders;\r\n }\r\n\r\n _getHosts(client: BaseClient) {\r\n /* If we're a connected realtime client, try the endpoint we're connected\r\n * to first -- but still have fallbacks, being connected is not an absolute\r\n * guarantee that a datacenter has free capacity to service REST requests. */\r\n const connection = (client as BaseRealtime).connection,\r\n connectionHost = connection && connection.connectionManager.host;\r\n\r\n if (connectionHost) {\r\n return [connectionHost].concat(Defaults.getFallbackHosts(client.options));\r\n }\r\n\r\n return Defaults.getHosts(client.options);\r\n }\r\n\r\n /**\r\n * This method will not throw any errors; rather, it will communicate any error by populating the {@link RequestResult.error} property of the returned {@link RequestResult}.\r\n */\r\n async do(\r\n method: HttpMethods,\r\n path: PathParameter,\r\n headers: Record<string, string> | null,\r\n body: RequestBody | null,\r\n params: RequestParams,\r\n ): Promise<RequestResult> {\r\n try {\r\n /* Unlike for doUri, the presence of `this.client` here is mandatory, as it's used to generate the hosts */\r\n const client = this.client;\r\n if (!client) {\r\n return { error: new ErrorInfo('http.do called without client', 50000, 500) };\r\n }\r\n\r\n const uriFromHost =\r\n typeof path === 'function'\r\n ? path\r\n : function (host: string) {\r\n return client.baseUri(host) + path;\r\n };\r\n\r\n const currentFallback = client._currentFallback;\r\n if (currentFallback) {\r\n if (currentFallback.validUntil > Date.now()) {\r\n /* Use stored fallback */\r\n const result = await this.doUri(method, uriFromHost(currentFallback.host), headers, body, params);\r\n if (result.error && this.platformHttp.shouldFallback(result.error as ErrnoException)) {\r\n /* unstore the fallback and start from the top with the default sequence */\r\n client._currentFallback = null;\r\n return this.do(method, path, headers, body, params);\r\n }\r\n return result;\r\n } else {\r\n /* Fallback expired; remove it and fallthrough to normal sequence */\r\n client._currentFallback = null;\r\n }\r\n }\r\n\r\n const hosts = this._getHosts(client);\r\n\r\n /* see if we have one or more than one host */\r\n if (hosts.length === 1) {\r\n return this.doUri(method, uriFromHost(hosts[0]), headers, body, params);\r\n }\r\n\r\n let tryAHostStartedAt: Date | null = null;\r\n const tryAHost = async (candidateHosts: Array<string>, persistOnSuccess?: boolean): Promise<RequestResult> => {\r\n const host = candidateHosts.shift();\r\n tryAHostStartedAt = tryAHostStartedAt ?? new Date();\r\n const result = await this.doUri(method, uriFromHost(host as string), headers, body, params);\r\n if (result.error && this.platformHttp.shouldFallback(result.error as ErrnoException) && candidateHosts.length) {\r\n // TO3l6\r\n const elapsedTime = Date.now() - tryAHostStartedAt.getTime();\r\n if (elapsedTime > client.options.timeouts.httpMaxRetryDuration) {\r\n return {\r\n error: new ErrorInfo(\r\n `Timeout for trying fallback hosts retries. Total elapsed time exceeded the ${client.options.timeouts.httpMaxRetryDuration}ms limit`,\r\n 50003,\r\n 500,\r\n ),\r\n };\r\n }\r\n\r\n return tryAHost(candidateHosts, true);\r\n }\r\n if (persistOnSuccess) {\r\n /* RSC15f */\r\n client._currentFallback = {\r\n host: host as string,\r\n validUntil: Date.now() + client.options.timeouts.fallbackRetryTimeout,\r\n };\r\n }\r\n return result;\r\n };\r\n return tryAHost(hosts);\r\n } catch (err) {\r\n // Handle any unexpected error, to ensure we always meet our contract of not throwing any errors\r\n return { error: new ErrorInfo(`Unexpected error in Http.do: ${Utils.inspectError(err)}`, 500, 50000) };\r\n }\r\n }\r\n\r\n /**\r\n * This method will not throw any errors; rather, it will communicate any error by populating the {@link RequestResult.error} property of the returned {@link RequestResult}.\r\n */\r\n async doUri(\r\n method: HttpMethods,\r\n uri: string,\r\n headers: Record<string, string> | null,\r\n body: RequestBody | null,\r\n params: RequestParams,\r\n ): Promise<RequestResult> {\r\n try {\r\n logRequest(method, uri, body, params, this.logger);\r\n\r\n const result = await this.platformHttp.doUri(method, uri, headers, body, params);\r\n\r\n if (this.logger.shouldLog(Logger.LOG_MICRO)) {\r\n logResult(result, method, uri, params, this.logger);\r\n }\r\n\r\n return result;\r\n } catch (err) {\r\n // Handle any unexpected error, to ensure we always meet our contract of not throwing any errors\r\n return { error: new ErrorInfo(`Unexpected error in Http.doUri: ${Utils.inspectError(err)}`, 500, 50000) };\r\n }\r\n }\r\n}\r\n\r\nexport interface ErrnoException extends Error {\r\n errno?: number;\r\n code?: string;\r\n path?: string;\r\n syscall?: string;\r\n stack?: string;\r\n statusCode: number;\r\n}\r\n","import Logger, { LoggerOptions } from '../util/logger';\r\nimport Defaults from '../util/defaults';\r\nimport Auth from './auth';\r\nimport { HttpPaginatedResponse, PaginatedResult } from './paginatedresource';\r\nimport ErrorInfo from '../types/errorinfo';\r\nimport Stats from '../types/stats';\r\nimport { Http, RequestParams } from '../../types/http';\r\nimport ClientOptions, { NormalisedClientOptions } from '../../types/ClientOptions';\r\nimport * as API from '../../../../ably';\r\nimport * as Utils from '../util/utils';\r\n\r\nimport Platform from '../../platform';\r\nimport { Rest } from './rest';\r\nimport { IUntypedCryptoStatic } from 'common/types/ICryptoStatic';\r\nimport { throwMissingPluginError } from '../util/utils';\r\nimport { MsgPack } from 'common/types/msgpack';\r\nimport { HTTPRequestImplementations } from 'platform/web/lib/http/http';\r\nimport { FilteredSubscriptions } from './filteredsubscriptions';\r\nimport type { LocalDevice } from 'plugins/push/pushactivation';\r\n\r\ntype BatchResult<T> = API.BatchResult<T>;\r\ntype BatchPublishSpec = API.BatchPublishSpec;\r\ntype BatchPublishSuccessResult = API.BatchPublishSuccessResult;\r\ntype BatchPublishFailureResult = API.BatchPublishFailureResult;\r\ntype BatchPublishResult = BatchResult<BatchPublishSuccessResult | BatchPublishFailureResult>;\r\ntype BatchPresenceSuccessResult = API.BatchPresenceSuccessResult;\r\ntype BatchPresenceFailureResult = API.BatchPresenceFailureResult;\r\ntype BatchPresenceResult = BatchResult<BatchPresenceSuccessResult | BatchPresenceFailureResult>;\r\n\r\n/**\r\n `BaseClient` acts as the base class for all of the client classes exported by the SDK. It is an implementation detail and this class is not advertised publicly.\r\n */\r\nclass BaseClient {\r\n options: NormalisedClientOptions;\r\n _currentFallback: null | {\r\n host: string;\r\n validUntil: number;\r\n };\r\n serverTimeOffset: number | null;\r\n http: Http;\r\n auth: Auth;\r\n\r\n private readonly _rest: Rest | null;\r\n readonly _Crypto: IUntypedCryptoStatic | null;\r\n readonly _MsgPack: MsgPack | null;\r\n // Extra HTTP request implementations available to this client, in addition to those in web’s Http.bundledRequestImplementations\r\n readonly _additionalHTTPRequestImplementations: HTTPRequestImplementations | null;\r\n private readonly __FilteredSubscriptions: typeof FilteredSubscriptions | null;\r\n readonly logger: Logger;\r\n _device?: LocalDevice;\r\n\r\n constructor(options: ClientOptions) {\r\n this._additionalHTTPRequestImplementations = options.plugins ?? null;\r\n\r\n this.logger = new Logger();\r\n this.logger.setLog(options.logLevel, options.logHandler);\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'BaseClient()',\r\n 'initialized with clientOptions ' + Platform.Config.inspect(options),\r\n );\r\n\r\n this._MsgPack = options.plugins?.MsgPack ?? null;\r\n const normalOptions = (this.options = Defaults.normaliseOptions(options, this._MsgPack, this.logger));\r\n\r\n /* process options */\r\n if (normalOptions.key) {\r\n const keyMatch = normalOptions.key.match(/^([^:\\s]+):([^:.\\s]+)$/);\r\n if (!keyMatch) {\r\n const msg = 'invalid key parameter';\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'BaseClient()', msg);\r\n throw new ErrorInfo(msg, 40400, 404);\r\n }\r\n normalOptions.keyName = keyMatch[1];\r\n normalOptions.keySecret = keyMatch[2];\r\n }\r\n\r\n if ('clientId' in normalOptions) {\r\n if (!(typeof normalOptions.clientId === 'string' || normalOptions.clientId === null))\r\n throw new ErrorInfo('clientId must be either a string or null', 40012, 400);\r\n else if (normalOptions.clientId === '*')\r\n throw new ErrorInfo(\r\n 'Can’t use \"*\" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, use {defaultTokenParams: {clientId: \"*\"}})',\r\n 40012,\r\n 400,\r\n );\r\n }\r\n\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'BaseClient()', 'started; version = ' + Defaults.version);\r\n\r\n this._currentFallback = null;\r\n\r\n this.serverTimeOffset = null;\r\n this.http = new Http(this);\r\n this.auth = new Auth(this, normalOptions);\r\n\r\n this._rest = options.plugins?.Rest ? new options.plugins.Rest(this) : null;\r\n this._Crypto = options.plugins?.Crypto ?? null;\r\n this.__FilteredSubscriptions = options.plugins?.MessageInteractions ?? null;\r\n }\r\n\r\n get rest(): Rest {\r\n if (!this._rest) {\r\n throwMissingPluginError('Rest');\r\n }\r\n return this._rest;\r\n }\r\n\r\n get _FilteredSubscriptions(): typeof FilteredSubscriptions {\r\n if (!this.__FilteredSubscriptions) {\r\n throwMissingPluginError('MessageInteractions');\r\n }\r\n return this.__FilteredSubscriptions;\r\n }\r\n\r\n get channels() {\r\n return this.rest.channels;\r\n }\r\n\r\n get push() {\r\n return this.rest.push;\r\n }\r\n\r\n get device() {\r\n if (!this.options.plugins?.Push || !this.push.LocalDevice) {\r\n throwMissingPluginError('Push');\r\n }\r\n if (!this._device) {\r\n this._device = this.push.LocalDevice.load(this);\r\n }\r\n return this._device;\r\n }\r\n\r\n baseUri(host: string) {\r\n return Defaults.getHttpScheme(this.options) + host + ':' + Defaults.getPort(this.options, false);\r\n }\r\n\r\n async stats(params: RequestParams): Promise<PaginatedResult<Stats>> {\r\n return this.rest.stats(params);\r\n }\r\n\r\n async time(params?: RequestParams): Promise<number> {\r\n return this.rest.time(params);\r\n }\r\n\r\n async request(\r\n method: string,\r\n path: string,\r\n version: number,\r\n params: RequestParams,\r\n body: unknown,\r\n customHeaders: Record<string, string>,\r\n ): Promise<HttpPaginatedResponse<unknown>> {\r\n return this.rest.request(method, path, version, params, body, customHeaders);\r\n }\r\n\r\n batchPublish<T extends BatchPublishSpec | BatchPublishSpec[]>(\r\n specOrSpecs: T,\r\n ): Promise<T extends BatchPublishSpec ? BatchPublishResult : BatchPublishResult[]> {\r\n return this.rest.batchPublish(specOrSpecs);\r\n }\r\n\r\n batchPresence(channels: string[]): Promise<BatchPresenceResult> {\r\n return this.rest.batchPresence(channels);\r\n }\r\n\r\n setLog(logOptions: LoggerOptions): void {\r\n this.logger.setLog(logOptions.level, logOptions.handler);\r\n }\r\n\r\n static Platform = Platform;\r\n\r\n /**\r\n * These exports are for use by UMD plugins; reason being so that constructors and static methods can be accessed by these plugins without needing to import the classes directly and result in the class existing in both the plugin and the core library.\r\n */\r\n Platform = Platform;\r\n ErrorInfo = ErrorInfo;\r\n Logger = Logger;\r\n Defaults = Defaults;\r\n Utils = Utils;\r\n}\r\n\r\nexport default BaseClient;\r\n","import { MsgPack } from 'common/types/msgpack';\nimport type { LocalDevice } from 'plugins/push/pushactivation';\nimport * as Utils from '../util/utils';\nimport ErrorInfo, { IConvertibleToErrorInfo } from './errorinfo';\n\nexport enum DeviceFormFactor {\n Phone = 'phone',\n Tablet = 'tablet',\n Desktop = 'desktop',\n TV = 'tv',\n Watch = 'watch',\n Car = 'car',\n Embedded = 'embedded',\n Other = 'other',\n}\n\nexport enum DevicePlatform {\n Android = 'android',\n IOS = 'ios',\n Browser = 'browser',\n}\n\ntype DevicePushState = 'ACTIVE' | 'FAILING' | 'FAILED';\n\ninterface WebPushEncryptionKey {\n p256dh: string;\n auth: string;\n}\n\ninterface WebPushRecipient {\n transportType: 'web';\n targetUrl: string;\n encryptionKey: WebPushEncryptionKey;\n publicVapidKey: string;\n}\n\ninterface PushChannelRecipient {\n transportType: 'ablyChannel';\n channel: string;\n ablyKey: string;\n ablyUrl: string;\n}\n\ntype PushRecipient = WebPushRecipient | PushChannelRecipient;\n\nexport type DevicePushDetails = {\n error?: ErrorInfo;\n recipient?: PushRecipient;\n state?: DevicePushState;\n metadata?: string;\n};\n\nclass DeviceDetails {\n id?: string;\n clientId?: string;\n deviceSecret?: string;\n formFactor?: DeviceFormFactor;\n platform?: DevicePlatform;\n push?: DevicePushDetails;\n metadata?: string;\n deviceIdentityToken?: string;\n\n toJSON(): DeviceDetails {\n return {\n id: this.id,\n deviceSecret: this.deviceSecret,\n platform: this.platform,\n formFactor: this.formFactor,\n clientId: this.clientId,\n metadata: this.metadata,\n deviceIdentityToken: this.deviceIdentityToken,\n push: {\n recipient: this.push?.recipient,\n state: this.push?.state,\n error: this.push?.error,\n },\n } as DeviceDetails;\n }\n\n toString(): string {\n let result = '[DeviceDetails';\n if (this.id) result += '; id=' + this.id;\n if (this.platform) result += '; platform=' + this.platform;\n if (this.formFactor) result += '; formFactor=' + this.formFactor;\n if (this.clientId) result += '; clientId=' + this.clientId;\n if (this.metadata) result += '; metadata=' + this.metadata;\n if (this.deviceIdentityToken) result += '; deviceIdentityToken=' + JSON.stringify(this.deviceIdentityToken);\n if (this.push?.recipient) result += '; push.recipient=' + JSON.stringify(this.push.recipient);\n if (this.push?.state) result += '; push.state=' + this.push.state;\n if (this.push?.error) result += '; push.error=' + JSON.stringify(this.push.error);\n if (this.push?.metadata) result += '; push.metadata=' + this.push.metadata;\n result += ']';\n return result;\n }\n\n static toRequestBody(body: unknown, MsgPack: MsgPack | null, format?: Utils.Format) {\n return Utils.encodeBody(body, MsgPack, format);\n }\n\n static fromResponseBody(\n body: Array<Record<string, unknown>> | Record<string, unknown>,\n MsgPack: MsgPack | null,\n format?: Utils.Format,\n ): DeviceDetails | DeviceDetails[] {\n if (format) {\n body = Utils.decodeBody(body, MsgPack, format);\n }\n\n if (Array.isArray(body)) {\n return DeviceDetails.fromValuesArray(body);\n } else {\n return DeviceDetails.fromValues(body);\n }\n }\n\n static fromValues(values: Record<string, unknown>): DeviceDetails {\n values.error = values.error && ErrorInfo.fromValues(values.error as IConvertibleToErrorInfo);\n return Object.assign(new DeviceDetails(), values);\n }\n\n static fromLocalDevice(device: LocalDevice): DeviceDetails {\n return Object.assign(new DeviceDetails(), device);\n }\n\n static fromValuesArray(values: Array<Record<string, unknown>>): DeviceDetails[] {\n const count = values.length,\n result = new Array(count);\n for (let i = 0; i < count; i++) result[i] = DeviceDetails.fromValues(values[i]);\n return result;\n }\n}\n\nexport default DeviceDetails;\n","import Platform from '../../platform';\nimport * as Utils from '../util/utils';\nimport Logger from '../util/logger';\nimport Auth from './auth';\nimport HttpMethods from '../../constants/HttpMethods';\nimport ErrorInfo, { IPartialErrorInfo, PartialErrorInfo } from '../types/errorinfo';\nimport BaseClient from './baseclient';\nimport { MsgPack } from 'common/types/msgpack';\nimport { RequestBody, ResponseHeaders, appendingParams as urlFromPathAndParams, paramString } from 'common/types/http';\nimport httpStatusCodes from '../../constants/HttpStatusCodes';\n\nasync function withAuthDetails<T>(\n client: BaseClient,\n headers: ResponseHeaders | undefined,\n params: Record<string, any>,\n opCallback: Function,\n): Promise<ResourceResult<T>> {\n if (client.http.supportsAuthHeaders) {\n const authHeaders = await client.auth.getAuthHeaders();\n return opCallback(Utils.mixin(authHeaders!, headers), params);\n } else {\n const authParams = await client.auth.getAuthParams();\n return opCallback(headers, Utils.mixin(authParams!, params));\n }\n}\n\nfunction unenvelope<T>(\n result: ResourceResult<T>,\n MsgPack: MsgPack | null,\n format: Utils.Format | null,\n): ResourceResult<T> {\n if (result.err && !result.body) {\n return { err: result.err };\n }\n\n if (result.statusCode === httpStatusCodes.NoContent) {\n return { ...result, body: [] as any, unpacked: true };\n }\n\n let body = result.body;\n\n if (!result.unpacked) {\n try {\n body = Utils.decodeBody(body, MsgPack, format);\n } catch (e) {\n if (Utils.isErrorInfoOrPartialErrorInfo(e)) {\n return { err: e };\n } else {\n return { err: new PartialErrorInfo(Utils.inspectError(e), null) };\n }\n }\n }\n\n if (!body) {\n return { err: new PartialErrorInfo('unenvelope(): Response body is missing', null) };\n }\n\n const { statusCode: wrappedStatusCode, response, headers: wrappedHeaders } = body as Record<string, any>;\n\n if (wrappedStatusCode === undefined) {\n /* Envelope already unwrapped by the transport */\n return { ...result, body, unpacked: true };\n }\n\n if (wrappedStatusCode < 200 || wrappedStatusCode >= 300) {\n /* handle wrapped errors */\n let wrappedErr = (response && response.error) || result.err;\n if (!wrappedErr) {\n wrappedErr = new Error('Error in unenveloping ' + body);\n wrappedErr.statusCode = wrappedStatusCode;\n }\n return { err: wrappedErr, body: response, headers: wrappedHeaders, unpacked: true, statusCode: wrappedStatusCode };\n }\n\n return { err: result.err, body: response, headers: wrappedHeaders, unpacked: true, statusCode: wrappedStatusCode };\n}\n\nfunction logResult<T>(\n result: ResourceResult<T>,\n method: HttpMethods,\n path: string,\n params: Record<string, string>,\n logger: Logger,\n) {\n if (result.err) {\n Logger.logAction(\n logger,\n Logger.LOG_MICRO,\n 'Resource.' + method + '()',\n 'Received Error; ' + urlFromPathAndParams(path, params) + '; Error: ' + Utils.inspectError(result.err),\n );\n } else {\n Logger.logAction(\n logger,\n Logger.LOG_MICRO,\n 'Resource.' + method + '()',\n 'Received; ' +\n urlFromPathAndParams(path, params) +\n '; Headers: ' +\n paramString(result.headers as Record<string, any>) +\n '; StatusCode: ' +\n result.statusCode +\n '; Body: ' +\n (Platform.BufferUtils.isBuffer(result.body)\n ? ' (Base64): ' + Platform.BufferUtils.base64Encode(result.body)\n : ': ' + Platform.Config.inspect(result.body)),\n );\n }\n}\n\nexport interface ResourceResponse<T> {\n body?: T;\n headers?: ResponseHeaders;\n unpacked?: boolean;\n statusCode?: number;\n}\n\nexport interface ResourceResult<T> extends ResourceResponse<T> {\n /**\n * Any error returned by the underlying HTTP client.\n */\n err: IPartialErrorInfo | null;\n}\n\nclass Resource {\n /**\n * @param throwError Whether to throw any error returned by the underlying HTTP client.\n *\n * If you specify `true`, then this method will return a `ResourceResponse<T>`, and if the underlying HTTP client returns an error, this method call will throw that error. If you specify `false`, then it will return a `ResourceResult<T>`, whose `err` property contains any error that was returned by the underlying HTTP client.\n */\n static async get<T = unknown>(\n client: BaseClient,\n path: string,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: true,\n ): Promise<ResourceResponse<T>>;\n static async get<T = unknown>(\n client: BaseClient,\n path: string,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: false,\n ): Promise<ResourceResult<T>>;\n static async get<T = unknown>(\n client: BaseClient,\n path: string,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: boolean,\n ): Promise<ResourceResponse<T> | ResourceResult<T>> {\n return Resource.do(HttpMethods.Get, client, path, null, headers, params, envelope, throwError ?? false);\n }\n\n /**\n * @param throwError Whether to throw any error returned by the underlying HTTP client.\n *\n * If you specify `true`, then this method will return a `ResourceResponse<T>`, and if the underlying HTTP client returns an error, this method call will throw that error. If you specify `false`, then it will return a `ResourceResult<T>`, whose `err` property contains any error that was returned by the underlying HTTP client.\n */\n static async delete<T = unknown>(\n client: BaseClient,\n path: string,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: true,\n ): Promise<ResourceResponse<T>>;\n static async delete<T = unknown>(\n client: BaseClient,\n path: string,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: false,\n ): Promise<ResourceResult<T>>;\n static async delete<T = unknown>(\n client: BaseClient,\n path: string,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: boolean,\n ): Promise<ResourceResponse<T> | ResourceResult<T>> {\n return Resource.do(HttpMethods.Delete, client, path, null, headers, params, envelope, throwError);\n }\n\n /**\n * @param throwError Whether to throw any error returned by the underlying HTTP client.\n *\n * If you specify `true`, then this method will return a `ResourceResponse<T>`, and if the underlying HTTP client returns an error, this method call will throw that error. If you specify `false`, then it will return a `ResourceResult<T>`, whose `err` property contains any error that was returned by the underlying HTTP client.\n */\n static async post<T = unknown>(\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: true,\n ): Promise<ResourceResponse<T>>;\n static async post<T = unknown>(\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: false,\n ): Promise<ResourceResult<T>>;\n static async post<T = unknown>(\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: boolean,\n ): Promise<ResourceResponse<T> | ResourceResult<T>> {\n return Resource.do(HttpMethods.Post, client, path, body, headers, params, envelope, throwError);\n }\n\n /**\n * @param throwError Whether to throw any error returned by the underlying HTTP client.\n *\n * If you specify `true`, then this method will return a `ResourceResponse<T>`, and if the underlying HTTP client returns an error, this method call will throw that error. If you specify `false`, then it will return a `ResourceResult<T>`, whose `err` property contains any error that was returned by the underlying HTTP client.\n */\n static async patch<T = unknown>(\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: true,\n ): Promise<ResourceResponse<T>>;\n static async patch<T = unknown>(\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: false,\n ): Promise<ResourceResult<T>>;\n static async patch<T = unknown>(\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: boolean,\n ): Promise<ResourceResponse<T> | ResourceResult<T>> {\n return Resource.do(HttpMethods.Patch, client, path, body, headers, params, envelope, throwError);\n }\n\n /**\n * @param throwError Whether to throw any error returned by the underlying HTTP client.\n *\n * If you specify `true`, then this method will return a `ResourceResponse<T>`, and if the underlying HTTP client returns an error, this method call will throw that error. If you specify `false`, then it will return a `ResourceResult<T>`, whose `err` property contains any error that was returned by the underlying HTTP client.\n */\n static async put<T = unknown>(\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: true,\n ): Promise<ResourceResponse<T>>;\n static async put<T = unknown>(\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: false,\n ): Promise<ResourceResult<T>>;\n static async put<T = unknown>(\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: boolean,\n ): Promise<ResourceResponse<T> | ResourceResult<T>> {\n return Resource.do(HttpMethods.Put, client, path, body, headers, params, envelope, throwError);\n }\n\n static async do<T>(\n method: HttpMethods,\n client: BaseClient,\n path: string,\n body: RequestBody | null,\n headers: Record<string, string>,\n params: Record<string, any>,\n envelope: Utils.Format | null,\n throwError: boolean,\n ): Promise<ResourceResponse<T> | ResourceResult<T>> {\n if (envelope) {\n (params = params || {})['envelope'] = envelope;\n }\n\n const logger = client.logger;\n\n async function doRequest(\n this: any,\n headers: Record<string, string>,\n params: Record<string, any>,\n ): Promise<ResourceResult<T>> {\n if (logger.shouldLog(Logger.LOG_MICRO)) {\n let decodedBody = body;\n if (headers['content-type']?.indexOf('msgpack') > 0) {\n try {\n if (!client._MsgPack) {\n Utils.throwMissingPluginError('MsgPack');\n }\n decodedBody = client._MsgPack.decode(body as Buffer);\n } catch (decodeErr) {\n Logger.logAction(\n logger,\n Logger.LOG_MICRO,\n 'Resource.' + method + '()',\n 'Sending MsgPack Decoding Error: ' + Utils.inspectError(decodeErr),\n );\n }\n }\n Logger.logAction(\n logger,\n Logger.LOG_MICRO,\n 'Resource.' + method + '()',\n 'Sending; ' + urlFromPathAndParams(path, params) + '; Body: ' + decodedBody,\n );\n }\n\n const httpResult = await client.http.do(method, path, headers, body, params);\n\n if (httpResult.error && Auth.isTokenErr(httpResult.error as ErrorInfo)) {\n /* token has expired, so get a new one */\n await client.auth.authorize(null, null);\n /* retry ... */\n return withAuthDetails(client, headers, params, doRequest);\n }\n\n return {\n err: httpResult.error as ErrorInfo,\n body: httpResult.body as T | undefined,\n headers: httpResult.headers,\n unpacked: httpResult.unpacked,\n statusCode: httpResult.statusCode,\n };\n }\n\n let result = await withAuthDetails<T>(client, headers, params, doRequest);\n\n if (envelope) {\n result = unenvelope(result, client._MsgPack, envelope);\n }\n\n if (logger.shouldLog(Logger.LOG_MICRO)) {\n logResult(result, method, path, params, logger);\n }\n\n if (throwError) {\n if (result.err) {\n throw result.err;\n } else {\n const response: Omit<ResourceResult<T>, 'err'> & Pick<Partial<ResourceResult<T>>, 'err'> = { ...result };\n delete response.err;\n return response;\n }\n }\n\n return result;\n }\n}\n\nexport default Resource;\n","import * as Utils from '../util/utils';\nimport Logger from '../util/logger';\nimport Resource, { ResourceResult } from './resource';\nimport { IPartialErrorInfo } from '../types/errorinfo';\nimport BaseClient from './baseclient';\nimport { RequestBody, ResponseHeaders } from 'common/types/http';\nimport HttpStatusCodes from '../../constants/HttpStatusCodes';\n\nexport type BodyHandler = (body: unknown, headers: ResponseHeaders, unpacked?: boolean) => Promise<any>;\n\nfunction getRelParams(linkUrl: string) {\n const urlMatch = linkUrl.match(/^\\.\\/(\\w+)\\?(.*)$/);\n return urlMatch && urlMatch[2] && Utils.parseQueryString(urlMatch[2]);\n}\n\nfunction parseRelLinks(linkHeader: string | Array<string>) {\n if (typeof linkHeader == 'string') linkHeader = linkHeader.split(',');\n\n const relParams: Record<string, Record<string, string>> = {};\n for (let i = 0; i < linkHeader.length; i++) {\n const linkMatch = linkHeader[i].match(/^\\s*<(.+)>;\\s*rel=\"(\\w+)\"$/);\n if (linkMatch) {\n const params = getRelParams(linkMatch[1]);\n if (params) relParams[linkMatch[2]] = params;\n }\n }\n return relParams;\n}\n\nfunction returnErrOnly(err: IPartialErrorInfo, body: unknown, useHPR?: boolean) {\n /* If using httpPaginatedResponse, errors from Ably are returned as part of\n * the HPR, only throw `err` for network errors etc. which don't\n * return a body and/or have no ably-originated error code (non-numeric\n * error codes originate from node) */\n return !(useHPR && (body || typeof err.code === 'number'));\n}\n\nclass PaginatedResource {\n client: BaseClient;\n path: string;\n headers: Record<string, string>;\n envelope: Utils.Format | null;\n bodyHandler: BodyHandler;\n useHttpPaginatedResponse: boolean;\n\n constructor(\n client: BaseClient,\n path: string,\n headers: Record<string, string>,\n envelope: Utils.Format | undefined,\n bodyHandler: BodyHandler,\n useHttpPaginatedResponse?: boolean,\n ) {\n this.client = client;\n this.path = path;\n this.headers = headers;\n this.envelope = envelope ?? null;\n this.bodyHandler = bodyHandler;\n this.useHttpPaginatedResponse = useHttpPaginatedResponse || false;\n }\n\n get logger(): Logger {\n return this.client.logger;\n }\n\n async get<T1, T2>(params: Record<string, T2>): Promise<PaginatedResult<T1>> {\n const result = await Resource.get<T1>(this.client, this.path, this.headers, params, this.envelope, false);\n return this.handlePage(result);\n }\n\n async delete<T1, T2>(params: Record<string, T2>): Promise<PaginatedResult<T1>> {\n const result = await Resource.delete<T1>(this.client, this.path, this.headers, params, this.envelope, false);\n return this.handlePage(result);\n }\n\n async post<T1, T2>(params: Record<string, T2>, body: RequestBody | null): Promise<PaginatedResult<T1>> {\n const result = await Resource.post<T1>(this.client, this.path, body, this.headers, params, this.envelope, false);\n return this.handlePage(result);\n }\n\n async put<T1, T2>(params: Record<string, T2>, body: RequestBody | null): Promise<PaginatedResult<T1>> {\n const result = await Resource.put<T1>(this.client, this.path, body, this.headers, params, this.envelope, false);\n return this.handlePage(result);\n }\n\n async patch<T1, T2>(params: Record<string, T2>, body: RequestBody | null): Promise<PaginatedResult<T1>> {\n const result = await Resource.patch<T1>(this.client, this.path, body, this.headers, params, this.envelope, false);\n return this.handlePage(result);\n }\n\n async handlePage<T>(result: ResourceResult<T>): Promise<PaginatedResult<T>> {\n if (result.err && returnErrOnly(result.err, result.body, this.useHttpPaginatedResponse)) {\n Logger.logAction(\n this.logger,\n Logger.LOG_ERROR,\n 'PaginatedResource.handlePage()',\n 'Unexpected error getting resource: err = ' + Utils.inspectError(result.err),\n );\n throw result.err;\n }\n\n let items, linkHeader, relParams;\n\n try {\n items =\n result.statusCode == HttpStatusCodes.NoContent\n ? []\n : await this.bodyHandler(result.body, result.headers || {}, result.unpacked);\n } catch (e) {\n /* If we got an error, the failure to parse the body is almost certainly\n * due to that, so throw that in preference over the parse error */\n throw result.err || e;\n }\n\n if (result.headers && (linkHeader = result.headers['Link'] || result.headers['link'])) {\n relParams = parseRelLinks(linkHeader);\n }\n\n if (this.useHttpPaginatedResponse) {\n return new HttpPaginatedResponse(\n this,\n items,\n result.headers || {},\n result.statusCode as number,\n relParams,\n result.err,\n );\n } else {\n return new PaginatedResult(this, items, relParams);\n }\n }\n}\n\nexport class PaginatedResult<T> {\n resource: PaginatedResource;\n items: T[];\n first?: () => Promise<PaginatedResult<T>>;\n next?: () => Promise<PaginatedResult<T> | null>;\n current?: () => Promise<PaginatedResult<T>>;\n hasNext?: () => boolean;\n isLast?: () => boolean;\n\n constructor(resource: PaginatedResource, items: T[], relParams?: Record<string, any>) {\n this.resource = resource;\n this.items = items;\n\n const self = this;\n if (relParams) {\n if ('first' in relParams) {\n this.first = async function () {\n return self.get(relParams.first);\n };\n }\n if ('current' in relParams) {\n this.current = async function () {\n return self.get(relParams.current);\n };\n }\n this.next = async function () {\n if ('next' in relParams) {\n return self.get(relParams.next);\n } else {\n return null;\n }\n };\n\n this.hasNext = function () {\n return 'next' in relParams;\n };\n this.isLast = () => {\n return !this.hasNext?.();\n };\n }\n }\n\n /* We assume that only the initial request can be a POST, and that accessing\n * the rest of a multipage set of results can always be done with GET */\n async get(params: any): Promise<PaginatedResult<T>> {\n const res = this.resource;\n const result = await Resource.get<T>(res.client, res.path, res.headers, params, res.envelope, false);\n return res.handlePage(result);\n }\n}\n\nexport class HttpPaginatedResponse<T> extends PaginatedResult<T> {\n statusCode: number;\n success: boolean;\n headers: ResponseHeaders;\n errorCode?: number | null;\n errorMessage?: string | null;\n\n constructor(\n resource: PaginatedResource,\n items: T[],\n headers: ResponseHeaders,\n statusCode: number,\n relParams: any,\n err: IPartialErrorInfo | null,\n ) {\n super(resource, items, relParams);\n this.statusCode = statusCode;\n this.success = statusCode < 300 && statusCode >= 200;\n this.headers = headers;\n this.errorCode = err && err.code;\n this.errorMessage = err && err.message;\n }\n\n toJSON() {\n return {\n items: this.items,\n statusCode: this.statusCode,\n success: this.success,\n headers: this.headers,\n errorCode: this.errorCode,\n errorMessage: this.errorMessage,\n };\n }\n}\n\nexport default PaginatedResource;\n","import { MsgPack } from 'common/types/msgpack';\nimport * as Utils from '../util/utils';\n\ntype PushChannelSubscriptionObject = {\n channel?: string;\n deviceId?: string;\n clientId?: string;\n};\n\nclass PushChannelSubscription {\n channel?: string;\n deviceId?: string;\n clientId?: string;\n\n /**\n * Overload toJSON() to intercept JSON.stringify()\n * @return {*}\n */\n toJSON(): PushChannelSubscriptionObject {\n return {\n channel: this.channel,\n deviceId: this.deviceId,\n clientId: this.clientId,\n };\n }\n\n toString(): string {\n let result = '[PushChannelSubscription';\n if (this.channel) result += '; channel=' + this.channel;\n if (this.deviceId) result += '; deviceId=' + this.deviceId;\n if (this.clientId) result += '; clientId=' + this.clientId;\n result += ']';\n return result;\n }\n\n static toRequestBody = Utils.encodeBody;\n\n static fromResponseBody(\n body: Array<Record<string, unknown>> | Record<string, unknown>,\n MsgPack: MsgPack | null,\n format?: Utils.Format,\n ): PushChannelSubscription | PushChannelSubscription[] {\n if (format) {\n body = Utils.decodeBody(body, MsgPack, format) as Record<string, unknown>;\n }\n\n if (Array.isArray(body)) {\n return PushChannelSubscription.fromValuesArray(body);\n } else {\n return PushChannelSubscription.fromValues(body);\n }\n }\n\n static fromValues(values: Record<string, unknown>): PushChannelSubscription {\n return Object.assign(new PushChannelSubscription(), values);\n }\n\n static fromValuesArray(values: Array<Record<string, unknown>>): PushChannelSubscription[] {\n const count = values.length,\n result = new Array(count);\n for (let i = 0; i < count; i++) result[i] = PushChannelSubscription.fromValues(values[i]);\n return result;\n }\n}\n\nexport default PushChannelSubscription;\n","import * as Utils from '../util/utils';\nimport DeviceDetails from '../types/devicedetails';\nimport Resource from './resource';\nimport PaginatedResource, { PaginatedResult } from './paginatedresource';\nimport ErrorInfo from '../types/errorinfo';\nimport PushChannelSubscription from '../types/pushchannelsubscription';\nimport BaseClient from './baseclient';\nimport Defaults from '../util/defaults';\nimport type {\n ActivationStateMachine,\n DeregisterCallback,\n LocalDeviceFactory,\n RegisterCallback,\n} from 'plugins/push/pushactivation';\nimport Platform from 'common/platform';\nimport type { ErrCallback } from 'common/types/utils';\n\nclass Push {\n client: BaseClient;\n admin: Admin;\n stateMachine?: ActivationStateMachine;\n LocalDevice?: LocalDeviceFactory;\n\n constructor(client: BaseClient) {\n this.client = client;\n this.admin = new Admin(client);\n if (Platform.Config.push && client.options.plugins?.Push) {\n this.stateMachine = new client.options.plugins.Push.ActivationStateMachine(client);\n this.LocalDevice = client.options.plugins.Push.localDeviceFactory(DeviceDetails);\n }\n }\n\n async activate(registerCallback?: RegisterCallback, updateFailedCallback?: ErrCallback) {\n await new Promise<void>((resolve, reject) => {\n if (!this.client.options.plugins?.Push) {\n reject(Utils.createMissingPluginError('Push'));\n return;\n }\n if (!this.stateMachine) {\n reject(new ErrorInfo('This platform is not supported as a target of push notifications', 40000, 400));\n return;\n }\n if (this.stateMachine.activatedCallback) {\n reject(new ErrorInfo('Activation already in progress', 40000, 400));\n return;\n }\n this.stateMachine.activatedCallback = (err: ErrorInfo) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n };\n this.stateMachine.updateFailedCallback = updateFailedCallback;\n this.stateMachine.handleEvent(\n new this.client.options.plugins.Push.CalledActivate(this.stateMachine, registerCallback),\n );\n });\n }\n\n async deactivate(deregisterCallback: DeregisterCallback) {\n await new Promise<void>((resolve, reject) => {\n if (!this.client.options.plugins?.Push) {\n reject(Utils.createMissingPluginError('Push'));\n return;\n }\n if (!this.stateMachine) {\n reject(new ErrorInfo('This platform is not supported as a target of push notifications', 40000, 400));\n return;\n }\n if (this.stateMachine.deactivatedCallback) {\n reject(new ErrorInfo('Deactivation already in progress', 40000, 400));\n return;\n }\n this.stateMachine.deactivatedCallback = (err: ErrorInfo) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n };\n this.stateMachine.handleEvent(\n new this.client.options.plugins.Push.CalledDeactivate(this.stateMachine, deregisterCallback),\n );\n });\n }\n}\n\nclass Admin {\n client: BaseClient;\n deviceRegistrations: DeviceRegistrations;\n channelSubscriptions: ChannelSubscriptions;\n\n constructor(client: BaseClient) {\n this.client = client;\n this.deviceRegistrations = new DeviceRegistrations(client);\n this.channelSubscriptions = new ChannelSubscriptions(client);\n }\n\n async publish(recipient: any, payload: any): Promise<void> {\n const client = this.client;\n const format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultPostHeaders(client.options, { format }),\n params = {};\n const body = Utils.mixin({ recipient: recipient }, payload);\n\n Utils.mixin(headers, client.options.headers);\n\n if (client.options.pushFullWait) Utils.mixin(params, { fullWait: 'true' });\n\n const requestBody = Utils.encodeBody(body, client._MsgPack, format);\n await Resource.post(client, '/push/publish', requestBody, headers, params, null, true);\n }\n}\n\nclass DeviceRegistrations {\n client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n async save(device: any): Promise<DeviceDetails> {\n const client = this.client;\n const body = DeviceDetails.fromValues(device);\n const format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultPostHeaders(client.options, { format }),\n params = {};\n\n Utils.mixin(headers, client.options.headers);\n\n if (client.options.pushFullWait) Utils.mixin(params, { fullWait: 'true' });\n\n const requestBody = Utils.encodeBody(body, client._MsgPack, format);\n const response = await Resource.put(\n client,\n '/push/deviceRegistrations/' + encodeURIComponent(device.id),\n requestBody,\n headers,\n params,\n null,\n true,\n );\n\n return DeviceDetails.fromResponseBody(\n response.body as Record<string, unknown>,\n client._MsgPack,\n response.unpacked ? undefined : format,\n ) as DeviceDetails;\n }\n\n async get(deviceIdOrDetails: any): Promise<DeviceDetails> {\n const client = this.client,\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultGetHeaders(client.options, { format }),\n deviceId = deviceIdOrDetails.id || deviceIdOrDetails;\n\n if (typeof deviceId !== 'string' || !deviceId.length) {\n throw new ErrorInfo(\n 'First argument to DeviceRegistrations#get must be a deviceId string or DeviceDetails',\n 40000,\n 400,\n );\n }\n\n Utils.mixin(headers, client.options.headers);\n\n const response = await Resource.get(\n client,\n '/push/deviceRegistrations/' + encodeURIComponent(deviceId),\n headers,\n {},\n null,\n true,\n );\n\n return DeviceDetails.fromResponseBody(\n response.body as Record<string, unknown>,\n client._MsgPack,\n response.unpacked ? undefined : format,\n ) as DeviceDetails;\n }\n\n async list(params: any): Promise<PaginatedResult<unknown>> {\n const client = this.client,\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n envelope = this.client.http.supportsLinkHeaders ? undefined : format,\n headers = Defaults.defaultGetHeaders(client.options, { format });\n\n Utils.mixin(headers, client.options.headers);\n\n return new PaginatedResource(client, '/push/deviceRegistrations', headers, envelope, async function (\n body,\n headers,\n unpacked,\n ) {\n return DeviceDetails.fromResponseBody(\n body as Record<string, unknown>[],\n client._MsgPack,\n unpacked ? undefined : format,\n );\n }).get(params);\n }\n\n async remove(deviceIdOrDetails: any): Promise<void> {\n const client = this.client,\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultGetHeaders(client.options, { format }),\n params = {},\n deviceId = deviceIdOrDetails.id || deviceIdOrDetails;\n\n if (typeof deviceId !== 'string' || !deviceId.length) {\n throw new ErrorInfo(\n 'First argument to DeviceRegistrations#remove must be a deviceId string or DeviceDetails',\n 40000,\n 400,\n );\n }\n\n Utils.mixin(headers, client.options.headers);\n\n if (client.options.pushFullWait) Utils.mixin(params, { fullWait: 'true' });\n\n await Resource['delete'](\n client,\n '/push/deviceRegistrations/' + encodeURIComponent(deviceId),\n headers,\n params,\n null,\n true,\n );\n }\n\n async removeWhere(params: any): Promise<void> {\n const client = this.client,\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultGetHeaders(client.options, { format });\n\n Utils.mixin(headers, client.options.headers);\n\n if (client.options.pushFullWait) Utils.mixin(params, { fullWait: 'true' });\n\n await Resource['delete'](client, '/push/deviceRegistrations', headers, params, null, true);\n }\n}\n\nclass ChannelSubscriptions {\n client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n async save(subscription: Record<string, unknown>): Promise<PushChannelSubscription> {\n const client = this.client;\n const body = PushChannelSubscription.fromValues(subscription);\n const format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultPostHeaders(client.options, { format }),\n params = {};\n\n Utils.mixin(headers, client.options.headers);\n\n if (client.options.pushFullWait) Utils.mixin(params, { fullWait: 'true' });\n\n const requestBody = Utils.encodeBody(body, client._MsgPack, format);\n const response = await Resource.post(\n client,\n '/push/channelSubscriptions',\n requestBody,\n headers,\n params,\n null,\n true,\n );\n\n return PushChannelSubscription.fromResponseBody(\n response.body as Record<string, any>,\n client._MsgPack,\n response.unpacked ? undefined : format,\n ) as PushChannelSubscription;\n }\n\n async list(params: any): Promise<PaginatedResult<unknown>> {\n const client = this.client,\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n envelope = this.client.http.supportsLinkHeaders ? undefined : format,\n headers = Defaults.defaultGetHeaders(client.options, { format });\n\n Utils.mixin(headers, client.options.headers);\n\n return new PaginatedResource(client, '/push/channelSubscriptions', headers, envelope, async function (\n body,\n headers,\n unpacked,\n ) {\n return PushChannelSubscription.fromResponseBody(\n body as Record<string, unknown>[],\n client._MsgPack,\n unpacked ? undefined : format,\n );\n }).get(params);\n }\n\n async removeWhere(params: any): Promise<void> {\n const client = this.client,\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultGetHeaders(client.options, { format });\n\n Utils.mixin(headers, client.options.headers);\n\n if (client.options.pushFullWait) Utils.mixin(params, { fullWait: 'true' });\n\n await Resource['delete'](client, '/push/channelSubscriptions', headers, params, null, true);\n }\n\n /* ChannelSubscriptions have no unique id; removing one is equivalent to removeWhere by its properties */\n remove = ChannelSubscriptions.prototype.removeWhere;\n\n async listChannels(params: any): Promise<PaginatedResult<unknown>> {\n const client = this.client,\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n envelope = this.client.http.supportsLinkHeaders ? undefined : format,\n headers = Defaults.defaultGetHeaders(client.options, { format });\n\n Utils.mixin(headers, client.options.headers);\n\n if (client.options.pushFullWait) Utils.mixin(params, { fullWait: 'true' });\n\n return new PaginatedResource(client, '/push/channels', headers, envelope, async function (body, headers, unpacked) {\n const parsedBody = (\n !unpacked && format ? Utils.decodeBody(body, client._MsgPack, format) : body\n ) as Array<string>;\n\n for (let i = 0; i < parsedBody.length; i++) {\n parsedBody[i] = String(parsedBody[i]);\n }\n return parsedBody;\n }).get(params);\n }\n}\n\nexport default Push;\n","import Platform from 'common/platform';\r\nimport Logger from '../util/logger';\r\nimport ErrorInfo from './errorinfo';\r\nimport PresenceMessage from './presencemessage';\r\nimport * as Utils from '../util/utils';\r\nimport { Bufferlike as BrowserBufferlike } from '../../../platform/web/lib/util/bufferutils';\r\nimport * as API from '../../../../ably';\r\n\r\nimport type { IUntypedCryptoStatic } from 'common/types/ICryptoStatic';\r\nimport type { ChannelOptions } from '../../types/channel';\r\nimport type { Properties } from '../util/utils';\r\nimport type RestChannel from '../client/restchannel';\r\nimport type RealtimeChannel from '../client/realtimechannel';\r\ntype Channel = RestChannel | RealtimeChannel;\r\n\r\nconst MessageActionArray: API.MessageAction[] = [\r\n 'message.unset',\r\n 'message.create',\r\n 'message.update',\r\n 'message.delete',\r\n 'annotation.create',\r\n 'annotation.delete',\r\n 'meta.occupancy',\r\n];\r\n\r\nconst MessageActionMap = new Map<API.MessageAction, number>(MessageActionArray.map((action, index) => [action, index]));\r\n\r\nconst ReverseMessageActionMap = new Map<number, API.MessageAction>(\r\n MessageActionArray.map((action, index) => [index, action]),\r\n);\r\n\r\nfunction toMessageActionString(actionNumber: number): API.MessageAction | undefined {\r\n return ReverseMessageActionMap.get(actionNumber);\r\n}\r\n\r\nfunction toMessageActionNumber(messageAction?: API.MessageAction): number | undefined {\r\n return messageAction ? MessageActionMap.get(messageAction) : undefined;\r\n}\r\n\r\nexport type CipherOptions = {\r\n channelCipher: {\r\n encrypt: Function;\r\n algorithm: 'aes';\r\n };\r\n cipher?: {\r\n channelCipher: {\r\n encrypt: Function;\r\n algorithm: 'aes';\r\n };\r\n };\r\n};\r\n\r\nexport type EncodingDecodingContext = {\r\n channelOptions: ChannelOptions;\r\n plugins: {\r\n vcdiff?: {\r\n decode: (delta: Uint8Array, source: Uint8Array) => Uint8Array;\r\n };\r\n };\r\n baseEncodedPreviousPayload?: Buffer | BrowserBufferlike;\r\n};\r\n\r\nexport type WireProtocolMessage = Omit<Message, 'action'> & { action: number };\r\n\r\nfunction normaliseContext(context: CipherOptions | EncodingDecodingContext | ChannelOptions): EncodingDecodingContext {\r\n if (!context || !(context as EncodingDecodingContext).channelOptions) {\r\n return {\r\n channelOptions: context as ChannelOptions,\r\n plugins: {},\r\n baseEncodedPreviousPayload: undefined,\r\n };\r\n }\r\n return context as EncodingDecodingContext;\r\n}\r\n\r\nexport function normalizeCipherOptions(\r\n Crypto: IUntypedCryptoStatic | null,\r\n logger: Logger,\r\n options: API.ChannelOptions | null,\r\n): ChannelOptions {\r\n if (options && options.cipher) {\r\n if (!Crypto) Utils.throwMissingPluginError('Crypto');\r\n const cipher = Crypto.getCipher(options.cipher, logger);\r\n return {\r\n cipher: cipher.cipherParams,\r\n channelCipher: cipher.cipher,\r\n };\r\n }\r\n return options ?? {};\r\n}\r\n\r\nfunction getMessageSize(msg: Message) {\r\n let size = 0;\r\n if (msg.name) {\r\n size += msg.name.length;\r\n }\r\n if (msg.clientId) {\r\n size += msg.clientId.length;\r\n }\r\n if (msg.extras) {\r\n size += JSON.stringify(msg.extras).length;\r\n }\r\n if (msg.data) {\r\n size += Utils.dataSizeBytes(msg.data);\r\n }\r\n return size;\r\n}\r\n\r\nexport async function fromEncoded(\r\n logger: Logger,\r\n Crypto: IUntypedCryptoStatic | null,\r\n encoded: WireProtocolMessage,\r\n inputOptions?: API.ChannelOptions,\r\n): Promise<Message> {\r\n const msg = fromWireProtocol(encoded);\r\n const options = normalizeCipherOptions(Crypto, logger, inputOptions ?? null);\r\n /* if decoding fails at any point, catch and return the message decoded to\r\n * the fullest extent possible */\r\n try {\r\n await decode(msg, options);\r\n } catch (e) {\r\n Logger.logAction(logger, Logger.LOG_ERROR, 'Message.fromEncoded()', (e as Error).toString());\r\n }\r\n return msg;\r\n}\r\n\r\nexport async function fromEncodedArray(\r\n logger: Logger,\r\n Crypto: IUntypedCryptoStatic | null,\r\n encodedArray: Array<WireProtocolMessage>,\r\n options?: API.ChannelOptions,\r\n): Promise<Message[]> {\r\n return Promise.all(\r\n encodedArray.map(function (encoded) {\r\n return fromEncoded(logger, Crypto, encoded, options);\r\n }),\r\n );\r\n}\r\n\r\n// these forms of the functions are used internally when we have a channel instance\r\n// already, so don't need to normalise channel options\r\nexport async function _fromEncoded(encoded: WireProtocolMessage, channel: Channel): Promise<Message> {\r\n const msg = fromWireProtocol(encoded);\r\n try {\r\n await decode(msg, channel.channelOptions);\r\n } catch (e) {\r\n Logger.logAction(channel.logger, Logger.LOG_ERROR, 'Message._fromEncoded()', (e as Error).toString());\r\n }\r\n return msg;\r\n}\r\n\r\nexport async function _fromEncodedArray(encodedArray: WireProtocolMessage[], channel: Channel): Promise<Message[]> {\r\n return Promise.all(\r\n encodedArray.map(function (encoded) {\r\n return _fromEncoded(encoded, channel);\r\n }),\r\n );\r\n}\r\n\r\nasync function encrypt<T extends Message | PresenceMessage>(msg: T, options: CipherOptions): Promise<T> {\r\n let data = msg.data,\r\n encoding = msg.encoding,\r\n cipher = options.channelCipher;\r\n\r\n encoding = encoding ? encoding + '/' : '';\r\n if (!Platform.BufferUtils.isBuffer(data)) {\r\n data = Platform.BufferUtils.utf8Encode(String(data));\r\n encoding = encoding + 'utf-8/';\r\n }\r\n const ciphertext = await cipher.encrypt(data);\r\n msg.data = ciphertext;\r\n msg.encoding = encoding + 'cipher+' + cipher.algorithm;\r\n return msg;\r\n}\r\n\r\nexport async function encode<T extends Message | PresenceMessage>(msg: T, options: CipherOptions): Promise<T> {\r\n const data = msg.data;\r\n const nativeDataType =\r\n typeof data == 'string' || Platform.BufferUtils.isBuffer(data) || data === null || data === undefined;\r\n\r\n if (!nativeDataType) {\r\n if (Utils.isObject(data) || Array.isArray(data)) {\r\n msg.data = JSON.stringify(data);\r\n msg.encoding = msg.encoding ? msg.encoding + '/json' : 'json';\r\n } else {\r\n throw new ErrorInfo('Data type is unsupported', 40013, 400);\r\n }\r\n }\r\n\r\n if (options != null && options.cipher) {\r\n return encrypt(msg, options);\r\n } else {\r\n return msg;\r\n }\r\n}\r\n\r\nexport async function encodeArray(messages: Array<Message>, options: CipherOptions): Promise<Array<Message>> {\r\n return Promise.all(messages.map((message) => encode(message, options)));\r\n}\r\n\r\nexport const serialize = Utils.encodeBody;\r\n\r\nexport async function decode(\r\n message: Message | PresenceMessage,\r\n inputContext: CipherOptions | EncodingDecodingContext | ChannelOptions,\r\n): Promise<void> {\r\n const context = normaliseContext(inputContext);\r\n\r\n let lastPayload = message.data;\r\n const encoding = message.encoding;\r\n if (encoding) {\r\n const xforms = encoding.split('/');\r\n let lastProcessedEncodingIndex,\r\n encodingsToProcess = xforms.length,\r\n data = message.data;\r\n\r\n let xform = '';\r\n try {\r\n while ((lastProcessedEncodingIndex = encodingsToProcess) > 0) {\r\n // eslint-disable-next-line security/detect-unsafe-regex\r\n const match = xforms[--encodingsToProcess].match(/([-\\w]+)(\\+([\\w-]+))?/);\r\n if (!match) break;\r\n xform = match[1];\r\n switch (xform) {\r\n case 'base64':\r\n data = Platform.BufferUtils.base64Decode(String(data));\r\n if (lastProcessedEncodingIndex == xforms.length) {\r\n lastPayload = data;\r\n }\r\n continue;\r\n case 'utf-8':\r\n data = Platform.BufferUtils.utf8Decode(data);\r\n continue;\r\n case 'json':\r\n data = JSON.parse(data);\r\n continue;\r\n case 'cipher':\r\n if (\r\n context.channelOptions != null &&\r\n context.channelOptions.cipher &&\r\n context.channelOptions.channelCipher\r\n ) {\r\n const xformAlgorithm = match[3],\r\n cipher = context.channelOptions.channelCipher;\r\n /* don't attempt to decrypt unless the cipher params are compatible */\r\n if (xformAlgorithm != cipher.algorithm) {\r\n throw new Error('Unable to decrypt message with given cipher; incompatible cipher params');\r\n }\r\n data = await cipher.decrypt(data);\r\n continue;\r\n } else {\r\n throw new Error('Unable to decrypt message; not an encrypted channel');\r\n }\r\n case 'vcdiff':\r\n if (!context.plugins || !context.plugins.vcdiff) {\r\n throw new ErrorInfo('Missing Vcdiff decoder (https://github.com/ably-forks/vcdiff-decoder)', 40019, 400);\r\n }\r\n if (typeof Uint8Array === 'undefined') {\r\n throw new ErrorInfo(\r\n 'Delta decoding not supported on this browser (need ArrayBuffer & Uint8Array)',\r\n 40020,\r\n 400,\r\n );\r\n }\r\n try {\r\n let deltaBase = context.baseEncodedPreviousPayload;\r\n if (typeof deltaBase === 'string') {\r\n deltaBase = Platform.BufferUtils.utf8Encode(deltaBase);\r\n }\r\n\r\n // vcdiff expects Uint8Arrays, can't copy with ArrayBuffers.\r\n const deltaBaseBuffer = Platform.BufferUtils.toBuffer(deltaBase as Buffer);\r\n data = Platform.BufferUtils.toBuffer(data);\r\n\r\n data = Platform.BufferUtils.arrayBufferViewToBuffer(context.plugins.vcdiff.decode(data, deltaBaseBuffer));\r\n lastPayload = data;\r\n } catch (e) {\r\n throw new ErrorInfo('Vcdiff delta decode failed with ' + e, 40018, 400);\r\n }\r\n continue;\r\n default:\r\n throw new Error('Unknown encoding');\r\n }\r\n }\r\n } catch (e) {\r\n const err = e as ErrorInfo;\r\n throw new ErrorInfo(\r\n 'Error processing the ' + xform + ' encoding, decoder returned ‘' + err.message + '’',\r\n err.code || 40013,\r\n 400,\r\n );\r\n } finally {\r\n message.encoding =\r\n (lastProcessedEncodingIndex as number) <= 0 ? null : xforms.slice(0, lastProcessedEncodingIndex).join('/');\r\n message.data = data;\r\n }\r\n }\r\n context.baseEncodedPreviousPayload = lastPayload;\r\n}\r\n\r\nexport function fromValues(values: Properties<Message>): Message {\r\n return Object.assign(new Message(), values);\r\n}\r\n\r\nexport function fromWireProtocol(values: WireProtocolMessage): Message {\r\n const action = toMessageActionString(values.action as number) || values.action;\r\n const res = Object.assign(new Message(), { ...values, action });\r\n res.expandFields();\r\n return res;\r\n}\r\n\r\nexport function fromValuesArray(values: Properties<Message>[]): Message[] {\r\n return values.map(fromValues);\r\n}\r\n\r\n/* This should be called on encode()d (and encrypt()d) Messages (as it\r\n * assumes the data is a string or buffer) */\r\nexport function getMessagesSize(messages: Message[]): number {\r\n let msg,\r\n total = 0;\r\n for (let i = 0; i < messages.length; i++) {\r\n msg = messages[i];\r\n total += msg.size || (msg.size = getMessageSize(msg));\r\n }\r\n return total;\r\n}\r\n\r\nclass Message {\r\n name?: string;\r\n id?: string;\r\n timestamp?: number;\r\n clientId?: string;\r\n connectionId?: string;\r\n connectionKey?: string;\r\n data?: any;\r\n encoding?: string | null;\r\n extras?: any;\r\n size?: number;\r\n action?: API.MessageAction;\r\n serial?: string;\r\n refSerial?: string;\r\n refType?: string;\r\n createdAt?: number;\r\n version?: string;\r\n operation?: API.Operation;\r\n\r\n /**\r\n * Overload toJSON() to intercept JSON.stringify()\r\n * @return {*}\r\n */\r\n toJSON() {\r\n /* encode data to base64 if present and we're returning real JSON;\r\n * although msgpack calls toJSON(), we know it is a stringify()\r\n * call if it has a non-empty arguments list */\r\n let encoding = this.encoding;\r\n let data = this.data;\r\n if (data && Platform.BufferUtils.isBuffer(data)) {\r\n if (arguments.length > 0) {\r\n /* stringify call */\r\n encoding = encoding ? encoding + '/base64' : 'base64';\r\n data = Platform.BufferUtils.base64Encode(data);\r\n } else {\r\n /* Called by msgpack. toBuffer returns a datatype understandable by\r\n * that platform's msgpack implementation (Buffer in node, Uint8Array\r\n * in browsers) */\r\n data = Platform.BufferUtils.toBuffer(data);\r\n }\r\n }\r\n return {\r\n name: this.name,\r\n id: this.id,\r\n clientId: this.clientId,\r\n connectionId: this.connectionId,\r\n connectionKey: this.connectionKey,\r\n extras: this.extras,\r\n serial: this.serial,\r\n action: toMessageActionNumber(this.action as API.MessageAction) || this.action,\r\n refSerial: this.refSerial,\r\n refType: this.refType,\r\n createdAt: this.createdAt,\r\n version: this.version,\r\n operation: this.operation,\r\n encoding,\r\n data,\r\n };\r\n }\r\n\r\n expandFields() {\r\n if (this.action === 'message.create') {\r\n // TM2k\r\n if (this.version && !this.serial) {\r\n this.serial = this.version;\r\n }\r\n // TM2o\r\n if (this.timestamp && !this.createdAt) {\r\n this.createdAt = this.timestamp;\r\n }\r\n }\r\n }\r\n\r\n toString(): string {\r\n let result = '[Message';\r\n if (this.name) result += '; name=' + this.name;\r\n if (this.id) result += '; id=' + this.id;\r\n if (this.timestamp) result += '; timestamp=' + this.timestamp;\r\n if (this.clientId) result += '; clientId=' + this.clientId;\r\n if (this.connectionId) result += '; connectionId=' + this.connectionId;\r\n if (this.encoding) result += '; encoding=' + this.encoding;\r\n if (this.extras) result += '; extras =' + JSON.stringify(this.extras);\r\n if (this.data) {\r\n if (typeof this.data == 'string') result += '; data=' + this.data;\r\n else if (Platform.BufferUtils.isBuffer(this.data))\r\n result += '; data (buffer)=' + Platform.BufferUtils.base64Encode(this.data);\r\n else result += '; data (json)=' + JSON.stringify(this.data);\r\n }\r\n if (this.extras) result += '; extras=' + JSON.stringify(this.extras);\r\n\r\n if (this.action) result += '; action=' + this.action;\r\n if (this.serial) result += '; serial=' + this.serial;\r\n if (this.version) result += '; version=' + this.version;\r\n if (this.refSerial) result += '; refSerial=' + this.refSerial;\r\n if (this.refType) result += '; refType=' + this.refType;\r\n if (this.createdAt) result += '; createdAt=' + this.createdAt;\r\n if (this.operation) result += '; operation=' + JSON.stringify(this.operation);\r\n result += ']';\r\n return result;\r\n }\r\n}\r\n\r\nexport default Message;\r\n","import Logger from '../util/logger';\r\nimport Platform from 'common/platform';\r\nimport { normalizeCipherOptions, encode as encodeMessage, decode as decodeMessage, getMessagesSize } from './message';\r\nimport * as API from '../../../../ably';\r\n\r\nimport type { IUntypedCryptoStatic } from 'common/types/ICryptoStatic';\r\nimport type { Properties } from '../util/utils';\r\nimport type RestChannel from '../client/restchannel';\r\nimport type RealtimeChannel from '../client/realtimechannel';\r\ntype Channel = RestChannel | RealtimeChannel;\r\n\r\nconst actions = ['absent', 'present', 'enter', 'leave', 'update'];\r\n\r\nexport type WireProtocolPresenceMessage = Omit<PresenceMessage, 'action'> & { action: number };\r\n\r\nfunction toActionValue(actionString: string) {\r\n return actions.indexOf(actionString);\r\n}\r\n\r\nexport async function fromEncoded(\r\n logger: Logger,\r\n Crypto: IUntypedCryptoStatic | null,\r\n encoded: WireProtocolPresenceMessage,\r\n inputOptions?: API.ChannelOptions,\r\n): Promise<PresenceMessage> {\r\n const msg = fromWireProtocol(encoded);\r\n const options = normalizeCipherOptions(Crypto, logger, inputOptions ?? null);\r\n /* if decoding fails at any point, catch and return the message decoded to\r\n * the fullest extent possible */\r\n try {\r\n await decode(msg, options ?? {});\r\n } catch (e) {\r\n Logger.logAction(logger, Logger.LOG_ERROR, 'PresenceMessage.fromEncoded()', (e as Error).toString());\r\n }\r\n return msg;\r\n}\r\n\r\nexport async function fromEncodedArray(\r\n logger: Logger,\r\n Crypto: IUntypedCryptoStatic | null,\r\n encodedArray: WireProtocolPresenceMessage[],\r\n options?: API.ChannelOptions,\r\n): Promise<PresenceMessage[]> {\r\n return Promise.all(\r\n encodedArray.map(function (encoded) {\r\n return fromEncoded(logger, Crypto, encoded, options);\r\n }),\r\n );\r\n}\r\n\r\n// these forms of the functions are used internally when we have a channel instance\r\n// already, so don't need to normalise channel options\r\nexport async function _fromEncoded(encoded: WireProtocolPresenceMessage, channel: Channel): Promise<PresenceMessage> {\r\n const msg = fromWireProtocol(encoded);\r\n try {\r\n await decode(msg, channel.channelOptions);\r\n } catch (e) {\r\n Logger.logAction(channel.logger, Logger.LOG_ERROR, 'PresenceMessage._fromEncoded()', (e as Error).toString());\r\n }\r\n return msg;\r\n}\r\n\r\nexport async function _fromEncodedArray(\r\n encodedArray: WireProtocolPresenceMessage[],\r\n channel: Channel,\r\n): Promise<PresenceMessage[]> {\r\n return Promise.all(\r\n encodedArray.map(function (encoded) {\r\n return _fromEncoded(encoded, channel);\r\n }),\r\n );\r\n}\r\n\r\nexport function fromValues(values: Properties<PresenceMessage>): PresenceMessage {\r\n return Object.assign(new PresenceMessage(), values);\r\n}\r\n\r\nexport function fromWireProtocol(values: WireProtocolPresenceMessage): PresenceMessage {\r\n const action = actions[values.action];\r\n return Object.assign(new PresenceMessage(), { ...values, action });\r\n}\r\n\r\nexport { encodeMessage as encode };\r\nexport const decode = decodeMessage;\r\n\r\nexport function fromValuesArray(values: Properties<PresenceMessage>[]): PresenceMessage[] {\r\n return values.map(fromValues);\r\n}\r\n\r\nexport function fromData(data: any): PresenceMessage {\r\n if (data instanceof PresenceMessage) {\r\n return data;\r\n }\r\n return fromValues({\r\n data,\r\n });\r\n}\r\n\r\nexport { getMessagesSize };\r\n\r\nclass PresenceMessage {\r\n action?: string;\r\n id?: string;\r\n timestamp?: number;\r\n clientId?: string;\r\n connectionId?: string;\r\n data?: string | Buffer | Uint8Array;\r\n encoding?: string;\r\n extras?: any;\r\n size?: number;\r\n\r\n /* Returns whether this presenceMessage is synthesized, i.e. was not actually\r\n * sent by the connection (usually means a leave event sent 15s after a\r\n * disconnection). This is useful because synthesized messages cannot be\r\n * compared for newness by id lexicographically - RTP2b1\r\n */\r\n isSynthesized(): boolean {\r\n if (!this.id || !this.connectionId) {\r\n return true;\r\n }\r\n return this.id.substring(this.connectionId.length, 0) !== this.connectionId;\r\n }\r\n\r\n /* RTP2b2 */\r\n parseId(): { connectionId: string; msgSerial: number; index: number } {\r\n if (!this.id) throw new Error('parseId(): Presence message does not contain an id');\r\n const parts = this.id.split(':');\r\n return {\r\n connectionId: parts[0],\r\n msgSerial: parseInt(parts[1], 10),\r\n index: parseInt(parts[2], 10),\r\n };\r\n }\r\n\r\n /**\r\n * Overload toJSON() to intercept JSON.stringify()\r\n * @return {*}\r\n */\r\n toJSON(): {\r\n id?: string;\r\n clientId?: string;\r\n action: number;\r\n data: string | Buffer | Uint8Array;\r\n encoding?: string;\r\n extras?: any;\r\n } {\r\n /* encode data to base64 if present and we're returning real JSON;\r\n * although msgpack calls toJSON(), we know it is a stringify()\r\n * call if it has a non-empty arguments list */\r\n let data = this.data as string | Buffer | Uint8Array;\r\n let encoding = this.encoding;\r\n if (data && Platform.BufferUtils.isBuffer(data)) {\r\n if (arguments.length > 0) {\r\n /* stringify call */\r\n encoding = encoding ? encoding + '/base64' : 'base64';\r\n data = Platform.BufferUtils.base64Encode(data);\r\n } else {\r\n /* Called by msgpack. toBuffer returns a datatype understandable by\r\n * that platform's msgpack implementation (Buffer in node, Uint8Array\r\n * in browsers) */\r\n data = Platform.BufferUtils.toBuffer(data);\r\n }\r\n }\r\n return {\r\n id: this.id,\r\n clientId: this.clientId,\r\n /* Convert presence action back to an int for sending to Ably */\r\n action: toActionValue(this.action as string),\r\n data: data,\r\n encoding: encoding,\r\n extras: this.extras,\r\n };\r\n }\r\n\r\n toString(): string {\r\n let result = '[PresenceMessage';\r\n result += '; action=' + this.action;\r\n if (this.id) result += '; id=' + this.id;\r\n if (this.timestamp) result += '; timestamp=' + this.timestamp;\r\n if (this.clientId) result += '; clientId=' + this.clientId;\r\n if (this.connectionId) result += '; connectionId=' + this.connectionId;\r\n if (this.encoding) result += '; encoding=' + this.encoding;\r\n if (this.data) {\r\n if (typeof this.data == 'string') result += '; data=' + this.data;\r\n else if (Platform.BufferUtils.isBuffer(this.data))\r\n result += '; data (buffer)=' + Platform.BufferUtils.base64Encode(this.data);\r\n else result += '; data (json)=' + JSON.stringify(this.data);\r\n }\r\n if (this.extras) {\r\n result += '; extras=' + JSON.stringify(this.extras);\r\n }\r\n result += ']';\r\n return result;\r\n }\r\n}\r\n\r\nexport default PresenceMessage;\r\n","import * as Utils from '../util/utils';\r\nimport Logger from '../util/logger';\r\nimport PaginatedResource, { PaginatedResult } from './paginatedresource';\r\nimport PresenceMessage, { WireProtocolPresenceMessage, _fromEncodedArray } from '../types/presencemessage';\r\nimport RestChannel from './restchannel';\r\nimport Defaults from '../util/defaults';\r\n\r\nclass RestPresence {\r\n channel: RestChannel;\r\n\r\n constructor(channel: RestChannel) {\r\n this.channel = channel;\r\n }\r\n\r\n get logger(): Logger {\r\n return this.channel.logger;\r\n }\r\n\r\n async get(params: any): Promise<PaginatedResult<PresenceMessage>> {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'RestPresence.get()', 'channel = ' + this.channel.name);\r\n const client = this.channel.client,\r\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\r\n envelope = this.channel.client.http.supportsLinkHeaders ? undefined : format,\r\n headers = Defaults.defaultGetHeaders(client.options, { format });\r\n\r\n Utils.mixin(headers, client.options.headers);\r\n\r\n return new PaginatedResource(\r\n client,\r\n this.channel.client.rest.presenceMixin.basePath(this),\r\n headers,\r\n envelope,\r\n async (body, headers, unpacked) => {\r\n const decoded: WireProtocolPresenceMessage[] = unpacked\r\n ? (body as WireProtocolPresenceMessage[])\r\n : Utils.decodeBody(body, client._MsgPack, format);\r\n\r\n return _fromEncodedArray(decoded, this.channel);\r\n },\r\n ).get(params);\r\n }\r\n\r\n async history(params: any): Promise<PaginatedResult<PresenceMessage>> {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'RestPresence.history()', 'channel = ' + this.channel.name);\r\n return this.channel.client.rest.presenceMixin.history(this, params);\r\n }\r\n}\r\n\r\nexport default RestPresence;\r\n","import * as Utils from '../util/utils';\r\nimport Logger from '../util/logger';\r\nimport RestPresence from './restpresence';\r\nimport Message, {\r\n encodeArray as encodeMessagesArray,\r\n serialize as serializeMessage,\r\n getMessagesSize,\r\n CipherOptions,\r\n fromValues as messageFromValues,\r\n fromValuesArray as messagesFromValuesArray,\r\n} from '../types/message';\r\nimport ErrorInfo from '../types/errorinfo';\r\nimport { PaginatedResult } from './paginatedresource';\r\nimport Resource from './resource';\r\nimport { ChannelOptions } from '../../types/channel';\r\nimport BaseRest from './baseclient';\r\nimport * as API from '../../../../ably';\r\nimport Defaults, { normaliseChannelOptions } from '../util/defaults';\r\nimport { RestHistoryParams } from './restchannelmixin';\r\nimport { RequestBody } from 'common/types/http';\r\nimport type { PushChannel } from 'plugins/push';\r\n\r\nconst MSG_ID_ENTROPY_BYTES = 9;\r\n\r\nfunction allEmptyIds(messages: Array<Message>) {\r\n return messages.every(function (message: Message) {\r\n return !message.id;\r\n });\r\n}\r\n\r\nclass RestChannel {\r\n client: BaseRest;\r\n name: string;\r\n presence: RestPresence;\r\n channelOptions: ChannelOptions;\r\n _push?: PushChannel;\r\n\r\n constructor(client: BaseRest, name: string, channelOptions?: ChannelOptions) {\r\n Logger.logAction(client.logger, Logger.LOG_MINOR, 'RestChannel()', 'started; name = ' + name);\r\n this.name = name;\r\n this.client = client;\r\n this.presence = new RestPresence(this);\r\n this.channelOptions = normaliseChannelOptions(client._Crypto ?? null, this.logger, channelOptions);\r\n if (client.options.plugins?.Push) {\r\n this._push = new client.options.plugins.Push.PushChannel(this);\r\n }\r\n }\r\n\r\n get push() {\r\n if (!this._push) {\r\n Utils.throwMissingPluginError('Push');\r\n }\r\n return this._push;\r\n }\r\n\r\n get logger(): Logger {\r\n return this.client.logger;\r\n }\r\n\r\n setOptions(options?: ChannelOptions): void {\r\n this.channelOptions = normaliseChannelOptions(this.client._Crypto ?? null, this.logger, options);\r\n }\r\n\r\n async history(params: RestHistoryParams | null): Promise<PaginatedResult<Message>> {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'RestChannel.history()', 'channel = ' + this.name);\r\n return this.client.rest.channelMixin.history(this, params);\r\n }\r\n\r\n async publish(...args: any[]): Promise<void> {\r\n const first = args[0],\r\n second = args[1];\r\n let messages: Array<Message>;\r\n let params: any;\r\n\r\n if (typeof first === 'string' || first === null) {\r\n /* (name, data, ...) */\r\n messages = [messageFromValues({ name: first, data: second })];\r\n params = args[2];\r\n } else if (Utils.isObject(first)) {\r\n messages = [messageFromValues(first)];\r\n params = args[1];\r\n } else if (Array.isArray(first)) {\r\n messages = messagesFromValuesArray(first);\r\n params = args[1];\r\n } else {\r\n throw new ErrorInfo(\r\n 'The single-argument form of publish() expects a message object or an array of message objects',\r\n 40013,\r\n 400,\r\n );\r\n }\r\n\r\n if (!params) {\r\n /* No params supplied */\r\n params = {};\r\n }\r\n\r\n const client = this.client,\r\n options = client.options,\r\n format = options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\r\n idempotentRestPublishing = client.options.idempotentRestPublishing,\r\n headers = Defaults.defaultPostHeaders(client.options, { format });\r\n\r\n Utils.mixin(headers, options.headers);\r\n\r\n if (idempotentRestPublishing && allEmptyIds(messages)) {\r\n const msgIdBase = await Utils.randomString(MSG_ID_ENTROPY_BYTES);\r\n messages.forEach(function (message, index) {\r\n message.id = msgIdBase + ':' + index.toString();\r\n });\r\n }\r\n\r\n await encodeMessagesArray(messages, this.channelOptions as CipherOptions);\r\n\r\n /* RSL1i */\r\n const size = getMessagesSize(messages),\r\n maxMessageSize = options.maxMessageSize;\r\n if (size > maxMessageSize) {\r\n throw new ErrorInfo(\r\n 'Maximum size of messages that can be published at once exceeded ( was ' +\r\n size +\r\n ' bytes; limit is ' +\r\n maxMessageSize +\r\n ' bytes)',\r\n 40009,\r\n 400,\r\n );\r\n }\r\n\r\n await this._publish(serializeMessage(messages, client._MsgPack, format), headers, params);\r\n }\r\n\r\n async _publish(requestBody: RequestBody | null, headers: Record<string, string>, params: any): Promise<void> {\r\n await Resource.post(\r\n this.client,\r\n this.client.rest.channelMixin.basePath(this) + '/messages',\r\n requestBody,\r\n headers,\r\n params,\r\n null,\r\n true,\r\n );\r\n }\r\n\r\n async status(): Promise<API.ChannelDetails> {\r\n return this.client.rest.channelMixin.status(this);\r\n }\r\n}\r\n\r\nexport default RestChannel;\r\n","type StatsValues = {\n entries?: Partial<Record<string, number>>;\n schema?: string;\n appId?: string;\n inProgress?: never;\n unit?: never;\n intervalId?: never;\n};\n\nclass Stats {\n entries?: Partial<Record<string, number>>;\n schema?: string;\n appId?: string;\n inProgress?: never;\n unit?: never;\n intervalId?: never;\n\n constructor(values?: StatsValues) {\n this.entries = (values && values.entries) || undefined;\n this.schema = (values && values.schema) || undefined;\n this.appId = (values && values.appId) || undefined;\n this.inProgress = (values && values.inProgress) || undefined;\n this.unit = (values && values.unit) || undefined;\n this.intervalId = (values && values.intervalId) || undefined;\n }\n\n static fromValues(values: StatsValues): Stats {\n return new Stats(values);\n }\n}\n\nexport default Stats;\n","import * as API from '../../../../ably';\r\nimport RestChannel from './restchannel';\r\nimport RealtimeChannel from './realtimechannel';\r\nimport * as Utils from '../util/utils';\r\nimport Message, { WireProtocolMessage, _fromEncodedArray } from '../types/message';\r\nimport Defaults from '../util/defaults';\r\nimport PaginatedResource, { PaginatedResult } from './paginatedresource';\r\nimport Resource from './resource';\r\n\r\nexport interface RestHistoryParams {\r\n start?: number;\r\n end?: number;\r\n direction?: string;\r\n limit?: number;\r\n}\r\n\r\nexport class RestChannelMixin {\r\n static basePath(channel: RestChannel | RealtimeChannel) {\r\n return '/channels/' + encodeURIComponent(channel.name);\r\n }\r\n\r\n static history(\r\n channel: RestChannel | RealtimeChannel,\r\n params: RestHistoryParams | null,\r\n ): Promise<PaginatedResult<Message>> {\r\n const client = channel.client,\r\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\r\n envelope = channel.client.http.supportsLinkHeaders ? undefined : format,\r\n headers = Defaults.defaultGetHeaders(client.options, { format });\r\n\r\n Utils.mixin(headers, client.options.headers);\r\n\r\n return new PaginatedResource(client, this.basePath(channel) + '/messages', headers, envelope, async function (\r\n body,\r\n headers,\r\n unpacked,\r\n ) {\r\n const decoded: WireProtocolMessage[] = unpacked\r\n ? (body as WireProtocolMessage[])\r\n : Utils.decodeBody(body, client._MsgPack, format);\r\n\r\n return _fromEncodedArray(decoded, channel);\r\n }).get(params as Record<string, unknown>);\r\n }\r\n\r\n static async status(channel: RestChannel | RealtimeChannel): Promise<API.ChannelDetails> {\r\n const format = channel.client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json;\r\n const headers = Defaults.defaultPostHeaders(channel.client.options, { format });\r\n\r\n const response = await Resource.get<API.ChannelDetails>(\r\n channel.client,\r\n this.basePath(channel),\r\n headers,\r\n {},\r\n format,\r\n true,\r\n );\r\n\r\n return response.body!;\r\n }\r\n}\r\n","import RestPresence from './restpresence';\r\nimport RealtimePresence from './realtimepresence';\r\nimport * as Utils from '../util/utils';\r\nimport Defaults from '../util/defaults';\r\nimport PaginatedResource, { PaginatedResult } from './paginatedresource';\r\nimport PresenceMessage, { WireProtocolPresenceMessage, _fromEncodedArray } from '../types/presencemessage';\r\nimport { RestChannelMixin } from './restchannelmixin';\r\n\r\nexport class RestPresenceMixin {\r\n static basePath(presence: RestPresence | RealtimePresence) {\r\n return RestChannelMixin.basePath(presence.channel) + '/presence';\r\n }\r\n\r\n static async history(\r\n presence: RestPresence | RealtimePresence,\r\n params: any,\r\n ): Promise<PaginatedResult<PresenceMessage>> {\r\n const client = presence.channel.client,\r\n format = client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\r\n envelope = presence.channel.client.http.supportsLinkHeaders ? undefined : format,\r\n headers = Defaults.defaultGetHeaders(client.options, { format });\r\n\r\n Utils.mixin(headers, client.options.headers);\r\n\r\n return new PaginatedResource(\r\n client,\r\n this.basePath(presence) + '/history',\r\n headers,\r\n envelope,\r\n async (body, headers, unpacked) => {\r\n const decoded: WireProtocolPresenceMessage[] = unpacked\r\n ? (body as WireProtocolPresenceMessage[])\r\n : Utils.decodeBody(body, client._MsgPack, format);\r\n\r\n return _fromEncodedArray(decoded, presence.channel);\r\n },\r\n ).get(params);\r\n }\r\n}\r\n","import * as Utils from '../util/utils';\nimport Defaults from '../util/defaults';\nimport Push from './push';\nimport PaginatedResource, { HttpPaginatedResponse, PaginatedResult } from './paginatedresource';\nimport RestChannel from './restchannel';\nimport ErrorInfo from '../types/errorinfo';\nimport Stats from '../types/stats';\nimport HttpMethods from '../../constants/HttpMethods';\nimport { ChannelOptions } from '../../types/channel';\nimport { RequestBody, RequestParams } from '../../types/http';\nimport * as API from '../../../../ably';\nimport Resource from './resource';\n\nimport Platform from '../../platform';\nimport BaseClient from './baseclient';\nimport { useTokenAuth } from './auth';\nimport { RestChannelMixin } from './restchannelmixin';\nimport { RestPresenceMixin } from './restpresencemixin';\nimport DeviceDetails from '../types/devicedetails';\n\ntype BatchResult<T> = API.BatchResult<T>;\n\ntype BatchPublishSpec = API.BatchPublishSpec;\ntype BatchPublishSuccessResult = API.BatchPublishSuccessResult;\ntype BatchPublishFailureResult = API.BatchPublishFailureResult;\ntype BatchPublishResult = BatchResult<BatchPublishSuccessResult | BatchPublishFailureResult>;\ntype BatchPresenceSuccessResult = API.BatchPresenceSuccessResult;\ntype BatchPresenceFailureResult = API.BatchPresenceFailureResult;\ntype BatchPresenceResult = BatchResult<BatchPresenceSuccessResult | BatchPresenceFailureResult>;\n\ntype TokenRevocationTargetSpecifier = API.TokenRevocationTargetSpecifier;\ntype TokenRevocationOptions = API.TokenRevocationOptions;\ntype TokenRevocationSuccessResult = API.TokenRevocationSuccessResult;\ntype TokenRevocationFailureResult = API.TokenRevocationFailureResult;\ntype TokenRevocationResult = BatchResult<TokenRevocationSuccessResult | TokenRevocationFailureResult>;\n\nexport class Rest {\n private readonly client: BaseClient;\n readonly channels: Channels;\n readonly push: Push;\n\n readonly channelMixin = RestChannelMixin;\n readonly presenceMixin = RestPresenceMixin;\n\n // exposed for plugins but shouldn't be bundled with minimal realtime\n Resource = Resource;\n DeviceDetails = DeviceDetails;\n\n constructor(client: BaseClient) {\n this.client = client;\n this.channels = new Channels(this.client);\n this.push = new Push(this.client);\n }\n\n async stats(params: RequestParams): Promise<PaginatedResult<Stats>> {\n const headers = Defaults.defaultGetHeaders(this.client.options),\n format = this.client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n envelope = this.client.http.supportsLinkHeaders ? undefined : format;\n\n Utils.mixin(headers, this.client.options.headers);\n\n return new PaginatedResource(this.client, '/stats', headers, envelope, function (body, headers, unpacked) {\n const statsValues = unpacked ? body : JSON.parse(body as string);\n for (let i = 0; i < statsValues.length; i++) statsValues[i] = Stats.fromValues(statsValues[i]);\n return statsValues;\n }).get(params as Record<string, string>);\n }\n\n async time(params?: RequestParams): Promise<number> {\n const headers = Defaults.defaultGetHeaders(this.client.options);\n if (this.client.options.headers) Utils.mixin(headers, this.client.options.headers);\n const timeUri = (host: string) => {\n return this.client.baseUri(host) + '/time';\n };\n\n let { error, body, unpacked } = await this.client.http.do(\n HttpMethods.Get,\n timeUri,\n headers,\n null,\n params as RequestParams,\n );\n\n if (error) {\n throw error;\n }\n if (!unpacked) body = JSON.parse(body as string);\n const time = (body as number[])[0];\n if (!time) {\n throw new ErrorInfo('Internal error (unexpected result type from GET /time)', 50000, 500);\n }\n /* calculate time offset only once for this device by adding to the prototype */\n this.client.serverTimeOffset = time - Date.now();\n return time;\n }\n\n async request(\n method: string,\n path: string,\n version: number,\n params: RequestParams,\n body: unknown,\n customHeaders: Record<string, string>,\n ): Promise<HttpPaginatedResponse<unknown>> {\n const [encoder, decoder, format] = (() => {\n if (this.client.options.useBinaryProtocol) {\n if (!this.client._MsgPack) {\n Utils.throwMissingPluginError('MsgPack');\n }\n return [this.client._MsgPack.encode, this.client._MsgPack.decode, Utils.Format.msgpack];\n } else {\n return [JSON.stringify, JSON.parse, Utils.Format.json];\n }\n })();\n const envelope = this.client.http.supportsLinkHeaders ? undefined : format;\n params = params || {};\n const _method = method.toLowerCase() as HttpMethods;\n const headers =\n _method == 'get'\n ? Defaults.defaultGetHeaders(this.client.options, { format, protocolVersion: version })\n : Defaults.defaultPostHeaders(this.client.options, { format, protocolVersion: version });\n\n if (typeof body !== 'string') {\n body = encoder(body) ?? null;\n }\n Utils.mixin(headers, this.client.options.headers);\n if (customHeaders) {\n Utils.mixin(headers, customHeaders);\n }\n const paginatedResource = new PaginatedResource(\n this.client,\n path,\n headers,\n envelope,\n async function (resbody, headers, unpacked) {\n return Utils.ensureArray(unpacked ? resbody : decoder(resbody as string & Buffer));\n },\n /* useHttpPaginatedResponse: */ true,\n );\n\n if (!Platform.Http.methods.includes(_method)) {\n throw new ErrorInfo('Unsupported method ' + _method, 40500, 405);\n }\n\n if (Platform.Http.methodsWithBody.includes(_method)) {\n return paginatedResource[_method as HttpMethods.Post](params, body as RequestBody) as Promise<\n HttpPaginatedResponse<unknown>\n >;\n } else {\n return paginatedResource[_method as HttpMethods.Get | HttpMethods.Delete](params) as Promise<\n HttpPaginatedResponse<unknown>\n >;\n }\n }\n\n async batchPublish<T extends BatchPublishSpec | BatchPublishSpec[]>(\n specOrSpecs: T,\n ): Promise<T extends BatchPublishSpec ? BatchPublishResult : BatchPublishResult[]> {\n let requestBodyDTO: BatchPublishSpec[];\n let singleSpecMode: boolean;\n if (Array.isArray(specOrSpecs)) {\n requestBodyDTO = specOrSpecs;\n singleSpecMode = false;\n } else {\n requestBodyDTO = [specOrSpecs];\n singleSpecMode = true;\n }\n\n const format = this.client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultPostHeaders(this.client.options, { format });\n\n if (this.client.options.headers) Utils.mixin(headers, this.client.options.headers);\n\n const requestBody = Utils.encodeBody(requestBodyDTO, this.client._MsgPack, format);\n\n const response = await Resource.post(this.client, '/messages', requestBody, headers, {}, null, true);\n\n const batchResults = (\n response.unpacked ? response.body : Utils.decodeBody(response.body, this.client._MsgPack, format)\n ) as BatchPublishResult[];\n\n // I don't love the below type assertions but not sure how to avoid them\n if (singleSpecMode) {\n return batchResults[0] as T extends BatchPublishSpec ? BatchPublishResult : BatchPublishResult[];\n } else {\n return batchResults as T extends BatchPublishSpec ? BatchPublishResult : BatchPublishResult[];\n }\n }\n\n async batchPresence(channels: string[]): Promise<BatchPresenceResult> {\n const format = this.client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultPostHeaders(this.client.options, { format });\n\n if (this.client.options.headers) Utils.mixin(headers, this.client.options.headers);\n\n const channelsParam = channels.join(',');\n\n const response = await Resource.get(this.client, '/presence', headers, { channels: channelsParam }, null, true);\n\n return (\n response.unpacked ? response.body : Utils.decodeBody(response.body, this.client._MsgPack, format)\n ) as BatchPresenceResult;\n }\n\n async revokeTokens(\n specifiers: TokenRevocationTargetSpecifier[],\n options?: TokenRevocationOptions,\n ): Promise<TokenRevocationResult> {\n if (useTokenAuth(this.client.options)) {\n throw new ErrorInfo('Cannot revoke tokens when using token auth', 40162, 401);\n }\n\n const keyName = this.client.options.keyName!;\n\n let resolvedOptions = options ?? {};\n\n const requestBodyDTO = {\n targets: specifiers.map((specifier) => `${specifier.type}:${specifier.value}`),\n ...resolvedOptions,\n };\n\n const format = this.client.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json,\n headers = Defaults.defaultPostHeaders(this.client.options, { format });\n\n if (this.client.options.headers) Utils.mixin(headers, this.client.options.headers);\n\n const requestBody = Utils.encodeBody(requestBodyDTO, this.client._MsgPack, format);\n\n const response = await Resource.post(\n this.client,\n `/keys/${keyName}/revokeTokens`,\n requestBody,\n headers,\n {},\n null,\n true,\n );\n\n return (\n response.unpacked ? response.body : Utils.decodeBody(response.body, this.client._MsgPack, format)\n ) as TokenRevocationResult;\n }\n}\n\nclass Channels {\n client: BaseClient;\n all: Record<string, RestChannel>;\n\n constructor(client: BaseClient) {\n this.client = client;\n this.all = Object.create(null);\n }\n\n get(name: string, channelOptions?: ChannelOptions) {\n name = String(name);\n let channel = this.all[name];\n if (!channel) {\n this.all[name] = channel = new RestChannel(this.client, name, channelOptions);\n } else if (channelOptions) {\n channel.setOptions(channelOptions);\n }\n\n return channel;\n }\n\n /* Included to support certain niche use-cases; most users should ignore this.\n * Please do not use this unless you know what you're doing */\n release(name: string) {\n delete this.all[String(name)];\n }\n}\n","import BaseClient from './baseclient';\nimport ClientOptions from '../../types/ClientOptions';\nimport { Rest } from './rest';\nimport Defaults from '../util/defaults';\nimport Logger from '../util/logger';\n\n/**\n `BaseRest` is an export of the tree-shakable version of the SDK, and acts as the base class for the `DefaultRest` class exported by the non tree-shakable version.\n\n It always includes the `Rest` plugin.\n */\nexport class BaseRest extends BaseClient {\n /*\n * The public typings declare that this only accepts an object, but since we want to emit a good error message in the case where a non-TypeScript user does one of these things:\n *\n * 1. passes a string (which is quite likely if they’re e.g. migrating from the default variant to the modular variant)\n * 2. passes no argument at all\n *\n * tell the compiler that these cases are possible so that it forces us to handle them.\n */\n constructor(options?: ClientOptions | string) {\n super(Defaults.objectifyOptions(options, false, 'BaseRest', Logger.defaultLogger, { Rest }));\n }\n}\n","import { Rest } from './rest';\r\nimport { IUntypedCryptoStatic } from '../../types/ICryptoStatic';\r\nimport { MsgPack } from 'common/types/msgpack';\r\nimport RealtimePresence from './realtimepresence';\r\nimport XHRRequest from 'platform/web/lib/http/request/xhrrequest';\r\nimport fetchRequest from 'platform/web/lib/http/request/fetchrequest';\r\nimport { FilteredSubscriptions } from './filteredsubscriptions';\r\nimport {\r\n fromValues as presenceMessageFromValues,\r\n fromValuesArray as presenceMessagesFromValuesArray,\r\n fromWireProtocol as presenceMessageFromWireProtocol,\r\n} from '../types/presencemessage';\r\nimport { TransportCtor } from '../transport/transport';\r\nimport * as PushPlugin from 'plugins/push';\r\n\r\nexport interface PresenceMessagePlugin {\r\n presenceMessageFromValues: typeof presenceMessageFromValues;\r\n presenceMessagesFromValuesArray: typeof presenceMessagesFromValuesArray;\r\n presenceMessageFromWireProtocol: typeof presenceMessageFromWireProtocol;\r\n}\r\n\r\nexport type RealtimePresencePlugin = PresenceMessagePlugin & {\r\n RealtimePresence: typeof RealtimePresence;\r\n};\r\n\r\nexport interface ModularPlugins {\r\n Rest?: typeof Rest;\r\n Crypto?: IUntypedCryptoStatic;\r\n MsgPack?: MsgPack;\r\n RealtimePresence?: RealtimePresencePlugin;\r\n WebSocketTransport?: TransportCtor;\r\n XHRPolling?: TransportCtor;\r\n XHRRequest?: typeof XHRRequest;\r\n FetchRequest?: typeof fetchRequest;\r\n MessageInteractions?: typeof FilteredSubscriptions;\r\n Push?: typeof PushPlugin;\r\n}\r\n\r\nexport const allCommonModularPlugins: ModularPlugins = { Rest };\r\n","import Message, {\r\n WireProtocolMessage,\r\n CipherOptions,\r\n decode,\r\n encode,\r\n EncodingDecodingContext,\r\n fromEncoded,\r\n fromEncodedArray,\r\n fromValues,\r\n fromWireProtocol,\r\n} from './message';\r\nimport * as API from '../../../../ably';\r\nimport Platform from 'common/platform';\r\nimport PresenceMessage from './presencemessage';\r\nimport { ChannelOptions } from 'common/types/channel';\r\nimport Logger from '../util/logger';\r\nimport type { Properties } from '../util/utils';\r\n\r\n/**\r\n `DefaultMessage` is the class returned by `DefaultRest` and `DefaultRealtime`’s `Message` static property. It introduces the static methods described in the `MessageStatic` interface of the public API of the non tree-shakable version of the library.\r\n */\r\nexport class DefaultMessage extends Message {\r\n static async fromEncoded(encoded: unknown, inputOptions?: API.ChannelOptions): Promise<Message> {\r\n return fromEncoded(Logger.defaultLogger, Platform.Crypto, encoded as WireProtocolMessage, inputOptions);\r\n }\r\n\r\n static async fromEncodedArray(encodedArray: Array<unknown>, options?: API.ChannelOptions): Promise<Message[]> {\r\n return fromEncodedArray(Logger.defaultLogger, Platform.Crypto, encodedArray as WireProtocolMessage[], options);\r\n }\r\n\r\n // Used by tests\r\n static fromValues(values: Properties<Message>): Message {\r\n return fromValues(values);\r\n }\r\n\r\n // Used by tests\r\n static fromWireProtocol(values: WireProtocolMessage): Message {\r\n return fromWireProtocol(values);\r\n }\r\n\r\n // Used by tests\r\n static async encode<T extends Message | PresenceMessage>(msg: T, options: CipherOptions): Promise<T> {\r\n return encode(msg, options);\r\n }\r\n\r\n // Used by tests\r\n static async decode(\r\n message: Message | PresenceMessage,\r\n inputContext: CipherOptions | EncodingDecodingContext | ChannelOptions,\r\n ): Promise<void> {\r\n return decode(message, inputContext);\r\n }\r\n}\r\n","import * as API from '../../../../ably';\r\nimport Logger from '../util/logger';\r\nimport PresenceMessage, {\r\n fromEncoded,\r\n fromEncodedArray,\r\n fromValues,\r\n WireProtocolPresenceMessage,\r\n} from './presencemessage';\r\nimport Platform from 'common/platform';\r\nimport type { Properties } from '../util/utils';\r\n\r\n/**\r\n `DefaultPresenceMessage` is the class returned by `DefaultRest` and `DefaultRealtime`’s `PresenceMessage` static property. It introduces the static methods described in the `PresenceMessageStatic` interface of the public API of the non tree-shakable version of the library.\r\n */\r\nexport class DefaultPresenceMessage extends PresenceMessage {\r\n static async fromEncoded(encoded: unknown, inputOptions?: API.ChannelOptions): Promise<PresenceMessage> {\r\n return fromEncoded(Logger.defaultLogger, Platform.Crypto, encoded as WireProtocolPresenceMessage, inputOptions);\r\n }\r\n\r\n static async fromEncodedArray(\r\n encodedArray: Array<unknown>,\r\n options?: API.ChannelOptions,\r\n ): Promise<PresenceMessage[]> {\r\n return fromEncodedArray(\r\n Logger.defaultLogger,\r\n Platform.Crypto,\r\n encodedArray as WireProtocolPresenceMessage[],\r\n options,\r\n );\r\n }\r\n\r\n static fromValues(values: Properties<PresenceMessage>): PresenceMessage {\r\n return fromValues(values);\r\n }\r\n}\r\n","import { BaseRest } from './baserest';\nimport ClientOptions from '../../types/ClientOptions';\nimport { allCommonModularPlugins } from './modularplugins';\nimport Platform from 'common/platform';\nimport { DefaultMessage } from '../types/defaultmessage';\nimport { MsgPack } from 'common/types/msgpack';\nimport { DefaultPresenceMessage } from '../types/defaultpresencemessage';\nimport { Http } from 'common/types/http';\nimport Defaults from '../util/defaults';\nimport Logger from '../util/logger';\n\n/**\n `DefaultRest` is the class that the non tree-shakable version of the SDK exports as `Rest`. It ensures that this version of the SDK includes all of the functionality which is optionally available in the tree-shakable version.\n */\nexport class DefaultRest extends BaseRest {\n // The public typings declare that this requires an argument to be passed, but since we want to emit a good error message in the case where a non-TypeScript user does not pass an argument, tell the compiler that this is possible so that it forces us to handle it.\n constructor(options?: ClientOptions | string) {\n const MsgPack = DefaultRest._MsgPack;\n if (!MsgPack) {\n throw new Error('Expected DefaultRest._MsgPack to have been set');\n }\n\n super(\n Defaults.objectifyOptions(options, true, 'Rest', Logger.defaultLogger, {\n ...allCommonModularPlugins,\n Crypto: DefaultRest.Crypto ?? undefined,\n MsgPack: DefaultRest._MsgPack ?? undefined,\n }),\n );\n }\n\n private static _Crypto: typeof Platform.Crypto = null;\n static get Crypto() {\n if (this._Crypto === null) {\n throw new Error('Encryption not enabled; use ably.encryption.js instead');\n }\n\n return this._Crypto;\n }\n static set Crypto(newValue: typeof Platform.Crypto) {\n this._Crypto = newValue;\n }\n\n static Message = DefaultMessage;\n static PresenceMessage = DefaultPresenceMessage;\n\n static _MsgPack: MsgPack | null = null;\n\n // Used by tests\n static _Http = Http;\n}\n","import * as Utils from './utils';\nimport Logger from './logger';\nimport Platform from 'common/platform';\n\n/* Call the listener, catch any exceptions and log, but continue operation*/\nfunction callListener(logger: Logger, eventThis: { event: string }, listener: Function, args: unknown[]) {\n try {\n listener.apply(eventThis, args);\n } catch (e) {\n Logger.logAction(\n logger,\n Logger.LOG_ERROR,\n 'EventEmitter.emit()',\n 'Unexpected listener exception: ' + e + '; stack = ' + (e && (e as Error).stack),\n );\n }\n}\n\n/**\n * Remove listeners that match listener\n * @param targetListeners is an array of listener arrays or event objects with arrays of listeners\n * @param listener the listener callback to remove\n * @param eventFilter (optional) event name instructing the function to only remove listeners for the specified event\n */\nfunction removeListener(targetListeners: any, listener: Function, eventFilter?: string) {\n let listeners: Record<string, unknown>;\n let index;\n let eventName;\n\n for (let targetListenersIndex = 0; targetListenersIndex < targetListeners.length; targetListenersIndex++) {\n listeners = targetListeners[targetListenersIndex];\n if (eventFilter) {\n listeners = listeners[eventFilter] as Record<string, unknown>;\n }\n\n if (Array.isArray(listeners)) {\n while ((index = listeners.indexOf(listener)) !== -1) {\n listeners.splice(index, 1);\n }\n /* If events object has an event name key with no listeners then\n\t\t\t\t\tremove the key to stop the list growing indefinitely */\n if (eventFilter && listeners.length === 0) {\n delete targetListeners[targetListenersIndex][eventFilter];\n }\n } else if (Utils.isObject(listeners)) {\n /* events */\n for (eventName in listeners) {\n if (Object.prototype.hasOwnProperty.call(listeners, eventName) && Array.isArray(listeners[eventName])) {\n removeListener([listeners], listener, eventName);\n }\n }\n }\n }\n}\n\nclass EventEmitter {\n any: Array<Function>;\n events: Record<string, Array<Function>>;\n anyOnce: Array<Function>;\n eventsOnce: Record<string, Array<Function>>;\n\n constructor(readonly logger: Logger) {\n this.any = [];\n this.events = Object.create(null);\n this.anyOnce = [];\n this.eventsOnce = Object.create(null);\n }\n\n /**\n * Add an event listener\n * @param listener the listener to be called\n */\n on(listener: Function): void;\n\n /**\n * Add an event listener\n * @param event (optional) the name of the event to listen to\n * @param listener the listener to be called\n */\n on(event: null | string | string[], listener: Function): void;\n\n on(...args: unknown[]) {\n if (args.length === 1) {\n const listener = args[0];\n if (typeof listener === 'function') {\n this.any.push(listener);\n } else {\n throw new Error('EventListener.on(): Invalid arguments: ' + Platform.Config.inspect(args));\n }\n }\n if (args.length === 2) {\n const [event, listener] = args;\n if (typeof listener !== 'function') {\n throw new Error('EventListener.on(): Invalid arguments: ' + Platform.Config.inspect(args));\n }\n if (Utils.isNil(event)) {\n this.any.push(listener);\n } else if (Array.isArray(event)) {\n event.forEach((eventName) => {\n this.on(eventName, listener);\n });\n } else {\n if (typeof event !== 'string') {\n throw new Error('EventListener.on(): Invalid arguments: ' + Platform.Config.inspect(args));\n }\n const listeners = this.events[event] || (this.events[event] = []);\n listeners.push(listener);\n }\n }\n }\n\n /**\n * Remove one or more event listeners\n * @param listener (optional) the listener to remove. If not\n * supplied, all listeners are removed.\n */\n off(listener?: Function): void;\n\n /**\n * Remove one or more event listeners\n * @param event (optional) the name of the event whose listener\n * is to be removed. If not supplied, the listener is\n * treated as an 'any' listener\n * @param listener (optional) the listener to remove. If not\n * supplied, all listeners are removed.\n */\n off(event: string | string[] | null, listener?: Function | null): void;\n\n off(...args: unknown[]) {\n if (args.length == 0 || (Utils.isNil(args[0]) && Utils.isNil(args[1]))) {\n this.any = [];\n this.events = Object.create(null);\n this.anyOnce = [];\n this.eventsOnce = Object.create(null);\n return;\n }\n const [firstArg, secondArg] = args;\n let listener: Function | null = null;\n let event: unknown = null;\n if (args.length === 1 || !secondArg) {\n if (typeof firstArg === 'function') {\n /* we take this to be the listener and treat the event as \"any\" .. */\n listener = firstArg;\n } else {\n event = firstArg;\n }\n /* ... or we take event to be the actual event name and listener to be all */\n } else {\n if (typeof secondArg !== 'function') {\n throw new Error('EventEmitter.off(): invalid arguments:' + Platform.Config.inspect(args));\n }\n [event, listener] = [firstArg, secondArg];\n }\n\n if (listener && Utils.isNil(event)) {\n removeListener([this.any, this.events, this.anyOnce, this.eventsOnce], listener);\n return;\n }\n\n if (Array.isArray(event)) {\n event.forEach((eventName) => {\n this.off(eventName, listener);\n });\n return;\n }\n\n /* \"normal\" case where event is an actual event */\n if (typeof event !== 'string') {\n throw new Error('EventEmitter.off(): invalid arguments:' + Platform.Config.inspect(args));\n }\n if (listener) {\n removeListener([this.events, this.eventsOnce], listener, event);\n } else {\n delete this.events[event];\n delete this.eventsOnce[event];\n }\n }\n\n /**\n * Get the array of listeners for a given event; excludes once events\n * @param event (optional) the name of the event, or none for 'any'\n * @return array of events, or null if none\n */\n listeners(event: string) {\n if (event) {\n const listeners = this.events[event] || [];\n if (this.eventsOnce[event]) Array.prototype.push.apply(listeners, this.eventsOnce[event]);\n return listeners.length ? listeners : null;\n }\n return this.any.length ? this.any : null;\n }\n\n /**\n * Emit an event\n * @param event the event name\n * @param args the arguments to pass to the listener\n */\n emit(event: string, ...args: unknown[] /* , args... */) {\n const eventThis = { event };\n const listeners: Function[] = [];\n\n if (this.anyOnce.length) {\n Array.prototype.push.apply(listeners, this.anyOnce);\n this.anyOnce = [];\n }\n if (this.any.length) {\n Array.prototype.push.apply(listeners, this.any);\n }\n const eventsOnceListeners = this.eventsOnce[event];\n if (eventsOnceListeners) {\n Array.prototype.push.apply(listeners, eventsOnceListeners);\n delete this.eventsOnce[event];\n }\n const eventsListeners = this.events[event];\n if (eventsListeners) {\n Array.prototype.push.apply(listeners, eventsListeners);\n }\n\n listeners.forEach((listener) => {\n callListener(this.logger, eventThis, listener, args);\n });\n }\n\n /**\n * Listen for a single occurrence of an event\n * @param event the name of the event to listen to\n */\n once(event: string): Promise<void>;\n\n /**\n * Listen for a single occurrence of any event\n * @param listener the listener to be called\n */\n once(listener: Function): void;\n\n /**\n * Listen for a single occurrence of an event\n * @param event the name of the event to listen to\n * @param listener the listener to be called\n */\n once(event?: string | string[] | null, listener?: Function): void;\n\n once(...args: unknown[]): void | Promise<void> {\n const argCount = args.length;\n if (argCount === 0 || (argCount === 1 && typeof args[0] !== 'function')) {\n const event = args[0];\n return new Promise((resolve) => {\n this.once(event as string | string[] | null, resolve);\n });\n }\n\n const [firstArg, secondArg] = args;\n if (args.length === 1 && typeof firstArg === 'function') {\n this.anyOnce.push(firstArg);\n } else if (Utils.isNil(firstArg)) {\n if (typeof secondArg !== 'function') {\n throw new Error('EventEmitter.once(): Invalid arguments:' + Platform.Config.inspect(args));\n }\n this.anyOnce.push(secondArg);\n } else if (Array.isArray(firstArg)) {\n const self = this;\n const listenerWrapper = function (this: any) {\n const innerArgs = Array.prototype.slice.call(arguments);\n firstArg.forEach(function (eventName) {\n self.off(eventName, listenerWrapper);\n });\n if (typeof secondArg !== 'function') {\n throw new Error('EventEmitter.once(): Invalid arguments:' + Platform.Config.inspect(args));\n }\n secondArg.apply(this, innerArgs);\n };\n firstArg.forEach(function (eventName) {\n self.on(eventName, listenerWrapper);\n });\n } else {\n if (typeof firstArg !== 'string') {\n throw new Error('EventEmitter.once(): Invalid arguments:' + Platform.Config.inspect(args));\n }\n const listeners = this.eventsOnce[firstArg] || (this.eventsOnce[firstArg] = []);\n if (secondArg) {\n if (typeof secondArg !== 'function') {\n throw new Error('EventEmitter.once(): Invalid arguments:' + Platform.Config.inspect(args));\n }\n listeners.push(secondArg);\n }\n }\n }\n\n /**\n * Listen for a single occurrence of a state event and fire immediately if currentState matches targetState\n * @param targetState the name of the state event to listen to\n * @param currentState the name of the current state of this object\n */\n async whenState(targetState: string, currentState: string) {\n if (typeof targetState !== 'string' || typeof currentState !== 'string') {\n throw new Error('whenState requires a valid state String argument');\n }\n if (targetState === currentState) {\n return null;\n } else {\n return this.once(targetState);\n }\n }\n}\n\nexport default EventEmitter;\n","import { MsgPack } from 'common/types/msgpack';\r\nimport * as API from '../../../../ably';\r\nimport { PresenceMessagePlugin } from '../client/modularplugins';\r\nimport * as Utils from '../util/utils';\r\nimport ErrorInfo from './errorinfo';\r\nimport Message, {\r\n fromWireProtocol as messageFromWireProtocol,\r\n fromValuesArray as messagesFromValuesArray,\r\n WireProtocolMessage,\r\n} from './message';\r\nimport PresenceMessage, {\r\n fromWireProtocol as presenceMessageFromWireProtocol,\r\n fromValues as presenceMessageFromValues,\r\n fromValuesArray as presenceMessagesFromValuesArray,\r\n WireProtocolPresenceMessage,\r\n} from './presencemessage';\r\n\r\nexport const actions = {\r\n HEARTBEAT: 0,\r\n ACK: 1,\r\n NACK: 2,\r\n CONNECT: 3,\r\n CONNECTED: 4,\r\n DISCONNECT: 5,\r\n DISCONNECTED: 6,\r\n CLOSE: 7,\r\n CLOSED: 8,\r\n ERROR: 9,\r\n ATTACH: 10,\r\n ATTACHED: 11,\r\n DETACH: 12,\r\n DETACHED: 13,\r\n PRESENCE: 14,\r\n MESSAGE: 15,\r\n SYNC: 16,\r\n AUTH: 17,\r\n ACTIVATE: 18,\r\n};\r\n\r\nexport const ActionName: string[] = [];\r\nObject.keys(actions).forEach(function (name) {\r\n ActionName[(actions as { [key: string]: number })[name]] = name;\r\n});\r\n\r\nconst flags: { [key: string]: number } = {\r\n /* Channel attach state flags */\r\n HAS_PRESENCE: 1 << 0,\r\n HAS_BACKLOG: 1 << 1,\r\n RESUMED: 1 << 2,\r\n TRANSIENT: 1 << 4,\r\n ATTACH_RESUME: 1 << 5,\r\n /* Channel mode flags */\r\n PRESENCE: 1 << 16,\r\n PUBLISH: 1 << 17,\r\n SUBSCRIBE: 1 << 18,\r\n PRESENCE_SUBSCRIBE: 1 << 19,\r\n};\r\nconst flagNames = Object.keys(flags);\r\nflags.MODE_ALL = flags.PRESENCE | flags.PUBLISH | flags.SUBSCRIBE | flags.PRESENCE_SUBSCRIBE;\r\n\r\nfunction toStringArray(array?: any[]): string {\r\n const result = [];\r\n if (array) {\r\n for (let i = 0; i < array.length; i++) {\r\n result.push(array[i].toString());\r\n }\r\n }\r\n return '[ ' + result.join(', ') + ' ]';\r\n}\r\n\r\nexport const channelModes = ['PRESENCE', 'PUBLISH', 'SUBSCRIBE', 'PRESENCE_SUBSCRIBE'];\r\n\r\nexport const serialize = Utils.encodeBody;\r\n\r\nexport function deserialize(\r\n serialized: unknown,\r\n MsgPack: MsgPack | null,\r\n presenceMessagePlugin: PresenceMessagePlugin | null,\r\n format?: Utils.Format,\r\n): ProtocolMessage {\r\n const deserialized = Utils.decodeBody<Record<string, unknown>>(serialized, MsgPack, format);\r\n return fromDeserialized(deserialized, presenceMessagePlugin);\r\n}\r\n\r\nexport function fromDeserialized(\r\n deserialized: Record<string, unknown>,\r\n presenceMessagePlugin: PresenceMessagePlugin | null,\r\n): ProtocolMessage {\r\n const error = deserialized.error;\r\n if (error) {\r\n deserialized.error = ErrorInfo.fromValues(error as ErrorInfo);\r\n }\r\n\r\n let messages: Message[] | undefined;\r\n if (deserialized.messages) {\r\n const dm = deserialized.messages as WireProtocolMessage[];\r\n messages = dm.map((m) => messageFromWireProtocol(m));\r\n }\r\n\r\n let presence: PresenceMessage[] | undefined;\r\n if (presenceMessagePlugin && deserialized.presence) {\r\n const dp = deserialized.presence as WireProtocolPresenceMessage[];\r\n presence = dp.map((pm) => presenceMessagePlugin.presenceMessageFromWireProtocol(pm));\r\n }\r\n\r\n return Object.assign(new ProtocolMessage(), { ...deserialized, presence, messages });\r\n}\r\n\r\n/**\r\n * Used by the tests.\r\n */\r\nexport function fromDeserializedIncludingDependencies(deserialized: Record<string, unknown>): ProtocolMessage {\r\n return fromDeserialized(deserialized, {\r\n presenceMessageFromValues,\r\n presenceMessagesFromValuesArray,\r\n presenceMessageFromWireProtocol,\r\n });\r\n}\r\n\r\nexport function fromValues(values: unknown): ProtocolMessage {\r\n return Object.assign(new ProtocolMessage(), values);\r\n}\r\n\r\nexport function stringify(msg: any, presenceMessagePlugin: PresenceMessagePlugin | null): string {\r\n let result = '[ProtocolMessage';\r\n if (msg.action !== undefined) result += '; action=' + ActionName[msg.action] || msg.action;\r\n\r\n const simpleAttributes = ['id', 'channel', 'channelSerial', 'connectionId', 'count', 'msgSerial', 'timestamp'];\r\n let attribute;\r\n for (let attribIndex = 0; attribIndex < simpleAttributes.length; attribIndex++) {\r\n attribute = simpleAttributes[attribIndex];\r\n if (msg[attribute] !== undefined) result += '; ' + attribute + '=' + msg[attribute];\r\n }\r\n\r\n if (msg.messages) result += '; messages=' + toStringArray(messagesFromValuesArray(msg.messages));\r\n if (msg.presence && presenceMessagePlugin)\r\n result += '; presence=' + toStringArray(presenceMessagePlugin.presenceMessagesFromValuesArray(msg.presence));\r\n if (msg.error) result += '; error=' + ErrorInfo.fromValues(msg.error).toString();\r\n if (msg.auth && msg.auth.accessToken) result += '; token=' + msg.auth.accessToken;\r\n if (msg.flags) result += '; flags=' + flagNames.filter(msg.hasFlag).join(',');\r\n if (msg.params) {\r\n let stringifiedParams = '';\r\n Utils.forInOwnNonNullProperties(msg.params, function (prop: string) {\r\n if (stringifiedParams.length > 0) {\r\n stringifiedParams += '; ';\r\n }\r\n stringifiedParams += prop + '=' + msg.params[prop];\r\n });\r\n if (stringifiedParams.length > 0) {\r\n result += '; params=[' + stringifiedParams + ']';\r\n }\r\n }\r\n result += ']';\r\n return result;\r\n}\r\n\r\nclass ProtocolMessage {\r\n action?: number;\r\n flags?: number;\r\n id?: string;\r\n timestamp?: number;\r\n count?: number;\r\n error?: ErrorInfo;\r\n connectionId?: string;\r\n channel?: string;\r\n channelSerial?: string | null;\r\n msgSerial?: number;\r\n messages?: Message[];\r\n // This will be undefined if we skipped decoding this property due to user not requesting presence functionality — see `fromDeserialized`\r\n presence?: PresenceMessage[];\r\n auth?: unknown;\r\n connectionDetails?: Record<string, unknown>;\r\n\r\n hasFlag = (flag: string): boolean => {\r\n return ((this.flags as number) & flags[flag]) > 0;\r\n };\r\n\r\n setFlag(flag: API.ChannelMode): number {\r\n return (this.flags = (this.flags as number) | flags[flag]);\r\n }\r\n\r\n getMode(): number | undefined {\r\n return this.flags && this.flags & flags.MODE_ALL;\r\n }\r\n\r\n encodeModesToFlags(modes: API.ChannelMode[]): void {\r\n modes.forEach((mode) => this.setFlag(mode));\r\n }\r\n\r\n decodeModesFromFlags(): string[] | undefined {\r\n const modes: string[] = [];\r\n channelModes.forEach((mode) => {\r\n if (this.hasFlag(mode)) {\r\n modes.push(mode);\r\n }\r\n });\r\n return modes.length > 0 ? modes : undefined;\r\n }\r\n}\r\n\r\nexport default ProtocolMessage;\r\n","import ErrorInfo from '../types/errorinfo';\nimport EventEmitter from '../util/eventemitter';\nimport Logger from '../util/logger';\nimport { PendingMessage } from './protocol';\n\nclass MessageQueue extends EventEmitter {\n messages: Array<PendingMessage>;\n\n constructor(logger: Logger) {\n super(logger);\n this.messages = [];\n }\n\n count(): number {\n return this.messages.length;\n }\n\n push(message: PendingMessage): void {\n this.messages.push(message);\n }\n\n shift(): PendingMessage | undefined {\n return this.messages.shift();\n }\n\n last(): PendingMessage {\n return this.messages[this.messages.length - 1];\n }\n\n copyAll(): PendingMessage[] {\n return this.messages.slice();\n }\n\n append(messages: Array<PendingMessage>): void {\n this.messages.push.apply(this.messages, messages);\n }\n\n prepend(messages: Array<PendingMessage>): void {\n this.messages.unshift.apply(this.messages, messages);\n }\n\n completeMessages(serial: number, count: number, err?: ErrorInfo | null): void {\n Logger.logAction(\n this.logger,\n Logger.LOG_MICRO,\n 'MessageQueue.completeMessages()',\n 'serial = ' + serial + '; count = ' + count,\n );\n err = err || null;\n const messages = this.messages;\n if (messages.length === 0) {\n throw new Error('MessageQueue.completeMessages(): completeMessages called on any empty MessageQueue');\n }\n const first = messages[0];\n if (first) {\n const startSerial = first.message.msgSerial as number;\n const endSerial = serial + count; /* the serial of the first message that is *not* the subject of this call */\n if (endSerial > startSerial) {\n const completeMessages = messages.splice(0, endSerial - startSerial);\n for (const message of completeMessages) {\n (message.callback as Function)(err);\n }\n }\n if (messages.length == 0) this.emit('idle');\n }\n }\n\n completeAllMessages(err: ErrorInfo): void {\n this.completeMessages(0, Number.MAX_SAFE_INTEGER || Number.MAX_VALUE, err);\n }\n\n resetSendAttempted(): void {\n for (let msg of this.messages) {\n msg.sendAttempted = false;\n }\n }\n\n clear(): void {\n Logger.logAction(\n this.logger,\n Logger.LOG_MICRO,\n 'MessageQueue.clear()',\n 'clearing ' + this.messages.length + ' messages',\n );\n this.messages = [];\n this.emit('idle');\n }\n}\n\nexport default MessageQueue;\n","import ProtocolMessage, { actions, stringify as stringifyProtocolMessage } from '../types/protocolmessage';\r\nimport * as Utils from '../util/utils';\r\nimport EventEmitter from '../util/eventemitter';\r\nimport Logger from '../util/logger';\r\nimport MessageQueue from './messagequeue';\r\nimport ErrorInfo from '../types/errorinfo';\r\nimport Transport from './transport';\r\nimport { ErrCallback } from '../../types/utils';\r\n\r\nexport class PendingMessage {\r\n message: ProtocolMessage;\r\n callback?: ErrCallback;\r\n merged: boolean;\r\n sendAttempted: boolean;\r\n ackRequired: boolean;\r\n\r\n constructor(message: ProtocolMessage, callback?: ErrCallback) {\r\n this.message = message;\r\n this.callback = callback;\r\n this.merged = false;\r\n const action = message.action;\r\n this.sendAttempted = false;\r\n this.ackRequired = action == actions.MESSAGE || action == actions.PRESENCE;\r\n }\r\n}\r\n\r\nclass Protocol extends EventEmitter {\r\n transport: Transport;\r\n messageQueue: MessageQueue;\r\n\r\n constructor(transport: Transport) {\r\n super(transport.logger);\r\n this.transport = transport;\r\n this.messageQueue = new MessageQueue(this.logger);\r\n transport.on('ack', (serial: number, count: number) => {\r\n this.onAck(serial, count);\r\n });\r\n transport.on('nack', (serial: number, count: number, err: ErrorInfo) => {\r\n this.onNack(serial, count, err);\r\n });\r\n }\r\n\r\n onAck(serial: number, count: number): void {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'Protocol.onAck()', 'serial = ' + serial + '; count = ' + count);\r\n this.messageQueue.completeMessages(serial, count);\r\n }\r\n\r\n onNack(serial: number, count: number, err: ErrorInfo): void {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'Protocol.onNack()',\r\n 'serial = ' + serial + '; count = ' + count + '; err = ' + Utils.inspectError(err),\r\n );\r\n if (!err) {\r\n err = new ErrorInfo('Unable to send message; channel not responding', 50001, 500);\r\n }\r\n this.messageQueue.completeMessages(serial, count, err);\r\n }\r\n\r\n onceIdle(listener: ErrCallback): void {\r\n const messageQueue = this.messageQueue;\r\n if (messageQueue.count() === 0) {\r\n listener();\r\n return;\r\n }\r\n messageQueue.once('idle', listener);\r\n }\r\n\r\n send(pendingMessage: PendingMessage): void {\r\n if (pendingMessage.ackRequired) {\r\n this.messageQueue.push(pendingMessage);\r\n }\r\n if (this.logger.shouldLog(Logger.LOG_MICRO)) {\r\n Logger.logActionNoStrip(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'Protocol.send()',\r\n 'sending msg; ' +\r\n stringifyProtocolMessage(pendingMessage.message, this.transport.connectionManager.realtime._RealtimePresence),\r\n );\r\n }\r\n pendingMessage.sendAttempted = true;\r\n this.transport.send(pendingMessage.message);\r\n }\r\n\r\n getTransport(): Transport {\r\n return this.transport;\r\n }\r\n\r\n getPendingMessages(): PendingMessage[] {\r\n return this.messageQueue.copyAll();\r\n }\r\n\r\n clearPendingMessages(): void {\r\n return this.messageQueue.clear();\r\n }\r\n\r\n finish(): void {\r\n const transport = this.transport;\r\n this.onceIdle(function () {\r\n transport.disconnect();\r\n });\r\n }\r\n}\r\n\r\nexport default Protocol;\r\n","import { IPartialErrorInfo } from '../types/errorinfo';\n\nclass ConnectionStateChange {\n previous?: string;\n current?: string;\n retryIn?: number;\n reason?: IPartialErrorInfo;\n\n constructor(previous?: string, current?: string, retryIn?: number | null, reason?: IPartialErrorInfo) {\n this.previous = previous;\n this.current = current;\n if (retryIn) this.retryIn = retryIn;\n if (reason) this.reason = reason;\n }\n}\n\nexport default ConnectionStateChange;\n","import ErrorInfo from '../types/errorinfo';\n\nconst ConnectionErrorCodes = {\n DISCONNECTED: 80003,\n SUSPENDED: 80002,\n FAILED: 80000,\n CLOSING: 80017,\n CLOSED: 80017,\n UNKNOWN_CONNECTION_ERR: 50002,\n UNKNOWN_CHANNEL_ERR: 50001,\n};\n\nconst ConnectionErrors = {\n disconnected: () =>\n ErrorInfo.fromValues({\n statusCode: 400,\n code: ConnectionErrorCodes.DISCONNECTED,\n message: 'Connection to server temporarily unavailable',\n }),\n suspended: () =>\n ErrorInfo.fromValues({\n statusCode: 400,\n code: ConnectionErrorCodes.SUSPENDED,\n message: 'Connection to server unavailable',\n }),\n failed: () =>\n ErrorInfo.fromValues({\n statusCode: 400,\n code: ConnectionErrorCodes.FAILED,\n message: 'Connection failed or disconnected by server',\n }),\n closing: () =>\n ErrorInfo.fromValues({\n statusCode: 400,\n code: ConnectionErrorCodes.CLOSING,\n message: 'Connection closing',\n }),\n closed: () =>\n ErrorInfo.fromValues({\n statusCode: 400,\n code: ConnectionErrorCodes.CLOSED,\n message: 'Connection closed',\n }),\n unknownConnectionErr: () =>\n ErrorInfo.fromValues({\n statusCode: 500,\n code: ConnectionErrorCodes.UNKNOWN_CONNECTION_ERR,\n message: 'Internal connection error',\n }),\n unknownChannelErr: () =>\n ErrorInfo.fromValues({\n statusCode: 500,\n code: ConnectionErrorCodes.UNKNOWN_CONNECTION_ERR,\n message: 'Internal channel error',\n }),\n};\n\nexport function isRetriable(err: ErrorInfo) {\n if (!err.statusCode || !err.code || err.statusCode >= 500) {\n return true;\n }\n return Object.values(ConnectionErrorCodes).includes(err.code);\n}\n\nexport default ConnectionErrors;\n","import ProtocolMessage, {\r\n actions,\r\n fromValues as protocolMessageFromValues,\r\n stringify as stringifyProtocolMessage,\r\n} from '../types/protocolmessage';\r\nimport * as Utils from '../util/utils';\r\nimport EventEmitter from '../util/eventemitter';\r\nimport Logger from '../util/logger';\r\nimport ConnectionErrors from './connectionerrors';\r\nimport ErrorInfo from '../types/errorinfo';\r\nimport Auth from '../client/auth';\r\nimport * as API from '../../../../ably';\r\nimport ConnectionManager, { TransportParams } from './connectionmanager';\r\nimport Platform from 'common/platform';\r\nimport TransportName from 'common/constants/TransportName';\r\n\r\nexport type TryConnectCallback = (\r\n wrappedErr: { error: ErrorInfo; event: string } | null,\r\n transport?: Transport,\r\n) => void;\r\n\r\nexport interface TransportCtor {\r\n new (\r\n connectionManager: ConnectionManager,\r\n auth: Auth,\r\n params: TransportParams,\r\n forceJsonProtocol?: boolean,\r\n ): Transport;\r\n\r\n isAvailable(): boolean;\r\n}\r\n\r\nconst closeMessage = protocolMessageFromValues({ action: actions.CLOSE });\r\nconst disconnectMessage = protocolMessageFromValues({ action: actions.DISCONNECT });\r\n\r\n/*\r\n * Transport instances inherit from EventEmitter and emit the following events:\r\n *\r\n * event name data\r\n * closed error\r\n * failed error\r\n * disposed\r\n * connected null error, connectionSerial, connectionId, connectionDetails\r\n * event channel message object\r\n */\r\n\r\nabstract class Transport extends EventEmitter {\r\n connectionManager: ConnectionManager;\r\n auth: Auth;\r\n params: TransportParams;\r\n timeouts: Record<string, number>;\r\n format?: Utils.Format;\r\n isConnected: boolean;\r\n isFinished: boolean;\r\n isDisposed: boolean;\r\n maxIdleInterval: number | null;\r\n idleTimer: NodeJS.Timeout | number | null;\r\n lastActivity: number | null;\r\n\r\n constructor(connectionManager: ConnectionManager, auth: Auth, params: TransportParams, forceJsonProtocol?: boolean) {\r\n super(connectionManager.logger);\r\n if (forceJsonProtocol) {\r\n params.format = undefined;\r\n params.heartbeats = true;\r\n }\r\n this.connectionManager = connectionManager;\r\n this.auth = auth;\r\n this.params = params;\r\n this.timeouts = params.options.timeouts;\r\n this.format = params.format;\r\n this.isConnected = false;\r\n this.isFinished = false;\r\n this.isDisposed = false;\r\n this.maxIdleInterval = null;\r\n this.idleTimer = null;\r\n this.lastActivity = null;\r\n }\r\n\r\n abstract shortName: TransportName;\r\n abstract send(message: ProtocolMessage): void;\r\n\r\n connect(): void {}\r\n\r\n close(): void {\r\n if (this.isConnected) {\r\n this.requestClose();\r\n }\r\n this.finish('closed', ConnectionErrors.closed());\r\n }\r\n\r\n disconnect(err?: Error | ErrorInfo): void {\r\n /* Used for network/transport issues that need to result in the transport\r\n * being disconnected, but should not transition the connection to 'failed' */\r\n if (this.isConnected) {\r\n this.requestDisconnect();\r\n }\r\n this.finish('disconnected', err || ConnectionErrors.disconnected());\r\n }\r\n\r\n fail(err: ErrorInfo): void {\r\n /* Used for client-side-detected fatal connection issues */\r\n if (this.isConnected) {\r\n this.requestDisconnect();\r\n }\r\n this.finish('failed', err || ConnectionErrors.failed());\r\n }\r\n\r\n finish(event: string, err?: Error | ErrorInfo): void {\r\n if (this.isFinished) {\r\n return;\r\n }\r\n\r\n this.isFinished = true;\r\n this.isConnected = false;\r\n this.maxIdleInterval = null;\r\n clearTimeout(this.idleTimer ?? undefined);\r\n this.idleTimer = null;\r\n this.emit(event, err);\r\n this.dispose();\r\n }\r\n\r\n onProtocolMessage(message: ProtocolMessage): void {\r\n if (this.logger.shouldLog(Logger.LOG_MICRO)) {\r\n Logger.logActionNoStrip(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'Transport.onProtocolMessage()',\r\n 'received on ' +\r\n this.shortName +\r\n ': ' +\r\n stringifyProtocolMessage(message, this.connectionManager.realtime._RealtimePresence) +\r\n '; connectionId = ' +\r\n this.connectionManager.connectionId,\r\n );\r\n }\r\n this.onActivity();\r\n\r\n switch (message.action) {\r\n case actions.HEARTBEAT:\r\n Logger.logActionNoStrip(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'Transport.onProtocolMessage()',\r\n this.shortName + ' heartbeat; connectionId = ' + this.connectionManager.connectionId,\r\n );\r\n this.emit('heartbeat', message.id);\r\n break;\r\n case actions.CONNECTED:\r\n this.onConnect(message);\r\n this.emit('connected', message.error, message.connectionId, message.connectionDetails, message);\r\n break;\r\n case actions.CLOSED:\r\n this.onClose(message);\r\n break;\r\n case actions.DISCONNECTED:\r\n this.onDisconnect(message);\r\n break;\r\n case actions.ACK:\r\n this.emit('ack', message.msgSerial, message.count);\r\n break;\r\n case actions.NACK:\r\n this.emit('nack', message.msgSerial, message.count, message.error);\r\n break;\r\n case actions.SYNC:\r\n this.connectionManager.onChannelMessage(message, this);\r\n break;\r\n case actions.ACTIVATE:\r\n // Ignored.\r\n break;\r\n case actions.AUTH:\r\n Utils.whenPromiseSettles(this.auth.authorize(), (err: ErrorInfo | null) => {\r\n if (err) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'Transport.onProtocolMessage()',\r\n 'Ably requested re-authentication, but unable to obtain a new token: ' + Utils.inspectError(err),\r\n );\r\n }\r\n });\r\n break;\r\n case actions.ERROR:\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'Transport.onProtocolMessage()',\r\n 'received error action; connectionId = ' +\r\n this.connectionManager.connectionId +\r\n '; err = ' +\r\n Platform.Config.inspect(message.error) +\r\n (message.channel ? ', channel: ' + message.channel : ''),\r\n );\r\n if (message.channel === undefined) {\r\n this.onFatalError(message);\r\n break;\r\n }\r\n /* otherwise it's a channel-specific error, so handle it in the channel */\r\n this.connectionManager.onChannelMessage(message, this);\r\n break;\r\n default:\r\n /* all other actions are channel-specific */\r\n this.connectionManager.onChannelMessage(message, this);\r\n }\r\n }\r\n\r\n onConnect(message: ProtocolMessage): void {\r\n this.isConnected = true;\r\n if (!message.connectionDetails) {\r\n throw new Error('Transport.onConnect(): Connect message recieved without connectionDetails');\r\n }\r\n const maxPromisedIdle = message.connectionDetails.maxIdleInterval as number;\r\n if (maxPromisedIdle) {\r\n this.maxIdleInterval = maxPromisedIdle + this.timeouts.realtimeRequestTimeout;\r\n this.onActivity();\r\n }\r\n /* else Realtime declines to guarantee any maximum idle interval - CD2h */\r\n }\r\n\r\n onDisconnect(message: ProtocolMessage): void {\r\n /* Used for when the server has disconnected the client (usually with a\r\n * DISCONNECTED action) */\r\n const err = message && message.error;\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Transport.onDisconnect()', 'err = ' + Utils.inspectError(err));\r\n this.finish('disconnected', err);\r\n }\r\n\r\n onFatalError(message: ProtocolMessage): void {\r\n /* On receipt of a fatal connection error, we can assume that the server\r\n * will close the connection and the transport, and do not need to request\r\n * a disconnection - RTN15i */\r\n const err = message && message.error;\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Transport.onFatalError()', 'err = ' + Utils.inspectError(err));\r\n this.finish('failed', err);\r\n }\r\n\r\n onClose(message: ProtocolMessage): void {\r\n const err = message && message.error;\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Transport.onClose()', 'err = ' + Utils.inspectError(err));\r\n this.finish('closed', err);\r\n }\r\n\r\n requestClose(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Transport.requestClose()', '');\r\n this.send(closeMessage);\r\n }\r\n\r\n requestDisconnect(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Transport.requestDisconnect()', '');\r\n this.send(disconnectMessage);\r\n }\r\n\r\n ping(id: string): void {\r\n const msg: Record<string, number | string> = { action: actions.HEARTBEAT };\r\n if (id) msg.id = id;\r\n this.send(protocolMessageFromValues(msg));\r\n }\r\n\r\n dispose(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Transport.dispose()', '');\r\n this.isDisposed = true;\r\n this.off();\r\n }\r\n\r\n onActivity(): void {\r\n if (!this.maxIdleInterval) {\r\n return;\r\n }\r\n this.lastActivity = this.connectionManager.lastActivity = Date.now();\r\n this.setIdleTimer(this.maxIdleInterval + 100);\r\n }\r\n\r\n setIdleTimer(timeout: number): void {\r\n if (!this.idleTimer) {\r\n this.idleTimer = setTimeout(() => {\r\n this.onIdleTimerExpire();\r\n }, timeout);\r\n }\r\n }\r\n\r\n onIdleTimerExpire(): void {\r\n if (!this.lastActivity || !this.maxIdleInterval) {\r\n throw new Error('Transport.onIdleTimerExpire(): lastActivity/maxIdleInterval not set');\r\n }\r\n this.idleTimer = null;\r\n const sinceLast = Date.now() - this.lastActivity;\r\n const timeRemaining = this.maxIdleInterval - sinceLast;\r\n if (timeRemaining <= 0) {\r\n const msg = 'No activity seen from realtime in ' + sinceLast + 'ms; assuming connection has dropped';\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'Transport.onIdleTimerExpire()', msg);\r\n this.disconnect(new ErrorInfo(msg, 80003, 408));\r\n } else {\r\n this.setIdleTimer(timeRemaining + 100);\r\n }\r\n }\r\n\r\n static tryConnect(\r\n transportCtor: TransportCtor,\r\n connectionManager: ConnectionManager,\r\n auth: Auth,\r\n transportParams: TransportParams,\r\n callback: TryConnectCallback,\r\n ): Transport {\r\n const transport = new transportCtor(connectionManager, auth, transportParams);\r\n\r\n let transportAttemptTimer: NodeJS.Timeout | number;\r\n\r\n const errorCb = function (this: { event: string }, err: ErrorInfo) {\r\n clearTimeout(transportAttemptTimer);\r\n callback({ event: this.event, error: err });\r\n };\r\n\r\n const realtimeRequestTimeout = connectionManager.options.timeouts.realtimeRequestTimeout;\r\n transportAttemptTimer = setTimeout(() => {\r\n transport.off(['preconnect', 'disconnected', 'failed']);\r\n transport.dispose();\r\n errorCb.call(\r\n { event: 'disconnected' },\r\n new ErrorInfo('Timeout waiting for transport to indicate itself viable', 50000, 500),\r\n );\r\n }, realtimeRequestTimeout);\r\n\r\n transport.on(['failed', 'disconnected'], errorCb);\r\n transport.on('preconnect', function () {\r\n Logger.logAction(\r\n connectionManager.logger,\r\n Logger.LOG_MINOR,\r\n 'Transport.tryConnect()',\r\n 'viable transport ' + transport,\r\n );\r\n clearTimeout(transportAttemptTimer);\r\n transport.off(['failed', 'disconnected'], errorCb);\r\n callback(null, transport);\r\n });\r\n transport.connect();\r\n return transport;\r\n }\r\n\r\n onAuthUpdated?: (tokenDetails: API.TokenDetails) => void;\r\n\r\n static isAvailable(): boolean {\r\n throw new ErrorInfo('isAvailable not implemented for transport', 50000, 500);\r\n }\r\n}\r\n\r\nexport default Transport;\r\n","export namespace TransportNames {\n export const WebSocket = 'web_socket' as const;\n export const Comet = 'comet' as const;\n export const XhrPolling = 'xhr_polling' as const;\n}\n\ntype TransportName = typeof TransportNames.WebSocket | typeof TransportNames.Comet | typeof TransportNames.XhrPolling;\n\nexport default TransportName;\n","import ProtocolMessage, {\r\n actions,\r\n stringify as stringifyProtocolMessage,\r\n fromValues as protocolMessageFromValues,\r\n} from 'common/lib/types/protocolmessage';\r\nimport * as Utils from 'common/lib/util/utils';\r\nimport Protocol, { PendingMessage } from './protocol';\r\nimport Defaults, { getAgentString } from 'common/lib/util/defaults';\r\nimport Platform, { TransportImplementations } from 'common/platform';\r\nimport EventEmitter from '../util/eventemitter';\r\nimport MessageQueue from './messagequeue';\r\nimport Logger from '../util/logger';\r\nimport ConnectionStateChange from 'common/lib/client/connectionstatechange';\r\nimport ConnectionErrors, { isRetriable } from './connectionerrors';\r\nimport ErrorInfo, { IPartialErrorInfo, PartialErrorInfo } from 'common/lib/types/errorinfo';\r\nimport Auth from 'common/lib/client/auth';\r\nimport Message, { getMessagesSize } from 'common/lib/types/message';\r\nimport Multicaster, { MulticasterInstance } from 'common/lib/util/multicaster';\r\nimport Transport, { TransportCtor } from './transport';\r\nimport * as API from '../../../../ably';\r\nimport { ErrCallback } from 'common/types/utils';\r\nimport HttpStatusCodes from 'common/constants/HttpStatusCodes';\r\nimport BaseRealtime from '../client/baserealtime';\r\nimport { NormalisedClientOptions } from 'common/types/ClientOptions';\r\nimport TransportName, { TransportNames } from 'common/constants/TransportName';\r\n\r\nlet globalObject = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : self;\r\n\r\nconst haveWebStorage = () => typeof Platform.WebStorage !== 'undefined' && Platform.WebStorage?.localSupported;\r\nconst haveSessionStorage = () => typeof Platform.WebStorage !== 'undefined' && Platform.WebStorage?.sessionSupported;\r\nconst noop = function () {};\r\nconst transportPreferenceName = 'ably-transport-preference';\r\n\r\nfunction bundleWith(dest: ProtocolMessage, src: ProtocolMessage, maxSize: number) {\r\n let action;\r\n if (dest.channel !== src.channel) {\r\n /* RTL6d3 */\r\n return false;\r\n }\r\n if ((action = dest.action) !== actions.PRESENCE && action !== actions.MESSAGE) {\r\n /* RTL6d - can only bundle messages or presence */\r\n return false;\r\n }\r\n if (action !== src.action) {\r\n /* RTL6d4 */\r\n return false;\r\n }\r\n const kind = action === actions.PRESENCE ? 'presence' : 'messages',\r\n proposed = (dest as Record<string, any>)[kind].concat((src as Record<string, any>)[kind]),\r\n size = getMessagesSize(proposed);\r\n if (size > maxSize) {\r\n /* RTL6d1 */\r\n return false;\r\n }\r\n if (!Utils.allSame(proposed, 'clientId')) {\r\n /* RTL6d2 */\r\n return false;\r\n }\r\n if (\r\n !proposed.every(function (msg: Message) {\r\n return !msg.id;\r\n })\r\n ) {\r\n /* RTL6d7 */\r\n return false;\r\n }\r\n /* we're good to go! */\r\n (dest as Record<string, any>)[kind] = proposed;\r\n return true;\r\n}\r\n\r\ntype RecoveryContext = {\r\n connectionKey: string;\r\n msgSerial: number;\r\n channelSerials: { [name: string]: string };\r\n};\r\n\r\nfunction decodeRecoveryKey(recoveryKey: NormalisedClientOptions['recover']): RecoveryContext | null {\r\n try {\r\n return JSON.parse(recoveryKey as string);\r\n } catch (e) {\r\n return null;\r\n }\r\n}\r\n\r\nexport class TransportParams {\r\n options: NormalisedClientOptions;\r\n host: string | null;\r\n mode: string;\r\n format?: Utils.Format;\r\n connectionKey?: string;\r\n stream?: any;\r\n heartbeats?: boolean;\r\n\r\n constructor(options: NormalisedClientOptions, host: string | null, mode: string, connectionKey?: string) {\r\n this.options = options;\r\n this.host = host;\r\n this.mode = mode;\r\n this.connectionKey = connectionKey;\r\n this.format = options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json;\r\n }\r\n\r\n getConnectParams(authParams: Record<string, unknown>): Record<string, string> {\r\n const params = authParams ? Utils.copy(authParams) : {};\r\n const options = this.options;\r\n switch (this.mode) {\r\n case 'resume':\r\n params.resume = this.connectionKey as string;\r\n break;\r\n case 'recover': {\r\n const recoveryContext = decodeRecoveryKey(options.recover);\r\n if (recoveryContext) {\r\n params.recover = recoveryContext.connectionKey;\r\n }\r\n break;\r\n }\r\n default:\r\n }\r\n if (options.clientId !== undefined) {\r\n params.clientId = options.clientId;\r\n }\r\n if (options.echoMessages === false) {\r\n params.echo = 'false';\r\n }\r\n if (this.format !== undefined) {\r\n params.format = this.format;\r\n }\r\n if (this.stream !== undefined) {\r\n params.stream = this.stream;\r\n }\r\n if (this.heartbeats !== undefined) {\r\n params.heartbeats = this.heartbeats;\r\n }\r\n params.v = Defaults.protocolVersion;\r\n params.agent = getAgentString(this.options);\r\n if (options.transportParams !== undefined) {\r\n Utils.mixin(params, options.transportParams);\r\n }\r\n return params as Record<string, string>;\r\n }\r\n\r\n toString(): string {\r\n let result = '[mode=' + this.mode;\r\n if (this.host) {\r\n result += ',host=' + this.host;\r\n }\r\n if (this.connectionKey) {\r\n result += ',connectionKey=' + this.connectionKey;\r\n }\r\n if (this.format) {\r\n result += ',format=' + this.format;\r\n }\r\n result += ']';\r\n\r\n return result;\r\n }\r\n}\r\n\r\ntype ConnectionState = {\r\n state: string;\r\n terminal?: boolean;\r\n queueEvents?: boolean;\r\n sendEvents?: boolean;\r\n failState?: string;\r\n retryDelay?: number;\r\n retryImmediately?: boolean;\r\n error?: IPartialErrorInfo;\r\n};\r\n\r\nclass ConnectionManager extends EventEmitter {\r\n supportedTransports: Partial<Record<TransportName, TransportCtor>> = {};\r\n realtime: BaseRealtime;\r\n options: NormalisedClientOptions;\r\n states: Record<string, ConnectionState>;\r\n state: ConnectionState;\r\n errorReason: IPartialErrorInfo | null;\r\n queuedMessages: MessageQueue;\r\n msgSerial: number;\r\n connectionDetails?: Record<string, any>;\r\n connectionId?: string;\r\n connectionKey?: string;\r\n connectionStateTtl: number;\r\n maxIdleInterval: number | null;\r\n transports: TransportName[];\r\n baseTransport?: TransportName;\r\n webSocketTransportAvailable?: true;\r\n transportPreference: string | null;\r\n httpHosts: string[];\r\n wsHosts: string[];\r\n activeProtocol: null | Protocol;\r\n pendingTransport?: Transport;\r\n proposedTransport?: Transport;\r\n host: string | null;\r\n lastAutoReconnectAttempt: number | null;\r\n lastActivity: number | null;\r\n forceFallbackHost: boolean;\r\n transitionTimer?: number | NodeJS.Timeout | null;\r\n suspendTimer?: number | NodeJS.Timeout | null;\r\n retryTimer?: number | NodeJS.Timeout | null;\r\n disconnectedRetryCount: number = 0;\r\n pendingChannelMessagesState: {\r\n // Whether a message is currently being processed\r\n isProcessing: boolean;\r\n // The messages remaining to be processed (excluding any message currently being processed)\r\n queue: { message: ProtocolMessage; transport: Transport }[];\r\n } = { isProcessing: false, queue: [] };\r\n webSocketSlowTimer: NodeJS.Timeout | null;\r\n wsCheckResult: boolean | null;\r\n webSocketGiveUpTimer: NodeJS.Timeout | null;\r\n abandonedWebSocket: boolean;\r\n connectCounter: number;\r\n\r\n constructor(realtime: BaseRealtime, options: NormalisedClientOptions) {\r\n super(realtime.logger);\r\n this.realtime = realtime;\r\n this.initTransports();\r\n this.options = options;\r\n const timeouts = options.timeouts;\r\n /* connectingTimeout: leave webSocketConnectTimeout (~6s) to try the\r\n * websocket transport, then realtimeRequestTimeout (~10s) to establish\r\n * the base transport in case that fails */\r\n const connectingTimeout = timeouts.webSocketConnectTimeout + timeouts.realtimeRequestTimeout;\r\n this.states = {\r\n initialized: {\r\n state: 'initialized',\r\n terminal: false,\r\n queueEvents: true,\r\n sendEvents: false,\r\n failState: 'disconnected',\r\n },\r\n connecting: {\r\n state: 'connecting',\r\n terminal: false,\r\n queueEvents: true,\r\n sendEvents: false,\r\n retryDelay: connectingTimeout,\r\n failState: 'disconnected',\r\n },\r\n connected: {\r\n state: 'connected',\r\n terminal: false,\r\n queueEvents: false,\r\n sendEvents: true,\r\n failState: 'disconnected',\r\n },\r\n disconnected: {\r\n state: 'disconnected',\r\n terminal: false,\r\n queueEvents: true,\r\n sendEvents: false,\r\n retryDelay: timeouts.disconnectedRetryTimeout,\r\n failState: 'disconnected',\r\n },\r\n suspended: {\r\n state: 'suspended',\r\n terminal: false,\r\n queueEvents: false,\r\n sendEvents: false,\r\n retryDelay: timeouts.suspendedRetryTimeout,\r\n failState: 'suspended',\r\n },\r\n closing: {\r\n state: 'closing',\r\n terminal: false,\r\n queueEvents: false,\r\n sendEvents: false,\r\n retryDelay: timeouts.realtimeRequestTimeout,\r\n failState: 'closed',\r\n },\r\n closed: { state: 'closed', terminal: true, queueEvents: false, sendEvents: false, failState: 'closed' },\r\n failed: { state: 'failed', terminal: true, queueEvents: false, sendEvents: false, failState: 'failed' },\r\n };\r\n this.state = this.states.initialized;\r\n this.errorReason = null;\r\n\r\n this.queuedMessages = new MessageQueue(this.logger);\r\n this.msgSerial = 0;\r\n this.connectionDetails = undefined;\r\n this.connectionId = undefined;\r\n this.connectionKey = undefined;\r\n this.connectionStateTtl = timeouts.connectionStateTtl;\r\n this.maxIdleInterval = null;\r\n\r\n this.transports = Utils.intersect(options.transports || Defaults.defaultTransports, this.supportedTransports);\r\n this.transportPreference = null;\r\n\r\n if (this.transports.includes(TransportNames.WebSocket)) {\r\n this.webSocketTransportAvailable = true;\r\n }\r\n if (this.transports.includes(TransportNames.XhrPolling)) {\r\n this.baseTransport = TransportNames.XhrPolling;\r\n } else if (this.transports.includes(TransportNames.Comet)) {\r\n this.baseTransport = TransportNames.Comet;\r\n }\r\n\r\n this.httpHosts = Defaults.getHosts(options);\r\n this.wsHosts = Defaults.getHosts(options, true);\r\n this.activeProtocol = null;\r\n this.host = null;\r\n this.lastAutoReconnectAttempt = null;\r\n this.lastActivity = null;\r\n this.forceFallbackHost = false;\r\n this.connectCounter = 0;\r\n this.wsCheckResult = null;\r\n this.webSocketSlowTimer = null;\r\n this.webSocketGiveUpTimer = null;\r\n this.abandonedWebSocket = false;\r\n\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Realtime.ConnectionManager()', 'started');\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'Realtime.ConnectionManager()',\r\n 'requested transports = [' + (options.transports || Defaults.defaultTransports) + ']',\r\n );\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'Realtime.ConnectionManager()',\r\n 'available transports = [' + this.transports + ']',\r\n );\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'Realtime.ConnectionManager()',\r\n 'http hosts = [' + this.httpHosts + ']',\r\n );\r\n\r\n if (!this.transports.length) {\r\n const msg = 'no requested transports available';\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'realtime.ConnectionManager()', msg);\r\n throw new Error(msg);\r\n }\r\n\r\n const addEventListener = Platform.Config.addEventListener;\r\n if (addEventListener) {\r\n /* intercept close event in browser to persist connection id if requested */\r\n if (haveSessionStorage() && typeof options.recover === 'function') {\r\n addEventListener('beforeunload', this.persistConnection.bind(this));\r\n }\r\n\r\n if (options.closeOnUnload === true) {\r\n addEventListener('beforeunload', () => {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MAJOR,\r\n 'Realtime.ConnectionManager()',\r\n 'beforeunload event has triggered the connection to close as closeOnUnload is true',\r\n );\r\n this.requestState({ state: 'closing' });\r\n });\r\n }\r\n\r\n /* Listen for online and offline events */\r\n addEventListener('online', () => {\r\n if (this.state == this.states.disconnected || this.state == this.states.suspended) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager caught browser ‘online’ event',\r\n 'reattempting connection',\r\n );\r\n this.requestState({ state: 'connecting' });\r\n } else if (this.state == this.states.connecting) {\r\n // RTN20c: if 'online' event recieved while CONNECTING, abandon connection attempt and retry\r\n this.pendingTransport?.off();\r\n this.disconnectAllTransports();\r\n\r\n this.startConnect();\r\n }\r\n });\r\n\r\n addEventListener('offline', () => {\r\n if (this.state == this.states.connected) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager caught browser ‘offline’ event',\r\n 'disconnecting active transport',\r\n );\r\n // Not sufficient to just go to the 'disconnected' state, want to\r\n // force all transports to reattempt the connection. Will immediately\r\n // retry.\r\n this.disconnectAllTransports();\r\n }\r\n });\r\n }\r\n }\r\n\r\n /*********************\r\n * transport management\r\n *********************/\r\n\r\n // Used by tests\r\n static supportedTransports(additionalImplementations: TransportImplementations) {\r\n const storage: TransportStorage = { supportedTransports: {} };\r\n this.initTransports(additionalImplementations, storage);\r\n return storage.supportedTransports;\r\n }\r\n\r\n private static initTransports(additionalImplementations: TransportImplementations, storage: TransportStorage) {\r\n const implementations = { ...Platform.Transports.bundledImplementations, ...additionalImplementations };\r\n\r\n [TransportNames.WebSocket, ...Platform.Transports.order].forEach((transportName) => {\r\n const transport = implementations[transportName];\r\n if (transport && transport.isAvailable()) {\r\n storage.supportedTransports[transportName] = transport;\r\n }\r\n });\r\n }\r\n\r\n initTransports() {\r\n ConnectionManager.initTransports(this.realtime._additionalTransportImplementations, this);\r\n }\r\n\r\n createTransportParams(host: string | null, mode: string): TransportParams {\r\n return new TransportParams(this.options, host, mode, this.connectionKey);\r\n }\r\n\r\n getTransportParams(callback: Function): void {\r\n const decideMode = (modeCb: Function) => {\r\n if (this.connectionKey) {\r\n modeCb('resume');\r\n return;\r\n }\r\n\r\n if (typeof this.options.recover === 'string') {\r\n modeCb('recover');\r\n return;\r\n }\r\n\r\n const recoverFn = this.options.recover,\r\n lastSessionData = this.getSessionRecoverData(),\r\n sessionRecoveryName = this.sessionRecoveryName();\r\n if (lastSessionData && typeof recoverFn === 'function') {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.getTransportParams()',\r\n 'Calling clientOptions-provided recover function with last session data (recovery scope: ' +\r\n sessionRecoveryName +\r\n ')',\r\n );\r\n recoverFn(lastSessionData, (shouldRecover?: boolean) => {\r\n if (shouldRecover) {\r\n this.options.recover = lastSessionData.recoveryKey;\r\n modeCb('recover');\r\n } else {\r\n modeCb('clean');\r\n }\r\n });\r\n return;\r\n }\r\n modeCb('clean');\r\n };\r\n\r\n decideMode((mode: string) => {\r\n const transportParams = this.createTransportParams(null, mode);\r\n if (mode === 'recover') {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.getTransportParams()',\r\n 'Transport recovery mode = recover; recoveryKey = ' + this.options.recover,\r\n );\r\n const recoveryContext = decodeRecoveryKey(this.options.recover);\r\n if (recoveryContext) {\r\n this.msgSerial = recoveryContext.msgSerial;\r\n }\r\n } else {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.getTransportParams()',\r\n 'Transport params = ' + transportParams.toString(),\r\n );\r\n }\r\n callback(transportParams);\r\n });\r\n }\r\n\r\n /**\r\n * Attempt to connect using a given transport\r\n * @param transportParams\r\n * @param candidate, the transport to try\r\n * @param callback\r\n */\r\n tryATransport(transportParams: TransportParams, candidate: TransportName, callback: Function): void {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'ConnectionManager.tryATransport()', 'trying ' + candidate);\r\n\r\n this.proposedTransport = Transport.tryConnect(\r\n this.supportedTransports[candidate]!,\r\n this,\r\n this.realtime.auth,\r\n transportParams,\r\n (wrappedErr: { error: ErrorInfo; event: string } | null, transport?: Transport) => {\r\n const state = this.state;\r\n if (state == this.states.closing || state == this.states.closed || state == this.states.failed) {\r\n if (transport) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.tryATransport()',\r\n 'connection ' + state.state + ' while we were attempting the transport; closing ' + transport,\r\n );\r\n transport.close();\r\n }\r\n callback(true);\r\n return;\r\n }\r\n\r\n if (wrappedErr) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.tryATransport()',\r\n 'transport ' + candidate + ' ' + wrappedErr.event + ', err: ' + wrappedErr.error.toString(),\r\n );\r\n\r\n /* Comet transport onconnect token errors can be dealt with here.\r\n * Websocket ones only happen after the transport claims to be viable,\r\n * so are dealt with as non-onconnect token errors */\r\n if (\r\n Auth.isTokenErr(wrappedErr.error) &&\r\n !(this.errorReason && Auth.isTokenErr(this.errorReason as ErrorInfo))\r\n ) {\r\n this.errorReason = wrappedErr.error;\r\n /* re-get a token and try again */\r\n Utils.whenPromiseSettles(this.realtime.auth._forceNewToken(null, null), (err: ErrorInfo | null) => {\r\n if (err) {\r\n this.actOnErrorFromAuthorize(err);\r\n return;\r\n }\r\n this.tryATransport(transportParams, candidate, callback);\r\n });\r\n } else if (wrappedErr.event === 'failed') {\r\n /* Error that's fatal to the connection */\r\n this.notifyState({ state: 'failed', error: wrappedErr.error });\r\n callback(true);\r\n } else if (wrappedErr.event === 'disconnected') {\r\n if (!isRetriable(wrappedErr.error)) {\r\n /* Error received from the server that does not call for trying a fallback host, eg a rate limit */\r\n this.notifyState({ state: this.states.connecting.failState as string, error: wrappedErr.error });\r\n callback(true);\r\n } else {\r\n /* Error with that transport only; continue trying other fallback hosts */\r\n callback(false);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.tryATransport()',\r\n 'viable transport ' + candidate + '; setting pending',\r\n );\r\n this.setTransportPending(transport as Transport, transportParams);\r\n callback(null, transport);\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Called when a transport is indicated to be viable, and the ConnectionManager\r\n * expects to activate this transport as soon as it is connected.\r\n * @param transport\r\n * @param transportParams\r\n */\r\n setTransportPending(transport: Transport, transportParams: TransportParams): void {\r\n const mode = transportParams.mode;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.setTransportPending()',\r\n 'transport = ' + transport + '; mode = ' + mode,\r\n );\r\n\r\n this.pendingTransport = transport;\r\n\r\n this.cancelWebSocketSlowTimer();\r\n this.cancelWebSocketGiveUpTimer();\r\n\r\n transport.once('connected', (error: ErrorInfo, connectionId: string, connectionDetails: Record<string, any>) => {\r\n this.activateTransport(error, transport, connectionId, connectionDetails);\r\n\r\n if (mode === 'recover' && this.options.recover) {\r\n /* After a successful recovery, we unpersist, as a recovery key cannot\r\n * be used more than once */\r\n delete this.options.recover;\r\n this.unpersistConnection();\r\n }\r\n });\r\n\r\n const self = this;\r\n transport.on(['disconnected', 'closed', 'failed'], function (this: { event: string }, error: ErrorInfo) {\r\n self.deactivateTransport(transport, this.event, error);\r\n });\r\n\r\n this.emit('transport.pending', transport);\r\n }\r\n\r\n /**\r\n * Called when a transport is connected, and the connectionmanager decides that\r\n * it will now be the active transport. Returns whether or not it activated\r\n * the transport (if the connection is closing/closed it will choose not to).\r\n * @param transport the transport instance\r\n * @param connectionId the id of the new active connection\r\n * @param connectionDetails the details of the new active connection\r\n */\r\n activateTransport(\r\n error: ErrorInfo,\r\n transport: Transport,\r\n connectionId: string,\r\n connectionDetails: Record<string, any>,\r\n ): boolean {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.activateTransport()',\r\n 'transport = ' + transport,\r\n );\r\n if (error) {\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'ConnectionManager.activateTransport()', 'error = ' + error);\r\n }\r\n if (connectionId) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.activateTransport()',\r\n 'connectionId = ' + connectionId,\r\n );\r\n }\r\n if (connectionDetails) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.activateTransport()',\r\n 'connectionDetails = ' + JSON.stringify(connectionDetails),\r\n );\r\n }\r\n\r\n this.persistTransportPreference(transport);\r\n\r\n /* if the connectionmanager moved to the closing/closed state before this\r\n * connection event, then we won't activate this transport */\r\n const existingState = this.state,\r\n connectedState = this.states.connected.state;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.activateTransport()',\r\n 'current state = ' + existingState.state,\r\n );\r\n if (\r\n existingState.state == this.states.closing.state ||\r\n existingState.state == this.states.closed.state ||\r\n existingState.state == this.states.failed.state\r\n ) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.activateTransport()',\r\n 'Disconnecting transport and abandoning',\r\n );\r\n transport.disconnect();\r\n return false;\r\n }\r\n\r\n delete this.pendingTransport;\r\n\r\n /* if the transport is not connected then don't activate it */\r\n if (!transport.isConnected) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.activateTransport()',\r\n 'Declining to activate transport ' + transport + ' since it appears to no longer be connected',\r\n );\r\n return false;\r\n }\r\n\r\n /* the given transport is connected; this will immediately\r\n * take over as the active transport */\r\n const existingActiveProtocol = this.activeProtocol;\r\n this.activeProtocol = new Protocol(transport);\r\n this.host = transport.params.host;\r\n\r\n const connectionKey = connectionDetails.connectionKey;\r\n if (connectionKey && this.connectionKey != connectionKey) {\r\n this.setConnection(connectionId, connectionDetails, !!error);\r\n }\r\n\r\n /* Rebroadcast any new connectionDetails from the active transport, which\r\n * can come at any time (eg following a reauth), and emit an RTN24 UPDATE\r\n * event. (Listener added on nextTick because we're in a transport.on('connected')\r\n * callback at the moment; if we add it now we'll be adding it to the end\r\n * of the listeners array and it'll be called immediately) */\r\n this.onConnectionDetailsUpdate(connectionDetails, transport);\r\n Platform.Config.nextTick(() => {\r\n transport.on(\r\n 'connected',\r\n (connectedErr: ErrorInfo, _connectionId: string, connectionDetails: Record<string, any>) => {\r\n this.onConnectionDetailsUpdate(connectionDetails, transport);\r\n this.emit('update', new ConnectionStateChange(connectedState, connectedState, null, connectedErr));\r\n },\r\n );\r\n });\r\n\r\n /* If previously not connected, notify the state change (including any\r\n * error). */\r\n if (existingState.state === this.states.connected.state) {\r\n if (error) {\r\n this.errorReason = this.realtime.connection.errorReason = error;\r\n this.emit('update', new ConnectionStateChange(connectedState, connectedState, null, error));\r\n }\r\n } else {\r\n this.notifyState({ state: 'connected', error: error });\r\n this.errorReason = this.realtime.connection.errorReason = error || null;\r\n }\r\n\r\n /* Send after the connection state update, as Channels hooks into this to\r\n * resend attaches on a new transport if necessary */\r\n this.emit('transport.active', transport);\r\n\r\n /* Gracefully terminate existing protocol */\r\n if (existingActiveProtocol) {\r\n if (existingActiveProtocol.messageQueue.count() > 0) {\r\n /* We could just requeue pending messages on the new transport, but\r\n * actually this should never happen: transports should only take over\r\n * from other active transports when upgrading, and upgrading waits for\r\n * the old transport to be idle. So log an error. */\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'ConnectionManager.activateTransport()',\r\n 'Previous active protocol (for transport ' +\r\n existingActiveProtocol.transport.shortName +\r\n ', new one is ' +\r\n transport.shortName +\r\n ') finishing with ' +\r\n existingActiveProtocol.messageQueue.count() +\r\n ' messages still pending',\r\n );\r\n }\r\n if (existingActiveProtocol.transport === transport) {\r\n const msg =\r\n 'Assumption violated: activating a transport that was also the transport for the previous active protocol; transport = ' +\r\n transport.shortName +\r\n '; stack = ' +\r\n new Error().stack;\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'ConnectionManager.activateTransport()', msg);\r\n } else {\r\n existingActiveProtocol.finish();\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Called when a transport is no longer the active transport. This can occur\r\n * in any transport connection state.\r\n * @param transport\r\n */\r\n deactivateTransport(transport: Transport, state: string, error: ErrorInfo): void {\r\n const currentProtocol = this.activeProtocol,\r\n wasActive = currentProtocol && currentProtocol.getTransport() === transport,\r\n wasPending = transport === this.pendingTransport,\r\n noTransportsScheduledForActivation = this.noTransportsScheduledForActivation();\r\n\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.deactivateTransport()',\r\n 'transport = ' + transport,\r\n );\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.deactivateTransport()',\r\n 'state = ' +\r\n state +\r\n (wasActive ? '; was active' : wasPending ? '; was pending' : '') +\r\n (noTransportsScheduledForActivation ? '' : '; another transport is scheduled for activation'),\r\n );\r\n if (error && error.message)\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.deactivateTransport()',\r\n 'reason = ' + error.message,\r\n );\r\n\r\n if (wasActive) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.deactivateTransport()',\r\n 'Getting, clearing, and requeuing ' +\r\n (this.activeProtocol as Protocol).messageQueue.count() +\r\n ' pending messages',\r\n );\r\n this.queuePendingMessages((currentProtocol as Protocol).getPendingMessages());\r\n /* Clear any messages we requeue to allow the protocol to become idle.*/\r\n (currentProtocol as Protocol).clearPendingMessages();\r\n this.activeProtocol = this.host = null;\r\n }\r\n\r\n this.emit('transport.inactive', transport);\r\n\r\n /* this transport state change is a state change for the connectionmanager if\r\n * - the transport was the active transport and there are no transports\r\n * which are connected and scheduled for activation, just waiting for the\r\n * active transport to finish what its doing; or\r\n * - the transport was the active transport and the error was fatal (so\r\n * unhealable by another transport); or\r\n * - there is no active transport, and this is the last remaining\r\n * pending transport (so we were in the connecting state)\r\n */\r\n if (\r\n (wasActive && noTransportsScheduledForActivation) ||\r\n (wasActive && state === 'failed') ||\r\n state === 'closed' ||\r\n (currentProtocol === null && wasPending)\r\n ) {\r\n /* If we're disconnected with a 5xx we need to try fallback hosts\r\n * (RTN14d), but (a) due to how the upgrade sequence works, the\r\n * host/transport selection sequence only cares about getting to\r\n * `preconnect` (eg establishing a websocket) getting a `disconnected`\r\n * protocol message afterwards is too late; and (b) host retry only\r\n * applies to connectBase unless the stored preference transport doesn't\r\n * work. We solve this by unpersisting the transport preference and\r\n * setting an instance variable to force fallback hosts to be used (if\r\n * any) here. Bit of a kludge, but no real better alternatives without\r\n * rewriting the entire thing */\r\n if (state === 'disconnected' && error && (error.statusCode as number) > 500 && this.httpHosts.length > 1) {\r\n this.unpersistTransportPreference();\r\n this.forceFallbackHost = true;\r\n /* and try to connect again to try a fallback host without waiting for the usual 15s disconnectedRetryTimeout */\r\n this.notifyState({ state: state, error: error, retryImmediately: true });\r\n return;\r\n }\r\n\r\n /* TODO remove below line once realtime sends token errors as DISCONNECTEDs */\r\n const newConnectionState = state === 'failed' && Auth.isTokenErr(error) ? 'disconnected' : state;\r\n this.notifyState({ state: newConnectionState, error: error });\r\n return;\r\n }\r\n }\r\n\r\n /* Helper that returns true if there are no transports which are pending,\r\n * have been connected, and are just waiting for onceNoPending to fire before\r\n * being activated */\r\n noTransportsScheduledForActivation(): boolean {\r\n return !this.pendingTransport || !this.pendingTransport.isConnected;\r\n }\r\n\r\n setConnection(connectionId: string, connectionDetails: Record<string, any>, hasConnectionError?: boolean): void {\r\n /* if connectionKey changes but connectionId stays the same, then just a\r\n * transport change on the same connection. If connectionId changes, we're\r\n * on a new connection, with implications for msgSerial and channel state */\r\n /* If no previous connectionId, don't reset the msgSerial as it may have\r\n * been set by recover data (unless the recover failed) */\r\n const prevConnId = this.connectionId,\r\n connIdChanged = prevConnId && prevConnId !== connectionId,\r\n recoverFailure = !prevConnId && hasConnectionError;\r\n if (connIdChanged || recoverFailure) {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'ConnectionManager.setConnection()', 'Resetting msgSerial');\r\n this.msgSerial = 0;\r\n // RTN19a2: In the event of a new connectionId, previous msgSerials are\r\n // meaningless.\r\n this.queuedMessages.resetSendAttempted();\r\n }\r\n if (this.connectionId !== connectionId) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.setConnection()',\r\n 'New connectionId; reattaching any attached channels',\r\n );\r\n }\r\n this.realtime.connection.id = this.connectionId = connectionId;\r\n this.realtime.connection.key = this.connectionKey = connectionDetails.connectionKey;\r\n }\r\n\r\n clearConnection(): void {\r\n this.realtime.connection.id = this.connectionId = undefined;\r\n this.realtime.connection.key = this.connectionKey = undefined;\r\n this.msgSerial = 0;\r\n this.unpersistConnection();\r\n }\r\n\r\n createRecoveryKey(): string | null {\r\n // RTN16g2.\r\n if (!this.connectionKey) {\r\n return null;\r\n }\r\n\r\n return JSON.stringify({\r\n connectionKey: this.connectionKey,\r\n msgSerial: this.msgSerial,\r\n channelSerials: this.realtime.channels.channelSerials(),\r\n });\r\n }\r\n\r\n checkConnectionStateFreshness(): void {\r\n if (!this.lastActivity || !this.connectionId) {\r\n return;\r\n }\r\n\r\n const sinceLast = Date.now() - this.lastActivity;\r\n if (sinceLast > this.connectionStateTtl + (this.maxIdleInterval as number)) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.checkConnectionStateFreshness()',\r\n 'Last known activity from realtime was ' + sinceLast + 'ms ago; discarding connection state',\r\n );\r\n this.clearConnection();\r\n this.states.connecting.failState = 'suspended';\r\n }\r\n }\r\n\r\n /**\r\n * Called when the connectionmanager wants to persist transport\r\n * state for later recovery. Only applicable in the browser context.\r\n */\r\n persistConnection(): void {\r\n if (haveSessionStorage()) {\r\n const recoveryKey = this.createRecoveryKey();\r\n if (recoveryKey) {\r\n this.setSessionRecoverData({\r\n recoveryKey: recoveryKey,\r\n disconnectedAt: Date.now(),\r\n location: globalObject.location,\r\n clientId: this.realtime.auth.clientId,\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Called when the connectionmanager wants to persist transport\r\n * state for later recovery. Only applicable in the browser context.\r\n */\r\n unpersistConnection(): void {\r\n this.clearSessionRecoverData();\r\n }\r\n\r\n /*********************\r\n * state management\r\n *********************/\r\n\r\n getError(): IPartialErrorInfo | string {\r\n if (this.errorReason) {\r\n // create new PartialErrorInfo so it has the correct stack trace\r\n // which points to the place which caused us to return this error.\r\n const newError = PartialErrorInfo.fromValues(this.errorReason);\r\n newError.cause = this.errorReason;\r\n return newError;\r\n }\r\n\r\n return this.getStateError();\r\n }\r\n\r\n getStateError(): ErrorInfo {\r\n return (ConnectionErrors as Record<string, () => ErrorInfo>)[this.state.state]?.();\r\n }\r\n\r\n activeState(): boolean | void {\r\n return this.state.queueEvents || this.state.sendEvents;\r\n }\r\n\r\n enactStateChange(stateChange: ConnectionStateChange): void {\r\n const action = 'Connection state';\r\n const message = stateChange.current + (stateChange.reason ? '; reason: ' + stateChange.reason : '');\r\n if (stateChange.current === 'failed') {\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, action, message);\r\n } else {\r\n Logger.logAction(this.logger, Logger.LOG_MAJOR, action, message);\r\n }\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.enactStateChange',\r\n 'setting new state: ' +\r\n stateChange.current +\r\n '; reason = ' +\r\n (stateChange.reason && (stateChange.reason as ErrorInfo).message),\r\n );\r\n const newState = (this.state = this.states[stateChange.current as string]);\r\n if (stateChange.reason) {\r\n this.errorReason = stateChange.reason;\r\n // TODO remove this type assertion after fixing https://github.com/ably/ably-js/issues/1405\r\n this.realtime.connection.errorReason = stateChange.reason as ErrorInfo;\r\n }\r\n if (newState.terminal || newState.state === 'suspended') {\r\n /* suspended is nonterminal, but once in the suspended state, realtime\r\n * will have discarded our connection state, so futher connection\r\n * attempts should start from scratch */\r\n this.clearConnection();\r\n }\r\n this.emit('connectionstate', stateChange);\r\n }\r\n\r\n /****************************************\r\n * ConnectionManager connection lifecycle\r\n ****************************************/\r\n\r\n startTransitionTimer(transitionState: ConnectionState): void {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.startTransitionTimer()',\r\n 'transitionState: ' + transitionState.state,\r\n );\r\n\r\n if (this.transitionTimer) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.startTransitionTimer()',\r\n 'clearing already-running timer',\r\n );\r\n clearTimeout(this.transitionTimer as number);\r\n }\r\n\r\n this.transitionTimer = setTimeout(() => {\r\n if (this.transitionTimer) {\r\n this.transitionTimer = null;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager ' + transitionState.state + ' timer expired',\r\n 'requesting new state: ' + transitionState.failState,\r\n );\r\n this.notifyState({ state: transitionState.failState as string });\r\n }\r\n }, transitionState.retryDelay);\r\n }\r\n\r\n cancelTransitionTimer(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'ConnectionManager.cancelTransitionTimer()', '');\r\n if (this.transitionTimer) {\r\n clearTimeout(this.transitionTimer as number);\r\n this.transitionTimer = null;\r\n }\r\n }\r\n\r\n startSuspendTimer(): void {\r\n if (this.suspendTimer) return;\r\n this.suspendTimer = setTimeout(() => {\r\n if (this.suspendTimer) {\r\n this.suspendTimer = null;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager suspend timer expired',\r\n 'requesting new state: suspended',\r\n );\r\n this.states.connecting.failState = 'suspended';\r\n this.notifyState({ state: 'suspended' });\r\n }\r\n }, this.connectionStateTtl);\r\n }\r\n\r\n checkSuspendTimer(state: string): void {\r\n if (state !== 'disconnected' && state !== 'suspended' && state !== 'connecting') this.cancelSuspendTimer();\r\n }\r\n\r\n cancelSuspendTimer(): void {\r\n this.states.connecting.failState = 'disconnected';\r\n if (this.suspendTimer) {\r\n clearTimeout(this.suspendTimer as number);\r\n this.suspendTimer = null;\r\n }\r\n }\r\n\r\n startRetryTimer(interval: number): void {\r\n this.retryTimer = setTimeout(() => {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'ConnectionManager retry timer expired', 'retrying');\r\n this.retryTimer = null;\r\n this.requestState({ state: 'connecting' });\r\n }, interval);\r\n }\r\n\r\n cancelRetryTimer(): void {\r\n if (this.retryTimer) {\r\n clearTimeout(this.retryTimer as NodeJS.Timeout);\r\n this.retryTimer = null;\r\n }\r\n }\r\n\r\n startWebSocketSlowTimer() {\r\n this.webSocketSlowTimer = setTimeout(() => {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager WebSocket slow timer',\r\n 'checking connectivity',\r\n );\r\n this.checkWsConnectivity()\r\n .then(() => {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager WebSocket slow timer',\r\n 'ws connectivity check succeeded',\r\n );\r\n this.wsCheckResult = true;\r\n })\r\n .catch(() => {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MAJOR,\r\n 'ConnectionManager WebSocket slow timer',\r\n 'ws connectivity check failed',\r\n );\r\n this.wsCheckResult = false;\r\n });\r\n if (this.realtime.http.checkConnectivity) {\r\n Utils.whenPromiseSettles(this.realtime.http.checkConnectivity(), (err, connectivity) => {\r\n if (err || !connectivity) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MAJOR,\r\n 'ConnectionManager WebSocket slow timer',\r\n 'http connectivity check failed',\r\n );\r\n this.cancelWebSocketGiveUpTimer();\r\n this.notifyState({\r\n state: 'disconnected',\r\n error: new ErrorInfo('Unable to connect (network unreachable)', 80003, 404),\r\n });\r\n } else {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager WebSocket slow timer',\r\n 'http connectivity check succeeded',\r\n );\r\n }\r\n });\r\n }\r\n }, this.options.timeouts.webSocketSlowTimeout);\r\n }\r\n\r\n cancelWebSocketSlowTimer() {\r\n if (this.webSocketSlowTimer) {\r\n clearTimeout(this.webSocketSlowTimer);\r\n this.webSocketSlowTimer = null;\r\n }\r\n }\r\n\r\n startWebSocketGiveUpTimer(transportParams: TransportParams) {\r\n this.webSocketGiveUpTimer = setTimeout(() => {\r\n if (!this.wsCheckResult) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager WebSocket give up timer',\r\n 'websocket connection took more than 10s; ' + (this.baseTransport ? 'trying base transport' : ''),\r\n );\r\n if (this.baseTransport) {\r\n this.abandonedWebSocket = true;\r\n this.proposedTransport?.dispose();\r\n this.pendingTransport?.dispose();\r\n this.connectBase(transportParams, ++this.connectCounter);\r\n } else {\r\n // if we don't have a base transport to fallback to, just let the websocket connection attempt time out\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MAJOR,\r\n 'ConnectionManager WebSocket give up timer',\r\n 'websocket connectivity appears to be unavailable but no other transports to try',\r\n );\r\n }\r\n }\r\n }, this.options.timeouts.webSocketConnectTimeout);\r\n }\r\n\r\n cancelWebSocketGiveUpTimer() {\r\n if (this.webSocketGiveUpTimer) {\r\n clearTimeout(this.webSocketGiveUpTimer);\r\n this.webSocketGiveUpTimer = null;\r\n }\r\n }\r\n\r\n notifyState(indicated: ConnectionState): void {\r\n const state = indicated.state;\r\n\r\n /* We retry immediately if:\r\n * - something disconnects us while we're connected, or\r\n * - a viable (but not yet active) transport fails due to a token error (so\r\n * this.errorReason will be set, and startConnect will do a forced\r\n * authorize). If this.errorReason is already set (to a token error),\r\n * then there has been at least one previous attempt to connect that also\r\n * failed for a token error, so by RTN14b we go to DISCONNECTED and wait\r\n * before trying again */\r\n const retryImmediately =\r\n state === 'disconnected' &&\r\n (this.state === this.states.connected ||\r\n indicated.retryImmediately ||\r\n (this.state === this.states.connecting &&\r\n indicated.error &&\r\n Auth.isTokenErr(indicated.error) &&\r\n !(this.errorReason && Auth.isTokenErr(this.errorReason as ErrorInfo))));\r\n\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.notifyState()',\r\n 'new state: ' + state + (retryImmediately ? '; will retry connection immediately' : ''),\r\n );\r\n /* do nothing if we're already in the indicated state */\r\n if (state == this.state.state) return;\r\n\r\n /* kill timers (possibly excepting suspend timer depending on the notified\r\n * state), as these are superseded by this notification */\r\n this.cancelTransitionTimer();\r\n this.cancelRetryTimer();\r\n this.cancelWebSocketSlowTimer();\r\n this.cancelWebSocketGiveUpTimer();\r\n this.checkSuspendTimer(indicated.state);\r\n\r\n if (state === 'suspended' || state === 'connected') {\r\n this.disconnectedRetryCount = 0;\r\n }\r\n\r\n /* do nothing if we're unable to move from the current state */\r\n if (this.state.terminal) return;\r\n\r\n /* process new state */\r\n const newState = this.states[indicated.state];\r\n\r\n let retryDelay = newState.retryDelay;\r\n if (newState.state === 'disconnected') {\r\n this.disconnectedRetryCount++;\r\n retryDelay = Utils.getRetryTime(newState.retryDelay as number, this.disconnectedRetryCount);\r\n }\r\n\r\n const change = new ConnectionStateChange(\r\n this.state.state,\r\n newState.state,\r\n retryDelay,\r\n indicated.error || (ConnectionErrors as Partial<Record<string, () => ErrorInfo>>)[newState.state]?.(),\r\n );\r\n\r\n if (retryImmediately) {\r\n const autoReconnect = () => {\r\n if (this.state === this.states.disconnected) {\r\n this.lastAutoReconnectAttempt = Date.now();\r\n this.requestState({ state: 'connecting' });\r\n }\r\n };\r\n const sinceLast = this.lastAutoReconnectAttempt && Date.now() - this.lastAutoReconnectAttempt + 1;\r\n if (sinceLast && sinceLast < 1000) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.notifyState()',\r\n 'Last reconnect attempt was only ' +\r\n sinceLast +\r\n 'ms ago, waiting another ' +\r\n (1000 - sinceLast) +\r\n 'ms before trying again',\r\n );\r\n setTimeout(autoReconnect, 1000 - sinceLast);\r\n } else {\r\n Platform.Config.nextTick(autoReconnect);\r\n }\r\n } else if (state === 'disconnected' || state === 'suspended') {\r\n this.startRetryTimer(retryDelay as number);\r\n }\r\n\r\n /* If going into disconnect/suspended (and not retrying immediately), or a\r\n * terminal state, ensure there are no orphaned transports hanging around. */\r\n if ((state === 'disconnected' && !retryImmediately) || state === 'suspended' || newState.terminal) {\r\n /* Wait till the next tick so the connection state change is enacted,\r\n * so aborting transports doesn't trigger redundant state changes */\r\n Platform.Config.nextTick(() => {\r\n this.disconnectAllTransports();\r\n });\r\n }\r\n\r\n if (state == 'connected' && !this.activeProtocol) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'ConnectionManager.notifyState()',\r\n 'Broken invariant: attempted to go into connected state, but there is no active protocol',\r\n );\r\n }\r\n\r\n /* implement the change and notify */\r\n this.enactStateChange(change);\r\n if (this.state.sendEvents) {\r\n this.sendQueuedMessages();\r\n } else if (!this.state.queueEvents) {\r\n this.realtime.channels.propogateConnectionInterruption(state, change.reason);\r\n this.failQueuedMessages(change.reason as ErrorInfo); // RTN7c\r\n }\r\n }\r\n\r\n requestState(request: any): void {\r\n const state = request.state;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.requestState()',\r\n 'requested state: ' + state + '; current state: ' + this.state.state,\r\n );\r\n if (state == this.state.state) return; /* silently do nothing */\r\n\r\n /* kill running timers, as this request supersedes them */\r\n this.cancelWebSocketSlowTimer();\r\n this.cancelWebSocketGiveUpTimer();\r\n this.cancelTransitionTimer();\r\n this.cancelRetryTimer();\r\n /* for suspend timer check rather than cancel -- eg requesting a connecting\r\n * state should not reset the suspend timer */\r\n this.checkSuspendTimer(state);\r\n\r\n if (state == 'connecting' && this.state.state == 'connected') return;\r\n if (state == 'closing' && this.state.state == 'closed') return;\r\n\r\n const newState = this.states[state],\r\n change = new ConnectionStateChange(\r\n this.state.state,\r\n newState.state,\r\n null,\r\n request.error || (ConnectionErrors as Partial<Record<string, () => ErrorInfo>>)[newState.state]?.(),\r\n );\r\n\r\n this.enactStateChange(change);\r\n\r\n if (state == 'connecting') {\r\n Platform.Config.nextTick(() => {\r\n this.startConnect();\r\n });\r\n }\r\n if (state == 'closing') {\r\n this.closeImpl();\r\n }\r\n }\r\n\r\n startConnect(): void {\r\n if (this.state !== this.states.connecting) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.startConnect()',\r\n 'Must be in connecting state to connect, but was ' + this.state.state,\r\n );\r\n return;\r\n }\r\n\r\n const auth = this.realtime.auth;\r\n\r\n /* The point of the connectCounter mechanism is to ensure that the\r\n * connection procedure can be cancelled. We want disconnectAllTransports\r\n * to be able to stop any in-progress connection, even before it gets to\r\n * the stage of having a pending (or even a proposed) transport that it can\r\n * dispose() of. So we check that it's still current after any async stage,\r\n * up until the stage that is synchronous with instantiating a transport */\r\n const connectCount = ++this.connectCounter;\r\n\r\n const connect = () => {\r\n this.checkConnectionStateFreshness();\r\n this.getTransportParams((transportParams: TransportParams) => {\r\n if (transportParams.mode === 'recover' && transportParams.options.recover) {\r\n const recoveryContext = decodeRecoveryKey(transportParams.options.recover);\r\n if (recoveryContext) {\r\n this.realtime.channels.recoverChannels(recoveryContext.channelSerials);\r\n }\r\n }\r\n\r\n if (connectCount !== this.connectCounter) {\r\n return;\r\n }\r\n this.connectImpl(transportParams, connectCount);\r\n });\r\n };\r\n\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'ConnectionManager.startConnect()', 'starting connection');\r\n this.startSuspendTimer();\r\n this.startTransitionTimer(this.states.connecting);\r\n\r\n if (auth.method === 'basic') {\r\n connect();\r\n } else {\r\n const authCb = (err: ErrorInfo | null) => {\r\n if (connectCount !== this.connectCounter) {\r\n return;\r\n }\r\n if (err) {\r\n this.actOnErrorFromAuthorize(err);\r\n } else {\r\n connect();\r\n }\r\n };\r\n if (this.errorReason && Auth.isTokenErr(this.errorReason as ErrorInfo)) {\r\n /* Force a refetch of a new token */\r\n Utils.whenPromiseSettles(auth._forceNewToken(null, null), authCb);\r\n } else {\r\n Utils.whenPromiseSettles(auth._ensureValidAuthCredentials(false), authCb);\r\n }\r\n }\r\n }\r\n\r\n /*\r\n * there are, at most, two transports available with which a connection may\r\n * be attempted: web_socket and/or a base transport (xhr_polling in browsers,\r\n * comet in nodejs). web_socket is always preferred, and the base transport is\r\n * only used in case web_socket connectivity appears to be unavailable.\r\n *\r\n * connectImpl begins the transport selection process by checking which transports\r\n * are available, and if there is a cached preference. It then defers to the\r\n * transport-specific connect methods: connectWs and connectBase.\r\n *\r\n * It is also responsible for invalidating the cache in the case that a base\r\n * transport preference is stored but web socket connectivity is now available.\r\n *\r\n * handling of the case where we need to failover from web_socket to the base\r\n * transport is implemented in the connectWs method.\r\n */\r\n connectImpl(transportParams: TransportParams, connectCount: number): void {\r\n const state = this.state.state;\r\n if (state !== this.states.connecting.state) {\r\n /* Only keep trying as long as in the 'connecting' state (or 'connected'\r\n * for upgrading). Any operation can put us into 'disconnected' to cancel\r\n * connection attempts and wait before retrying, or 'failed' to fail. */\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.connectImpl()',\r\n 'Must be in connecting state to connect, but was ' + state,\r\n );\r\n return;\r\n }\r\n\r\n const transportPreference = this.getTransportPreference();\r\n\r\n // If transport preference is for a non-ws transport but websocket is now available, unpersist the preference for next time\r\n if (transportPreference && transportPreference === this.baseTransport && this.webSocketTransportAvailable) {\r\n this.checkWsConnectivity()\r\n .then(() => {\r\n this.unpersistTransportPreference();\r\n if (this.state === this.states.connecting) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.connectImpl():',\r\n 'web socket connectivity available, cancelling connection attempt with ' + this.baseTransport,\r\n );\r\n this.disconnectAllTransports();\r\n this.connectWs(transportParams, ++this.connectCounter);\r\n }\r\n })\r\n .catch(noop);\r\n }\r\n\r\n if (\r\n (transportPreference && transportPreference === this.baseTransport) ||\r\n (this.baseTransport && !this.webSocketTransportAvailable)\r\n ) {\r\n this.connectBase(transportParams, connectCount);\r\n } else {\r\n this.connectWs(transportParams, connectCount);\r\n }\r\n }\r\n\r\n /*\r\n * connectWs starts two timers to monitor the success of a web_socket connection attempt:\r\n * - webSocketSlowTimer: if this timer fires before the connection succeeds,\r\n * cm will simultaneously check websocket and http/xhr connectivity. if the http\r\n * connectivity check fails, we give up the connection sequence entirely and\r\n * transition to disconnected. if the websocket connectivity check fails then\r\n * we assume no ws connectivity and failover to base transport. in the case that\r\n * the checks succeed, we continue with websocket and wait for it to try fallback hosts\r\n * and, if unsuccessful, ultimately transition to disconnected.\r\n * - webSocketGiveUpTimer: if this timer fires, and the preceding websocket\r\n * connectivity check is still pending then we assume that there is an issue\r\n * with the transport and fallback to base transport.\r\n */\r\n connectWs(transportParams: TransportParams, connectCount: number) {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'ConnectionManager.connectWs()');\r\n this.wsCheckResult = null;\r\n this.abandonedWebSocket = false;\r\n this.startWebSocketSlowTimer();\r\n this.startWebSocketGiveUpTimer(transportParams);\r\n\r\n this.tryTransportWithFallbacks('web_socket', transportParams, true, connectCount, () => {\r\n return this.wsCheckResult !== false && !this.abandonedWebSocket;\r\n });\r\n }\r\n\r\n connectBase(transportParams: TransportParams, connectCount: number) {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'ConnectionManager.connectBase()');\r\n if (this.baseTransport) {\r\n this.tryTransportWithFallbacks(this.baseTransport, transportParams, false, connectCount, () => true);\r\n } else {\r\n this.notifyState({\r\n state: 'disconnected',\r\n error: new ErrorInfo('No transports left to try', 80000, 404),\r\n });\r\n }\r\n }\r\n\r\n tryTransportWithFallbacks(\r\n transportName: TransportName,\r\n transportParams: TransportParams,\r\n ws: boolean,\r\n connectCount: number,\r\n shouldContinue: () => boolean,\r\n ): void {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.tryTransportWithFallbacks()',\r\n transportName,\r\n );\r\n const giveUp = (err: IPartialErrorInfo) => {\r\n this.notifyState({ state: this.states.connecting.failState as string, error: err });\r\n };\r\n\r\n const candidateHosts = ws ? this.wsHosts.slice() : this.httpHosts.slice();\r\n\r\n const hostAttemptCb = (fatal: boolean, transport: Transport) => {\r\n if (connectCount !== this.connectCounter) {\r\n return;\r\n }\r\n if (!shouldContinue()) {\r\n if (transport) {\r\n transport.dispose();\r\n }\r\n return;\r\n }\r\n if (!transport && !fatal) {\r\n tryFallbackHosts();\r\n }\r\n };\r\n\r\n /* first try to establish a connection with the priority host with http transport */\r\n const host = candidateHosts.shift();\r\n if (!host) {\r\n giveUp(new ErrorInfo('Unable to connect (no available host)', 80003, 404));\r\n return;\r\n }\r\n transportParams.host = host;\r\n\r\n /* this is what we'll be doing if the attempt for the main host fails */\r\n const tryFallbackHosts = () => {\r\n /* if there aren't any fallback hosts, fail */\r\n if (!candidateHosts.length) {\r\n giveUp(new ErrorInfo('Unable to connect (and no more fallback hosts to try)', 80003, 404));\r\n return;\r\n }\r\n /* before trying any fallback (or any remaining fallback) we decide if\r\n * there is a problem with the ably host, or there is a general connectivity\r\n * problem */\r\n if (!this.realtime.http.checkConnectivity) {\r\n giveUp(new PartialErrorInfo('Internal error: Http.checkConnectivity not set', null, 500));\r\n return;\r\n }\r\n Utils.whenPromiseSettles(\r\n this.realtime.http.checkConnectivity(),\r\n (err?: ErrorInfo | null, connectivity?: boolean) => {\r\n if (connectCount !== this.connectCounter) {\r\n return;\r\n }\r\n if (!shouldContinue()) {\r\n return;\r\n }\r\n /* we know err won't happen but handle it here anyway */\r\n if (err) {\r\n giveUp(err);\r\n return;\r\n }\r\n if (!connectivity) {\r\n /* the internet isn't reachable, so don't try the fallback hosts */\r\n giveUp(new ErrorInfo('Unable to connect (network unreachable)', 80003, 404));\r\n return;\r\n }\r\n /* the network is there, so there's a problem with the main host, or\r\n * its dns. Try the fallback hosts. We could try them simultaneously but\r\n * that would potentially cause a huge spike in load on the load balancer */\r\n transportParams.host = Utils.arrPopRandomElement(candidateHosts);\r\n this.tryATransport(transportParams, transportName, hostAttemptCb);\r\n },\r\n );\r\n };\r\n\r\n if (this.forceFallbackHost && candidateHosts.length) {\r\n this.forceFallbackHost = false;\r\n tryFallbackHosts();\r\n return;\r\n }\r\n\r\n this.tryATransport(transportParams, transportName, hostAttemptCb);\r\n }\r\n\r\n closeImpl(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'ConnectionManager.closeImpl()', 'closing connection');\r\n this.cancelSuspendTimer();\r\n this.startTransitionTimer(this.states.closing);\r\n\r\n if (this.pendingTransport) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.closeImpl()',\r\n 'Closing pending transport: ' + this.pendingTransport,\r\n );\r\n this.pendingTransport.close();\r\n }\r\n\r\n if (this.activeProtocol) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.closeImpl()',\r\n 'Closing active transport: ' + this.activeProtocol.getTransport(),\r\n );\r\n this.activeProtocol.getTransport().close();\r\n }\r\n\r\n /* If there was an active transport, this will probably be\r\n * preempted by the notifyState call in deactivateTransport */\r\n this.notifyState({ state: 'closed' });\r\n }\r\n\r\n onAuthUpdated(tokenDetails: API.TokenDetails, callback: Function): void {\r\n switch (this.state.state) {\r\n case 'connected': {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.onAuthUpdated()',\r\n 'Sending AUTH message on active transport',\r\n );\r\n\r\n /* Do any transport-specific new-token action */\r\n const activeTransport = this.activeProtocol?.getTransport();\r\n if (activeTransport && activeTransport.onAuthUpdated) {\r\n activeTransport.onAuthUpdated(tokenDetails);\r\n }\r\n\r\n const authMsg = protocolMessageFromValues({\r\n action: actions.AUTH,\r\n auth: {\r\n accessToken: tokenDetails.token,\r\n },\r\n });\r\n this.send(authMsg);\r\n\r\n /* The answer will come back as either a connectiondetails event\r\n * (realtime sends a CONNECTED to acknowledge the reauth) or a\r\n * statechange to failed */\r\n const successListener = () => {\r\n this.off(failureListener);\r\n callback(null, tokenDetails);\r\n };\r\n const failureListener = (stateChange: ConnectionStateChange) => {\r\n if (stateChange.current === 'failed') {\r\n this.off(successListener);\r\n this.off(failureListener);\r\n callback(stateChange.reason || this.getStateError());\r\n }\r\n };\r\n this.once('connectiondetails', successListener);\r\n this.on('connectionstate', failureListener);\r\n break;\r\n }\r\n\r\n case 'connecting':\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.onAuthUpdated()',\r\n 'Aborting current connection attempts in order to start again with the new auth details',\r\n );\r\n this.disconnectAllTransports();\r\n /* fallthrough to add statechange listener */\r\n\r\n default: {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.onAuthUpdated()',\r\n 'Connection state is ' + this.state.state + '; waiting until either connected or failed',\r\n );\r\n const listener = (stateChange: ConnectionStateChange) => {\r\n switch (stateChange.current) {\r\n case 'connected':\r\n this.off(listener);\r\n callback(null, tokenDetails);\r\n break;\r\n case 'failed':\r\n case 'closed':\r\n case 'suspended':\r\n this.off(listener);\r\n callback(stateChange.reason || this.getStateError());\r\n break;\r\n default:\r\n /* ignore till we get either connected or failed */\r\n break;\r\n }\r\n };\r\n this.on('connectionstate', listener);\r\n if (this.state.state === 'connecting') {\r\n /* can happen if in the connecting state but no transport was pending\r\n * yet, so disconnectAllTransports did not trigger a disconnected state */\r\n this.startConnect();\r\n } else {\r\n this.requestState({ state: 'connecting' });\r\n }\r\n }\r\n }\r\n }\r\n\r\n disconnectAllTransports(): void {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MINOR,\r\n 'ConnectionManager.disconnectAllTransports()',\r\n 'Disconnecting all transports',\r\n );\r\n\r\n /* This will prevent any connection procedure in an async part of one of its early stages from continuing */\r\n this.connectCounter++;\r\n\r\n if (this.pendingTransport) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.disconnectAllTransports()',\r\n 'Disconnecting pending transport: ' + this.pendingTransport,\r\n );\r\n this.pendingTransport.disconnect();\r\n }\r\n delete this.pendingTransport;\r\n\r\n if (this.proposedTransport) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.disconnectAllTransports()',\r\n 'Disconnecting proposed transport: ' + this.pendingTransport,\r\n );\r\n this.proposedTransport.disconnect();\r\n }\r\n delete this.pendingTransport;\r\n\r\n if (this.activeProtocol) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.disconnectAllTransports()',\r\n 'Disconnecting active transport: ' + this.activeProtocol.getTransport(),\r\n );\r\n this.activeProtocol.getTransport().disconnect();\r\n }\r\n /* No need to notify state disconnected; disconnecting the active transport\r\n * will have that effect */\r\n }\r\n\r\n /******************\r\n * event queueing\r\n ******************/\r\n\r\n send(msg: ProtocolMessage, queueEvent?: boolean, callback?: ErrCallback): void {\r\n callback = callback || noop;\r\n const state = this.state;\r\n\r\n if (state.sendEvents) {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'ConnectionManager.send()', 'sending event');\r\n this.sendImpl(new PendingMessage(msg, callback));\r\n return;\r\n }\r\n const shouldQueue = queueEvent && state.queueEvents;\r\n if (!shouldQueue) {\r\n const err = 'rejecting event, queueEvent was ' + queueEvent + ', state was ' + state.state;\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'ConnectionManager.send()', err);\r\n callback(this.errorReason || new ErrorInfo(err, 90000, 400));\r\n return;\r\n }\r\n if (this.logger.shouldLog(Logger.LOG_MICRO)) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.send()',\r\n 'queueing msg; ' + stringifyProtocolMessage(msg, this.realtime._RealtimePresence),\r\n );\r\n }\r\n this.queue(msg, callback);\r\n }\r\n\r\n sendImpl(pendingMessage: PendingMessage): void {\r\n const msg = pendingMessage.message;\r\n /* If have already attempted to send this, resend with the same msgSerial,\r\n * so Ably can dedup if the previous send succeeded */\r\n if (pendingMessage.ackRequired && !pendingMessage.sendAttempted) {\r\n msg.msgSerial = this.msgSerial++;\r\n }\r\n try {\r\n (this.activeProtocol as Protocol).send(pendingMessage);\r\n } catch (e) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_ERROR,\r\n 'ConnectionManager.sendImpl()',\r\n 'Unexpected exception in transport.send(): ' + (e as Error).stack,\r\n );\r\n }\r\n }\r\n\r\n queue(msg: ProtocolMessage, callback: ErrCallback): void {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'ConnectionManager.queue()', 'queueing event');\r\n const lastQueued = this.queuedMessages.last();\r\n const maxSize = this.options.maxMessageSize;\r\n /* If have already attempted to send a message, don't merge more messages\r\n * into it, as if the previous send actually succeeded and realtime ignores\r\n * the dup, they'll be lost */\r\n if (lastQueued && !lastQueued.sendAttempted && bundleWith(lastQueued.message, msg, maxSize)) {\r\n if (!lastQueued.merged) {\r\n lastQueued.callback = Multicaster.create(this.logger, [lastQueued.callback]);\r\n lastQueued.merged = true;\r\n }\r\n (lastQueued.callback as MulticasterInstance<void>).push(callback);\r\n } else {\r\n this.queuedMessages.push(new PendingMessage(msg, callback));\r\n }\r\n }\r\n\r\n sendQueuedMessages(): void {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.sendQueuedMessages()',\r\n 'sending ' + this.queuedMessages.count() + ' queued messages',\r\n );\r\n let pendingMessage;\r\n while ((pendingMessage = this.queuedMessages.shift())) this.sendImpl(pendingMessage);\r\n }\r\n\r\n queuePendingMessages(pendingMessages: Array<PendingMessage>): void {\r\n if (pendingMessages && pendingMessages.length) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_MICRO,\r\n 'ConnectionManager.queuePendingMessages()',\r\n 'queueing ' + pendingMessages.length + ' pending messages',\r\n );\r\n this.queuedMessages.prepend(pendingMessages);\r\n }\r\n }\r\n\r\n failQueuedMessages(err: ErrorInfo): void {\r\n const numQueued = this.queuedMessages.count();\r\n if (numQueued > 0) {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_ERROR,\r\n 'ConnectionManager.failQueuedMessages()',\r\n 'failing ' + numQueued + ' queued messages, err = ' + Utils.inspectError(err),\r\n );\r\n this.queuedMessages.completeAllMessages(err);\r\n }\r\n }\r\n\r\n onChannelMessage(message: ProtocolMessage, transport: Transport): void {\r\n this.pendingChannelMessagesState.queue.push({ message, transport });\r\n\r\n if (!this.pendingChannelMessagesState.isProcessing) {\r\n this.processNextPendingChannelMessage();\r\n }\r\n }\r\n\r\n private processNextPendingChannelMessage() {\r\n if (this.pendingChannelMessagesState.queue.length > 0) {\r\n this.pendingChannelMessagesState.isProcessing = true;\r\n\r\n const pendingChannelMessage = this.pendingChannelMessagesState.queue.shift()!;\r\n this.processChannelMessage(pendingChannelMessage.message)\r\n .catch((err) => {\r\n Logger.logAction(\r\n this.logger,\r\n\r\n Logger.LOG_ERROR,\r\n 'ConnectionManager.processNextPendingChannelMessage() received error ',\r\n err,\r\n );\r\n })\r\n .finally(() => {\r\n this.pendingChannelMessagesState.isProcessing = false;\r\n this.processNextPendingChannelMessage();\r\n });\r\n }\r\n }\r\n\r\n private async processChannelMessage(message: ProtocolMessage) {\r\n await this.realtime.channels.processChannelMessage(message);\r\n }\r\n\r\n async ping(): Promise<number> {\r\n if (this.state.state !== 'connected') {\r\n throw new ErrorInfo('Unable to ping service; not connected', 40000, 400);\r\n }\r\n\r\n const transport = this.activeProtocol?.getTransport();\r\n if (!transport) {\r\n throw this.getStateError();\r\n }\r\n\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'ConnectionManager.ping()', 'transport = ' + transport);\r\n\r\n const pingStart = Date.now();\r\n const id = Utils.cheapRandStr();\r\n\r\n return Utils.withTimeoutAsync<number>(\r\n new Promise((resolve) => {\r\n const onHeartbeat = (responseId: string) => {\r\n if (responseId === id) {\r\n transport.off('heartbeat', onHeartbeat);\r\n resolve(Date.now() - pingStart);\r\n }\r\n };\r\n transport.on('heartbeat', onHeartbeat);\r\n transport.ping(id);\r\n }),\r\n this.options.timeouts.realtimeRequestTimeout,\r\n 'Timeout waiting for heartbeat response',\r\n );\r\n }\r\n\r\n abort(error: ErrorInfo): void {\r\n (this.activeProtocol as Protocol).getTransport().fail(error);\r\n }\r\n\r\n getTransportPreference(): TransportName {\r\n return this.transportPreference || (haveWebStorage() && Platform.WebStorage?.get?.(transportPreferenceName));\r\n }\r\n\r\n persistTransportPreference(transport: Transport): void {\r\n this.transportPreference = transport.shortName;\r\n if (haveWebStorage()) {\r\n Platform.WebStorage?.set?.(transportPreferenceName, transport.shortName);\r\n }\r\n }\r\n\r\n unpersistTransportPreference(): void {\r\n this.transportPreference = null;\r\n if (haveWebStorage()) {\r\n Platform.WebStorage?.remove?.(transportPreferenceName);\r\n }\r\n }\r\n\r\n /* This method is only used during connection attempts, so implements RSA4c1, RSA4c2,\r\n * and RSA4d. It is generally not invoked for serverside-triggered reauths or manual\r\n * reauths, so RSA4c3 does not apply, except (per per RSA4d1) in the case that the auth\r\n * server returns 403. */\r\n actOnErrorFromAuthorize(err: ErrorInfo): void {\r\n if (err.code === 40171) {\r\n /* No way to reauth */\r\n this.notifyState({ state: 'failed', error: err });\r\n } else if (err.code === 40102) {\r\n this.notifyState({ state: 'failed', error: err });\r\n } else if (err.statusCode === HttpStatusCodes.Forbidden) {\r\n const msg = 'Client configured authentication provider returned 403; failing the connection';\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'ConnectionManager.actOnErrorFromAuthorize()', msg);\r\n this.notifyState({ state: 'failed', error: new ErrorInfo(msg, 80019, 403, err) });\r\n } else {\r\n const msg = 'Client configured authentication provider request failed';\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'ConnectionManager.actOnErrorFromAuthorize', msg);\r\n this.notifyState({ state: this.state.failState as string, error: new ErrorInfo(msg, 80019, 401, err) });\r\n }\r\n }\r\n\r\n onConnectionDetailsUpdate(connectionDetails: Record<string, any>, transport: Transport): void {\r\n if (!connectionDetails) {\r\n return;\r\n }\r\n this.connectionDetails = connectionDetails;\r\n if (connectionDetails.maxMessageSize) {\r\n this.options.maxMessageSize = connectionDetails.maxMessageSize;\r\n }\r\n const clientId = connectionDetails.clientId;\r\n if (clientId) {\r\n const err = this.realtime.auth._uncheckedSetClientId(clientId);\r\n if (err) {\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'ConnectionManager.onConnectionDetailsUpdate()', err.message);\r\n /* Errors setting the clientId are fatal to the connection */\r\n transport.fail(err);\r\n return;\r\n }\r\n }\r\n const connectionStateTtl = connectionDetails.connectionStateTtl;\r\n if (connectionStateTtl) {\r\n this.connectionStateTtl = connectionStateTtl;\r\n }\r\n this.maxIdleInterval = connectionDetails.maxIdleInterval;\r\n this.emit('connectiondetails', connectionDetails);\r\n }\r\n\r\n checkWsConnectivity() {\r\n const wsConnectivityCheckUrl = this.options.wsConnectivityCheckUrl || Defaults.wsConnectivityCheckUrl;\r\n const ws = new Platform.Config.WebSocket(wsConnectivityCheckUrl);\r\n return new Promise<void>((resolve, reject) => {\r\n let finished = false;\r\n ws.onopen = () => {\r\n if (!finished) {\r\n finished = true;\r\n resolve();\r\n ws.close();\r\n }\r\n };\r\n\r\n ws.onclose = ws.onerror = () => {\r\n if (!finished) {\r\n finished = true;\r\n reject();\r\n }\r\n };\r\n });\r\n }\r\n\r\n sessionRecoveryName() {\r\n return this.options.recoveryKeyStorageName || 'ably-connection-recovery';\r\n }\r\n\r\n getSessionRecoverData() {\r\n return haveSessionStorage() && Platform.WebStorage?.getSession?.(this.sessionRecoveryName());\r\n }\r\n setSessionRecoverData(value: any) {\r\n return haveSessionStorage() && Platform.WebStorage?.setSession?.(this.sessionRecoveryName(), value);\r\n }\r\n clearSessionRecoverData() {\r\n return haveSessionStorage() && Platform.WebStorage?.removeSession?.(this.sessionRecoveryName());\r\n }\r\n}\r\n\r\nexport default ConnectionManager;\r\n\r\nexport interface TransportStorage {\r\n supportedTransports: Partial<Record<TransportName, TransportCtor>>;\r\n}\r\n","import EventEmitter from '../util/eventemitter';\nimport ConnectionManager from '../transport/connectionmanager';\nimport Logger from '../util/logger';\nimport ConnectionStateChange from './connectionstatechange';\nimport ErrorInfo from '../types/errorinfo';\nimport { NormalisedClientOptions } from '../../types/ClientOptions';\nimport BaseRealtime from './baserealtime';\nimport Platform from 'common/platform';\n\nclass Connection extends EventEmitter {\n ably: BaseRealtime;\n connectionManager: ConnectionManager;\n state: string;\n key?: string;\n id?: string;\n errorReason: ErrorInfo | null;\n\n constructor(ably: BaseRealtime, options: NormalisedClientOptions) {\n super(ably.logger);\n this.ably = ably;\n this.connectionManager = new ConnectionManager(ably, options);\n this.state = this.connectionManager.state.state;\n this.key = undefined;\n this.id = undefined;\n this.errorReason = null;\n\n this.connectionManager.on('connectionstate', (stateChange: ConnectionStateChange) => {\n const state = (this.state = stateChange.current as string);\n Platform.Config.nextTick(() => {\n this.emit(state, stateChange);\n });\n });\n this.connectionManager.on('update', (stateChange: ConnectionStateChange) => {\n Platform.Config.nextTick(() => {\n this.emit('update', stateChange);\n });\n });\n }\n\n whenState = ((state: string) => {\n return EventEmitter.prototype.whenState.call(this, state, this.state);\n }) as any;\n\n connect(): void {\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Connection.connect()', '');\n this.connectionManager.requestState({ state: 'connecting' });\n }\n\n async ping(): Promise<number> {\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Connection.ping()', '');\n return this.connectionManager.ping();\n }\n\n close(): void {\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Connection.close()', 'connectionKey = ' + this.key);\n this.connectionManager.requestState({ state: 'closing' });\n }\n\n get recoveryKey(): string | null {\n this.logger.deprecationWarning(\n 'The `Connection.recoveryKey` attribute has been replaced by the `Connection.createRecoveryKey()` method. Replace your usage of `recoveryKey` with the return value of `createRecoveryKey()`. `recoveryKey` will be removed in a future version.',\n );\n return this.createRecoveryKey();\n }\n\n createRecoveryKey(): string | null {\n return this.connectionManager.createRecoveryKey();\n }\n}\n\nexport default Connection;\n","import ErrorInfo from '../types/errorinfo';\n\nclass ChannelStateChange {\n previous: string;\n current: string;\n resumed?: boolean;\n reason?: string | Error | ErrorInfo;\n hasBacklog?: boolean;\n\n constructor(\n previous: string,\n current: string,\n resumed?: boolean,\n hasBacklog?: boolean,\n reason?: string | Error | ErrorInfo | null,\n ) {\n this.previous = previous;\n this.current = current;\n if (current === 'attached') {\n this.resumed = resumed;\n this.hasBacklog = hasBacklog;\n }\n if (reason) this.reason = reason;\n }\n}\n\nexport default ChannelStateChange;\n","import ProtocolMessage, {\r\n actions,\r\n channelModes,\r\n fromValues as protocolMessageFromValues,\r\n} from '../types/protocolmessage';\r\nimport EventEmitter from '../util/eventemitter';\r\nimport * as Utils from '../util/utils';\r\nimport Logger from '../util/logger';\r\nimport RealtimePresence from './realtimepresence';\r\nimport Message, {\r\n fromValues as messageFromValues,\r\n fromValuesArray as messagesFromValuesArray,\r\n encodeArray as encodeMessagesArray,\r\n decode as decodeMessage,\r\n getMessagesSize,\r\n CipherOptions,\r\n EncodingDecodingContext,\r\n} from '../types/message';\r\nimport ChannelStateChange from './channelstatechange';\r\nimport ErrorInfo, { PartialErrorInfo } from '../types/errorinfo';\r\nimport PresenceMessage, { decode as decodePresenceMessage } from '../types/presencemessage';\r\nimport ConnectionErrors from '../transport/connectionerrors';\r\nimport * as API from '../../../../ably';\r\nimport ConnectionManager from '../transport/connectionmanager';\r\nimport ConnectionStateChange from './connectionstatechange';\r\nimport { ErrCallback, StandardCallback } from '../../types/utils';\r\nimport BaseRealtime from './baserealtime';\r\nimport { ChannelOptions } from '../../types/channel';\r\nimport { normaliseChannelOptions } from '../util/defaults';\r\nimport { PaginatedResult } from './paginatedresource';\r\nimport type { PushChannel } from 'plugins/push';\r\n\r\ninterface RealtimeHistoryParams {\r\n start?: number;\r\n end?: number;\r\n direction?: string;\r\n limit?: number;\r\n untilAttach?: boolean;\r\n from_serial?: string;\r\n}\r\n\r\nconst noop = function () {};\r\n\r\nfunction validateChannelOptions(options?: API.ChannelOptions) {\r\n if (options && 'params' in options && !Utils.isObject(options.params)) {\r\n return new ErrorInfo('options.params must be an object', 40000, 400);\r\n }\r\n if (options && 'modes' in options) {\r\n if (!Array.isArray(options.modes)) {\r\n return new ErrorInfo('options.modes must be an array', 40000, 400);\r\n }\r\n for (let i = 0; i < options.modes.length; i++) {\r\n const currentMode = options.modes[i];\r\n if (\r\n !currentMode ||\r\n typeof currentMode !== 'string' ||\r\n !channelModes.includes(String.prototype.toUpperCase.call(currentMode))\r\n ) {\r\n return new ErrorInfo('Invalid channel mode: ' + currentMode, 40000, 400);\r\n }\r\n }\r\n }\r\n}\r\n\r\nclass RealtimeChannel extends EventEmitter {\r\n name: string;\r\n channelOptions: ChannelOptions;\r\n client: BaseRealtime;\r\n private _presence: RealtimePresence | null;\r\n get presence(): RealtimePresence {\r\n if (!this._presence) {\r\n Utils.throwMissingPluginError('RealtimePresence');\r\n }\r\n return this._presence;\r\n }\r\n connectionManager: ConnectionManager;\r\n state: API.ChannelState;\r\n subscriptions: EventEmitter;\r\n filteredSubscriptions?: Map<API.messageCallback<Message>, Map<API.MessageFilter, API.messageCallback<Message>[]>>;\r\n syncChannelSerial?: string | null;\r\n properties: {\r\n attachSerial: string | null | undefined;\r\n channelSerial: string | null | undefined;\r\n };\r\n errorReason: ErrorInfo | string | null;\r\n _requestedFlags: Array<API.ChannelMode> | null;\r\n _mode?: null | number;\r\n _attachResume: boolean;\r\n _decodingContext: EncodingDecodingContext;\r\n _lastPayload: {\r\n messageId?: string | null;\r\n protocolMessageChannelSerial?: string | null;\r\n decodeFailureRecoveryInProgress: null | boolean;\r\n };\r\n _allChannelChanges: EventEmitter;\r\n params?: Record<string, any>;\r\n modes: string[] | undefined;\r\n stateTimer?: number | NodeJS.Timeout | null;\r\n retryTimer?: number | NodeJS.Timeout | null;\r\n retryCount: number = 0;\r\n _push?: PushChannel;\r\n\r\n constructor(client: BaseRealtime, name: string, options?: API.ChannelOptions) {\r\n super(client.logger);\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'RealtimeChannel()', 'started; name = ' + name);\r\n this.name = name;\r\n this.channelOptions = normaliseChannelOptions(client._Crypto ?? null, this.logger, options);\r\n this.client = client;\r\n this._presence = client._RealtimePresence ? new client._RealtimePresence.RealtimePresence(this) : null;\r\n this.connectionManager = client.connection.connectionManager;\r\n this.state = 'initialized';\r\n this.subscriptions = new EventEmitter(this.logger);\r\n this.syncChannelSerial = undefined;\r\n this.properties = {\r\n attachSerial: undefined,\r\n channelSerial: undefined,\r\n };\r\n this.setOptions(options);\r\n this.errorReason = null;\r\n this._requestedFlags = null;\r\n this._mode = null;\r\n this._attachResume = false;\r\n this._decodingContext = {\r\n channelOptions: this.channelOptions,\r\n plugins: client.options.plugins || {},\r\n baseEncodedPreviousPayload: undefined,\r\n };\r\n this._lastPayload = {\r\n messageId: null,\r\n protocolMessageChannelSerial: null,\r\n decodeFailureRecoveryInProgress: null,\r\n };\r\n /* Only differences between this and the public event emitter is that this emits an\r\n * update event for all ATTACHEDs, whether resumed or not */\r\n this._allChannelChanges = new EventEmitter(this.logger);\r\n\r\n if (client.options.plugins?.Push) {\r\n this._push = new client.options.plugins.Push.PushChannel(this);\r\n }\r\n }\r\n\r\n get push() {\r\n if (!this._push) {\r\n Utils.throwMissingPluginError('Push');\r\n }\r\n return this._push;\r\n }\r\n\r\n invalidStateError(): ErrorInfo {\r\n return new ErrorInfo(\r\n 'Channel operation failed as channel state is ' + this.state,\r\n 90001,\r\n 400,\r\n this.errorReason || undefined,\r\n );\r\n }\r\n\r\n static processListenerArgs(args: unknown[]): any[] {\r\n /* [event], listener */\r\n args = Array.prototype.slice.call(args);\r\n if (typeof args[0] === 'function') {\r\n args.unshift(null);\r\n }\r\n return args;\r\n }\r\n\r\n async setOptions(options?: API.ChannelOptions): Promise<void> {\r\n const previousChannelOptions = this.channelOptions;\r\n const err = validateChannelOptions(options);\r\n if (err) {\r\n throw err;\r\n }\r\n this.channelOptions = normaliseChannelOptions(this.client._Crypto ?? null, this.logger, options);\r\n if (this._decodingContext) this._decodingContext.channelOptions = this.channelOptions;\r\n if (this._shouldReattachToSetOptions(options, previousChannelOptions)) {\r\n /* This does not just do _attach(true, null, callback) because that would put us\r\n * into the 'attaching' state until we receive the new attached, which is\r\n * conceptually incorrect: we are still attached, we just have a pending request to\r\n * change some channel params. Per RTL17 going into the attaching state would mean\r\n * rejecting messages until we have confirmation that the options have changed,\r\n * which would unnecessarily lose message continuity. */\r\n this.attachImpl();\r\n return new Promise((resolve, reject) => {\r\n // Ignore 'attaching' -- could be just due to to a resume & reattach, should not\r\n // call back setOptions until we're definitely attached with the new options (or\r\n // else in a terminal state)\r\n this._allChannelChanges.once(\r\n ['attached', 'update', 'detached', 'failed'],\r\n function (this: { event: string }, stateChange: ConnectionStateChange) {\r\n switch (this.event) {\r\n case 'update':\r\n case 'attached':\r\n resolve();\r\n break;\r\n default:\r\n reject(stateChange.reason);\r\n }\r\n },\r\n );\r\n });\r\n }\r\n }\r\n\r\n _shouldReattachToSetOptions(options: API.ChannelOptions | undefined, prevOptions: API.ChannelOptions) {\r\n if (!(this.state === 'attached' || this.state === 'attaching')) {\r\n return false;\r\n }\r\n if (options?.params) {\r\n // Don't check against the `agent` param - it isn't returned in the ATTACHED message\r\n const requestedParams = omitAgent(options.params);\r\n const existingParams = omitAgent(prevOptions.params);\r\n\r\n if (Object.keys(requestedParams).length !== Object.keys(existingParams).length) {\r\n return true;\r\n }\r\n\r\n if (!Utils.shallowEquals(existingParams, requestedParams)) {\r\n return true;\r\n }\r\n }\r\n if (options?.modes) {\r\n if (!prevOptions.modes || !Utils.arrEquals(options.modes, prevOptions.modes)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n async publish(...args: any[]): Promise<void> {\r\n let messages = args[0];\r\n let argCount = args.length;\r\n\r\n if (!this.connectionManager.activeState()) {\r\n throw this.connectionManager.getError();\r\n }\r\n if (argCount == 1) {\r\n if (Utils.isObject(messages)) messages = [messageFromValues(messages)];\r\n else if (Array.isArray(messages)) messages = messagesFromValuesArray(messages);\r\n else\r\n throw new ErrorInfo(\r\n 'The single-argument form of publish() expects a message object or an array of message objects',\r\n 40013,\r\n 400,\r\n );\r\n } else {\r\n messages = [messageFromValues({ name: args[0], data: args[1] })];\r\n }\r\n const maxMessageSize = this.client.options.maxMessageSize;\r\n await encodeMessagesArray(messages, this.channelOptions as CipherOptions);\r\n /* RSL1i */\r\n const size = getMessagesSize(messages);\r\n if (size > maxMessageSize) {\r\n throw new ErrorInfo(\r\n 'Maximum size of messages that can be published at once exceeded ( was ' +\r\n size +\r\n ' bytes; limit is ' +\r\n maxMessageSize +\r\n ' bytes)',\r\n 40009,\r\n 400,\r\n );\r\n }\r\n return new Promise((resolve, reject) => {\r\n this._publish(messages, (err) => (err ? reject(err) : resolve()));\r\n });\r\n }\r\n\r\n _publish(messages: Array<Message>, callback: ErrCallback) {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'RealtimeChannel.publish()', 'message count = ' + messages.length);\r\n const state = this.state;\r\n switch (state) {\r\n case 'failed':\r\n case 'suspended':\r\n callback(ErrorInfo.fromValues(this.invalidStateError()));\r\n break;\r\n default: {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'RealtimeChannel.publish()',\r\n 'sending message; channel state is ' + state,\r\n );\r\n const msg = new ProtocolMessage();\r\n msg.action = actions.MESSAGE;\r\n msg.channel = this.name;\r\n msg.messages = messages;\r\n this.sendMessage(msg, callback);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n onEvent(messages: Array<any>): void {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'RealtimeChannel.onEvent()', 'received message');\r\n const subscriptions = this.subscriptions;\r\n for (let i = 0; i < messages.length; i++) {\r\n const message = messages[i];\r\n subscriptions.emit(message.name, message);\r\n }\r\n }\r\n\r\n async attach(): Promise<ChannelStateChange | null> {\r\n if (this.state === 'attached') {\r\n return null;\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n this._attach(false, null, (err, result) => (err ? reject(err) : resolve(result!)));\r\n });\r\n }\r\n\r\n _attach(\r\n forceReattach: boolean,\r\n attachReason: ErrorInfo | null,\r\n callback?: StandardCallback<ChannelStateChange>,\r\n ): void {\r\n if (!callback) {\r\n callback = (err?: ErrorInfo | null) => {\r\n if (err) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'RealtimeChannel._attach()',\r\n 'Channel attach failed: ' + err.toString(),\r\n );\r\n }\r\n };\r\n }\r\n\r\n const connectionManager = this.connectionManager;\r\n if (!connectionManager.activeState()) {\r\n callback(connectionManager.getError());\r\n return;\r\n }\r\n\r\n if (this.state !== 'attaching' || forceReattach) {\r\n this.requestState('attaching', attachReason);\r\n }\r\n\r\n this.once(function (this: { event: string }, stateChange: ChannelStateChange) {\r\n switch (this.event) {\r\n case 'attached':\r\n callback?.(null, stateChange);\r\n break;\r\n case 'detached':\r\n case 'suspended':\r\n case 'failed':\r\n callback?.(\r\n stateChange.reason ||\r\n connectionManager.getError() ||\r\n new ErrorInfo('Unable to attach; reason unknown; state = ' + this.event, 90000, 500),\r\n );\r\n break;\r\n case 'detaching':\r\n callback?.(new ErrorInfo('Attach request superseded by a subsequent detach request', 90000, 409));\r\n break;\r\n }\r\n });\r\n }\r\n\r\n attachImpl(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'RealtimeChannel.attachImpl()', 'sending ATTACH message');\r\n const attachMsg = protocolMessageFromValues({\r\n action: actions.ATTACH,\r\n channel: this.name,\r\n params: this.channelOptions.params,\r\n // RTL4c1: Includes the channel serial to resume from a previous message\r\n // or attachment.\r\n channelSerial: this.properties.channelSerial,\r\n });\r\n if (this._requestedFlags) {\r\n attachMsg.encodeModesToFlags(this._requestedFlags);\r\n } else if (this.channelOptions.modes) {\r\n attachMsg.encodeModesToFlags(Utils.allToUpperCase(this.channelOptions.modes) as API.ChannelMode[]);\r\n }\r\n if (this._attachResume) {\r\n attachMsg.setFlag('ATTACH_RESUME');\r\n }\r\n if (this._lastPayload.decodeFailureRecoveryInProgress) {\r\n attachMsg.channelSerial = this._lastPayload.protocolMessageChannelSerial;\r\n }\r\n this.sendMessage(attachMsg, noop);\r\n }\r\n\r\n async detach(): Promise<void> {\r\n const connectionManager = this.connectionManager;\r\n if (!connectionManager.activeState()) {\r\n throw connectionManager.getError();\r\n }\r\n switch (this.state) {\r\n case 'suspended':\r\n this.notifyState('detached');\r\n return;\r\n case 'detached':\r\n return;\r\n case 'failed':\r\n throw new ErrorInfo('Unable to detach; channel state = failed', 90001, 400);\r\n default:\r\n this.requestState('detaching');\r\n // eslint-disable-next-line no-fallthrough\r\n case 'detaching':\r\n return new Promise((resolve, reject) => {\r\n this.once(function (this: { event: string }, stateChange: ChannelStateChange) {\r\n switch (this.event) {\r\n case 'detached':\r\n resolve();\r\n break;\r\n case 'attached':\r\n case 'suspended':\r\n case 'failed':\r\n reject(\r\n stateChange.reason ||\r\n connectionManager.getError() ||\r\n new ErrorInfo('Unable to detach; reason unknown; state = ' + this.event, 90000, 500),\r\n );\r\n break;\r\n case 'attaching':\r\n reject(new ErrorInfo('Detach request superseded by a subsequent attach request', 90000, 409));\r\n break;\r\n }\r\n });\r\n });\r\n }\r\n }\r\n\r\n detachImpl(callback?: ErrCallback): void {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'RealtimeChannel.detach()', 'sending DETACH message');\r\n const msg = protocolMessageFromValues({ action: actions.DETACH, channel: this.name });\r\n this.sendMessage(msg, callback || noop);\r\n }\r\n\r\n async subscribe(...args: unknown[] /* [event], listener */): Promise<ChannelStateChange | null> {\r\n const [event, listener] = RealtimeChannel.processListenerArgs(args);\r\n\r\n if (this.state === 'failed') {\r\n throw ErrorInfo.fromValues(this.invalidStateError());\r\n }\r\n\r\n // Filtered\r\n if (event && typeof event === 'object' && !Array.isArray(event)) {\r\n this.client._FilteredSubscriptions.subscribeFilter(this, event, listener);\r\n } else {\r\n this.subscriptions.on(event, listener);\r\n }\r\n\r\n return this.attach();\r\n }\r\n\r\n unsubscribe(...args: unknown[] /* [event], listener */): void {\r\n const [event, listener] = RealtimeChannel.processListenerArgs(args);\r\n\r\n // If we either have a filtered listener, a filter or both we need to do additional processing to find the original function(s)\r\n if ((typeof event === 'object' && !listener) || this.filteredSubscriptions?.has(listener)) {\r\n this.client._FilteredSubscriptions\r\n .getAndDeleteFilteredSubscriptions(this, event, listener)\r\n .forEach((l) => this.subscriptions.off(l));\r\n return;\r\n }\r\n\r\n this.subscriptions.off(event, listener);\r\n }\r\n\r\n sync(): void {\r\n /* check preconditions */\r\n switch (this.state) {\r\n case 'initialized':\r\n case 'detaching':\r\n case 'detached':\r\n throw new PartialErrorInfo('Unable to sync to channel; not attached', 40000);\r\n default:\r\n }\r\n const connectionManager = this.connectionManager;\r\n if (!connectionManager.activeState()) {\r\n throw connectionManager.getError();\r\n }\r\n\r\n /* send sync request */\r\n const syncMessage = protocolMessageFromValues({ action: actions.SYNC, channel: this.name });\r\n if (this.syncChannelSerial) {\r\n syncMessage.channelSerial = this.syncChannelSerial;\r\n }\r\n connectionManager.send(syncMessage);\r\n }\r\n\r\n sendMessage(msg: ProtocolMessage, callback?: ErrCallback): void {\r\n this.connectionManager.send(msg, this.client.options.queueMessages, callback);\r\n }\r\n\r\n sendPresence(presence: PresenceMessage | PresenceMessage[], callback?: ErrCallback): void {\r\n const msg = protocolMessageFromValues({\r\n action: actions.PRESENCE,\r\n channel: this.name,\r\n presence: Array.isArray(presence)\r\n ? this.client._RealtimePresence!.presenceMessagesFromValuesArray(presence)\r\n : [this.client._RealtimePresence!.presenceMessageFromValues(presence)],\r\n });\r\n this.sendMessage(msg, callback);\r\n }\r\n\r\n // Access to this method is synchronised by ConnectionManager#processChannelMessage, in order to synchronise access to the state stored in _decodingContext.\r\n async processMessage(message: ProtocolMessage): Promise<void> {\r\n if (\r\n message.action === actions.ATTACHED ||\r\n message.action === actions.MESSAGE ||\r\n message.action === actions.PRESENCE\r\n ) {\r\n // RTL15b\r\n this.setChannelSerial(message.channelSerial);\r\n }\r\n\r\n let syncChannelSerial,\r\n isSync = false;\r\n switch (message.action) {\r\n case actions.ATTACHED: {\r\n this.properties.attachSerial = message.channelSerial;\r\n this._mode = message.getMode();\r\n this.params = (message as any).params || {};\r\n const modesFromFlags = message.decodeModesFromFlags();\r\n this.modes = (modesFromFlags && Utils.allToLowerCase(modesFromFlags)) || undefined;\r\n const resumed = message.hasFlag('RESUMED');\r\n const hasPresence = message.hasFlag('HAS_PRESENCE');\r\n const hasBacklog = message.hasFlag('HAS_BACKLOG');\r\n if (this.state === 'attached') {\r\n if (!resumed) {\r\n /* On a loss of continuity, the presence set needs to be re-synced */\r\n if (this._presence) {\r\n this._presence.onAttached(hasPresence);\r\n }\r\n }\r\n const change = new ChannelStateChange(this.state, this.state, resumed, hasBacklog, message.error);\r\n this._allChannelChanges.emit('update', change);\r\n if (!resumed || this.channelOptions.updateOnAttached) {\r\n this.emit('update', change);\r\n }\r\n } else if (this.state === 'detaching') {\r\n /* RTL5i: re-send DETACH and remain in the 'detaching' state */\r\n this.checkPendingState();\r\n } else {\r\n this.notifyState('attached', message.error, resumed, hasPresence, hasBacklog);\r\n }\r\n break;\r\n }\r\n\r\n case actions.DETACHED: {\r\n const detachErr = message.error\r\n ? ErrorInfo.fromValues(message.error)\r\n : new ErrorInfo('Channel detached', 90001, 404);\r\n if (this.state === 'detaching') {\r\n this.notifyState('detached', detachErr);\r\n } else if (this.state === 'attaching') {\r\n /* Only retry immediately if we were previously attached. If we were\r\n * attaching, go into suspended, fail messages, and wait a few seconds\r\n * before retrying */\r\n this.notifyState('suspended', detachErr);\r\n } else if (this.state === 'attached' || this.state === 'suspended') {\r\n // RTL13a\r\n this.requestState('attaching', detachErr);\r\n }\r\n // else no action (detached in initialized, detached, or failed state is a noop)\r\n break;\r\n }\r\n\r\n case actions.SYNC:\r\n /* syncs can have channelSerials, but might not if the sync is one page long */\r\n isSync = true;\r\n syncChannelSerial = this.syncChannelSerial = message.channelSerial;\r\n /* syncs can happen on channels with no presence data as part of connection\r\n * resuming, in which case protocol message has no presence property */\r\n if (!message.presence) break;\r\n // eslint-disable-next-line no-fallthrough\r\n case actions.PRESENCE: {\r\n const presenceMessages = message.presence;\r\n\r\n if (!presenceMessages) {\r\n break;\r\n }\r\n\r\n const options = this.channelOptions;\r\n await this._decodeAndPrepareMessages(message, presenceMessages, (msg) => decodePresenceMessage(msg, options));\r\n\r\n if (this._presence) {\r\n this._presence.setPresence(presenceMessages, isSync, syncChannelSerial as any);\r\n }\r\n break;\r\n }\r\n case actions.MESSAGE: {\r\n //RTL17\r\n if (this.state !== 'attached') {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MAJOR,\r\n 'RealtimeChannel.processMessage()',\r\n 'Message \"' +\r\n message.id +\r\n '\" skipped as this channel \"' +\r\n this.name +\r\n '\" state is not \"attached\" (state is \"' +\r\n this.state +\r\n '\").',\r\n );\r\n return;\r\n }\r\n\r\n const messages = message.messages as Array<Message>,\r\n firstMessage = messages[0],\r\n lastMessage = messages[messages.length - 1],\r\n channelSerial = message.channelSerial;\r\n\r\n if (\r\n firstMessage.extras &&\r\n firstMessage.extras.delta &&\r\n firstMessage.extras.delta.from !== this._lastPayload.messageId\r\n ) {\r\n const msg =\r\n 'Delta message decode failure - previous message not available for message \"' +\r\n message.id +\r\n '\" on this channel \"' +\r\n this.name +\r\n '\".';\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'RealtimeChannel.processMessage()', msg);\r\n this._startDecodeFailureRecovery(new ErrorInfo(msg, 40018, 400));\r\n break;\r\n }\r\n\r\n const { unrecoverableError } = await this._decodeAndPrepareMessages(\r\n message,\r\n messages,\r\n (msg) => decodeMessage(msg, this._decodingContext),\r\n (e) => {\r\n /* decrypt failed .. the most likely cause is that we have the wrong key */\r\n const errorInfo = e as ErrorInfo;\r\n\r\n switch (errorInfo.code) {\r\n case 40018:\r\n /* decode failure */\r\n this._startDecodeFailureRecovery(errorInfo);\r\n return { unrecoverableError: true };\r\n\r\n case 40019:\r\n /* No vcdiff plugin passed in - no point recovering, give up */\r\n // eslint-disable-next-line no-fallthrough\r\n case 40021:\r\n /* Browser does not support deltas, similarly no point recovering */\r\n this.notifyState('failed', errorInfo);\r\n return { unrecoverableError: true };\r\n\r\n default:\r\n return { unrecoverableError: false };\r\n }\r\n },\r\n );\r\n if (unrecoverableError) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < messages.length; i++) {\r\n const msg = messages[i];\r\n if (channelSerial && !msg.version) {\r\n msg.version = channelSerial + ':' + i.toString().padStart(3, '0');\r\n // already done in fromWireProtocol -- but for realtime messages the source\r\n // fields might be copied from the protocolmessage, so need to do it again\r\n msg.expandFields();\r\n }\r\n }\r\n\r\n this._lastPayload.messageId = lastMessage.id;\r\n this._lastPayload.protocolMessageChannelSerial = message.channelSerial;\r\n this.onEvent(messages);\r\n break;\r\n }\r\n\r\n case actions.ERROR: {\r\n /* there was a channel-specific error */\r\n const err = message.error as ErrorInfo;\r\n if (err && err.code == 80016) {\r\n /* attach/detach operation attempted on superseded transport handle */\r\n this.checkPendingState();\r\n } else {\r\n this.notifyState('failed', ErrorInfo.fromValues(err));\r\n }\r\n break;\r\n }\r\n\r\n default:\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'RealtimeChannel.processMessage()',\r\n 'Fatal protocol error: unrecognised action (' + message.action + ')',\r\n );\r\n this.connectionManager.abort(ConnectionErrors.unknownChannelErr());\r\n }\r\n }\r\n\r\n /**\r\n * Mutates provided messages by adding `connectionId`, `timestamp` and `id` fields, and decoding message data.\r\n *\r\n * @returns `unrecoverableError` flag. If `true` indicates that unrecoverable error was encountered during message decoding\r\n * and any further message processing should be stopped. Always equals to `false` if `decodeErrorRecoveryHandler` was not provided\r\n */\r\n private async _decodeAndPrepareMessages<T extends Message | PresenceMessage>(\r\n protocolMessage: ProtocolMessage,\r\n messages: T[],\r\n decodeFn: (msg: T) => Promise<void>,\r\n decodeErrorRecoveryHandler?: (e: Error) => { unrecoverableError: boolean },\r\n ): Promise<{ unrecoverableError: boolean }> {\r\n const { id, connectionId, timestamp } = protocolMessage;\r\n\r\n for (let i = 0; i < messages.length; i++) {\r\n const msg = messages[i];\r\n\r\n try {\r\n // decode underlying data for a message\r\n await decodeFn(msg);\r\n } catch (e) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'RealtimeChannel.decodeAndPrepareMessages()',\r\n (e as Error).toString(),\r\n );\r\n\r\n if (decodeErrorRecoveryHandler) {\r\n const { unrecoverableError } = decodeErrorRecoveryHandler(e as Error);\r\n if (unrecoverableError) {\r\n // break out of for loop by returning\r\n return { unrecoverableError: true };\r\n }\r\n }\r\n }\r\n\r\n if (!msg.connectionId) msg.connectionId = connectionId;\r\n if (!msg.timestamp) msg.timestamp = timestamp;\r\n if (id && !msg.id) msg.id = id + ':' + i;\r\n }\r\n\r\n return { unrecoverableError: false };\r\n }\r\n\r\n _startDecodeFailureRecovery(reason: ErrorInfo): void {\r\n if (!this._lastPayload.decodeFailureRecoveryInProgress) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MAJOR,\r\n 'RealtimeChannel.processMessage()',\r\n 'Starting decode failure recovery process.',\r\n );\r\n this._lastPayload.decodeFailureRecoveryInProgress = true;\r\n this._attach(true, reason, () => {\r\n this._lastPayload.decodeFailureRecoveryInProgress = false;\r\n });\r\n }\r\n }\r\n\r\n onAttached(): void {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'RealtimeChannel.onAttached',\r\n 'activating channel; name = ' + this.name,\r\n );\r\n }\r\n\r\n notifyState(\r\n state: API.ChannelState,\r\n reason?: ErrorInfo | null,\r\n resumed?: boolean,\r\n hasPresence?: boolean,\r\n hasBacklog?: boolean,\r\n ): void {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'RealtimeChannel.notifyState',\r\n 'name = ' + this.name + ', current state = ' + this.state + ', notifying state ' + state,\r\n );\r\n this.clearStateTimer();\r\n\r\n // RTP5a1\r\n if (['detached', 'suspended', 'failed'].includes(state)) {\r\n this.properties.channelSerial = null;\r\n }\r\n\r\n if (state === this.state) {\r\n return;\r\n }\r\n if (this._presence) {\r\n this._presence.actOnChannelState(state, hasPresence, reason);\r\n }\r\n if (state === 'suspended' && this.connectionManager.state.sendEvents) {\r\n this.startRetryTimer();\r\n } else {\r\n this.cancelRetryTimer();\r\n }\r\n if (reason) {\r\n this.errorReason = reason;\r\n }\r\n const change = new ChannelStateChange(this.state, state, resumed, hasBacklog, reason);\r\n const action = 'Channel state for channel \"' + this.name + '\"';\r\n const message = state + (reason ? '; reason: ' + reason : '');\r\n if (state === 'failed') {\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, action, message);\r\n } else {\r\n Logger.logAction(this.logger, Logger.LOG_MAJOR, action, message);\r\n }\r\n\r\n if (state !== 'attaching' && state !== 'suspended') {\r\n this.retryCount = 0;\r\n }\r\n\r\n /* Note: we don't set inProgress for pending states until the request is actually in progress */\r\n if (state === 'attached') {\r\n this.onAttached();\r\n }\r\n\r\n if (state === 'attached') {\r\n this._attachResume = true;\r\n } else if (state === 'detaching' || state === 'failed') {\r\n this._attachResume = false;\r\n }\r\n\r\n this.state = state;\r\n this._allChannelChanges.emit(state, change);\r\n this.emit(state, change);\r\n }\r\n\r\n requestState(state: API.ChannelState, reason?: ErrorInfo | null): void {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'RealtimeChannel.requestState',\r\n 'name = ' + this.name + ', state = ' + state,\r\n );\r\n this.notifyState(state, reason);\r\n /* send the event and await response */\r\n this.checkPendingState();\r\n }\r\n\r\n checkPendingState(): void {\r\n /* if can't send events, do nothing */\r\n const cmState = this.connectionManager.state;\r\n if (!cmState.sendEvents) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'RealtimeChannel.checkPendingState',\r\n 'sendEvents is false; state is ' + this.connectionManager.state.state,\r\n );\r\n return;\r\n }\r\n\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'RealtimeChannel.checkPendingState',\r\n 'name = ' + this.name + ', state = ' + this.state,\r\n );\r\n /* Only start the state timer running when actually sending the event */\r\n switch (this.state) {\r\n case 'attaching':\r\n this.startStateTimerIfNotRunning();\r\n this.attachImpl();\r\n break;\r\n case 'detaching':\r\n this.startStateTimerIfNotRunning();\r\n this.detachImpl();\r\n break;\r\n case 'attached':\r\n /* resume any sync operation that was in progress */\r\n this.sync();\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n timeoutPendingState(): void {\r\n switch (this.state) {\r\n case 'attaching': {\r\n const err = new ErrorInfo('Channel attach timed out', 90007, 408);\r\n this.notifyState('suspended', err);\r\n break;\r\n }\r\n case 'detaching': {\r\n const err = new ErrorInfo('Channel detach timed out', 90007, 408);\r\n this.notifyState('attached', err);\r\n break;\r\n }\r\n default:\r\n this.checkPendingState();\r\n break;\r\n }\r\n }\r\n\r\n startStateTimerIfNotRunning(): void {\r\n if (!this.stateTimer) {\r\n this.stateTimer = setTimeout(() => {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'RealtimeChannel.startStateTimerIfNotRunning', 'timer expired');\r\n this.stateTimer = null;\r\n this.timeoutPendingState();\r\n }, this.client.options.timeouts.realtimeRequestTimeout);\r\n }\r\n }\r\n\r\n clearStateTimer(): void {\r\n const stateTimer = this.stateTimer;\r\n if (stateTimer) {\r\n clearTimeout(stateTimer);\r\n this.stateTimer = null;\r\n }\r\n }\r\n\r\n startRetryTimer(): void {\r\n if (this.retryTimer) return;\r\n\r\n this.retryCount++;\r\n const retryDelay = Utils.getRetryTime(this.client.options.timeouts.channelRetryTimeout, this.retryCount);\r\n\r\n this.retryTimer = setTimeout(() => {\r\n /* If connection is not connected, just leave in suspended, a reattach\r\n * will be triggered once it connects again */\r\n if (this.state === 'suspended' && this.connectionManager.state.sendEvents) {\r\n this.retryTimer = null;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'RealtimeChannel retry timer expired',\r\n 'attempting a new attach',\r\n );\r\n this.requestState('attaching');\r\n }\r\n }, retryDelay);\r\n }\r\n\r\n cancelRetryTimer(): void {\r\n if (this.retryTimer) {\r\n clearTimeout(this.retryTimer as NodeJS.Timeout);\r\n this.retryTimer = null;\r\n }\r\n }\r\n\r\n history = async function (\r\n this: RealtimeChannel,\r\n params: RealtimeHistoryParams | null,\r\n ): Promise<PaginatedResult<Message>> {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'RealtimeChannel.history()', 'channel = ' + this.name);\r\n\r\n // We fetch this first so that any plugin-not-provided error takes priority over other errors\r\n const restMixin = this.client.rest.channelMixin;\r\n\r\n if (params && params.untilAttach) {\r\n if (this.state !== 'attached') {\r\n throw new ErrorInfo('option untilAttach requires the channel to be attached', 40000, 400);\r\n }\r\n if (!this.properties.attachSerial) {\r\n throw new ErrorInfo(\r\n 'untilAttach was specified and channel is attached, but attachSerial is not defined',\r\n 40000,\r\n 400,\r\n );\r\n }\r\n delete params.untilAttach;\r\n params.from_serial = this.properties.attachSerial;\r\n }\r\n\r\n return restMixin.history(this, params);\r\n } as any;\r\n\r\n whenState = ((state: string) => {\r\n return EventEmitter.prototype.whenState.call(this, state, this.state);\r\n }) as any;\r\n\r\n /* @returns null (if can safely be released) | ErrorInfo (if cannot) */\r\n getReleaseErr(): ErrorInfo | null {\r\n const s = this.state;\r\n if (s === 'initialized' || s === 'detached' || s === 'failed') {\r\n return null;\r\n }\r\n return new ErrorInfo(\r\n 'Can only release a channel in a state where there is no possibility of further updates from the server being received (initialized, detached, or failed); was ' +\r\n s,\r\n 90001,\r\n 400,\r\n );\r\n }\r\n\r\n setChannelSerial(channelSerial?: string | null): void {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'RealtimeChannel.setChannelSerial()',\r\n 'Updating channel serial; serial = ' + channelSerial + '; previous = ' + this.properties.channelSerial,\r\n );\r\n\r\n // RTP17h: Only update the channel serial if its present (it won't always\r\n // be set).\r\n if (channelSerial) {\r\n this.properties.channelSerial = channelSerial;\r\n }\r\n }\r\n\r\n async status(): Promise<API.ChannelDetails> {\r\n return this.client.rest.channelMixin.status(this);\r\n }\r\n}\r\n\r\nfunction omitAgent(channelParams?: API.ChannelParams) {\r\n const { agent: _, ...paramsWithoutAgent } = channelParams || {};\r\n return paramsWithoutAgent;\r\n}\r\n\r\nexport default RealtimeChannel;\r\n","import * as Utils from '../util/utils';\r\nimport BaseClient from './baseclient';\r\nimport EventEmitter from '../util/eventemitter';\r\nimport Logger from '../util/logger';\r\nimport Connection from './connection';\r\nimport RealtimeChannel from './realtimechannel';\r\nimport ErrorInfo from '../types/errorinfo';\r\nimport ProtocolMessage from '../types/protocolmessage';\r\nimport { ChannelOptions } from '../../types/channel';\r\nimport ClientOptions from '../../types/ClientOptions';\r\nimport * as API from '../../../../ably';\r\nimport { ModularPlugins, RealtimePresencePlugin } from './modularplugins';\r\nimport { TransportNames } from 'common/constants/TransportName';\r\nimport { TransportImplementations } from 'common/platform';\r\nimport Defaults from '../util/defaults';\r\n\r\n/**\r\n `BaseRealtime` is an export of the tree-shakable version of the SDK, and acts as the base class for the `DefaultRealtime` class exported by the non tree-shakable version.\r\n */\r\nclass BaseRealtime extends BaseClient {\r\n readonly _RealtimePresence: RealtimePresencePlugin | null;\r\n // Extra transport implementations available to this client, in addition to those in Platform.Transports.bundledImplementations\r\n readonly _additionalTransportImplementations: TransportImplementations;\r\n _channels: any;\r\n connection: Connection;\r\n\r\n // internal API to make EventEmitter usable in other SDKs\r\n static readonly EventEmitter = EventEmitter;\r\n\r\n /*\r\n * The public typings declare that this only accepts an object, but since we want to emit a good error message in the case where a non-TypeScript user does one of these things:\r\n *\r\n * 1. passes a string (which is quite likely if they’re e.g. migrating from the default variant to the modular variant)\r\n * 2. passes no argument at all\r\n *\r\n * tell the compiler that these cases are possible so that it forces us to handle them.\r\n */\r\n constructor(options?: ClientOptions | string) {\r\n super(Defaults.objectifyOptions(options, false, 'BaseRealtime', Logger.defaultLogger));\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Realtime()', '');\r\n\r\n // currently we cannot support using Ably.Realtime instances in Vercel Edge runtime.\r\n // this error can be removed after fixing https://github.com/ably/ably-js/issues/1731,\r\n // and https://github.com/ably/ably-js/issues/1732\r\n // @ts-ignore\r\n if (typeof EdgeRuntime === 'string') {\r\n throw new ErrorInfo(\r\n `Ably.Realtime instance cannot be used in Vercel Edge runtime.` +\r\n ` If you are running Vercel Edge functions, please replace your` +\r\n ` \"new Ably.Realtime()\" with \"new Ably.Rest()\" and use Ably Rest API` +\r\n ` instead of the Realtime API. If you are server-rendering your application` +\r\n ` in the Vercel Edge runtime, please use the condition \"if (typeof EdgeRuntime === 'string')\"` +\r\n ` to prevent instantiating Ably.Realtime instance during SSR in the Vercel Edge runtime.`,\r\n 40000,\r\n 400,\r\n );\r\n }\r\n\r\n this._additionalTransportImplementations = BaseRealtime.transportImplementationsFromPlugins(this.options.plugins);\r\n this._RealtimePresence = this.options.plugins?.RealtimePresence ?? null;\r\n this.connection = new Connection(this, this.options);\r\n this._channels = new Channels(this);\r\n if (this.options.autoConnect !== false) this.connect();\r\n }\r\n\r\n private static transportImplementationsFromPlugins(plugins?: ModularPlugins) {\r\n const transports: TransportImplementations = {};\r\n\r\n if (plugins?.WebSocketTransport) {\r\n transports[TransportNames.WebSocket] = plugins.WebSocketTransport;\r\n }\r\n if (plugins?.XHRPolling) {\r\n transports[TransportNames.XhrPolling] = plugins.XHRPolling;\r\n }\r\n\r\n return transports;\r\n }\r\n\r\n get channels() {\r\n return this._channels;\r\n }\r\n\r\n connect(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Realtime.connect()', '');\r\n this.connection.connect();\r\n }\r\n\r\n close(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'Realtime.close()', '');\r\n this.connection.close();\r\n }\r\n}\r\n\r\nclass Channels extends EventEmitter {\r\n realtime: BaseRealtime;\r\n all: Record<string, RealtimeChannel>;\r\n\r\n constructor(realtime: BaseRealtime) {\r\n super(realtime.logger);\r\n this.realtime = realtime;\r\n this.all = Object.create(null);\r\n realtime.connection.connectionManager.on('transport.active', () => {\r\n this.onTransportActive();\r\n });\r\n }\r\n\r\n channelSerials(): { [name: string]: string } {\r\n let serials: { [name: string]: string } = {};\r\n for (const name of Utils.keysArray(this.all, true)) {\r\n const channel = this.all[name];\r\n if (channel.properties.channelSerial) {\r\n serials[name] = channel.properties.channelSerial;\r\n }\r\n }\r\n return serials;\r\n }\r\n\r\n // recoverChannels gets the given channels and sets their channel serials.\r\n recoverChannels(channelSerials: { [name: string]: string }) {\r\n for (const name of Utils.keysArray(channelSerials, true)) {\r\n const channel = this.get(name);\r\n channel.properties.channelSerial = channelSerials[name];\r\n }\r\n }\r\n\r\n // Access to this method is synchronised by ConnectionManager#processChannelMessage.\r\n async processChannelMessage(msg: ProtocolMessage) {\r\n const channelName = msg.channel;\r\n if (channelName === undefined) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'Channels.processChannelMessage()',\r\n 'received event unspecified channel, action = ' + msg.action,\r\n );\r\n return;\r\n }\r\n const channel = this.all[channelName];\r\n if (!channel) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'Channels.processChannelMessage()',\r\n 'received event for non-existent channel: ' + channelName,\r\n );\r\n return;\r\n }\r\n await channel.processMessage(msg);\r\n }\r\n\r\n /* called when a transport becomes connected; reattempt attach/detach\r\n * for channels that are attaching or detaching. */\r\n onTransportActive() {\r\n for (const channelName in this.all) {\r\n const channel = this.all[channelName];\r\n if (channel.state === 'attaching' || channel.state === 'detaching') {\r\n channel.checkPendingState();\r\n } else if (channel.state === 'suspended') {\r\n channel._attach(false, null);\r\n } else if (channel.state === 'attached') {\r\n // Note explicity request the state, channel.attach() would do nothing\r\n // as its already attached.\r\n channel.requestState('attaching');\r\n }\r\n }\r\n }\r\n\r\n /* Connection interruptions (ie when the connection will no longer queue\r\n * events) imply connection state changes for any channel which is either\r\n * attached, pending, or will attempt to become attached in the future */\r\n propogateConnectionInterruption(connectionState: string, reason: ErrorInfo) {\r\n const connectionStateToChannelState: Record<string, API.ChannelState> = {\r\n closing: 'detached',\r\n closed: 'detached',\r\n failed: 'failed',\r\n suspended: 'suspended',\r\n };\r\n const fromChannelStates = ['attaching', 'attached', 'detaching', 'suspended'];\r\n const toChannelState = connectionStateToChannelState[connectionState];\r\n\r\n for (const channelId in this.all) {\r\n const channel = this.all[channelId];\r\n if (fromChannelStates.includes(channel.state)) {\r\n channel.notifyState(toChannelState, reason);\r\n }\r\n }\r\n }\r\n\r\n get(name: string, channelOptions?: ChannelOptions) {\r\n name = String(name);\r\n let channel = this.all[name];\r\n if (!channel) {\r\n channel = this.all[name] = new RealtimeChannel(this.realtime, name, channelOptions);\r\n } else if (channelOptions) {\r\n if (channel._shouldReattachToSetOptions(channelOptions, channel.channelOptions)) {\r\n throw new ErrorInfo(\r\n 'Channels.get() cannot be used to set channel options that would cause the channel to reattach. Please, use RealtimeChannel.setOptions() instead.',\r\n 40000,\r\n 400,\r\n );\r\n }\r\n channel.setOptions(channelOptions);\r\n }\r\n return channel;\r\n }\r\n\r\n getDerived(name: string, deriveOptions: API.DeriveOptions, channelOptions?: ChannelOptions) {\r\n if (deriveOptions.filter) {\r\n const filter = Utils.toBase64(deriveOptions.filter);\r\n const match = Utils.matchDerivedChannel(name);\r\n name = `[filter=${filter}${match.qualifierParam}]${match.channelName}`;\r\n }\r\n return this.get(name, channelOptions);\r\n }\r\n\r\n /* Included to support certain niche use-cases; most users should ignore this.\r\n * Please do not use this unless you know what you're doing */\r\n release(name: string) {\r\n name = String(name);\r\n const channel = this.all[name];\r\n if (!channel) {\r\n return;\r\n }\r\n const releaseErr = channel.getReleaseErr();\r\n if (releaseErr) {\r\n throw releaseErr;\r\n }\r\n delete this.all[name];\r\n }\r\n}\r\n\r\nexport default BaseRealtime;\r\n","import * as Utils from '../util/utils';\r\nimport EventEmitter from '../util/eventemitter';\r\nimport Logger from '../util/logger';\r\nimport PresenceMessage, { fromValues as presenceMessageFromValues } from '../types/presencemessage';\r\n\r\nimport type RealtimePresence from './realtimepresence';\r\n\r\ntype compFn = (item: PresenceMessage, existing: PresenceMessage) => boolean;\r\n\r\nexport interface RealtimePresenceParams {\r\n waitForSync?: boolean;\r\n clientId?: string;\r\n connectionId?: string;\r\n}\r\n\r\nfunction newerThan(item: PresenceMessage, existing: PresenceMessage): boolean {\r\n /* RTP2b1: if either is synthesised, compare by timestamp */\r\n if (item.isSynthesized() || existing.isSynthesized()) {\r\n // RTP2b1a: if equal, prefer the newly-arrived one\r\n return (item.timestamp as number) >= (existing.timestamp as number);\r\n }\r\n\r\n /* RTP2b2 */\r\n const itemOrderings = item.parseId(),\r\n existingOrderings = existing.parseId();\r\n if (itemOrderings.msgSerial === existingOrderings.msgSerial) {\r\n return itemOrderings.index > existingOrderings.index;\r\n } else {\r\n return itemOrderings.msgSerial > existingOrderings.msgSerial;\r\n }\r\n}\r\n\r\nexport class PresenceMap extends EventEmitter {\r\n map: Record<string, PresenceMessage>;\r\n residualMembers: Record<string, PresenceMessage> | null;\r\n syncInProgress: boolean;\r\n presence: RealtimePresence;\r\n memberKey: (item: PresenceMessage) => string;\r\n newerThan: compFn;\r\n\r\n constructor(presence: RealtimePresence, memberKey: (item: PresenceMessage) => string, newer: compFn = newerThan) {\r\n super(presence.logger);\r\n this.presence = presence;\r\n this.map = Object.create(null);\r\n this.syncInProgress = false;\r\n this.residualMembers = null;\r\n this.memberKey = memberKey;\r\n this.newerThan = newer;\r\n }\r\n\r\n get(key: string) {\r\n return this.map[key];\r\n }\r\n\r\n getClient(clientId: string) {\r\n const map = this.map,\r\n result = [];\r\n for (const key in map) {\r\n const item = map[key];\r\n if (item.clientId == clientId && item.action != 'absent') result.push(item);\r\n }\r\n return result;\r\n }\r\n\r\n list(params: RealtimePresenceParams) {\r\n const map = this.map,\r\n clientId = params && params.clientId,\r\n connectionId = params && params.connectionId,\r\n result = [];\r\n\r\n for (const key in map) {\r\n const item = map[key];\r\n if (item.action === 'absent') continue;\r\n if (clientId && clientId != item.clientId) continue;\r\n if (connectionId && connectionId != item.connectionId) continue;\r\n result.push(item);\r\n }\r\n return result;\r\n }\r\n\r\n put(item: PresenceMessage) {\r\n if (item.action === 'enter' || item.action === 'update') {\r\n item = presenceMessageFromValues(item);\r\n item.action = 'present';\r\n }\r\n const map = this.map,\r\n key = this.memberKey(item);\r\n /* we've seen this member, so do not remove it at the end of sync */\r\n if (this.residualMembers) delete this.residualMembers[key];\r\n\r\n /* compare the timestamp of the new item with any existing member (or ABSENT witness) */\r\n const existingItem = map[key];\r\n if (existingItem && !this.newerThan(item, existingItem)) {\r\n return false;\r\n }\r\n map[key] = item;\r\n return true;\r\n }\r\n\r\n values() {\r\n const map = this.map,\r\n result = [];\r\n for (const key in map) {\r\n const item = map[key];\r\n if (item.action != 'absent') result.push(item);\r\n }\r\n return result;\r\n }\r\n\r\n remove(item: PresenceMessage) {\r\n const map = this.map,\r\n key = this.memberKey(item);\r\n const existingItem = map[key];\r\n\r\n if (existingItem && !this.newerThan(item, existingItem)) {\r\n return false;\r\n }\r\n\r\n /* RTP2f */\r\n if (this.syncInProgress) {\r\n item = presenceMessageFromValues(item);\r\n item.action = 'absent';\r\n map[key] = item;\r\n } else {\r\n delete map[key];\r\n }\r\n\r\n return !!existingItem;\r\n }\r\n\r\n startSync() {\r\n const map = this.map,\r\n syncInProgress = this.syncInProgress;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'PresenceMap.startSync()',\r\n 'channel = ' + this.presence.channel.name + '; syncInProgress = ' + syncInProgress,\r\n );\r\n /* we might be called multiple times while a sync is in progress */\r\n if (!this.syncInProgress) {\r\n this.residualMembers = Utils.copy(map);\r\n this.setInProgress(true);\r\n }\r\n }\r\n\r\n endSync() {\r\n const map = this.map,\r\n syncInProgress = this.syncInProgress;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'PresenceMap.endSync()',\r\n 'channel = ' + this.presence.channel.name + '; syncInProgress = ' + syncInProgress,\r\n );\r\n if (syncInProgress) {\r\n /* we can now strip out the ABSENT members, as we have\r\n * received all of the out-of-order sync messages */\r\n for (const memberKey in map) {\r\n const entry = map[memberKey];\r\n if (entry.action === 'absent') {\r\n delete map[memberKey];\r\n }\r\n }\r\n /* any members that were present at the start of the sync,\r\n * and have not been seen in sync, can be removed, and leave events emitted */\r\n this.presence._synthesizeLeaves(Utils.valuesArray(this.residualMembers as Record<string, PresenceMessage>));\r\n for (const memberKey in this.residualMembers) {\r\n delete map[memberKey];\r\n }\r\n this.residualMembers = null;\r\n\r\n /* finish, notifying any waiters */\r\n this.setInProgress(false);\r\n }\r\n this.emit('sync');\r\n }\r\n\r\n waitSync(callback: () => void) {\r\n const syncInProgress = this.syncInProgress;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'PresenceMap.waitSync()',\r\n 'channel = ' + this.presence.channel.name + '; syncInProgress = ' + syncInProgress,\r\n );\r\n if (!syncInProgress) {\r\n callback();\r\n return;\r\n }\r\n this.once('sync', callback);\r\n }\r\n\r\n clear() {\r\n this.map = {};\r\n this.setInProgress(false);\r\n this.residualMembers = null;\r\n }\r\n\r\n setInProgress(inProgress: boolean) {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'PresenceMap.setInProgress()', 'inProgress = ' + inProgress);\r\n this.syncInProgress = inProgress;\r\n this.presence.syncComplete = !inProgress;\r\n }\r\n}\r\n","import * as Utils from '../util/utils';\r\nimport EventEmitter from '../util/eventemitter';\r\nimport Logger from '../util/logger';\r\nimport PresenceMessage, {\r\n fromValues as presenceMessageFromValues,\r\n fromData as presenceMessageFromData,\r\n encode as encodePresenceMessage,\r\n} from '../types/presencemessage';\r\nimport ErrorInfo, { PartialErrorInfo } from '../types/errorinfo';\r\nimport RealtimeChannel from './realtimechannel';\r\nimport Multicaster from '../util/multicaster';\r\nimport ChannelStateChange from './channelstatechange';\r\nimport { CipherOptions } from '../types/message';\r\nimport { ErrCallback } from '../../types/utils';\r\nimport { PaginatedResult } from './paginatedresource';\r\nimport { PresenceMap, RealtimePresenceParams } from './presencemap';\r\n\r\ninterface RealtimeHistoryParams {\r\n start?: number;\r\n end?: number;\r\n direction?: string;\r\n limit?: number;\r\n untilAttach?: boolean;\r\n from_serial?: string | null;\r\n}\r\n\r\nfunction getClientId(realtimePresence: RealtimePresence) {\r\n return realtimePresence.channel.client.auth.clientId;\r\n}\r\n\r\nfunction isAnonymousOrWildcard(realtimePresence: RealtimePresence) {\r\n const realtime = realtimePresence.channel.client;\r\n /* If not currently connected, we can't assume that we're an anonymous\r\n * client, as realtime may inform us of our clientId in the CONNECTED\r\n * message. So assume we're not anonymous and leave it to realtime to\r\n * return an error if we are */\r\n const clientId = realtime.auth.clientId;\r\n return (!clientId || clientId === '*') && realtime.connection.state === 'connected';\r\n}\r\n\r\n/* Callback is called only in the event of an error */\r\nfunction waitAttached(channel: RealtimeChannel, callback: ErrCallback, action: () => void) {\r\n switch (channel.state) {\r\n case 'attached':\r\n case 'suspended':\r\n action();\r\n break;\r\n case 'initialized':\r\n case 'detached':\r\n case 'detaching':\r\n case 'attaching':\r\n Utils.whenPromiseSettles(channel.attach(), function (err: Error | null) {\r\n if (err) callback(err);\r\n else action();\r\n });\r\n break;\r\n default:\r\n callback(ErrorInfo.fromValues(channel.invalidStateError()));\r\n }\r\n}\r\n\r\nclass RealtimePresence extends EventEmitter {\r\n channel: RealtimeChannel;\r\n pendingPresence: { presence: PresenceMessage; callback: ErrCallback }[];\r\n syncComplete: boolean;\r\n members: PresenceMap;\r\n _myMembers: PresenceMap;\r\n subscriptions: EventEmitter;\r\n name?: string;\r\n\r\n constructor(channel: RealtimeChannel) {\r\n super(channel.logger);\r\n this.channel = channel;\r\n this.syncComplete = false;\r\n this.members = new PresenceMap(this, (item) => item.clientId + ':' + item.connectionId);\r\n // RTP17h: Store own members by clientId only.\r\n this._myMembers = new PresenceMap(this, (item) => item.clientId!);\r\n this.subscriptions = new EventEmitter(this.logger);\r\n this.pendingPresence = [];\r\n }\r\n\r\n async enter(data: unknown): Promise<void> {\r\n if (isAnonymousOrWildcard(this)) {\r\n throw new ErrorInfo('clientId must be specified to enter a presence channel', 40012, 400);\r\n }\r\n return this._enterOrUpdateClient(undefined, undefined, data, 'enter');\r\n }\r\n\r\n async update(data: unknown): Promise<void> {\r\n if (isAnonymousOrWildcard(this)) {\r\n throw new ErrorInfo('clientId must be specified to update presence data', 40012, 400);\r\n }\r\n return this._enterOrUpdateClient(undefined, undefined, data, 'update');\r\n }\r\n\r\n async enterClient(clientId: string, data: unknown): Promise<void> {\r\n return this._enterOrUpdateClient(undefined, clientId, data, 'enter');\r\n }\r\n\r\n async updateClient(clientId: string, data: unknown): Promise<void> {\r\n return this._enterOrUpdateClient(undefined, clientId, data, 'update');\r\n }\r\n\r\n async _enterOrUpdateClient(\r\n id: string | undefined,\r\n clientId: string | undefined,\r\n data: unknown,\r\n action: string,\r\n ): Promise<void> {\r\n const channel = this.channel;\r\n if (!channel.connectionManager.activeState()) {\r\n throw channel.connectionManager.getError();\r\n }\r\n\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'RealtimePresence.' + action + 'Client()',\r\n 'channel = ' + channel.name + ', id = ' + id + ', client = ' + (clientId || '(implicit) ' + getClientId(this)),\r\n );\r\n\r\n const presence = presenceMessageFromData(data);\r\n presence.action = action;\r\n if (id) {\r\n presence.id = id;\r\n }\r\n if (clientId) {\r\n presence.clientId = clientId;\r\n }\r\n\r\n await encodePresenceMessage(presence, channel.channelOptions as CipherOptions);\r\n switch (channel.state) {\r\n case 'attached':\r\n return new Promise((resolve, reject) => {\r\n channel.sendPresence(presence, (err) => (err ? reject(err) : resolve()));\r\n });\r\n case 'initialized':\r\n case 'detached':\r\n channel.attach();\r\n // eslint-disable-next-line no-fallthrough\r\n case 'attaching':\r\n return new Promise((resolve, reject) => {\r\n this.pendingPresence.push({\r\n presence: presence,\r\n callback: (err) => (err ? reject(err) : resolve()),\r\n });\r\n });\r\n default: {\r\n const err = new PartialErrorInfo(\r\n 'Unable to ' + action + ' presence channel while in ' + channel.state + ' state',\r\n 90001,\r\n );\r\n err.code = 90001;\r\n throw err;\r\n }\r\n }\r\n }\r\n\r\n async leave(data: unknown): Promise<void> {\r\n if (isAnonymousOrWildcard(this)) {\r\n throw new ErrorInfo('clientId must have been specified to enter or leave a presence channel', 40012, 400);\r\n }\r\n return this.leaveClient(undefined, data);\r\n }\r\n\r\n async leaveClient(clientId?: string, data?: unknown): Promise<void> {\r\n const channel = this.channel;\r\n if (!channel.connectionManager.activeState()) {\r\n throw channel.connectionManager.getError();\r\n }\r\n\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'RealtimePresence.leaveClient()',\r\n 'leaving; channel = ' + this.channel.name + ', client = ' + clientId,\r\n );\r\n const presence = presenceMessageFromData(data);\r\n presence.action = 'leave';\r\n if (clientId) {\r\n presence.clientId = clientId;\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n switch (channel.state) {\r\n case 'attached':\r\n channel.sendPresence(presence, (err) => (err ? reject(err) : resolve()));\r\n break;\r\n case 'attaching':\r\n this.pendingPresence.push({\r\n presence: presence,\r\n callback: (err) => (err ? reject(err) : resolve()),\r\n });\r\n break;\r\n case 'initialized':\r\n case 'failed': {\r\n /* we're not attached; therefore we let any entered status\r\n * timeout by itself instead of attaching just in order to leave */\r\n const err = new PartialErrorInfo('Unable to leave presence channel (incompatible state)', 90001);\r\n reject(err);\r\n break;\r\n }\r\n default:\r\n reject(channel.invalidStateError());\r\n }\r\n });\r\n }\r\n\r\n async get(params?: RealtimePresenceParams): Promise<PresenceMessage[]> {\r\n const waitForSync = !params || ('waitForSync' in params ? params.waitForSync : true);\r\n\r\n return new Promise((resolve, reject) => {\r\n function returnMembers(members: PresenceMap) {\r\n resolve(params ? members.list(params) : members.values());\r\n }\r\n\r\n /* Special-case the suspended state: can still get (stale) presence set if waitForSync is false */\r\n if (this.channel.state === 'suspended') {\r\n if (waitForSync) {\r\n reject(\r\n ErrorInfo.fromValues({\r\n statusCode: 400,\r\n code: 91005,\r\n message: 'Presence state is out of sync due to channel being in the SUSPENDED state',\r\n }),\r\n );\r\n } else {\r\n returnMembers(this.members);\r\n }\r\n return;\r\n }\r\n\r\n waitAttached(\r\n this.channel,\r\n (err) => reject(err),\r\n () => {\r\n const members = this.members;\r\n if (waitForSync) {\r\n members.waitSync(function () {\r\n returnMembers(members);\r\n });\r\n } else {\r\n returnMembers(members);\r\n }\r\n },\r\n );\r\n });\r\n }\r\n\r\n async history(params: RealtimeHistoryParams | null): Promise<PaginatedResult<PresenceMessage>> {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'RealtimePresence.history()', 'channel = ' + this.name);\r\n // We fetch this first so that any plugin-not-provided error takes priority over other errors\r\n const restMixin = this.channel.client.rest.presenceMixin;\r\n\r\n if (params && params.untilAttach) {\r\n if (this.channel.state === 'attached') {\r\n delete params.untilAttach;\r\n params.from_serial = this.channel.properties.attachSerial;\r\n } else {\r\n throw new ErrorInfo(\r\n 'option untilAttach requires the channel to be attached, was: ' + this.channel.state,\r\n 40000,\r\n 400,\r\n );\r\n }\r\n }\r\n\r\n return restMixin.history(this, params);\r\n }\r\n\r\n setPresence(presenceSet: PresenceMessage[], isSync: boolean, syncChannelSerial?: string): void {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'RealtimePresence.setPresence()',\r\n 'received presence for ' + presenceSet.length + ' participants; syncChannelSerial = ' + syncChannelSerial,\r\n );\r\n let syncCursor, match;\r\n const members = this.members,\r\n myMembers = this._myMembers,\r\n broadcastMessages = [],\r\n connId = this.channel.connectionManager.connectionId;\r\n\r\n if (isSync) {\r\n this.members.startSync();\r\n if (syncChannelSerial && (match = syncChannelSerial.match(/^[\\w-]+:(.*)$/))) {\r\n syncCursor = match[1];\r\n }\r\n }\r\n\r\n for (let i = 0; i < presenceSet.length; i++) {\r\n const presence = presenceMessageFromValues(presenceSet[i]);\r\n switch (presence.action) {\r\n case 'leave':\r\n if (members.remove(presence)) {\r\n broadcastMessages.push(presence);\r\n }\r\n if (presence.connectionId === connId && !presence.isSynthesized()) {\r\n myMembers.remove(presence);\r\n }\r\n break;\r\n case 'enter':\r\n case 'present':\r\n case 'update':\r\n if (members.put(presence)) {\r\n broadcastMessages.push(presence);\r\n }\r\n if (presence.connectionId === connId) {\r\n myMembers.put(presence);\r\n }\r\n break;\r\n }\r\n }\r\n /* if this is the last (or only) message in a sequence of sync updates, end the sync */\r\n if (isSync && !syncCursor) {\r\n members.endSync();\r\n this.channel.syncChannelSerial = null;\r\n }\r\n\r\n /* broadcast to listeners */\r\n for (let i = 0; i < broadcastMessages.length; i++) {\r\n const presence = broadcastMessages[i];\r\n this.subscriptions.emit(presence.action as string, presence);\r\n }\r\n }\r\n\r\n onAttached(hasPresence?: boolean): void {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'RealtimePresence.onAttached()',\r\n 'channel = ' + this.channel.name + ', hasPresence = ' + hasPresence,\r\n );\r\n\r\n if (hasPresence) {\r\n this.members.startSync();\r\n } else {\r\n this._synthesizeLeaves(this.members.values());\r\n this.members.clear();\r\n }\r\n\r\n // RTP17f: Re-enter own members when moving into the attached state.\r\n this._ensureMyMembersPresent();\r\n\r\n /* NB this must be after the _ensureMyMembersPresent call, which may add items to pendingPresence */\r\n const pendingPresence = this.pendingPresence,\r\n pendingPresCount = pendingPresence.length;\r\n\r\n if (pendingPresCount) {\r\n this.pendingPresence = [];\r\n const presenceArray = [];\r\n const multicaster = Multicaster.create(this.logger);\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'RealtimePresence.onAttached',\r\n 'sending ' + pendingPresCount + ' queued presence messages',\r\n );\r\n for (let i = 0; i < pendingPresCount; i++) {\r\n const event = pendingPresence[i];\r\n presenceArray.push(event.presence);\r\n multicaster.push(event.callback);\r\n }\r\n this.channel.sendPresence(presenceArray, multicaster);\r\n }\r\n }\r\n\r\n actOnChannelState(state: string, hasPresence?: boolean, err?: ErrorInfo | null): void {\r\n switch (state) {\r\n case 'attached':\r\n this.onAttached(hasPresence);\r\n break;\r\n case 'detached':\r\n case 'failed':\r\n this._clearMyMembers();\r\n this.members.clear();\r\n /* falls through */\r\n case 'suspended':\r\n this.failPendingPresence(err);\r\n break;\r\n }\r\n }\r\n\r\n failPendingPresence(err?: ErrorInfo | null): void {\r\n if (this.pendingPresence.length) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'RealtimeChannel.failPendingPresence',\r\n 'channel; name = ' + this.channel.name + ', err = ' + Utils.inspectError(err),\r\n );\r\n for (let i = 0; i < this.pendingPresence.length; i++)\r\n try {\r\n this.pendingPresence[i].callback(err);\r\n // eslint-disable-next-line no-empty\r\n } catch (e) {}\r\n this.pendingPresence = [];\r\n }\r\n }\r\n\r\n _clearMyMembers(): void {\r\n this._myMembers.clear();\r\n }\r\n\r\n _ensureMyMembersPresent(): void {\r\n const myMembers = this._myMembers;\r\n const connId = this.channel.connectionManager.connectionId;\r\n\r\n for (const memberKey in myMembers.map) {\r\n const entry = myMembers.map[memberKey];\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'RealtimePresence._ensureMyMembersPresent()',\r\n 'Auto-reentering clientId \"' + entry.clientId + '\" into the presence set',\r\n );\r\n // RTP17g: Send ENTER containing the member id, clientId and data\r\n // attributes.\r\n // RTP17g1: suppress id if the connId has changed\r\n const id = entry.connectionId === connId ? entry.id : undefined;\r\n this._enterOrUpdateClient(id, entry.clientId, entry.data, 'enter').catch((err) => {\r\n const wrappedErr = new ErrorInfo('Presence auto re-enter failed', 91004, 400, err);\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'RealtimePresence._ensureMyMembersPresent()',\r\n 'Presence auto re-enter failed; reason = ' + Utils.inspectError(err),\r\n );\r\n const change = new ChannelStateChange(this.channel.state, this.channel.state, true, false, wrappedErr);\r\n this.channel.emit('update', change);\r\n });\r\n }\r\n }\r\n\r\n _synthesizeLeaves(items: PresenceMessage[]): void {\r\n const subscriptions = this.subscriptions;\r\n items.forEach(function (item) {\r\n const presence = presenceMessageFromValues({\r\n action: 'leave',\r\n connectionId: item.connectionId,\r\n clientId: item.clientId,\r\n data: item.data,\r\n encoding: item.encoding,\r\n timestamp: Date.now(),\r\n });\r\n subscriptions.emit('leave', presence);\r\n });\r\n }\r\n\r\n async subscribe(..._args: unknown[] /* [event], listener */): Promise<void> {\r\n const args = RealtimeChannel.processListenerArgs(_args);\r\n const event = args[0];\r\n const listener = args[1];\r\n const channel = this.channel;\r\n\r\n if (channel.state === 'failed') {\r\n throw ErrorInfo.fromValues(channel.invalidStateError());\r\n }\r\n\r\n this.subscriptions.on(event, listener);\r\n await channel.attach();\r\n }\r\n\r\n unsubscribe(..._args: unknown[] /* [event], listener */): void {\r\n const args = RealtimeChannel.processListenerArgs(_args);\r\n const event = args[0];\r\n const listener = args[1];\r\n this.subscriptions.off(event, listener);\r\n }\r\n}\r\n\r\nexport default RealtimePresence;\r\n","import Platform from 'common/platform';\r\nimport * as Utils from '../util/utils';\r\nimport Transport from './transport';\r\nimport Defaults from '../util/defaults';\r\nimport Logger from '../util/logger';\r\nimport ProtocolMessage, {\r\n serialize as serializeProtocolMessage,\r\n deserialize as deserializeProtocolMessage,\r\n} from '../types/protocolmessage';\r\nimport ErrorInfo from '../types/errorinfo';\r\nimport NodeWebSocket from 'ws';\r\nimport ConnectionManager, { TransportParams } from './connectionmanager';\r\nimport Auth from '../client/auth';\r\nimport { TransportNames } from 'common/constants/TransportName';\r\n\r\nconst shortName = TransportNames.WebSocket;\r\n\r\nfunction isNodeWebSocket(ws: WebSocket | NodeWebSocket): ws is NodeWebSocket {\r\n return !!(ws as NodeWebSocket).on;\r\n}\r\n\r\nclass WebSocketTransport extends Transport {\r\n shortName = shortName;\r\n wsHost: string;\r\n uri?: string;\r\n wsConnection?: WebSocket | NodeWebSocket;\r\n\r\n constructor(connectionManager: ConnectionManager, auth: Auth, params: TransportParams) {\r\n super(connectionManager, auth, params);\r\n /* If is a browser, can't detect pings, so request protocol heartbeats */\r\n params.heartbeats = Platform.Config.useProtocolHeartbeats;\r\n this.wsHost = params.host as string;\r\n }\r\n\r\n static isAvailable() {\r\n return !!Platform.Config.WebSocket;\r\n }\r\n\r\n createWebSocket(uri: string, connectParams: Record<string, string>) {\r\n this.uri = uri + Utils.toQueryString(connectParams);\r\n return new Platform.Config.WebSocket(this.uri);\r\n }\r\n\r\n toString() {\r\n return 'WebSocketTransport; uri=' + this.uri;\r\n }\r\n\r\n connect() {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'WebSocketTransport.connect()', 'starting');\r\n Transport.prototype.connect.call(this);\r\n const self = this,\r\n params = this.params,\r\n options = params.options;\r\n const wsScheme = options.tls ? 'wss://' : 'ws://';\r\n const wsUri = wsScheme + this.wsHost + ':' + Defaults.getPort(options) + '/';\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'WebSocketTransport.connect()', 'uri: ' + wsUri);\r\n Utils.whenPromiseSettles(\r\n this.auth.getAuthParams(),\r\n function (err: ErrorInfo | null, authParams?: Record<string, string>) {\r\n if (self.isDisposed) {\r\n return;\r\n }\r\n let paramStr = '';\r\n for (const param in authParams) paramStr += ' ' + param + ': ' + authParams[param] + ';';\r\n Logger.logAction(\r\n self.logger,\r\n Logger.LOG_MINOR,\r\n 'WebSocketTransport.connect()',\r\n 'authParams:' + paramStr + ' err: ' + err,\r\n );\r\n if (err) {\r\n self.disconnect(err);\r\n return;\r\n }\r\n const connectParams = params.getConnectParams(authParams!);\r\n try {\r\n const wsConnection = (self.wsConnection = self.createWebSocket(wsUri, connectParams));\r\n wsConnection.binaryType = Platform.Config.binaryType;\r\n wsConnection.onopen = function () {\r\n self.onWsOpen();\r\n };\r\n wsConnection.onclose = function (ev: CloseEvent) {\r\n self.onWsClose(ev);\r\n };\r\n wsConnection.onmessage = function (ev: MessageEvent) {\r\n self.onWsData(ev.data);\r\n };\r\n wsConnection.onerror = function (ev: Event) {\r\n self.onWsError(ev as ErrorEvent);\r\n };\r\n if (isNodeWebSocket(wsConnection)) {\r\n /* node; browsers currently don't have a general eventemitter and can't detect\r\n * pings. Also, no need to reply with a pong explicitly, ws lib handles that */\r\n wsConnection.on('ping', function () {\r\n self.onActivity();\r\n });\r\n }\r\n } catch (e) {\r\n Logger.logAction(\r\n self.logger,\r\n Logger.LOG_ERROR,\r\n 'WebSocketTransport.connect()',\r\n 'Unexpected exception creating websocket: err = ' + ((e as Error).stack || (e as Error).message),\r\n );\r\n self.disconnect(e as Error);\r\n }\r\n },\r\n );\r\n }\r\n\r\n send(message: ProtocolMessage) {\r\n const wsConnection = this.wsConnection;\r\n if (!wsConnection) {\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'WebSocketTransport.send()', 'No socket connection');\r\n return;\r\n }\r\n try {\r\n (wsConnection as NodeWebSocket).send(\r\n serializeProtocolMessage(message, this.connectionManager.realtime._MsgPack, this.params.format),\r\n );\r\n } catch (e) {\r\n const msg = 'Exception from ws connection when trying to send: ' + Utils.inspectError(e);\r\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'WebSocketTransport.send()', msg);\r\n /* Don't try to request a disconnect, that'll just involve sending data\r\n * down the websocket again. Just finish the transport. */\r\n this.finish('disconnected', new ErrorInfo(msg, 50000, 500));\r\n }\r\n }\r\n\r\n onWsData(data: string) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MICRO,\r\n 'WebSocketTransport.onWsData()',\r\n 'data received; length = ' + data.length + '; type = ' + typeof data,\r\n );\r\n try {\r\n this.onProtocolMessage(\r\n deserializeProtocolMessage(\r\n data,\r\n this.connectionManager.realtime._MsgPack,\r\n this.connectionManager.realtime._RealtimePresence,\r\n this.format,\r\n ),\r\n );\r\n } catch (e) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'WebSocketTransport.onWsData()',\r\n 'Unexpected exception handing channel message: ' + (e as Error).stack,\r\n );\r\n }\r\n }\r\n\r\n onWsOpen() {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'WebSocketTransport.onWsOpen()', 'opened WebSocket');\r\n this.emit('preconnect');\r\n }\r\n\r\n onWsClose(ev: number | CloseEvent) {\r\n let wasClean, code;\r\n if (typeof ev == 'object') {\r\n /* W3C spec-compatible */\r\n code = ev.code;\r\n // ev.wasClean is undefined in reactnative\r\n wasClean = ev.wasClean || code === 1000;\r\n } /*if(typeof(ev) == 'number')*/ else {\r\n /* ws in node */\r\n code = ev;\r\n wasClean = code == 1000;\r\n }\r\n delete this.wsConnection;\r\n if (wasClean) {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'WebSocketTransport.onWsClose()', 'Cleanly closed WebSocket');\r\n const err = new ErrorInfo('Websocket closed', 80003, 400);\r\n this.finish('disconnected', err);\r\n } else {\r\n const msg = 'Unclean disconnection of WebSocket ; code = ' + code,\r\n err = new ErrorInfo(msg, 80003, 400);\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'WebSocketTransport.onWsClose()', msg);\r\n this.finish('disconnected', err);\r\n }\r\n this.emit('disposed');\r\n }\r\n\r\n onWsError(err: ErrorEvent) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'WebSocketTransport.onError()',\r\n 'Error from WebSocket: ' + err.message,\r\n );\r\n /* Wait a tick before aborting: if the websocket was connected, this event\r\n * will be immediately followed by an onclose event with a close code. Allow\r\n * that to close it (so we see the close code) rather than anticipating it */\r\n Platform.Config.nextTick(() => {\r\n this.disconnect(Error(err.message));\r\n });\r\n }\r\n\r\n dispose() {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'WebSocketTransport.dispose()', '');\r\n this.isDisposed = true;\r\n const wsConnection = this.wsConnection;\r\n if (wsConnection) {\r\n /* Ignore any messages that come through after dispose() is called but before\r\n * websocket is actually closed. (mostly would be harmless, but if it's a\r\n * CONNECTED, it'll re-tick isConnected and cause all sorts of havoc) */\r\n wsConnection.onmessage = function () {};\r\n delete this.wsConnection;\r\n /* defer until the next event loop cycle before closing the socket,\r\n * giving some implementations the opportunity to send any outstanding close message */\r\n Platform.Config.nextTick(() => {\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'WebSocketTransport.dispose()', 'closing websocket');\r\n if (!wsConnection) {\r\n throw new Error('WebSocketTransport.dispose(): wsConnection is not defined');\r\n }\r\n wsConnection.close();\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default WebSocketTransport;\r\n","import * as API from '../../../../ably';\nimport RealtimeChannel from './realtimechannel';\nimport Message from '../types/message';\n\nexport class FilteredSubscriptions {\n static subscribeFilter(channel: RealtimeChannel, filter: API.MessageFilter, listener: API.messageCallback<Message>) {\n const filteredListener = (m: Message) => {\n const mapping: { [key in keyof API.MessageFilter]: any } = {\n name: m.name,\n refTimeserial: m.extras?.ref?.timeserial,\n refType: m.extras?.ref?.type,\n isRef: !!m.extras?.ref?.timeserial,\n clientId: m.clientId,\n };\n // Check if any values are defined in the filter and if they match the value in the message object\n if (\n Object.entries(filter).find(([key, value]) =>\n value !== undefined ? mapping[key as keyof API.MessageFilter] !== value : false,\n )\n ) {\n return;\n }\n listener(m);\n };\n this.addFilteredSubscription(channel, filter, listener, filteredListener);\n channel.subscriptions.on(filteredListener);\n }\n\n // Adds a new filtered subscription\n static addFilteredSubscription(\n channel: RealtimeChannel,\n filter: API.MessageFilter,\n realListener: API.messageCallback<Message>,\n filteredListener: API.messageCallback<Message>,\n ) {\n if (!channel.filteredSubscriptions) {\n channel.filteredSubscriptions = new Map<\n API.messageCallback<Message>,\n Map<API.MessageFilter, API.messageCallback<Message>[]>\n >();\n }\n if (channel.filteredSubscriptions.has(realListener)) {\n const realListenerMap = channel.filteredSubscriptions.get(realListener) as Map<\n API.MessageFilter,\n API.messageCallback<Message>[]\n >;\n // Add the filtered listener to the map, or append to the array if this filter has already been used\n realListenerMap.set(filter, realListenerMap?.get(filter)?.concat(filteredListener) || [filteredListener]);\n } else {\n channel.filteredSubscriptions.set(\n realListener,\n new Map<API.MessageFilter, API.messageCallback<Message>[]>([[filter, [filteredListener]]]),\n );\n }\n }\n\n static getAndDeleteFilteredSubscriptions(\n channel: RealtimeChannel,\n filter: API.MessageFilter | undefined,\n realListener: API.messageCallback<Message> | undefined,\n ): API.messageCallback<Message>[] {\n // No filtered subscriptions map means there has been no filtered subscriptions yet, so return nothing\n if (!channel.filteredSubscriptions) {\n return [];\n }\n // Only a filter is passed in with no specific listener\n if (!realListener && filter) {\n // Return each listener which is attached to the specified filter object\n return Array.from(channel.filteredSubscriptions.entries())\n .map(([key, filterMaps]) => {\n // Get (then delete) the maps matching this filter\n let listenerMaps = filterMaps.get(filter);\n filterMaps.delete(filter);\n // Clear the parent if nothing is left\n if (filterMaps.size === 0) {\n channel.filteredSubscriptions?.delete(key);\n }\n return listenerMaps;\n })\n .reduce(\n (prev, cur) => (cur ? (prev as API.messageCallback<Message>[]).concat(...cur) : prev),\n [],\n ) as API.messageCallback<Message>[];\n }\n\n // No subscriptions for this listener\n if (!realListener || !channel.filteredSubscriptions.has(realListener)) {\n return [];\n }\n const realListenerMap = channel.filteredSubscriptions.get(realListener) as Map<\n API.MessageFilter,\n API.messageCallback<Message>[]\n >;\n // If no filter is specified return all listeners using that function\n if (!filter) {\n // array.flat is not available unless we support es2019 or higher\n const listeners = Array.from(realListenerMap.values()).reduce((prev, cur) => prev.concat(...cur), []);\n // remove the listener from the map\n channel.filteredSubscriptions.delete(realListener);\n return listeners;\n }\n\n let listeners = realListenerMap.get(filter);\n realListenerMap.delete(filter);\n\n return listeners || [];\n }\n}\n","import BaseRealtime from './baserealtime';\r\nimport ClientOptions from '../../types/ClientOptions';\r\nimport { allCommonModularPlugins } from './modularplugins';\r\nimport * as Utils from '../util/utils';\r\nimport ConnectionManager from '../transport/connectionmanager';\r\nimport ProtocolMessage from '../types/protocolmessage';\r\nimport Platform from 'common/platform';\r\nimport { DefaultMessage } from '../types/defaultmessage';\r\nimport { MsgPack } from 'common/types/msgpack';\r\nimport RealtimePresence from './realtimepresence';\r\nimport { DefaultPresenceMessage } from '../types/defaultpresencemessage';\r\nimport WebSocketTransport from '../transport/websockettransport';\r\nimport { FilteredSubscriptions } from './filteredsubscriptions';\r\nimport { PresenceMap } from './presencemap';\r\nimport {\r\n fromValues as presenceMessageFromValues,\r\n fromValuesArray as presenceMessagesFromValuesArray,\r\n fromWireProtocol as presenceMessageFromWireProtocol,\r\n} from '../types/presencemessage';\r\nimport { Http } from 'common/types/http';\r\nimport Defaults from '../util/defaults';\r\nimport Logger from '../util/logger';\r\n\r\n/**\r\n `DefaultRealtime` is the class that the non tree-shakable version of the SDK exports as `Realtime`. It ensures that this version of the SDK includes all of the functionality which is optionally available in the tree-shakable version.\r\n */\r\nexport class DefaultRealtime extends BaseRealtime {\r\n // The public typings declare that this requires an argument to be passed, but since we want to emit a good error message in the case where a non-TypeScript user does not pass an argument, tell the compiler that this is possible so that it forces us to handle it.\r\n constructor(options?: ClientOptions | string) {\r\n const MsgPack = DefaultRealtime._MsgPack;\r\n if (!MsgPack) {\r\n throw new Error('Expected DefaultRealtime._MsgPack to have been set');\r\n }\r\n\r\n super(\r\n Defaults.objectifyOptions(options, true, 'Realtime', Logger.defaultLogger, {\r\n ...allCommonModularPlugins,\r\n Crypto: DefaultRealtime.Crypto ?? undefined,\r\n MsgPack,\r\n RealtimePresence: {\r\n RealtimePresence,\r\n presenceMessageFromValues,\r\n presenceMessagesFromValuesArray,\r\n presenceMessageFromWireProtocol,\r\n },\r\n WebSocketTransport,\r\n MessageInteractions: FilteredSubscriptions,\r\n }),\r\n );\r\n }\r\n\r\n static Utils = Utils;\r\n static ConnectionManager = ConnectionManager;\r\n static ProtocolMessage = ProtocolMessage;\r\n\r\n private static _Crypto: typeof Platform.Crypto = null;\r\n static get Crypto() {\r\n if (this._Crypto === null) {\r\n throw new Error('Encryption not enabled; use ably.encryption.js instead');\r\n }\r\n\r\n return this._Crypto;\r\n }\r\n static set Crypto(newValue: typeof Platform.Crypto) {\r\n this._Crypto = newValue;\r\n }\r\n\r\n static Message = DefaultMessage;\r\n static PresenceMessage = DefaultPresenceMessage;\r\n\r\n static _MsgPack: MsgPack | null = null;\r\n\r\n // Used by tests\r\n static _Http = Http;\r\n static _PresenceMap = PresenceMap;\r\n}\r\n","/**\n * Copied from https://gist.github.com/stevendesu/2d52f7b5e1f1184af3b667c0b5e054b8\n *\n * \"A simple, open-source, HMAC-SHA256 implementation in pure JavaScript. Designed for efficient minification.\"\n *\n * I asked about licensing, and the author said:\n *\n * > Feel free to use it however you'd like 😄 As the gist title indicates,\n * > this is \"a simple open source implementation\". Feel free to choose whatever\n * > license you find most permissible, but I offer no warranty for the code.\n * > It's 100% free to do with as you please.\n */\n\n// To ensure cross-browser support even without a proper SubtleCrypto\n// impelmentation (or without access to the impelmentation, as is the case with\n// Chrome loaded over HTTP instead of HTTPS), this library can create SHA-256\n// HMAC signatures using nothing but raw JavaScript\n\n/* eslint-disable no-magic-numbers, id-length, no-param-reassign, new-cap */\n\n// By giving internal functions names that we can mangle, future calls to\n// them are reduced to a single byte (minor space savings in minified file)\nvar uint8Array = Uint8Array;\nvar uint32Array = Uint32Array;\nvar pow = Math.pow;\n\n// Will be initialized below\n// Using a Uint32Array instead of a simple array makes the minified code\n// a bit bigger (we lose our `unshift()` hack), but comes with huge\n// performance gains\nvar DEFAULT_STATE = new uint32Array(8);\nvar ROUND_CONSTANTS: number[] = [];\n\n// Reusable object for expanded message\n// Using a Uint32Array instead of a simple array makes the minified code\n// 7 bytes larger, but comes with huge performance gains\nvar M = new uint32Array(64);\n\n// After minification the code to compute the default state and round\n// constants is smaller than the output. More importantly, this serves as a\n// good educational aide for anyone wondering where the magic numbers come\n// from. No magic numbers FTW!\nfunction getFractionalBits(n: number) {\n return ((n - (n | 0)) * pow(2, 32)) | 0;\n}\n\nvar n = 2,\n nPrime = 0;\nwhile (nPrime < 64) {\n // isPrime() was in-lined from its original function form to save\n // a few bytes\n var isPrime = true;\n // Math.sqrt() was replaced with pow(n, 1/2) to save a few bytes\n // var sqrtN = pow(n, 1 / 2);\n // So technically to determine if a number is prime you only need to\n // check numbers up to the square root. However this function only runs\n // once and we're only computing the first 64 primes (up to 311), so on\n // any modern CPU this whole function runs in a couple milliseconds.\n // By going to n / 2 instead of sqrt(n) we net 8 byte savings and no\n // scaling performance cost\n for (var factor = 2; factor <= n / 2; factor++) {\n if (n % factor === 0) {\n isPrime = false;\n }\n }\n if (isPrime) {\n if (nPrime < 8) {\n DEFAULT_STATE[nPrime] = getFractionalBits(pow(n, 1 / 2));\n }\n ROUND_CONSTANTS[nPrime] = getFractionalBits(pow(n, 1 / 3));\n\n nPrime++;\n }\n\n n++;\n}\n\n// For cross-platform support we need to ensure that all 32-bit words are\n// in the same endianness. A UTF-8 TextEncoder will return BigEndian data,\n// so upon reading or writing to our ArrayBuffer we'll only swap the bytes\n// if our system is LittleEndian (which is about 99% of CPUs)\nvar LittleEndian = !!new uint8Array(new uint32Array([1]).buffer)[0];\n\nfunction convertEndian(word: number) {\n if (LittleEndian) {\n return (\n // byte 1 -> byte 4\n (word >>> 24) |\n // byte 2 -> byte 3\n (((word >>> 16) & 0xff) << 8) |\n // byte 3 -> byte 2\n ((word & 0xff00) << 8) |\n // byte 4 -> byte 1\n (word << 24)\n );\n } else {\n return word;\n }\n}\n\nfunction rightRotate(word: number, bits: number) {\n return (word >>> bits) | (word << (32 - bits));\n}\n\nfunction sha256(data: Uint8Array) {\n // Copy default state\n var STATE = DEFAULT_STATE.slice();\n\n // Caching this reduces occurrences of \".length\" in minified JavaScript\n // 3 more byte savings! :D\n var legth = data.length;\n\n // Pad data\n var bitLength = legth * 8;\n var newBitLength = 512 - ((bitLength + 64) % 512) - 1 + bitLength + 65;\n\n // \"bytes\" and \"words\" are stored BigEndian\n var bytes = new uint8Array(newBitLength / 8);\n var words = new uint32Array(bytes.buffer);\n\n bytes.set(data, 0);\n // Append a 1\n bytes[legth] = 0b10000000;\n // Store length in BigEndian\n words[words.length - 1] = convertEndian(bitLength);\n\n // Loop iterator (avoid two instances of \"var\") -- saves 2 bytes\n var round;\n\n // Process blocks (512 bits / 64 bytes / 16 words at a time)\n for (var block = 0; block < newBitLength / 32; block += 16) {\n var workingState = STATE.slice();\n\n // Rounds\n for (round = 0; round < 64; round++) {\n var MRound;\n // Expand message\n if (round < 16) {\n // Convert to platform Endianness for later math\n MRound = convertEndian(words[block + round]);\n } else {\n var gamma0x = M[round - 15];\n var gamma1x = M[round - 2];\n MRound =\n M[round - 7] +\n M[round - 16] +\n (rightRotate(gamma0x, 7) ^ rightRotate(gamma0x, 18) ^ (gamma0x >>> 3)) +\n (rightRotate(gamma1x, 17) ^ rightRotate(gamma1x, 19) ^ (gamma1x >>> 10));\n }\n\n // M array matches platform endianness\n M[round] = MRound |= 0;\n\n // Computation\n var t1 =\n (rightRotate(workingState[4], 6) ^ rightRotate(workingState[4], 11) ^ rightRotate(workingState[4], 25)) +\n ((workingState[4] & workingState[5]) ^ (~workingState[4] & workingState[6])) +\n workingState[7] +\n MRound +\n ROUND_CONSTANTS[round];\n var t2 =\n (rightRotate(workingState[0], 2) ^ rightRotate(workingState[0], 13) ^ rightRotate(workingState[0], 22)) +\n ((workingState[0] & workingState[1]) ^ (workingState[2] & (workingState[0] ^ workingState[1])));\n for (var i = 7; i > 0; i--) {\n workingState[i] = workingState[i - 1];\n }\n workingState[0] = (t1 + t2) | 0;\n workingState[4] = (workingState[4] + t1) | 0;\n }\n\n // Update state\n for (round = 0; round < 8; round++) {\n STATE[round] = (STATE[round] + workingState[round]) | 0;\n }\n }\n\n // Finally the state needs to be converted to BigEndian for output\n // And we want to return a Uint8Array, not a Uint32Array\n return new uint8Array(\n new uint32Array(\n STATE.map(function (val) {\n return convertEndian(val);\n }),\n ).buffer,\n );\n}\n\nexport function hmac(key: Uint8Array, data: Uint8Array) {\n if (key.length > 64) key = sha256(key);\n\n if (key.length < 64) {\n const tmp = new Uint8Array(64);\n tmp.set(key, 0);\n key = tmp;\n }\n\n // Generate inner and outer keys\n var innerKey = new Uint8Array(64);\n var outerKey = new Uint8Array(64);\n for (var i = 0; i < 64; i++) {\n innerKey[i] = 0x36 ^ key[i];\n outerKey[i] = 0x5c ^ key[i];\n }\n\n // Append the innerKey\n var msg = new Uint8Array(data.length + 64);\n msg.set(innerKey, 0);\n msg.set(data, 64);\n\n // Has the previous message and append the outerKey\n var result = new Uint8Array(64 + 32);\n result.set(outerKey, 0);\n result.set(sha256(msg), 64);\n\n // Hash the previous message\n return sha256(result);\n}\n","import Platform from 'common/platform';\nimport IBufferUtils from 'common/types/IBufferUtils';\nimport { hmac as hmacSha256 } from './hmac-sha256';\n\n/* Most BufferUtils methods that return a binary object return an ArrayBuffer\n * The exception is toBuffer, which returns a Uint8Array */\n\nexport type Bufferlike = BufferSource;\nexport type Output = Bufferlike;\nexport type ToBufferOutput = Uint8Array;\n\nclass BufferUtils implements IBufferUtils<Bufferlike, Output, ToBufferOutput> {\n base64CharSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n hexCharSet = '0123456789abcdef';\n\n // https://gist.githubusercontent.com/jonleighton/958841/raw/f200e30dfe95212c0165ccf1ae000ca51e9de803/gistfile1.js\n private uint8ViewToBase64(bytes: Uint8Array): string {\n let base64 = '';\n const encodings = this.base64CharSet;\n\n const byteLength = bytes.byteLength;\n const byteRemainder = byteLength % 3;\n const mainLength = byteLength - byteRemainder;\n\n let a, b, c, d;\n let chunk;\n\n // Main loop deals with bytes in chunks of 3\n for (let i = 0; i < mainLength; i = i + 3) {\n // Combine the three bytes into a single integer\n chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];\n\n // Use bitmasks to extract 6-bit segments from the triplet\n a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18\n b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12\n c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6\n d = chunk & 63; // 63 = 2^6 - 1\n\n // Convert the raw binary segments to the appropriate ASCII encoding\n base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];\n }\n\n // Deal with the remaining bytes and padding\n if (byteRemainder == 1) {\n chunk = bytes[mainLength];\n\n a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2\n\n // Set the 4 least significant bits to zero\n b = (chunk & 3) << 4; // 3 = 2^2 - 1\n\n base64 += encodings[a] + encodings[b] + '==';\n } else if (byteRemainder == 2) {\n chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];\n\n a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10\n b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4\n\n // Set the 2 least significant bits to zero\n c = (chunk & 15) << 2; // 15 = 2^4 - 1\n\n base64 += encodings[a] + encodings[b] + encodings[c] + '=';\n }\n\n return base64;\n }\n\n private base64ToArrayBuffer(base64: string): Output {\n const binary_string = atob?.(base64) as string; // this will always be defined in browser so it's safe to cast\n const len = binary_string.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n const ascii = binary_string.charCodeAt(i);\n bytes[i] = ascii;\n }\n return this.toArrayBuffer(bytes);\n }\n\n isBuffer(buffer: unknown): buffer is Bufferlike {\n return buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer);\n }\n\n toBuffer(buffer: Bufferlike): ToBufferOutput {\n if (!ArrayBuffer) {\n throw new Error(\"Can't convert to Buffer: browser does not support the necessary types\");\n }\n\n if (buffer instanceof ArrayBuffer) {\n return new Uint8Array(buffer);\n }\n\n if (ArrayBuffer.isView(buffer)) {\n return new Uint8Array(this.toArrayBuffer(buffer));\n }\n\n throw new Error('BufferUtils.toBuffer expected an ArrayBuffer or a view onto one');\n }\n\n toArrayBuffer(buffer: Bufferlike): ArrayBuffer {\n if (!ArrayBuffer) {\n throw new Error(\"Can't convert to ArrayBuffer: browser does not support the necessary types\");\n }\n\n if (buffer instanceof ArrayBuffer) {\n return buffer;\n }\n\n if (ArrayBuffer.isView(buffer)) {\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);\n }\n\n throw new Error('BufferUtils.toArrayBuffer expected an ArrayBuffer or a view onto one');\n }\n\n base64Encode(buffer: Bufferlike): string {\n return this.uint8ViewToBase64(this.toBuffer(buffer));\n }\n\n base64Decode(str: string): Output {\n if (ArrayBuffer && Platform.Config.atob) {\n return this.base64ToArrayBuffer(str);\n } else {\n throw new Error('Expected ArrayBuffer to exist and Platform.Config.atob to be configured');\n }\n }\n\n hexEncode(buffer: Bufferlike): string {\n const uint8Array = this.toBuffer(buffer);\n return uint8Array.reduce((accum, byte) => accum + byte.toString(16).padStart(2, '0'), '');\n }\n\n hexDecode(hexEncodedBytes: string): Output {\n if (hexEncodedBytes.length % 2 !== 0) {\n throw new Error(\"Can't create a byte array from a hex string of odd length\");\n }\n\n const uint8Array = new Uint8Array(hexEncodedBytes.length / 2);\n\n for (let i = 0; i < uint8Array.length; i++) {\n uint8Array[i] = parseInt(hexEncodedBytes.slice(2 * i, 2 * (i + 1)), 16);\n }\n\n return this.toArrayBuffer(uint8Array);\n }\n\n utf8Encode(string: string): Output {\n if (Platform.Config.TextEncoder) {\n const encodedByteArray = new Platform.Config.TextEncoder().encode(string);\n return this.toArrayBuffer(encodedByteArray);\n } else {\n throw new Error('Expected TextEncoder to be configured');\n }\n }\n\n /* For utf8 decoding we apply slightly stricter input validation than to\n * hexEncode/base64Encode/etc: in those we accept anything that Buffer.from\n * can take (in particular allowing strings, which are just interpreted as\n * binary); here we ensure that the input is actually a buffer since trying\n * to utf8-decode a string to another string is almost certainly a mistake */\n utf8Decode(buffer: Bufferlike): string {\n if (!this.isBuffer(buffer)) {\n throw new Error('Expected input of utf8decode to be an arraybuffer or typed array');\n }\n if (TextDecoder) {\n return new TextDecoder().decode(buffer);\n } else {\n throw new Error('Expected TextDecoder to be configured');\n }\n }\n\n areBuffersEqual(buffer1: Bufferlike, buffer2: Bufferlike): boolean {\n if (!buffer1 || !buffer2) return false;\n const arrayBuffer1 = this.toArrayBuffer(buffer1);\n const arrayBuffer2 = this.toArrayBuffer(buffer2);\n\n if (arrayBuffer1.byteLength != arrayBuffer2.byteLength) return false;\n\n const bytes1 = new Uint8Array(arrayBuffer1);\n const bytes2 = new Uint8Array(arrayBuffer2);\n\n for (var i = 0; i < bytes1.length; i++) {\n if (bytes1[i] != bytes2[i]) return false;\n }\n return true;\n }\n\n byteLength(buffer: Bufferlike): number {\n if (buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer)) {\n return buffer.byteLength;\n }\n return -1;\n }\n\n arrayBufferViewToBuffer(arrayBufferView: ArrayBufferView): ArrayBuffer {\n return this.toArrayBuffer(arrayBufferView);\n }\n\n hmacSha256(message: Bufferlike, key: Bufferlike): Output {\n const hash = hmacSha256(this.toBuffer(key), this.toBuffer(message));\n return this.toArrayBuffer(hash);\n }\n}\n\nexport default new BufferUtils();\n","import Logger from '../../../../common/lib/util/logger';\nimport ErrorInfo from 'common/lib/types/errorinfo';\nimport * as API from '../../../../../ably';\nimport ICryptoStatic, { IGetCipherParams } from '../../../../common/types/ICryptoStatic';\nimport ICipher from '../../../../common/types/ICipher';\nimport { CryptoDataTypes } from '../../../../common/types/cryptoDataTypes';\nimport BufferUtils, { Bufferlike, Output as BufferUtilsOutput } from './bufferutils';\nimport { IPlatformConfig } from 'common/types/IPlatformConfig';\n\n// The type to which ./msgpack.ts deserializes elements of the `bin` or `ext` type\ntype MessagePackBinaryType = ArrayBuffer;\n\ntype IV = CryptoDataTypes.IV<BufferUtilsOutput>;\ntype InputPlaintext = CryptoDataTypes.InputPlaintext<Bufferlike, BufferUtilsOutput>;\ntype OutputCiphertext = ArrayBuffer;\ntype InputCiphertext = CryptoDataTypes.InputCiphertext<MessagePackBinaryType, BufferUtilsOutput>;\ntype OutputPlaintext = ArrayBuffer;\n\nvar createCryptoClass = function (config: IPlatformConfig, bufferUtils: typeof BufferUtils) {\n var DEFAULT_ALGORITHM = 'aes';\n var DEFAULT_KEYLENGTH = 256; // bits\n var DEFAULT_MODE = 'cbc';\n var DEFAULT_BLOCKLENGTH = 16; // bytes\n\n /**\n * Internal: checks that the cipherParams are a valid combination. Currently\n * just checks that the calculated keyLength is a valid one for aes-cbc\n */\n function validateCipherParams(params: API.CipherParams) {\n if (params.algorithm === 'aes' && params.mode === 'cbc') {\n if (params.keyLength === 128 || params.keyLength === 256) {\n return;\n }\n throw new Error(\n 'Unsupported key length ' +\n params.keyLength +\n ' for aes-cbc encryption. Encryption key must be 128 or 256 bits (16 or 32 ASCII characters)',\n );\n }\n }\n\n function normaliseBase64(string: string) {\n /* url-safe base64 strings use _ and - instread of / and + */\n return string.replace('_', '/').replace('-', '+');\n }\n\n function isCipherParams(params: API.CipherParams | API.CipherParamOptions): params is API.CipherParams {\n // Although API.CipherParams is an interface, the documentation for its `key` property makes it clear that the only valid way to form one is by using getDefaultParams. The implementation of getDefaultParams returns an instance of CipherParams.\n return params instanceof CipherParams;\n }\n\n /**\n * A class encapsulating the client-specifiable parameters for\n * the cipher.\n *\n * algorithm is the name of the algorithm in the default system provider,\n * or the lower-cased version of it; eg \"aes\" or \"AES\".\n *\n * Clients are recommended to not call this directly, but instead to use the\n * Crypto.getDefaultParams helper, which will fill in any fields not supplied\n * with default values and validation the result.\n */\n class CipherParams implements API.CipherParams {\n algorithm: string;\n keyLength: number;\n mode: string;\n key: ArrayBuffer;\n\n constructor(algorithm: string, keyLength: number, mode: string, key: ArrayBuffer) {\n this.algorithm = algorithm;\n this.keyLength = keyLength;\n this.mode = mode;\n this.key = key;\n }\n }\n\n /**\n * Utility classes and interfaces for message payload encryption.\n *\n * This class supports AES/CBC/PKCS5 with a default keylength of 128 bits\n * but supporting other keylengths. Other algorithms and chaining modes are\n * not supported directly, but supportable by extending/implementing the base\n * classes and interfaces here.\n *\n * Secure random data for creation of Initialization Vectors (IVs) and keys\n * is obtained from window.crypto.getRandomValues.\n *\n * Each message payload is encrypted with an IV in CBC mode, and the IV is\n * concatenated with the resulting raw ciphertext to construct the \"ciphertext\"\n * data passed to the recipient.\n */\n class Crypto {\n static CipherParams = CipherParams;\n\n /**\n * Obtain a complete CipherParams instance from the provided params, filling\n * in any not provided with default values, calculating a keyLength from\n * the supplied key, and validating the result.\n * @param params an object containing at a minimum a `key` key with value the\n * key, as either a binary or a base64-encoded string.\n * May optionally also contain: algorithm (defaults to AES),\n * mode (defaults to 'cbc')\n */\n static getDefaultParams(params: API.CipherParamOptions) {\n var key: ArrayBuffer;\n\n if (!params.key) {\n throw new Error('Crypto.getDefaultParams: a key is required');\n }\n\n if (typeof params.key === 'string') {\n key = bufferUtils.toArrayBuffer(bufferUtils.base64Decode(normaliseBase64(params.key)));\n } else if (params.key instanceof ArrayBuffer) {\n key = params.key;\n } else {\n key = bufferUtils.toArrayBuffer(params.key);\n }\n\n var algorithm = params.algorithm || DEFAULT_ALGORITHM;\n var keyLength = key.byteLength * 8;\n var mode = params.mode || DEFAULT_MODE;\n var cipherParams = new CipherParams(algorithm, keyLength, mode, key);\n\n if (params.keyLength && params.keyLength !== cipherParams.keyLength) {\n throw new Error(\n 'Crypto.getDefaultParams: a keyLength of ' +\n params.keyLength +\n ' was specified, but the key actually has length ' +\n cipherParams.keyLength,\n );\n }\n\n validateCipherParams(cipherParams);\n return cipherParams;\n }\n\n /**\n * Generate a random encryption key from the supplied keylength (or the\n * default keyLength if none supplied) as an ArrayBuffer\n * @param keyLength (optional) the required keyLength in bits\n */\n static async generateRandomKey(keyLength?: number): Promise<API.CipherKey> {\n try {\n return config.getRandomArrayBuffer((keyLength || DEFAULT_KEYLENGTH) / 8);\n } catch (err) {\n throw new ErrorInfo('Failed to generate random key: ' + (err as Error).message, 400, 50000, err as Error);\n }\n }\n\n /**\n * Internal; get a ChannelCipher instance based on the given cipherParams\n * @param params either a CipherParams instance or some subset of its\n * fields that includes a key\n */\n static getCipher(params: IGetCipherParams<IV>, logger: Logger) {\n var cipherParams = isCipherParams(params) ? (params as CipherParams) : this.getDefaultParams(params);\n\n return {\n cipherParams: cipherParams,\n cipher: new CBCCipher(cipherParams, params.iv ?? null, logger),\n };\n }\n }\n\n Crypto satisfies ICryptoStatic<IV, InputPlaintext, OutputCiphertext, InputCiphertext, OutputPlaintext>;\n\n class CBCCipher implements ICipher<InputPlaintext, OutputCiphertext, InputCiphertext, OutputPlaintext> {\n algorithm: string;\n webCryptoAlgorithm: string;\n key: ArrayBuffer;\n iv: ArrayBuffer | null;\n\n constructor(\n params: CipherParams,\n iv: IV | null,\n private readonly logger: Logger,\n ) {\n if (!crypto.subtle) {\n if (isSecureContext) {\n throw new Error(\n 'Crypto operations are not possible since the browser’s SubtleCrypto class is unavailable (reason unknown).',\n );\n } else {\n throw new Error(\n 'Crypto operations are is not possible since the current environment is a non-secure context and hence the browser’s SubtleCrypto class is not available.',\n );\n }\n }\n\n this.algorithm = params.algorithm + '-' + String(params.keyLength) + '-' + params.mode;\n this.webCryptoAlgorithm = params.algorithm + '-' + params.mode;\n this.key = bufferUtils.toArrayBuffer(params.key);\n this.iv = iv ? bufferUtils.toArrayBuffer(iv) : null;\n }\n\n private concat(buffer1: Bufferlike, buffer2: Bufferlike) {\n const output = new ArrayBuffer(buffer1.byteLength + buffer2.byteLength);\n const outputView = new DataView(output);\n\n const buffer1View = new DataView(bufferUtils.toArrayBuffer(buffer1));\n for (let i = 0; i < buffer1View.byteLength; i++) {\n outputView.setInt8(i, buffer1View.getInt8(i));\n }\n\n const buffer2View = new DataView(bufferUtils.toArrayBuffer(buffer2));\n for (let i = 0; i < buffer2View.byteLength; i++) {\n outputView.setInt8(buffer1View.byteLength + i, buffer2View.getInt8(i));\n }\n\n return output;\n }\n\n async encrypt(plaintext: InputPlaintext): Promise<OutputCiphertext> {\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'CBCCipher.encrypt()', '');\n\n const iv = await this.getIv();\n const cryptoKey = await crypto.subtle.importKey('raw', this.key, this.webCryptoAlgorithm, false, ['encrypt']);\n const ciphertext = await crypto.subtle.encrypt({ name: this.webCryptoAlgorithm, iv }, cryptoKey, plaintext);\n\n return this.concat(iv, ciphertext);\n }\n\n async decrypt(ciphertext: InputCiphertext): Promise<OutputPlaintext> {\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'CBCCipher.decrypt()', '');\n\n const ciphertextArrayBuffer = bufferUtils.toArrayBuffer(ciphertext);\n const iv = ciphertextArrayBuffer.slice(0, DEFAULT_BLOCKLENGTH);\n const ciphertextBody = ciphertextArrayBuffer.slice(DEFAULT_BLOCKLENGTH);\n\n const cryptoKey = await crypto.subtle.importKey('raw', this.key, this.webCryptoAlgorithm, false, ['decrypt']);\n return crypto.subtle.decrypt({ name: this.webCryptoAlgorithm, iv }, cryptoKey, ciphertextBody);\n }\n\n async getIv(): Promise<ArrayBuffer> {\n if (this.iv) {\n var iv = this.iv;\n this.iv = null;\n return iv;\n }\n\n const randomBlock = await config.getRandomArrayBuffer(DEFAULT_BLOCKLENGTH);\n return bufferUtils.toArrayBuffer(randomBlock);\n }\n }\n\n return Crypto;\n};\n\nexport { createCryptoClass };\n","enum XHRStates {\n REQ_SEND = 0,\n REQ_RECV = 1,\n REQ_RECV_POLL = 2,\n REQ_RECV_STREAM = 3,\n}\n\nexport default XHRStates;\n","import Platform from 'common/platform';\nimport Defaults from 'common/lib/util/defaults';\nimport ErrorInfo, { PartialErrorInfo } from 'common/lib/types/errorinfo';\nimport { RequestBody, RequestResultError, RequestParams, RequestResult } from 'common/types/http';\nimport HttpMethods from 'common/constants/HttpMethods';\nimport BaseClient from 'common/lib/client/baseclient';\nimport XHRStates from 'common/constants/XHRStates';\nimport Logger from 'common/lib/util/logger';\nimport { StandardCallback } from 'common/types/utils';\nimport { isSuccessCode } from 'common/constants/HttpStatusCodes';\nimport { ModularPlugins } from 'common/lib/client/modularplugins';\n\nexport type HTTPRequestImplementations = Pick<ModularPlugins, 'XHRRequest' | 'FetchRequest'>;\n\nfunction createMissingImplementationError() {\n return new ErrorInfo(\n 'No HTTP request plugin provided. Provide at least one of the FetchRequest or XHRRequest plugins.',\n 400,\n 40000,\n );\n}\n\nconst Http = class {\n static methods = [HttpMethods.Get, HttpMethods.Delete, HttpMethods.Post, HttpMethods.Put, HttpMethods.Patch];\n static methodsWithoutBody = [HttpMethods.Get, HttpMethods.Delete];\n static methodsWithBody = [HttpMethods.Post, HttpMethods.Put, HttpMethods.Patch];\n // HTTP request implementations that are available even without a BaseClient object (needed by some tests which directly instantiate `Http` without a client)\n static bundledRequestImplementations: HTTPRequestImplementations;\n checksInProgress: Array<StandardCallback<boolean>> | null = null;\n private client: BaseClient | null;\n\n constructor(client?: BaseClient) {\n this.client = client ?? null;\n const connectivityCheckUrl = client?.options.connectivityCheckUrl || Defaults.connectivityCheckUrl;\n const connectivityCheckParams = client?.options.connectivityCheckParams ?? null;\n const connectivityUrlIsDefault = !client?.options.connectivityCheckUrl;\n\n const requestImplementations = {\n ...Http.bundledRequestImplementations,\n ...client?._additionalHTTPRequestImplementations,\n };\n const xhrRequestImplementation = requestImplementations.XHRRequest;\n const fetchRequestImplementation = requestImplementations.FetchRequest;\n const hasImplementation = !!(xhrRequestImplementation || fetchRequestImplementation);\n\n if (!hasImplementation) {\n throw createMissingImplementationError();\n }\n\n if (Platform.Config.xhrSupported && xhrRequestImplementation) {\n this.supportsAuthHeaders = true;\n this.Request = async function (\n method: HttpMethods,\n uri: string,\n headers: Record<string, string> | null,\n params: RequestParams,\n body: RequestBody | null,\n ) {\n return new Promise((resolve) => {\n const req = xhrRequestImplementation.createRequest(\n uri,\n headers,\n params,\n body,\n XHRStates.REQ_SEND,\n (client && client.options.timeouts) ?? null,\n this.logger,\n method,\n );\n req.once(\n 'complete',\n (\n error: RequestResult['error'],\n body: RequestResult['body'],\n headers: RequestResult['headers'],\n unpacked: RequestResult['unpacked'],\n statusCode: RequestResult['statusCode'],\n ) => resolve({ error, body, headers, unpacked, statusCode }),\n );\n req.exec();\n });\n };\n if (client?.options.disableConnectivityCheck) {\n this.checkConnectivity = async function () {\n return true;\n };\n } else {\n this.checkConnectivity = async function () {\n Logger.logAction(\n this.logger,\n Logger.LOG_MICRO,\n '(XHRRequest)Http.checkConnectivity()',\n 'Sending; ' + connectivityCheckUrl,\n );\n\n const requestResult = await this.doUri(\n HttpMethods.Get,\n connectivityCheckUrl,\n null,\n null,\n connectivityCheckParams,\n );\n\n let result = false;\n if (!connectivityUrlIsDefault) {\n result = !requestResult.error && isSuccessCode(requestResult.statusCode as number);\n } else {\n result = !requestResult.error && (requestResult.body as string)?.replace(/\\n/, '') == 'yes';\n }\n\n Logger.logAction(this.logger, Logger.LOG_MICRO, '(XHRRequest)Http.checkConnectivity()', 'Result: ' + result);\n return result;\n };\n }\n } else if (Platform.Config.fetchSupported && fetchRequestImplementation) {\n this.supportsAuthHeaders = true;\n this.Request = async (method, uri, headers, params, body) => {\n return fetchRequestImplementation(method, client ?? null, uri, headers, params, body);\n };\n this.checkConnectivity = async function () {\n Logger.logAction(\n this.logger,\n Logger.LOG_MICRO,\n '(Fetch)Http.checkConnectivity()',\n 'Sending; ' + connectivityCheckUrl,\n );\n const requestResult = await this.doUri(HttpMethods.Get, connectivityCheckUrl, null, null, null);\n const result = !requestResult.error && (requestResult.body as string)?.replace(/\\n/, '') == 'yes';\n Logger.logAction(this.logger, Logger.LOG_MICRO, '(Fetch)Http.checkConnectivity()', 'Result: ' + result);\n return result;\n };\n } else {\n this.Request = async () => {\n const error = hasImplementation\n ? new PartialErrorInfo('no supported HTTP transports available', null, 400)\n : createMissingImplementationError();\n return { error };\n };\n }\n }\n\n get logger(): Logger {\n return this.client?.logger ?? Logger.defaultLogger;\n }\n\n async doUri(\n method: HttpMethods,\n uri: string,\n headers: Record<string, string> | null,\n body: RequestBody | null,\n params: RequestParams,\n ): Promise<RequestResult> {\n if (!this.Request) {\n return { error: new PartialErrorInfo('Request invoked before assigned to', null, 500) };\n }\n return this.Request(method, uri, headers, params, body);\n }\n\n private Request?: (\n method: HttpMethods,\n uri: string,\n headers: Record<string, string> | null,\n params: RequestParams,\n body: RequestBody | null,\n ) => Promise<RequestResult>;\n\n checkConnectivity?: () => Promise<boolean> = undefined;\n\n supportsAuthHeaders = false;\n supportsLinkHeaders = false;\n\n shouldFallback(errorInfo: RequestResultError) {\n const statusCode = errorInfo.statusCode as number;\n /* 400 + no code = a generic xhr onerror. Browser doesn't give us enough\n * detail to know whether it's fallback-fixable, but it may be (eg if a\n * network issue), so try just in case */\n return (\n (statusCode === 408 && !errorInfo.code) ||\n (statusCode === 400 && !errorInfo.code) ||\n (statusCode >= 500 && statusCode <= 504)\n );\n }\n};\n\nexport default Http;\n","import IWebStorage from 'common/types/IWebStorage';\n\nconst test = 'ablyjs-storage-test';\n\nlet globalObject = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : self;\n\nclass Webstorage implements IWebStorage {\n sessionSupported: boolean;\n localSupported: boolean;\n\n constructor() {\n /* Even just accessing the session/localStorage object can throw a\n * security exception in some circumstances with some browsers. In\n * others, calling setItem will throw. So have to check in this\n * somewhat roundabout way. (If unsupported or no global object,\n * will throw on accessing a property of undefined) */\n try {\n globalObject.sessionStorage.setItem(test, test);\n globalObject.sessionStorage.removeItem(test);\n this.sessionSupported = true;\n } catch (e) {\n this.sessionSupported = false;\n }\n\n try {\n globalObject.localStorage.setItem(test, test);\n globalObject.localStorage.removeItem(test);\n this.localSupported = true;\n } catch (e) {\n this.localSupported = false;\n }\n }\n\n get(name: string): any {\n return this._get(name, false);\n }\n\n getSession(name: string): any {\n return this._get(name, true);\n }\n\n remove(name: string): void {\n return this._remove(name, false);\n }\n\n removeSession(name: string): void {\n return this._remove(name, true);\n }\n\n set(name: string, value: string, ttl?: number): void {\n return this._set(name, value, ttl, false);\n }\n\n setSession(name: string, value: string, ttl?: number): void {\n return this._set(name, value, ttl, true);\n }\n\n private _set(name: string, value: string, ttl: number | undefined, session: any) {\n const wrappedValue: Record<string, any> = { value: value };\n if (ttl) {\n wrappedValue.expires = Date.now() + ttl;\n }\n return this.storageInterface(session).setItem(name, JSON.stringify(wrappedValue));\n }\n\n private _get(name: string, session?: boolean) {\n if (session && !this.sessionSupported) throw new Error('Session Storage not supported');\n if (!session && !this.localSupported) throw new Error('Local Storage not supported');\n const rawItem = this.storageInterface(session).getItem(name);\n if (!rawItem) return null;\n const wrappedValue = JSON.parse(rawItem);\n if (wrappedValue.expires && wrappedValue.expires < Date.now()) {\n this.storageInterface(session).removeItem(name);\n return null;\n }\n return wrappedValue.value;\n }\n\n private _remove(name: string, session?: boolean) {\n return this.storageInterface(session).removeItem(name);\n }\n\n private storageInterface(session?: boolean) {\n return session ? globalObject.sessionStorage : globalObject.localStorage;\n }\n}\n\nexport default new Webstorage();\n","import { IPlatformConfig } from '../../common/types/IPlatformConfig';\nimport * as Utils from 'common/lib/util/utils';\nimport { DeviceFormFactor, DevicePlatform } from 'common/lib/types/devicedetails';\nimport webstorage from './lib/util/webstorage';\n\n// Workaround for salesforce lightning locker compat\nconst globalObject = Utils.getGlobalObject();\n\n// @ts-ignore\nconst isVercelEdgeRuntime = typeof EdgeRuntime === 'string';\n\n// We get false positive result here in the Vercel Edge runtime because it lacks the usual global browser objects, such as Window.\n// However, it is closer to the browser environment, so it intentionally uses browser bundles when importing packages.\n// Therefore, we do an additional check to avoid logging this incorrect warning for Vercel Edge runtime.\nif (typeof Window === 'undefined' && typeof WorkerGlobalScope === 'undefined' && !isVercelEdgeRuntime) {\n console.log(\n \"Warning: this distribution of Ably is intended for browsers. On nodejs, please use the 'ably' package on npm\",\n );\n}\n\nfunction allowComet() {\n /* xhr requests from local files are unreliable in some browsers, such as Chrome 65 and higher -- see eg\n * https://stackoverflow.com/questions/49256429/chrome-65-unable-to-make-post-requests-from-local-files-to-flask\n * So if websockets are supported, then just forget about comet transports and use that */\n const loc = globalObject.location;\n return !globalObject.WebSocket || !loc || !loc.origin || loc.origin.indexOf('http') > -1;\n}\n\n// from: https://stackoverflow.com/a/18002694\nexport function isWebWorkerContext(): boolean {\n // run this in global scope of window or worker. since window.self = window, we're ok\n if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {\n return true;\n } else {\n return false;\n }\n}\n\nconst userAgent = globalObject.navigator && globalObject.navigator.userAgent.toString();\nconst currentUrl = globalObject.location && globalObject.location.href;\n\nconst Config: IPlatformConfig = {\n agent: 'browser',\n logTimestamps: true,\n userAgent: userAgent,\n currentUrl: currentUrl,\n binaryType: 'arraybuffer',\n WebSocket: globalObject.WebSocket,\n fetchSupported: !!globalObject.fetch,\n xhrSupported: globalObject.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest(),\n allowComet: allowComet(),\n useProtocolHeartbeats: true,\n supportsBinary: !!globalObject.TextDecoder,\n /* Per Paddy (https://ably-real-time.slack.com/archives/CURL4U2FP/p1705674537763479) web intentionally prefers JSON to MessagePack:\n *\n * > browsers' support for binary types in general was historically poor, and JSON transport performance is significantly better in a browser than msgpack. In modern browsers then binary is supported consistently, but I'd still expect that JSON encode/decode performance is dramatically better than msgpack in a browser.\n */\n preferBinary: false,\n ArrayBuffer: globalObject.ArrayBuffer,\n atob: globalObject.atob,\n nextTick:\n typeof globalObject.setImmediate !== 'undefined'\n ? globalObject.setImmediate.bind(globalObject)\n : function (f: () => void) {\n setTimeout(f, 0);\n },\n addEventListener: globalObject.addEventListener,\n inspect: JSON.stringify,\n stringByteSize: function (str: string) {\n /* str.length will be an underestimate for non-ascii strings. But if we're\n * in a browser too old to support TextDecoder, not much we can do. Better\n * to underestimate, so if we do go over-size, the server will reject the\n * message */\n return (globalObject.TextDecoder && new globalObject.TextEncoder().encode(str).length) || str.length;\n },\n TextEncoder: globalObject.TextEncoder,\n TextDecoder: globalObject.TextDecoder,\n getRandomArrayBuffer: async function (byteLength: number): Promise<ArrayBuffer> {\n const byteArray = new Uint8Array(byteLength);\n globalObject.crypto.getRandomValues(byteArray);\n return byteArray.buffer;\n },\n isWebworker: isWebWorkerContext(),\n push: {\n platform: DevicePlatform.Browser,\n formFactor: DeviceFormFactor.Desktop,\n storage: webstorage,\n },\n};\n\nexport default Config;\n","import * as Utils from '../util/utils';\r\nimport ProtocolMessage, {\r\n actions,\r\n fromValues as protocolMessageFromValues,\r\n fromDeserialized as protocolMessageFromDeserialized,\r\n} from '../types/protocolmessage';\r\nimport Transport from './transport';\r\nimport Logger from '../util/logger';\r\nimport Defaults from '../util/defaults';\r\nimport ConnectionErrors from './connectionerrors';\r\nimport Auth from '../client/auth';\r\nimport ErrorInfo from '../types/errorinfo';\r\nimport IXHRRequest from '../../types/IXHRRequest';\r\nimport * as API from '../../../../ably';\r\nimport ConnectionManager, { TransportParams } from './connectionmanager';\r\nimport XHRStates from '../../constants/XHRStates';\r\nimport Platform from 'common/platform';\r\n\r\n/* TODO: can remove once realtime sends protocol message responses for comet errors */\r\nfunction shouldBeErrorAction(err: ErrorInfo) {\r\n const UNRESOLVABLE_ERROR_CODES = [80015, 80017, 80030];\r\n if (err.code) {\r\n if (Auth.isTokenErr(err)) return false;\r\n if (UNRESOLVABLE_ERROR_CODES.includes(err.code)) return true;\r\n return err.code >= 40000 && err.code < 50000;\r\n } else {\r\n /* Likely a network or transport error of some kind. Certainly not fatal to the connection */\r\n return false;\r\n }\r\n}\r\n\r\nfunction protocolMessageFromRawError(err: ErrorInfo) {\r\n /* err will be either a legacy (non-protocolmessage) comet error response\r\n * (which will have an err.code), or a xhr/network error (which won't). */\r\n if (shouldBeErrorAction(err)) {\r\n return [protocolMessageFromValues({ action: actions.ERROR, error: err })];\r\n } else {\r\n return [protocolMessageFromValues({ action: actions.DISCONNECTED, error: err })];\r\n }\r\n}\r\n\r\n/*\r\n * A base comet transport class\r\n */\r\nabstract class CometTransport extends Transport {\r\n stream: string | boolean;\r\n sendRequest: IXHRRequest | null;\r\n recvRequest: null | IXHRRequest;\r\n pendingCallback: null;\r\n pendingItems: null | Array<ProtocolMessage>;\r\n baseUri?: string;\r\n authParams?: Record<string, any>;\r\n closeUri?: string;\r\n disconnectUri?: string;\r\n sendUri?: string;\r\n recvUri?: string;\r\n\r\n constructor(connectionManager: ConnectionManager, auth: Auth, params: TransportParams) {\r\n super(connectionManager, auth, params, /* binary not supported for comet so force JSON protocol */ true);\r\n this.stream = 'stream' in params ? params.stream : true;\r\n this.sendRequest = null;\r\n this.recvRequest = null;\r\n this.pendingCallback = null;\r\n this.pendingItems = null;\r\n }\r\n\r\n abstract createRequest(\r\n uri: string,\r\n headers: Record<string, string> | null,\r\n params?: Record<string, unknown> | null,\r\n body?: unknown,\r\n requestMode?: number,\r\n ): IXHRRequest;\r\n\r\n connect(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'CometTransport.connect()', 'starting');\r\n Transport.prototype.connect.call(this);\r\n const params = this.params;\r\n const options = params.options;\r\n const host = Defaults.getHost(options, params.host);\r\n const port = Defaults.getPort(options);\r\n const cometScheme = options.tls ? 'https://' : 'http://';\r\n\r\n this.baseUri = cometScheme + host + ':' + port + '/comet/';\r\n const connectUri = this.baseUri + 'connect';\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'CometTransport.connect()', 'uri: ' + connectUri);\r\n Utils.whenPromiseSettles(this.auth.getAuthParams(), (err: Error | null, authParams?: Record<string, any>) => {\r\n if (err) {\r\n this.disconnect(err);\r\n return;\r\n }\r\n if (this.isDisposed) {\r\n return;\r\n }\r\n this.authParams = authParams;\r\n const connectParams = this.params.getConnectParams(authParams!);\r\n if ('stream' in connectParams) this.stream = connectParams.stream;\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_MINOR,\r\n 'CometTransport.connect()',\r\n 'connectParams:' + Utils.toQueryString(connectParams),\r\n );\r\n\r\n /* this will be the 'recvRequest' so this connection can stream messages */\r\n let preconnected = false;\r\n const connectRequest = (this.recvRequest = this.createRequest(\r\n connectUri,\r\n null,\r\n connectParams,\r\n null,\r\n this.stream ? XHRStates.REQ_RECV_STREAM : XHRStates.REQ_RECV,\r\n ));\r\n\r\n connectRequest.on('data', (data: any) => {\r\n if (!this.recvRequest) {\r\n /* the transport was disposed before we connected */\r\n return;\r\n }\r\n if (!preconnected) {\r\n preconnected = true;\r\n this.emit('preconnect');\r\n }\r\n this.onData(data);\r\n });\r\n connectRequest.on('complete', (err: ErrorInfo) => {\r\n if (!this.recvRequest) {\r\n /* the transport was disposed before we connected */\r\n err = err || new ErrorInfo('Request cancelled', 80003, 400);\r\n }\r\n this.recvRequest = null;\r\n /* Connect request may complete without a emitting 'data' event since that is not\r\n * emitted for e.g. a non-streamed error response. Still implies preconnect. */\r\n if (!preconnected && !err) {\r\n preconnected = true;\r\n this.emit('preconnect');\r\n }\r\n this.onActivity();\r\n if (err) {\r\n if (err.code) {\r\n /* A protocol error received from realtime. TODO: once realtime\r\n * consistendly sends errors wrapped in protocol messages, should be\r\n * able to remove this */\r\n this.onData(protocolMessageFromRawError(err));\r\n } else {\r\n /* A network/xhr error. Don't bother wrapping in a protocol message,\r\n * just disconnect the transport */\r\n this.disconnect(err);\r\n }\r\n return;\r\n }\r\n Platform.Config.nextTick(() => {\r\n this.recv();\r\n });\r\n });\r\n connectRequest.exec();\r\n });\r\n }\r\n\r\n requestClose(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'CometTransport.requestClose()');\r\n this._requestCloseOrDisconnect(true);\r\n }\r\n\r\n requestDisconnect(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'CometTransport.requestDisconnect()');\r\n this._requestCloseOrDisconnect(false);\r\n }\r\n\r\n _requestCloseOrDisconnect(closing: boolean): void {\r\n const closeOrDisconnectUri = closing ? this.closeUri : this.disconnectUri;\r\n if (closeOrDisconnectUri) {\r\n const request = this.createRequest(closeOrDisconnectUri, null, this.authParams, null, XHRStates.REQ_SEND);\r\n\r\n request.on('complete', (err: ErrorInfo) => {\r\n if (err) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'CometTransport.request' + (closing ? 'Close()' : 'Disconnect()'),\r\n 'request returned err = ' + Utils.inspectError(err),\r\n );\r\n this.finish('disconnected', err);\r\n }\r\n });\r\n request.exec();\r\n }\r\n }\r\n\r\n dispose(): void {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'CometTransport.dispose()', '');\r\n if (!this.isDisposed) {\r\n this.isDisposed = true;\r\n if (this.recvRequest) {\r\n Logger.logAction(this.logger, Logger.LOG_MINOR, 'CometTransport.dispose()', 'aborting recv request');\r\n this.recvRequest.abort();\r\n this.recvRequest = null;\r\n }\r\n /* In almost all cases the transport will be finished before it's\r\n * disposed. Finish here just to make sure. */\r\n this.finish('disconnected', ConnectionErrors.disconnected());\r\n Platform.Config.nextTick(() => {\r\n this.emit('disposed');\r\n });\r\n }\r\n }\r\n\r\n onConnect(message: ProtocolMessage): void {\r\n /* if this transport has been disposed whilst awaiting connection, do nothing */\r\n if (this.isDisposed) {\r\n return;\r\n }\r\n\r\n /* the connectionKey in a comet connected response is really\r\n * <instId>-<connectionKey> */\r\n const connectionStr = message.connectionDetails?.connectionKey;\r\n Transport.prototype.onConnect.call(this, message);\r\n\r\n const baseConnectionUri = (this.baseUri as string) + connectionStr;\r\n Logger.logAction(this.logger, Logger.LOG_MICRO, 'CometTransport.onConnect()', 'baseUri = ' + baseConnectionUri);\r\n this.sendUri = baseConnectionUri + '/send';\r\n this.recvUri = baseConnectionUri + '/recv';\r\n this.closeUri = baseConnectionUri + '/close';\r\n this.disconnectUri = baseConnectionUri + '/disconnect';\r\n }\r\n\r\n send(message: ProtocolMessage): void {\r\n if (this.sendRequest) {\r\n /* there is a pending send, so queue this message */\r\n this.pendingItems = this.pendingItems || [];\r\n this.pendingItems.push(message);\r\n return;\r\n }\r\n /* send this, plus any pending, now */\r\n const pendingItems = this.pendingItems || [];\r\n pendingItems.push(message);\r\n this.pendingItems = null;\r\n\r\n this.sendItems(pendingItems);\r\n }\r\n\r\n sendAnyPending(): void {\r\n const pendingItems = this.pendingItems;\r\n\r\n if (!pendingItems) {\r\n return;\r\n }\r\n\r\n this.pendingItems = null;\r\n this.sendItems(pendingItems);\r\n }\r\n\r\n sendItems(items: Array<ProtocolMessage>): void {\r\n const sendRequest = (this.sendRequest = this.createRequest(\r\n this.sendUri as string,\r\n null,\r\n this.authParams,\r\n this.encodeRequest(items),\r\n XHRStates.REQ_SEND,\r\n ));\r\n\r\n sendRequest.on('complete', (err: ErrorInfo, data: string) => {\r\n if (err)\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'CometTransport.sendItems()',\r\n 'on complete: err = ' + Utils.inspectError(err),\r\n );\r\n this.sendRequest = null;\r\n\r\n /* the result of the request, even if a nack, is usually a protocol response\r\n * contained in the data. An err is anomolous, and indicates some issue with the\r\n * network,transport, or connection */\r\n if (err) {\r\n if (err.code) {\r\n /* A protocol error received from realtime. TODO: once realtime\r\n * consistendly sends errors wrapped in protocol messages, should be\r\n * able to remove this */\r\n this.onData(protocolMessageFromRawError(err));\r\n } else {\r\n /* A network/xhr error. Don't bother wrapping in a protocol message,\r\n * just disconnect the transport */\r\n this.disconnect(err);\r\n }\r\n return;\r\n }\r\n\r\n if (data) {\r\n this.onData(data);\r\n }\r\n\r\n if (this.pendingItems) {\r\n Platform.Config.nextTick(() => {\r\n /* If there's a new send request by now, any pending items will have\r\n * been picked up by that; any new ones added since then will be\r\n * picked up after that one completes */\r\n if (!this.sendRequest) {\r\n this.sendAnyPending();\r\n }\r\n });\r\n }\r\n });\r\n sendRequest.exec();\r\n }\r\n\r\n recv(): void {\r\n /* do nothing if there is an active request, which might be streaming */\r\n if (this.recvRequest) return;\r\n\r\n /* If we're no longer connected, do nothing */\r\n if (!this.isConnected) return;\r\n\r\n const recvRequest = (this.recvRequest = this.createRequest(\r\n this.recvUri as string,\r\n null,\r\n this.authParams,\r\n null,\r\n this.stream ? XHRStates.REQ_RECV_STREAM : XHRStates.REQ_RECV_POLL,\r\n ));\r\n\r\n recvRequest.on('data', (data: string) => {\r\n this.onData(data);\r\n });\r\n recvRequest.on('complete', (err: ErrorInfo) => {\r\n this.recvRequest = null;\r\n /* A request completing must be considered activity, as realtime sends\r\n * heartbeats every 15s since a request began, not every 15s absolutely */\r\n this.onActivity();\r\n if (err) {\r\n if (err.code) {\r\n /* A protocol error received from realtime. TODO: once realtime\r\n * consistently sends errors wrapped in protocol messages, should be\r\n * able to remove this */\r\n this.onData(protocolMessageFromRawError(err));\r\n } else {\r\n /* A network/xhr error. Don't bother wrapping in a protocol message,\r\n * just disconnect the transport */\r\n this.disconnect(err);\r\n }\r\n return;\r\n }\r\n Platform.Config.nextTick(() => {\r\n this.recv();\r\n });\r\n });\r\n recvRequest.exec();\r\n }\r\n\r\n onData(responseData: string | Record<string, any>): void {\r\n try {\r\n const items = this.decodeResponse(responseData);\r\n if (items && items.length)\r\n for (let i = 0; i < items.length; i++)\r\n this.onProtocolMessage(\r\n protocolMessageFromDeserialized(items[i], this.connectionManager.realtime._RealtimePresence),\r\n );\r\n } catch (e) {\r\n Logger.logAction(\r\n this.logger,\r\n Logger.LOG_ERROR,\r\n 'CometTransport.onData()',\r\n 'Unexpected exception handing channel event: ' + (e as Error).stack,\r\n );\r\n }\r\n }\r\n\r\n encodeRequest(requestItems: Array<ProtocolMessage>): string {\r\n return JSON.stringify(requestItems);\r\n }\r\n\r\n decodeResponse(responseData: string | Record<string, any>): Record<string, any> {\r\n if (typeof responseData == 'string') return JSON.parse(responseData);\r\n return responseData;\r\n }\r\n\r\n /* Historical comment, back from when we supported JSONP:\r\n *\r\n * > For comet, we could do the auth update by aborting the current recv and\r\n * > starting a new one with the new token, that'd be sufficient for realtime.\r\n * > Problem is JSONP - you can't cancel truly abort a recv once started. So\r\n * > we need to send an AUTH for jsonp. In which case it's simpler to keep all\r\n * > comet transports the same and do it for all of them. So we send the AUTH\r\n * > instead, and don't need to abort the recv\r\n *\r\n * Now that we’ve dropped JSONP support, we may be able to revisit the above;\r\n * see https://github.com/ably/ably-js/issues/1214.\r\n */\r\n onAuthUpdated = (tokenDetails: API.TokenDetails): void => {\r\n this.authParams = { access_token: tokenDetails.token };\r\n };\r\n}\r\n\r\nexport default CometTransport;\r\n","import * as Utils from 'common/lib/util/utils';\nimport EventEmitter from 'common/lib/util/eventemitter';\nimport ErrorInfo, { IPartialErrorInfo, PartialErrorInfo } from 'common/lib/types/errorinfo';\nimport Logger from 'common/lib/util/logger';\nimport Defaults from 'common/lib/util/defaults';\nimport HttpMethods from 'common/constants/HttpMethods';\nimport IXHRRequest from 'common/types/IXHRRequest';\nimport { RequestBody, RequestParams } from 'common/types/http';\nimport XHRStates from 'common/constants/XHRStates';\nimport Platform from 'common/platform';\n\nfunction isAblyError(responseBody: unknown, headers: Record<string, string>): responseBody is { error?: ErrorInfo } {\n return Utils.allToLowerCase(Utils.keysArray(headers)).includes('x-ably-errorcode');\n}\n\nfunction getAblyError(responseBody: unknown, headers: Record<string, string>) {\n if (isAblyError(responseBody, headers)) {\n return responseBody.error && ErrorInfo.fromValues(responseBody.error);\n }\n}\n\nconst noop = function () {};\nlet idCounter = 0;\nconst pendingRequests: Record<string, XHRRequest> = {};\n\nfunction getHeader(xhr: XMLHttpRequest, header: string) {\n return xhr.getResponseHeader && xhr.getResponseHeader(header);\n}\n\n/* Safari mysteriously returns 'Identity' for transfer-encoding when in fact\n * it is 'chunked'. So instead, decide that it is chunked when\n * transfer-encoding is present or content-length is absent. ('or' because\n * when using http2 streaming, there's no transfer-encoding header, but can\n * still deduce streaming from lack of content-length) */\nfunction isEncodingChunked(xhr: XMLHttpRequest) {\n return (\n xhr.getResponseHeader && (xhr.getResponseHeader('transfer-encoding') || !xhr.getResponseHeader('content-length'))\n );\n}\n\nfunction getHeadersAsObject(xhr: XMLHttpRequest) {\n const headerPairs = xhr.getAllResponseHeaders().trim().split('\\r\\n');\n const headers: Record<string, string> = {};\n for (let i = 0; i < headerPairs.length; i++) {\n const parts = headerPairs[i].split(':').map((x) => x.trim());\n headers[parts[0].toLowerCase()] = parts[1];\n }\n return headers;\n}\n\nclass XHRRequest extends EventEmitter implements IXHRRequest {\n uri: string;\n headers: Record<string, string>;\n body: RequestBody | null;\n method: string;\n requestMode: number;\n timeouts: Record<string, number>;\n timedOut: boolean;\n requestComplete: boolean;\n id: string;\n streamComplete?: boolean;\n xhr?: XMLHttpRequest | null;\n timer?: NodeJS.Timeout | number | null;\n\n constructor(\n uri: string,\n headers: Record<string, string> | null,\n params: Record<string, string>,\n body: RequestBody | null,\n requestMode: number,\n timeouts: Record<string, number>,\n logger: Logger,\n method?: HttpMethods,\n ) {\n super(logger);\n params = params || {};\n params.rnd = Utils.cheapRandStr();\n this.uri = uri + Utils.toQueryString(params);\n this.headers = headers || {};\n this.body = body;\n this.method = method ? method.toUpperCase() : Utils.isNil(body) ? 'GET' : 'POST';\n this.requestMode = requestMode;\n this.timeouts = timeouts;\n this.timedOut = false;\n this.requestComplete = false;\n this.id = String(++idCounter);\n pendingRequests[this.id] = this;\n }\n\n static createRequest(\n uri: string,\n headers: Record<string, string> | null,\n params: RequestParams,\n body: RequestBody | null,\n requestMode: number,\n timeouts: Record<string, number> | null,\n logger: Logger,\n method?: HttpMethods,\n ): XHRRequest {\n /* XHR requests are used either with the context being a realtime\n * transport, or with timeouts passed in (for when used by a rest client),\n * or completely standalone. Use the appropriate timeouts in each case */\n const _timeouts = timeouts || Defaults.TIMEOUTS;\n return new XHRRequest(\n uri,\n headers,\n Utils.copy(params) as Record<string, string>,\n body,\n requestMode,\n _timeouts,\n logger,\n method,\n );\n }\n\n complete(\n err?: IPartialErrorInfo | null,\n body?: unknown,\n headers?: Record<string, string> | null,\n unpacked?: boolean | null,\n statusCode?: number,\n ): void {\n if (!this.requestComplete) {\n this.requestComplete = true;\n if (!err && body) {\n this.emit('data', body);\n }\n this.emit('complete', err, body, headers, unpacked, statusCode);\n this.dispose();\n }\n }\n\n abort(): void {\n this.dispose();\n }\n\n exec(): void {\n let headers = this.headers;\n const timeout =\n this.requestMode == XHRStates.REQ_SEND ? this.timeouts.httpRequestTimeout : this.timeouts.recvTimeout,\n timer = (this.timer = setTimeout(() => {\n this.timedOut = true;\n xhr.abort();\n }, timeout)),\n method = this.method,\n xhr = (this.xhr = new XMLHttpRequest()),\n accept = headers['accept'];\n let body = this.body;\n let responseType: XMLHttpRequestResponseType = 'text';\n\n if (!accept) {\n // Default to JSON\n headers['accept'] = 'application/json';\n } else if (accept.indexOf('application/x-msgpack') === 0) {\n // Msgpack responses will be typed as ArrayBuffer\n responseType = 'arraybuffer';\n }\n\n if (body) {\n const contentType = headers['content-type'] || (headers['content-type'] = 'application/json');\n if (contentType.indexOf('application/json') > -1 && typeof body != 'string') body = JSON.stringify(body);\n }\n\n // Can probably remove this directive if https://github.com/nodesecurity/eslint-plugin-security/issues/26 is resolved\n // eslint-disable-next-line security/detect-non-literal-fs-filename\n xhr.open(method, this.uri, true);\n xhr.responseType = responseType;\n\n if ('authorization' in headers) {\n xhr.withCredentials = true;\n }\n\n for (const h in headers) xhr.setRequestHeader(h, headers[h]);\n\n const errorHandler = (\n errorEvent: ProgressEvent<EventTarget>,\n message: string,\n code: number | null,\n statusCode: number,\n ) => {\n let errorMessage = message + ' (event type: ' + errorEvent.type + ')';\n if (this?.xhr?.statusText) errorMessage += ', current statusText is ' + this.xhr.statusText;\n Logger.logAction(this.logger, Logger.LOG_ERROR, 'Request.on' + errorEvent.type + '()', errorMessage);\n this.complete(new PartialErrorInfo(errorMessage, code, statusCode));\n };\n xhr.onerror = function (errorEvent) {\n errorHandler(errorEvent, 'XHR error occurred', null, 400);\n };\n xhr.onabort = (errorEvent) => {\n if (this.timedOut) {\n errorHandler(errorEvent, 'Request aborted due to request timeout expiring', null, 408);\n } else {\n errorHandler(errorEvent, 'Request cancelled', null, 400);\n }\n };\n xhr.ontimeout = function (errorEvent) {\n errorHandler(errorEvent, 'Request timed out', null, 408);\n };\n\n let streaming: boolean | string;\n let statusCode: number;\n let successResponse: boolean;\n let streamPos = 0;\n let unpacked = false;\n\n const onResponse = () => {\n clearTimeout(timer);\n successResponse = statusCode < 400;\n if (statusCode == 204) {\n this.complete(null, null, null, null, statusCode);\n return;\n }\n streaming = this.requestMode == XHRStates.REQ_RECV_STREAM && successResponse && isEncodingChunked(xhr);\n };\n\n const onEnd = () => {\n let parsedResponse: any;\n try {\n const contentType = getHeader(xhr, 'content-type');\n /* Be liberal in what we accept; buggy auth servers may respond\n * without the correct contenttype, but assume they're still\n * responding with json */\n const json = contentType ? contentType.indexOf('application/json') >= 0 : xhr.responseType == 'text';\n\n if (json) {\n /* If we requested msgpack but server responded with json, then since\n * we set the responseType expecting msgpack, the response will be\n * an ArrayBuffer containing json */\n const jsonResponseBody =\n xhr.responseType === 'arraybuffer'\n ? Platform.BufferUtils.utf8Decode(xhr.response)\n : String(xhr.responseText);\n if (jsonResponseBody.length) {\n parsedResponse = JSON.parse(jsonResponseBody);\n } else {\n parsedResponse = jsonResponseBody;\n }\n unpacked = true;\n } else {\n parsedResponse = xhr.response;\n }\n\n if (parsedResponse.response !== undefined) {\n /* unwrap JSON envelope */\n statusCode = parsedResponse.statusCode;\n successResponse = statusCode < 400;\n headers = parsedResponse.headers;\n parsedResponse = parsedResponse.response;\n } else {\n headers = getHeadersAsObject(xhr);\n }\n } catch (e) {\n this.complete(new PartialErrorInfo('Malformed response body from server: ' + (e as Error).message, null, 400));\n return;\n }\n\n /* If response is an array, it's an array of protocol messages -- even if\n * is contains an error action (hence the nonsuccess statuscode), we can\n * consider the request to have succeeded, just pass it on to\n * onProtocolMessage to decide what to do */\n if (successResponse || Array.isArray(parsedResponse)) {\n this.complete(null, parsedResponse, headers, unpacked, statusCode);\n return;\n }\n\n let err: IPartialErrorInfo | undefined = getAblyError(parsedResponse, headers);\n if (!err) {\n err = new PartialErrorInfo(\n 'Error response received from server: ' +\n statusCode +\n ' body was: ' +\n Platform.Config.inspect(parsedResponse),\n null,\n statusCode,\n );\n }\n this.complete(err, parsedResponse, headers, unpacked, statusCode);\n };\n\n function onProgress() {\n const responseText = xhr.responseText;\n const bodyEnd = responseText.length - 1;\n let idx, chunk;\n while (streamPos < bodyEnd && (idx = responseText.indexOf('\\n', streamPos)) > -1) {\n chunk = responseText.slice(streamPos, idx);\n streamPos = idx + 1;\n onChunk(chunk);\n }\n }\n\n const onChunk = (chunk: string) => {\n try {\n chunk = JSON.parse(chunk);\n } catch (e) {\n this.complete(new PartialErrorInfo('Malformed response body from server: ' + (e as Error).message, null, 400));\n return;\n }\n this.emit('data', chunk);\n };\n\n const onStreamEnd = () => {\n onProgress();\n this.streamComplete = true;\n Platform.Config.nextTick(() => {\n this.complete();\n });\n };\n\n xhr.onreadystatechange = function () {\n const readyState = xhr.readyState;\n if (readyState < 3) return;\n if (xhr.status !== 0) {\n if (statusCode === undefined) {\n statusCode = xhr.status;\n onResponse();\n }\n if (readyState == 3 && streaming) {\n onProgress();\n } else if (readyState == 4) {\n if (streaming) onStreamEnd();\n else onEnd();\n }\n }\n };\n xhr.send(body as any);\n }\n\n dispose(): void {\n const xhr = this.xhr;\n if (xhr) {\n xhr.onreadystatechange = xhr.onerror = xhr.onabort = xhr.ontimeout = noop;\n this.xhr = null;\n const timer = this.timer;\n if (timer) {\n clearTimeout(timer as NodeJS.Timeout);\n this.timer = null;\n }\n if (!this.requestComplete) xhr.abort();\n }\n delete pendingRequests[this.id];\n }\n}\n\nexport default XHRRequest;\n","import Platform from '../../../../common/platform';\nimport CometTransport from '../../../../common/lib/transport/comettransport';\nimport XHRRequest from '../http/request/xhrrequest';\nimport ConnectionManager, { TransportParams } from 'common/lib/transport/connectionmanager';\nimport Auth from 'common/lib/client/auth';\nimport { RequestBody, RequestParams } from 'common/types/http';\nimport { TransportNames } from 'common/constants/TransportName';\n\nvar shortName = TransportNames.XhrPolling;\nclass XHRPollingTransport extends CometTransport {\n shortName = shortName;\n constructor(connectionManager: ConnectionManager, auth: Auth, params: TransportParams) {\n super(connectionManager, auth, params);\n params.stream = false;\n this.shortName = shortName;\n }\n\n static isAvailable() {\n return !!(Platform.Config.xhrSupported && Platform.Config.allowComet);\n }\n\n toString() {\n return 'XHRPollingTransport; uri=' + this.baseUri + '; isConnected=' + this.isConnected;\n }\n\n createRequest(\n uri: string,\n headers: Record<string, string>,\n params: RequestParams,\n body: RequestBody | null,\n requestMode: number,\n ) {\n return XHRRequest.createRequest(uri, headers, params, body, requestMode, this.timeouts, this.logger);\n }\n}\n\nexport default XHRPollingTransport;\n","import TransportName from 'common/constants/TransportName';\nimport Platform from 'common/platform';\nimport XhrPollingTransport from './xhrpollingtransport';\nimport WebSocketTransport from '../../../../common/lib/transport/websockettransport';\n\n// For reasons that I don’t understand, if we use [TransportNames.XhrPolling] for the keys in defaultTransports’s, then defaultTransports does not get tree-shaken. Hence using literals instead. They’re still correctly type-checked.\n\nconst order: TransportName[] = ['xhr_polling'];\n\nconst defaultTransports: (typeof Platform)['Transports'] = {\n order,\n bundledImplementations: {\n web_socket: WebSocketTransport,\n xhr_polling: XhrPollingTransport,\n },\n};\n\nexport default defaultTransports;\n\nexport const ModularTransports: (typeof Platform)['Transports'] = {\n order,\n bundledImplementations: {},\n};\n","import IDefaults from 'common/types/IDefaults';\nimport { TransportNames } from 'common/constants/TransportName';\n\nconst Defaults: IDefaults = {\n connectivityCheckUrl: 'https://internet-up.ably-realtime.com/is-the-internet-up.txt',\n wsConnectivityCheckUrl: 'wss://ws-up.ably-realtime.com',\n /* Order matters here: the base transport is the leftmost one in the\n * intersection of baseTransportOrder and the transports clientOption that's\n * supported. */\n defaultTransports: [TransportNames.XhrPolling, TransportNames.WebSocket],\n};\n\nexport default Defaults;\n","function inspect(buffer: undefined | ArrayBuffer | DataView) {\n if (buffer === undefined) return 'undefined';\n let view;\n let type;\n if (buffer instanceof ArrayBuffer) {\n type = 'ArrayBuffer';\n view = new DataView(buffer);\n } else if (buffer instanceof DataView) {\n type = 'DataView';\n view = buffer;\n }\n if (!view) return JSON.stringify(buffer);\n const bytes = [];\n for (let i = 0; i < buffer.byteLength; i++) {\n if (i > 20) {\n bytes.push('...');\n break;\n }\n let byte_ = view.getUint8(i).toString(16);\n if (byte_.length === 1) byte_ = '0' + byte_;\n bytes.push(byte_);\n }\n return '<' + type + ' ' + bytes.join(' ') + '>';\n}\n\n// Encode string as utf8 into dataview at offset\nfunction utf8Write(view: DataView, offset: number, string: string) {\n for (let i = 0, l = string.length; i < l; i++) {\n const codePoint = string.charCodeAt(i);\n\n // One byte of UTF-8\n if (codePoint < 0x80) {\n view.setUint8(offset++, ((codePoint >>> 0) & 0x7f) | 0x00);\n continue;\n }\n\n // Two bytes of UTF-8\n if (codePoint < 0x800) {\n view.setUint8(offset++, ((codePoint >>> 6) & 0x1f) | 0xc0);\n view.setUint8(offset++, ((codePoint >>> 0) & 0x3f) | 0x80);\n continue;\n }\n\n // Three bytes of UTF-8.\n if (codePoint < 0x10000) {\n view.setUint8(offset++, ((codePoint >>> 12) & 0x0f) | 0xe0);\n view.setUint8(offset++, ((codePoint >>> 6) & 0x3f) | 0x80);\n view.setUint8(offset++, ((codePoint >>> 0) & 0x3f) | 0x80);\n continue;\n }\n\n // Four bytes of UTF-8\n if (codePoint < 0x110000) {\n view.setUint8(offset++, ((codePoint >>> 18) & 0x07) | 0xf0);\n view.setUint8(offset++, ((codePoint >>> 12) & 0x3f) | 0x80);\n view.setUint8(offset++, ((codePoint >>> 6) & 0x3f) | 0x80);\n view.setUint8(offset++, ((codePoint >>> 0) & 0x3f) | 0x80);\n continue;\n }\n throw new Error('bad codepoint ' + codePoint);\n }\n}\n\nfunction utf8Read(view: DataView, offset: number, length: number) {\n let string = '';\n for (let i = offset, end = offset + length; i < end; i++) {\n const byte_ = view.getUint8(i);\n // One byte character\n if ((byte_ & 0x80) === 0x00) {\n string += String.fromCharCode(byte_);\n continue;\n }\n // Two byte character\n if ((byte_ & 0xe0) === 0xc0) {\n string += String.fromCharCode(((byte_ & 0x0f) << 6) | (view.getUint8(++i) & 0x3f));\n continue;\n }\n // Three byte character\n if ((byte_ & 0xf0) === 0xe0) {\n string += String.fromCharCode(\n ((byte_ & 0x0f) << 12) | ((view.getUint8(++i) & 0x3f) << 6) | ((view.getUint8(++i) & 0x3f) << 0),\n );\n continue;\n }\n // Four byte character\n if ((byte_ & 0xf8) === 0xf0) {\n string += String.fromCharCode(\n ((byte_ & 0x07) << 18) |\n ((view.getUint8(++i) & 0x3f) << 12) |\n ((view.getUint8(++i) & 0x3f) << 6) |\n ((view.getUint8(++i) & 0x3f) << 0),\n );\n continue;\n }\n throw new Error('Invalid byte ' + byte_.toString(16));\n }\n return string;\n}\n\nfunction utf8ByteCount(string: string) {\n let count = 0;\n for (let i = 0, l = string.length; i < l; i++) {\n const codePoint = string.charCodeAt(i);\n if (codePoint < 0x80) {\n count += 1;\n continue;\n }\n if (codePoint < 0x800) {\n count += 2;\n continue;\n }\n if (codePoint < 0x10000) {\n count += 3;\n continue;\n }\n if (codePoint < 0x110000) {\n count += 4;\n continue;\n }\n throw new Error('bad codepoint ' + codePoint);\n }\n return count;\n}\n\nfunction encode(value: unknown, sparse?: boolean) {\n const size = sizeof(value, sparse);\n if (size === 0) return undefined;\n const buffer = new ArrayBuffer(size);\n const view = new DataView(buffer);\n _encode(value, view, 0, sparse);\n return buffer;\n}\n\nconst SH_L_32 = (1 << 16) * (1 << 16),\n SH_R_32 = 1 / SH_L_32;\nfunction getInt64(view: DataView, offset: number) {\n offset = offset || 0;\n return view.getInt32(offset) * SH_L_32 + view.getUint32(offset + 4);\n}\n\nfunction getUint64(view: DataView, offset: number) {\n offset = offset || 0;\n return view.getUint32(offset) * SH_L_32 + view.getUint32(offset + 4);\n}\n\nfunction setInt64(view: DataView, offset: number, val: number) {\n if (val < 0x8000000000000000) {\n view.setInt32(offset, Math.floor(val * SH_R_32));\n view.setInt32(offset + 4, val & -1);\n } else {\n view.setUint32(offset, 0x7fffffff);\n view.setUint32(offset + 4, 0x7fffffff);\n }\n}\n\nfunction setUint64(view: DataView, offset: number, val: number) {\n if (val < 0x10000000000000000) {\n view.setUint32(offset, Math.floor(val * SH_R_32));\n view.setInt32(offset + 4, val & -1);\n } else {\n view.setUint32(offset, 0xffffffff);\n view.setUint32(offset + 4, 0xffffffff);\n }\n}\n\n// https://gist.github.com/frsyuki/5432559 - v5 spec\n//\n// I've used one extension point from `fixext 1` to store `undefined`. On the wire this\n// should translate to exactly 0xd40000\n//\n// +--------+--------+--------+\n// | 0xd4 | 0x00 | 0x00 |\n// +--------+--------+--------+\n// ^ fixext | ^ value part unused (fixed to be 0)\n// ^ indicates undefined value\n//\n\nclass Decoder {\n offset: number;\n view: DataView;\n\n constructor(view: DataView, offset?: number) {\n this.offset = offset || 0;\n this.view = view;\n }\n\n map = (length: number) => {\n const value: { [key: string]: ArrayBuffer } = {};\n for (let i = 0; i < length; i++) {\n const key = this.parse();\n value[key as string] = this.parse() as ArrayBuffer;\n }\n return value;\n };\n\n bin = (length: number) => {\n const value = new ArrayBuffer(length);\n new Uint8Array(value).set(new Uint8Array(this.view.buffer, this.offset, length), 0);\n this.offset += length;\n return value;\n };\n\n buf = this.bin;\n\n str = (length: number) => {\n const value = utf8Read(this.view, this.offset, length);\n this.offset += length;\n return value;\n };\n\n array = (length: number) => {\n const value = new Array(length);\n for (let i = 0; i < length; i++) {\n value[i] = this.parse();\n }\n return value;\n };\n\n ext = (length: number) => {\n this.offset += length;\n return {\n type: this.view.getInt8(this.offset),\n data: this.buf(length),\n };\n };\n\n parse = (): unknown => {\n const type = this.view.getUint8(this.offset);\n let value, length;\n\n // Positive FixInt - 0xxxxxxx\n if ((type & 0x80) === 0x00) {\n this.offset++;\n return type;\n }\n\n // FixMap - 1000xxxx\n if ((type & 0xf0) === 0x80) {\n length = type & 0x0f;\n this.offset++;\n return this.map(length);\n }\n\n // FixArray - 1001xxxx\n if ((type & 0xf0) === 0x90) {\n length = type & 0x0f;\n this.offset++;\n return this.array(length);\n }\n\n // FixStr - 101xxxxx\n if ((type & 0xe0) === 0xa0) {\n length = type & 0x1f;\n this.offset++;\n return this.str(length);\n }\n\n // Negative FixInt - 111xxxxx\n if ((type & 0xe0) === 0xe0) {\n value = this.view.getInt8(this.offset);\n this.offset++;\n return value;\n }\n\n switch (type) {\n // nil\n case 0xc0:\n this.offset++;\n return null;\n\n // 0xc1 never used - use for undefined (NON-STANDARD)\n case 0xc1:\n this.offset++;\n return undefined;\n\n // false\n case 0xc2:\n this.offset++;\n return false;\n\n // true\n case 0xc3:\n this.offset++;\n return true;\n\n // bin 8\n case 0xc4:\n length = this.view.getUint8(this.offset + 1);\n this.offset += 2;\n return this.bin(length);\n\n // bin 16\n case 0xc5:\n length = this.view.getUint16(this.offset + 1);\n this.offset += 3;\n return this.bin(length);\n\n // bin 32\n case 0xc6:\n length = this.view.getUint32(this.offset + 1);\n this.offset += 5;\n return this.bin(length);\n\n // ext 8\n case 0xc7:\n length = this.view.getUint8(this.offset + 1);\n this.offset += 2;\n return this.ext(length);\n\n // ext 16\n case 0xc8:\n length = this.view.getUint16(this.offset + 1);\n this.offset += 3;\n return this.ext(length);\n\n // ext 32\n case 0xc9:\n length = this.view.getUint32(this.offset + 1);\n this.offset += 5;\n return this.ext(length);\n\n // float 32\n case 0xca:\n value = this.view.getFloat32(this.offset + 1);\n this.offset += 5;\n return value;\n\n // float 64\n case 0xcb:\n value = this.view.getFloat64(this.offset + 1);\n this.offset += 9;\n return value;\n\n // uint8\n case 0xcc:\n value = this.view.getUint8(this.offset + 1);\n this.offset += 2;\n return value;\n\n // uint 16\n case 0xcd:\n value = this.view.getUint16(this.offset + 1);\n this.offset += 3;\n return value;\n\n // uint 32\n case 0xce:\n value = this.view.getUint32(this.offset + 1);\n this.offset += 5;\n return value;\n\n // uint 64\n case 0xcf:\n value = getUint64(this.view, this.offset + 1);\n this.offset += 9;\n return value;\n\n // int 8\n case 0xd0:\n value = this.view.getInt8(this.offset + 1);\n this.offset += 2;\n return value;\n\n // int 16\n case 0xd1:\n value = this.view.getInt16(this.offset + 1);\n this.offset += 3;\n return value;\n\n // int 32\n case 0xd2:\n value = this.view.getInt32(this.offset + 1);\n this.offset += 5;\n return value;\n\n // int 64\n case 0xd3:\n value = getInt64(this.view, this.offset + 1);\n this.offset += 9;\n return value;\n\n // fixext 1\n case 0xd4:\n length = 1;\n this.offset++;\n return this.ext(length);\n\n // fixext 2\n case 0xd5:\n length = 2;\n this.offset++;\n return this.ext(length);\n\n // fixext 4\n case 0xd6:\n length = 4;\n this.offset++;\n return this.ext(length);\n\n // fixext 8\n case 0xd7:\n length = 8;\n this.offset++;\n return this.ext(length);\n\n // fixext 16\n case 0xd8:\n length = 16;\n this.offset++;\n return this.ext(length);\n\n // str8\n case 0xd9:\n length = this.view.getUint8(this.offset + 1);\n this.offset += 2;\n return this.str(length);\n\n // str 16\n case 0xda:\n length = this.view.getUint16(this.offset + 1);\n this.offset += 3;\n return this.str(length);\n\n // str 32\n case 0xdb:\n length = this.view.getUint32(this.offset + 1);\n this.offset += 5;\n return this.str(length);\n\n // array 16\n case 0xdc:\n length = this.view.getUint16(this.offset + 1);\n this.offset += 3;\n return this.array(length);\n\n // array 32\n case 0xdd:\n length = this.view.getUint32(this.offset + 1);\n this.offset += 5;\n return this.array(length);\n\n // map 16\n case 0xde:\n length = this.view.getUint16(this.offset + 1);\n this.offset += 3;\n return this.map(length);\n\n // map 32\n case 0xdf:\n length = this.view.getUint32(this.offset + 1);\n this.offset += 5;\n return this.map(length);\n }\n throw new Error('Unknown type 0x' + type.toString(16));\n };\n}\n\nfunction decode(buffer: ArrayBuffer) {\n const view = new DataView(buffer);\n const decoder = new Decoder(view);\n const value = decoder.parse();\n if (decoder.offset !== buffer.byteLength) throw new Error(buffer.byteLength - decoder.offset + ' trailing bytes');\n return value;\n}\n\nfunction encodeableKeys(value: { [key: string]: unknown }, sparse?: boolean) {\n return Object.keys(value).filter(function (e) {\n const val = value[e],\n type = typeof val;\n return (!sparse || (val !== undefined && val !== null)) && ('function' !== type || !!(val as Date).toJSON);\n });\n}\n\nfunction _encode(value: unknown, view: DataView, offset: number, sparse?: boolean): number {\n const type = typeof value;\n\n // Strings Bytes\n // There are four string types: fixstr/str8/str16/str32\n if (typeof value === 'string') {\n const length = utf8ByteCount(value);\n\n // fixstr\n if (length < 0x20) {\n view.setUint8(offset, length | 0xa0);\n utf8Write(view, offset + 1, value);\n return 1 + length;\n }\n\n // str8\n if (length < 0x100) {\n view.setUint8(offset, 0xd9);\n view.setUint8(offset + 1, length);\n utf8Write(view, offset + 2, value);\n return 2 + length;\n }\n\n // str16\n if (length < 0x10000) {\n view.setUint8(offset, 0xda);\n view.setUint16(offset + 1, length);\n utf8Write(view, offset + 3, value);\n return 3 + length;\n }\n // str32\n if (length < 0x100000000) {\n view.setUint8(offset, 0xdb);\n view.setUint32(offset + 1, length);\n utf8Write(view, offset + 5, value);\n return 5 + length;\n }\n }\n\n if (ArrayBuffer.isView && ArrayBuffer.isView(value)) {\n // extract the arraybuffer and fallthrough\n value = value.buffer;\n }\n\n // There are three bin types: bin8/bin16/bin32\n if (value instanceof ArrayBuffer) {\n const length = value.byteLength;\n\n // bin8\n if (length < 0x100) {\n view.setUint8(offset, 0xc4);\n view.setUint8(offset + 1, length);\n new Uint8Array(view.buffer).set(new Uint8Array(value), offset + 2);\n return 2 + length;\n }\n\n // bin16\n if (length < 0x10000) {\n view.setUint8(offset, 0xc5);\n view.setUint16(offset + 1, length);\n new Uint8Array(view.buffer).set(new Uint8Array(value), offset + 3);\n return 3 + length;\n }\n\n // bin 32\n if (length < 0x100000000) {\n view.setUint8(offset, 0xc6);\n view.setUint32(offset + 1, length);\n new Uint8Array(view.buffer).set(new Uint8Array(value), offset + 5);\n return 5 + length;\n }\n }\n\n if (typeof value === 'number') {\n // Floating Point\n // NOTE: We're always using float64\n if (Math.floor(value) !== value) {\n view.setUint8(offset, 0xcb);\n view.setFloat64(offset + 1, value);\n return 9;\n }\n\n // Integers\n if (value >= 0) {\n // positive fixnum\n if (value < 0x80) {\n view.setUint8(offset, value);\n return 1;\n }\n // uint 8\n if (value < 0x100) {\n view.setUint8(offset, 0xcc);\n view.setUint8(offset + 1, value);\n return 2;\n }\n // uint 16\n if (value < 0x10000) {\n view.setUint8(offset, 0xcd);\n view.setUint16(offset + 1, value);\n return 3;\n }\n // uint 32\n if (value < 0x100000000) {\n view.setUint8(offset, 0xce);\n view.setUint32(offset + 1, value);\n return 5;\n }\n // uint 64\n if (value < 0x10000000000000000) {\n view.setUint8(offset, 0xcf);\n setUint64(view, offset + 1, value);\n return 9;\n }\n throw new Error('Number too big 0x' + value.toString(16));\n }\n\n // negative fixnum\n if (value >= -0x20) {\n view.setInt8(offset, value);\n return 1;\n }\n // int 8\n if (value >= -0x80) {\n view.setUint8(offset, 0xd0);\n view.setInt8(offset + 1, value);\n return 2;\n }\n // int 16\n if (value >= -0x8000) {\n view.setUint8(offset, 0xd1);\n view.setInt16(offset + 1, value);\n return 3;\n }\n // int 32\n if (value >= -0x80000000) {\n view.setUint8(offset, 0xd2);\n view.setInt32(offset + 1, value);\n return 5;\n }\n // int 64\n if (value >= -0x8000000000000000) {\n view.setUint8(offset, 0xd3);\n setInt64(view, offset + 1, value);\n return 9;\n }\n throw new Error('Number too small -0x' + (-value).toString(16).substr(1));\n }\n\n // undefined - use d4 (NON-STANDARD)\n if (type === 'undefined') {\n if (sparse) return 0;\n view.setUint8(offset, 0xd4);\n view.setUint8(offset + 1, 0x00);\n view.setUint8(offset + 2, 0x00);\n return 3;\n }\n\n // null\n if (value === null) {\n if (sparse) return 0;\n view.setUint8(offset, 0xc0);\n return 1;\n }\n\n // Boolean\n if (type === 'boolean') {\n view.setUint8(offset, value ? 0xc3 : 0xc2);\n return 1;\n }\n\n if ('function' === typeof (value as Date).toJSON) return _encode((value as Date).toJSON(), view, offset, sparse);\n\n // Container Types\n if (type === 'object') {\n let length: number,\n size = 0;\n let keys: string[] | undefined;\n const isArray = Array.isArray(value);\n\n if (isArray) {\n length = (value as unknown[]).length;\n } else {\n keys = encodeableKeys(value as { [key: string]: unknown }, sparse);\n length = keys.length;\n }\n\n if (length < 0x10) {\n view.setUint8(offset, length | (isArray ? 0x90 : 0x80));\n size = 1;\n } else if (length < 0x10000) {\n view.setUint8(offset, isArray ? 0xdc : 0xde);\n view.setUint16(offset + 1, length);\n size = 3;\n } else if (length < 0x100000000) {\n view.setUint8(offset, isArray ? 0xdd : 0xdf);\n view.setUint32(offset + 1, length);\n size = 5;\n }\n\n if (isArray) {\n for (let i = 0; i < length; i++) {\n size += _encode((value as unknown[])[i], view, offset + size, sparse);\n }\n } else if (keys) {\n for (let i = 0; i < length; i++) {\n const key = keys[i];\n size += _encode(key, view, offset + size);\n size += _encode((value as { [key: string]: unknown })[key], view, offset + size, sparse);\n }\n }\n\n return size;\n }\n if (type === 'function') return 0;\n\n throw new Error('Unknown type ' + type);\n}\n\nfunction sizeof(value: unknown, sparse?: boolean): number {\n const type = typeof value;\n\n // fixstr or str8 or str16 or str32\n if (type === 'string') {\n const length = utf8ByteCount(value as string);\n if (length < 0x20) {\n return 1 + length;\n }\n if (length < 0x100) {\n return 2 + length;\n }\n if (length < 0x10000) {\n return 3 + length;\n }\n if (length < 0x100000000) {\n return 5 + length;\n }\n }\n\n if (ArrayBuffer.isView && ArrayBuffer.isView(value)) {\n // extract the arraybuffer and fallthrough\n value = value.buffer;\n }\n\n // bin8 or bin16 or bin32\n if (value instanceof ArrayBuffer) {\n const length = value.byteLength;\n if (length < 0x100) {\n return 2 + length;\n }\n if (length < 0x10000) {\n return 3 + length;\n }\n if (length < 0x100000000) {\n return 5 + length;\n }\n }\n\n if (typeof value === 'number') {\n // Floating Point (32 bits)\n // double\n if (Math.floor(value) !== value) return 9;\n\n // Integers\n if (value >= 0) {\n // positive fixint\n if (value < 0x80) return 1;\n // uint 8\n if (value < 0x100) return 2;\n // uint 16\n if (value < 0x10000) return 3;\n // uint 32\n if (value < 0x100000000) return 5;\n // uint 64\n if (value < 0x10000000000000000) return 9;\n // Too big\n throw new Error('Number too big 0x' + value.toString(16));\n }\n // negative fixint\n if (value >= -0x20) return 1;\n // int 8\n if (value >= -0x80) return 2;\n // int 16\n if (value >= -0x8000) return 3;\n // int 32\n if (value >= -0x80000000) return 5;\n // int 64\n if (value >= -0x8000000000000000) return 9;\n // Too small\n throw new Error('Number too small -0x' + value.toString(16).substr(1));\n }\n\n // Boolean\n if (type === 'boolean') return 1;\n\n // undefined, null\n if (value === null) return sparse ? 0 : 1;\n if (value === undefined) return sparse ? 0 : 3;\n\n if ('function' === typeof (value as Date).toJSON) return sizeof((value as Date).toJSON(), sparse);\n\n // Container Types\n if (type === 'object') {\n let length: number,\n size = 0;\n if (Array.isArray(value)) {\n length = value.length;\n for (let i = 0; i < length; i++) {\n size += sizeof(value[i], sparse);\n }\n } else {\n const keys = encodeableKeys(value as { [key: string]: unknown }, sparse);\n length = keys.length;\n for (let i = 0; i < length; i++) {\n const key = keys[i];\n size += sizeof(key) + sizeof((value as { [key: string]: unknown })[key], sparse);\n }\n }\n if (length < 0x10) {\n return 1 + size;\n }\n if (length < 0x10000) {\n return 3 + size;\n }\n if (length < 0x100000000) {\n return 5 + size;\n }\n throw new Error('Array or object too long 0x' + length.toString(16));\n }\n if (type === 'function') return 0;\n\n throw new Error('Unknown type ' + type);\n}\n\nexport default {\n encode,\n decode,\n inspect,\n utf8Write,\n utf8Read,\n utf8ByteCount,\n};\n","import HttpMethods from 'common/constants/HttpMethods';\nimport BaseClient from 'common/lib/client/baseclient';\nimport ErrorInfo, { PartialErrorInfo } from 'common/lib/types/errorinfo';\nimport { RequestBody, RequestResultError, ResponseHeaders, RequestParams, RequestResult } from 'common/types/http';\nimport Platform from 'common/platform';\nimport Defaults from 'common/lib/util/defaults';\nimport * as Utils from 'common/lib/util/utils';\n\nfunction isAblyError(responseBody: unknown, headers: Headers): responseBody is { error?: ErrorInfo } {\n return !!headers.get('x-ably-errorcode');\n}\n\nfunction getAblyError(responseBody: unknown, headers: Headers) {\n if (isAblyError(responseBody, headers)) {\n return responseBody.error && ErrorInfo.fromValues(responseBody.error);\n }\n}\n\nfunction convertHeaders(headers: Headers) {\n const result: ResponseHeaders = {};\n\n headers.forEach((value, key) => {\n result[key] = value;\n });\n\n return result;\n}\n\nexport default async function fetchRequest(\n method: HttpMethods,\n client: BaseClient | null,\n uri: string,\n headers: Record<string, string> | null,\n params: RequestParams,\n body: RequestBody | null,\n): Promise<RequestResult> {\n const fetchHeaders = new Headers(headers || {});\n const _method = method ? method.toUpperCase() : Utils.isNil(body) ? 'GET' : 'POST';\n\n const controller = new AbortController();\n\n let timeout: ReturnType<typeof setTimeout>; // This way we don’t have to worry about the fact that the TypeScript compiler is — for reasons I haven’t looked into — picking up the signature of the Node version of setTimeout, which has a different return type to the web one\n const timeoutPromise: Promise<RequestResult> = new Promise((resolve) => {\n timeout = setTimeout(\n () => {\n controller.abort();\n // When AbortController.abort() is called, the fetch() promise rejects with a DOMException named AbortError (source: https://developer.mozilla.org/en-US/docs/Web/API/AbortController)\n // However, we beat it in the Promise.race() by resolving our custom 'Request timed out' error on the next line, thereby exposing users to the better-formatted error.\n resolve({ error: new PartialErrorInfo('Request timed out', null, 408) });\n },\n client ? client.options.timeouts.httpRequestTimeout : Defaults.TIMEOUTS.httpRequestTimeout,\n );\n });\n\n const requestInit: RequestInit = {\n method: _method,\n headers: fetchHeaders,\n body: body as any,\n signal: controller.signal,\n };\n\n if (!Platform.Config.isWebworker) {\n requestInit.credentials = fetchHeaders.has('authorization') ? 'include' : 'same-origin';\n }\n\n const resultPromise = (async (): Promise<RequestResult> => {\n try {\n const urlParams = new URLSearchParams(params || {});\n urlParams.set('rnd', Utils.cheapRandStr());\n const preparedURI = uri + '?' + urlParams;\n const res = await Utils.getGlobalObject().fetch(preparedURI, requestInit);\n\n clearTimeout(timeout!);\n\n if (res.status == 204) {\n return { error: null, statusCode: res.status };\n }\n\n const contentType = res.headers.get('Content-Type');\n let body;\n if (contentType && contentType.indexOf('application/x-msgpack') > -1) {\n body = await res.arrayBuffer();\n } else if (contentType && contentType.indexOf('application/json') > -1) {\n body = await res.json();\n } else {\n body = await res.text();\n }\n\n const unpacked = !!contentType && contentType.indexOf('application/x-msgpack') === -1;\n const headers = convertHeaders(res.headers);\n\n if (!res.ok) {\n const error =\n getAblyError(body, res.headers) ||\n new PartialErrorInfo(\n 'Error response received from server: ' + res.status + ' body was: ' + Platform.Config.inspect(body),\n null,\n res.status,\n );\n\n return { error, body, headers, unpacked, statusCode: res.status };\n } else {\n return { error: null, body, headers, unpacked, statusCode: res.status };\n }\n } catch (error) {\n clearTimeout(timeout!);\n return { error: error as RequestResultError };\n }\n })();\n\n return Promise.race([timeoutPromise, resultPromise]);\n}\n","import { HTTPRequestImplementations } from '../http';\nimport XHRRequest from './xhrrequest';\nimport fetchRequest from './fetchrequest';\n\nexport const defaultBundledRequestImplementations: HTTPRequestImplementations = {\n XHRRequest: XHRRequest,\n FetchRequest: fetchRequest,\n};\n\nexport const modularBundledRequestImplementations: HTTPRequestImplementations = {};\n","import { BaseportalChat } from './widget'\n\nexport { BaseportalChat }\nexport type {\n BaseportalChatConfig,\n ChannelInfo,\n Conversation,\n Message,\n VisitorData,\n} from './api/types'\n\nexport default BaseportalChat\n","import type { ChannelInfo, Conversation, Message } from './types'\n\nexport class ApiClient {\n private baseUrl: string\n private channelToken: string\n private visitorEmail?: string\n private visitorHash?: string\n\n constructor(channelToken: string, apiUrl: string) {\n this.channelToken = channelToken\n this.baseUrl = `${apiUrl}/public/chat`\n }\n\n setVisitorIdentity(email: string, hash?: string): void {\n this.visitorEmail = email\n this.visitorHash = hash\n }\n\n clearVisitorIdentity(): void {\n this.visitorEmail = undefined\n this.visitorHash = undefined\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-channel-token': this.channelToken,\n }\n if (this.visitorEmail) h['x-visitor-email'] = this.visitorEmail\n if (this.visitorHash) h['x-visitor-hash'] = this.visitorHash\n return h\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: this.headers(),\n body: body ? JSON.stringify(body) : undefined,\n })\n\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`[BaseportalChat] API error ${res.status}: ${text}`)\n }\n\n return res.json()\n }\n\n async getChannelInfo(): Promise<ChannelInfo> {\n return this.request('GET', '/channel-info')\n }\n\n async initConversation(data: {\n name?: string\n email?: string\n }): Promise<Conversation & { messages?: Message[] }> {\n return this.request('POST', '/conversations', {\n ...data,\n channelToken: this.channelToken,\n })\n }\n\n async getMessages(\n conversationId: string,\n params?: { limit?: number; page?: number }\n ): Promise<Message[]> {\n const qs = new URLSearchParams()\n if (params?.limit) qs.set('limit', String(params.limit))\n if (params?.page) qs.set('page', String(params.page))\n const query = qs.toString() ? `?${qs.toString()}` : ''\n return this.request('GET', `/conversations/${conversationId}/messages${query}`)\n }\n\n async uploadFile(conversationId: string, file: File): Promise<{ id: string; url: string; name: string; mimeType: string }> {\n const formData = new FormData()\n formData.append('file', file)\n\n const headers: Record<string, string> = {\n 'x-channel-token': this.channelToken,\n }\n if (this.visitorEmail) headers['x-visitor-email'] = this.visitorEmail\n if (this.visitorHash) headers['x-visitor-hash'] = this.visitorHash\n\n const res = await fetch(`${this.baseUrl}/conversations/${conversationId}/upload`, {\n method: 'POST',\n headers,\n body: formData,\n })\n\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`[BaseportalChat] Upload error ${res.status}: ${text}`)\n }\n\n return res.json()\n }\n\n async sendMessage(\n conversationId: string,\n data: { content?: string; mediaId?: string }\n ): Promise<Message> {\n return this.request(\n 'POST',\n `/conversations/${conversationId}/messages`,\n data\n )\n }\n\n async getVisitorConversations(): Promise<Conversation[]> {\n return this.request('GET', '/conversations')\n }\n\n async reopenConversation(conversationId: string): Promise<Conversation> {\n return this.request('POST', `/conversations/${conversationId}/reopen`)\n }\n\n async getAblyToken(conversationId: string): Promise<unknown> {\n return this.request('POST', '/ably-token', { conversationId })\n }\n}\n","import * as Ably from 'ably'\n\nimport type { ApiClient } from '../api/client'\nimport type { Conversation, Message } from '../api/types'\n\nexport interface RealtimeHandlers {\n onMessage: (message: Message) => void\n onConversationStatusUpdate: (conversation: Conversation) => void\n}\n\nexport class RealtimeClient {\n private client: Ably.Realtime | null = null\n private channel: Ably.RealtimeChannel | null = null\n private conversationId: string | null = null\n private apiClient: ApiClient\n private handlers: RealtimeHandlers | null = null\n\n constructor(apiClient: ApiClient) {\n this.apiClient = apiClient\n }\n\n async subscribe(\n conversationId: string,\n handlers: RealtimeHandlers\n ): Promise<void> {\n // Unsubscribe from previous if any\n this.unsubscribe()\n\n this.conversationId = conversationId\n this.handlers = handlers\n\n try {\n const tokenRequest = await this.apiClient.getAblyToken(conversationId)\n\n this.client = new Ably.Realtime({\n authCallback: (_data, callback) => {\n callback(null, tokenRequest as Ably.TokenRequest)\n },\n clientId: `visitor-${conversationId}`,\n })\n\n const channelName = `conversation-${conversationId}`\n this.channel = this.client.channels.get(channelName)\n\n this.channel.subscribe((msg) => {\n if (!msg.data) return\n\n try {\n const data =\n typeof msg.data === 'string' ? JSON.parse(msg.data) : msg.data\n\n if (data.text === 'conversation_status_updated' && data.metadata) {\n handlers.onConversationStatusUpdate(data.metadata as Conversation)\n } else if (\n data.text === 'created_or_updated_message' &&\n data.metadata\n ) {\n handlers.onMessage(data.metadata as Message)\n }\n } catch (e) {\n console.error('[BaseportalChat] Error parsing realtime message:', e)\n }\n })\n } catch (e) {\n console.error('[BaseportalChat] Error connecting to realtime:', e)\n }\n }\n\n unsubscribe(): void {\n if (this.channel) {\n this.channel.unsubscribe()\n this.channel = null\n }\n if (this.client) {\n this.client.close()\n this.client = null\n }\n this.conversationId = null\n this.handlers = null\n }\n\n isConnected(): boolean {\n return this.client?.connection.state === 'connected'\n }\n}\n","export interface Translations {\n prechat: {\n title: string\n description: string\n name: string\n namePlaceholder: string\n email: string\n emailPlaceholder: string\n start: string\n loading: string\n privacyPrefix: string\n privacyLink: string\n }\n chat: {\n placeholder: string\n closed: string\n reopen: string\n attachFile: string\n uploading: string\n fileTooLarge: string\n download: string\n }\n conversations: {\n title: string\n newConversation: string\n empty: string\n open: string\n closed: string\n noMessages: string\n }\n}\n\nconst pt: Translations = {\n prechat: {\n title: 'Iniciar conversa',\n description: 'Preencha os dados abaixo para iniciar o atendimento.',\n name: 'Nome',\n namePlaceholder: 'Seu nome',\n email: 'E-mail',\n emailPlaceholder: 'seu@email.com',\n start: 'Iniciar conversa',\n loading: 'Iniciando...',\n privacyPrefix: 'Ao enviar, você concorda com nossa',\n privacyLink: 'Política de Privacidade',\n },\n chat: {\n placeholder: 'Digite uma mensagem...',\n closed: 'Esta conversa foi encerrada.',\n reopen: 'Reabrir conversa',\n attachFile: 'Anexar arquivo',\n uploading: 'Enviando...',\n fileTooLarge: 'Arquivo muito grande (máx. 25MB)',\n download: 'Baixar',\n },\n conversations: {\n title: 'Atendimento',\n newConversation: 'Nova conversa',\n empty: 'Nenhuma conversa encontrada.',\n open: 'Aberta',\n closed: 'Fechada',\n noMessages: 'Nenhuma mensagem ainda',\n },\n}\n\nconst en: Translations = {\n prechat: {\n title: 'Start a conversation',\n description: 'Fill in the details below to start chatting.',\n name: 'Name',\n namePlaceholder: 'Your name',\n email: 'Email',\n emailPlaceholder: 'you@email.com',\n start: 'Start conversation',\n loading: 'Starting...',\n privacyPrefix: 'By sending, you agree to our',\n privacyLink: 'Privacy Policy',\n },\n chat: {\n placeholder: 'Type a message...',\n closed: 'This conversation has been closed.',\n reopen: 'Reopen conversation',\n attachFile: 'Attach file',\n uploading: 'Uploading...',\n fileTooLarge: 'File too large (max 25MB)',\n download: 'Download',\n },\n conversations: {\n title: 'Support',\n newConversation: 'New conversation',\n empty: 'No conversations found.',\n open: 'Open',\n closed: 'Closed',\n noMessages: 'No messages yet',\n },\n}\n\nconst es: Translations = {\n prechat: {\n title: 'Iniciar conversación',\n description: 'Complete los datos a continuación para iniciar la atención.',\n name: 'Nombre',\n namePlaceholder: 'Tu nombre',\n email: 'Correo electrónico',\n emailPlaceholder: 'tu@email.com',\n start: 'Iniciar conversación',\n loading: 'Iniciando...',\n privacyPrefix: 'Al enviar, aceptas nuestra',\n privacyLink: 'Política de Privacidad',\n },\n chat: {\n placeholder: 'Escribe un mensaje...',\n closed: 'Esta conversación ha sido cerrada.',\n reopen: 'Reabrir conversación',\n attachFile: 'Adjuntar archivo',\n uploading: 'Subiendo...',\n fileTooLarge: 'Archivo demasiado grande (máx. 25MB)',\n download: 'Descargar',\n },\n conversations: {\n title: 'Atención',\n newConversation: 'Nueva conversación',\n empty: 'No se encontraron conversaciones.',\n open: 'Abierta',\n closed: 'Cerrada',\n noMessages: 'Sin mensajes aún',\n },\n}\n\nconst locales: Record<string, Translations> = { pt, en, es }\n\nexport function getTranslations(locale: string): Translations {\n return locales[locale] || locales['pt']\n}\n","/** Normal hydration that attaches to a DOM tree but does not diff it. */\nexport const MODE_HYDRATE = 1 << 5;\n/** Signifies this VNode suspended on the previous render */\nexport const MODE_SUSPENDED = 1 << 7;\n/** Indicates that this node needs to be inserted while patching children */\nexport const INSERT_VNODE = 1 << 16;\n/** Indicates a VNode has been matched with another VNode in the diff */\nexport const MATCHED = 1 << 17;\n\n/** Reset all mode flags */\nexport const RESET_MODE = ~(MODE_HYDRATE | MODE_SUSPENDED);\n\nexport const UNDEFINED = undefined;\nexport const EMPTY_OBJ = /** @type {any} */ ({});\nexport const EMPTY_ARR = [];\nexport const IS_NON_DIMENSIONAL =\n\t/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;\n","import { EMPTY_ARR } from './constants';\n\nexport const isArray = Array.isArray;\n\n/**\n * Assign properties from `props` to `obj`\n * @template O, P The obj and props types\n * @param {O} obj The object to copy properties to\n * @param {P} props The object to copy properties from\n * @returns {O & P}\n */\nexport function assign(obj, props) {\n\t// @ts-expect-error We change the type of `obj` to be `O & P`\n\tfor (let i in props) obj[i] = props[i];\n\treturn /** @type {O & P} */ (obj);\n}\n\n/**\n * Remove a child node from its parent if attached. This is a workaround for\n * IE11 which doesn't support `Element.prototype.remove()`. Using this function\n * is smaller than including a dedicated polyfill.\n * @param {preact.ContainerNode} node The node to remove\n */\nexport function removeNode(node) {\n\tif (node && node.parentNode) node.parentNode.removeChild(node);\n}\n\nexport const slice = EMPTY_ARR.slice;\n","import { _catchError } from './diff/catch-error';\n\n/**\n * The `option` object can potentially contain callback functions\n * that are called during various stages of our renderer. This is the\n * foundation on which all our addons like `preact/debug`, `preact/compat`,\n * and `preact/hooks` are based on. See the `Options` type in `internal.d.ts`\n * for a full list of available option hooks (most editors/IDEs allow you to\n * ctrl+click or cmd+click on mac the type definition below).\n * @type {Options}\n */\nconst options = {\n\t_catchError\n};\n\nexport default options;\n","import { slice } from './util';\nimport options from './options';\nimport { UNDEFINED } from './constants';\n\nlet vnodeId = 0;\n\n/**\n * Create an virtual node (used for JSX)\n * @param {VNode[\"type\"]} type The node name or Component constructor for this\n * virtual node\n * @param {object | null | undefined} [props] The properties of the virtual node\n * @param {Array<import('.').ComponentChildren>} [children] The children of the\n * virtual node\n * @returns {VNode}\n */\nexport function createElement(type, props, children) {\n\tlet normalizedProps = {},\n\t\tkey,\n\t\tref,\n\t\ti;\n\tfor (i in props) {\n\t\tif (i == 'key') key = props[i];\n\t\telse if (i == 'ref') ref = props[i];\n\t\telse normalizedProps[i] = props[i];\n\t}\n\n\tif (arguments.length > 2) {\n\t\tnormalizedProps.children =\n\t\t\targuments.length > 3 ? slice.call(arguments, 2) : children;\n\t}\n\n\t// If a Component VNode, check for and apply defaultProps\n\t// Note: type may be undefined in development, must never error here.\n\tif (typeof type == 'function' && type.defaultProps != null) {\n\t\tfor (i in type.defaultProps) {\n\t\t\tif (normalizedProps[i] === UNDEFINED) {\n\t\t\t\tnormalizedProps[i] = type.defaultProps[i];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn createVNode(type, normalizedProps, key, ref, null);\n}\n\n/**\n * Create a VNode (used internally by Preact)\n * @param {VNode[\"type\"]} type The node name or Component\n * Constructor for this virtual node\n * @param {object | string | number | null} props The properties of this virtual node.\n * If this virtual node represents a text node, this is the text of the node (string or number).\n * @param {string | number | null} key The key for this virtual node, used when\n * diffing it against its children\n * @param {VNode[\"ref\"]} ref The ref property that will\n * receive a reference to its created child\n * @returns {VNode}\n */\nexport function createVNode(type, props, key, ref, original) {\n\t// V8 seems to be better at detecting type shapes if the object is allocated from the same call site\n\t// Do not inline into createElement and coerceToVNode!\n\t/** @type {VNode} */\n\tconst vnode = {\n\t\ttype,\n\t\tprops,\n\t\tkey,\n\t\tref,\n\t\t_children: null,\n\t\t_parent: null,\n\t\t_depth: 0,\n\t\t_dom: null,\n\t\t// _nextDom must be initialized to undefined b/c it will eventually\n\t\t// be set to dom.nextSibling which can return `null` and it is important\n\t\t// to be able to distinguish between an uninitialized _nextDom and\n\t\t// a _nextDom that has been set to `null`\n\t\t_nextDom: UNDEFINED,\n\t\t_component: null,\n\t\tconstructor: UNDEFINED,\n\t\t_original: original == null ? ++vnodeId : original,\n\t\t_index: -1,\n\t\t_flags: 0\n\t};\n\n\t// Only invoke the vnode hook if this was *not* a direct copy:\n\tif (original == null && options.vnode != null) options.vnode(vnode);\n\n\treturn vnode;\n}\n\nexport function createRef() {\n\treturn { current: null };\n}\n\nexport function Fragment(props) {\n\treturn props.children;\n}\n\n/**\n * Check if a the argument is a valid Preact VNode.\n * @param {*} vnode\n * @returns {vnode is VNode}\n */\nexport const isValidElement = vnode =>\n\tvnode != null && vnode.constructor == UNDEFINED;\n","import { assign } from './util';\nimport { diff, commitRoot } from './diff/index';\nimport options from './options';\nimport { Fragment } from './create-element';\nimport { MODE_HYDRATE } from './constants';\n\n/**\n * Base Component class. Provides `setState()` and `forceUpdate()`, which\n * trigger rendering\n * @param {object} props The initial component props\n * @param {object} context The initial context from parent components'\n * getChildContext\n */\nexport function BaseComponent(props, context) {\n\tthis.props = props;\n\tthis.context = context;\n}\n\n/**\n * Update component state and schedule a re-render.\n * @this {Component}\n * @param {object | ((s: object, p: object) => object)} update A hash of state\n * properties to update with new values or a function that given the current\n * state and props returns a new partial state\n * @param {() => void} [callback] A function to be called once component state is\n * updated\n */\nBaseComponent.prototype.setState = function (update, callback) {\n\t// only clone state when copying to nextState the first time.\n\tlet s;\n\tif (this._nextState != null && this._nextState !== this.state) {\n\t\ts = this._nextState;\n\t} else {\n\t\ts = this._nextState = assign({}, this.state);\n\t}\n\n\tif (typeof update == 'function') {\n\t\t// Some libraries like `immer` mark the current state as readonly,\n\t\t// preventing us from mutating it, so we need to clone it. See #2716\n\t\tupdate = update(assign({}, s), this.props);\n\t}\n\n\tif (update) {\n\t\tassign(s, update);\n\t}\n\n\t// Skip update if updater function returned null\n\tif (update == null) return;\n\n\tif (this._vnode) {\n\t\tif (callback) {\n\t\t\tthis._stateCallbacks.push(callback);\n\t\t}\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Immediately perform a synchronous re-render of the component\n * @this {Component}\n * @param {() => void} [callback] A function to be called after component is\n * re-rendered\n */\nBaseComponent.prototype.forceUpdate = function (callback) {\n\tif (this._vnode) {\n\t\t// Set render mode so that we can differentiate where the render request\n\t\t// is coming from. We need this because forceUpdate should never call\n\t\t// shouldComponentUpdate\n\t\tthis._force = true;\n\t\tif (callback) this._renderCallbacks.push(callback);\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Accepts `props` and `state`, and returns a new Virtual DOM tree to build.\n * Virtual DOM is generally constructed via [JSX](http://jasonformat.com/wtf-is-jsx).\n * @param {object} props Props (eg: JSX attributes) received from parent\n * element/component\n * @param {object} state The component's current state\n * @param {object} context Context object, as returned by the nearest\n * ancestor's `getChildContext()`\n * @returns {ComponentChildren | void}\n */\nBaseComponent.prototype.render = Fragment;\n\n/**\n * @param {VNode} vnode\n * @param {number | null} [childIndex]\n */\nexport function getDomSibling(vnode, childIndex) {\n\tif (childIndex == null) {\n\t\t// Use childIndex==null as a signal to resume the search from the vnode's sibling\n\t\treturn vnode._parent\n\t\t\t? getDomSibling(vnode._parent, vnode._index + 1)\n\t\t\t: null;\n\t}\n\n\tlet sibling;\n\tfor (; childIndex < vnode._children.length; childIndex++) {\n\t\tsibling = vnode._children[childIndex];\n\n\t\tif (sibling != null && sibling._dom != null) {\n\t\t\t// Since updateParentDomPointers keeps _dom pointer correct,\n\t\t\t// we can rely on _dom to tell us if this subtree contains a\n\t\t\t// rendered DOM node, and what the first rendered DOM node is\n\t\t\treturn sibling._dom;\n\t\t}\n\t}\n\n\t// If we get here, we have not found a DOM node in this vnode's children.\n\t// We must resume from this vnode's sibling (in it's parent _children array)\n\t// Only climb up and search the parent if we aren't searching through a DOM\n\t// VNode (meaning we reached the DOM parent of the original vnode that began\n\t// the search)\n\treturn typeof vnode.type == 'function' ? getDomSibling(vnode) : null;\n}\n\n/**\n * Trigger in-place re-rendering of a component.\n * @param {Component} component The component to rerender\n */\nfunction renderComponent(component) {\n\tlet oldVNode = component._vnode,\n\t\toldDom = oldVNode._dom,\n\t\tcommitQueue = [],\n\t\trefQueue = [];\n\n\tif (component._parentDom) {\n\t\tconst newVNode = assign({}, oldVNode);\n\t\tnewVNode._original = oldVNode._original + 1;\n\t\tif (options.vnode) options.vnode(newVNode);\n\n\t\tdiff(\n\t\t\tcomponent._parentDom,\n\t\t\tnewVNode,\n\t\t\toldVNode,\n\t\t\tcomponent._globalContext,\n\t\t\tcomponent._parentDom.namespaceURI,\n\t\t\toldVNode._flags & MODE_HYDRATE ? [oldDom] : null,\n\t\t\tcommitQueue,\n\t\t\toldDom == null ? getDomSibling(oldVNode) : oldDom,\n\t\t\t!!(oldVNode._flags & MODE_HYDRATE),\n\t\t\trefQueue\n\t\t);\n\n\t\tnewVNode._original = oldVNode._original;\n\t\tnewVNode._parent._children[newVNode._index] = newVNode;\n\t\tcommitRoot(commitQueue, newVNode, refQueue);\n\n\t\tif (newVNode._dom != oldDom) {\n\t\t\tupdateParentDomPointers(newVNode);\n\t\t}\n\t}\n}\n\n/**\n * @param {VNode} vnode\n */\nfunction updateParentDomPointers(vnode) {\n\tif ((vnode = vnode._parent) != null && vnode._component != null) {\n\t\tvnode._dom = vnode._component.base = null;\n\t\tfor (let i = 0; i < vnode._children.length; i++) {\n\t\t\tlet child = vnode._children[i];\n\t\t\tif (child != null && child._dom != null) {\n\t\t\t\tvnode._dom = vnode._component.base = child._dom;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn updateParentDomPointers(vnode);\n\t}\n}\n\n/**\n * The render queue\n * @type {Array<Component>}\n */\nlet rerenderQueue = [];\n\n/*\n * The value of `Component.debounce` must asynchronously invoke the passed in callback. It is\n * important that contributors to Preact can consistently reason about what calls to `setState`, etc.\n * do, and when their effects will be applied. See the links below for some further reading on designing\n * asynchronous APIs.\n * * [Designing APIs for Asynchrony](https://blog.izs.me/2013/08/designing-apis-for-asynchrony)\n * * [Callbacks synchronous and asynchronous](https://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/)\n */\n\nlet prevDebounce;\n\nconst defer =\n\ttypeof Promise == 'function'\n\t\t? Promise.prototype.then.bind(Promise.resolve())\n\t\t: setTimeout;\n\n/**\n * Enqueue a rerender of a component\n * @param {Component} c The component to rerender\n */\nexport function enqueueRender(c) {\n\tif (\n\t\t(!c._dirty &&\n\t\t\t(c._dirty = true) &&\n\t\t\trerenderQueue.push(c) &&\n\t\t\t!process._rerenderCount++) ||\n\t\tprevDebounce !== options.debounceRendering\n\t) {\n\t\tprevDebounce = options.debounceRendering;\n\t\t(prevDebounce || defer)(process);\n\t}\n}\n\n/**\n * @param {Component} a\n * @param {Component} b\n */\nconst depthSort = (a, b) => a._vnode._depth - b._vnode._depth;\n\n/** Flush the render queue by rerendering all queued components */\nfunction process() {\n\tlet c;\n\trerenderQueue.sort(depthSort);\n\t// Don't update `renderCount` yet. Keep its value non-zero to prevent unnecessary\n\t// process() calls from getting scheduled while `queue` is still being consumed.\n\twhile ((c = rerenderQueue.shift())) {\n\t\tif (c._dirty) {\n\t\t\tlet renderQueueLength = rerenderQueue.length;\n\t\t\trenderComponent(c);\n\t\t\tif (rerenderQueue.length > renderQueueLength) {\n\t\t\t\t// When i.e. rerendering a provider additional new items can be injected, we want to\n\t\t\t\t// keep the order from top to bottom with those new items so we can handle them in a\n\t\t\t\t// single pass\n\t\t\t\trerenderQueue.sort(depthSort);\n\t\t\t}\n\t\t}\n\t}\n\tprocess._rerenderCount = 0;\n}\n\nprocess._rerenderCount = 0;\n","import { IS_NON_DIMENSIONAL } from '../constants';\nimport options from '../options';\n\nfunction setStyle(style, key, value) {\n\tif (key[0] === '-') {\n\t\tstyle.setProperty(key, value == null ? '' : value);\n\t} else if (value == null) {\n\t\tstyle[key] = '';\n\t} else if (typeof value != 'number' || IS_NON_DIMENSIONAL.test(key)) {\n\t\tstyle[key] = value;\n\t} else {\n\t\tstyle[key] = value + 'px';\n\t}\n}\n\n// A logical clock to solve issues like https://github.com/preactjs/preact/issues/3927.\n// When the DOM performs an event it leaves micro-ticks in between bubbling up which means that\n// an event can trigger on a newly reated DOM-node while the event bubbles up.\n//\n// Originally inspired by Vue\n// (https://github.com/vuejs/core/blob/caeb8a68811a1b0f79/packages/runtime-dom/src/modules/events.ts#L90-L101),\n// but modified to use a logical clock instead of Date.now() in case event handlers get attached\n// and events get dispatched during the same millisecond.\n//\n// The clock is incremented after each new event dispatch. This allows 1 000 000 new events\n// per second for over 280 years before the value reaches Number.MAX_SAFE_INTEGER (2**53 - 1).\nlet eventClock = 0;\n\n/**\n * Set a property value on a DOM node\n * @param {PreactElement} dom The DOM node to modify\n * @param {string} name The name of the property to set\n * @param {*} value The value to set the property to\n * @param {*} oldValue The old value the property had\n * @param {string} namespace Whether or not this DOM node is an SVG node or not\n */\nexport function setProperty(dom, name, value, oldValue, namespace) {\n\tlet useCapture;\n\n\to: if (name === 'style') {\n\t\tif (typeof value == 'string') {\n\t\t\tdom.style.cssText = value;\n\t\t} else {\n\t\t\tif (typeof oldValue == 'string') {\n\t\t\t\tdom.style.cssText = oldValue = '';\n\t\t\t}\n\n\t\t\tif (oldValue) {\n\t\t\t\tfor (name in oldValue) {\n\t\t\t\t\tif (!(value && name in value)) {\n\t\t\t\t\t\tsetStyle(dom.style, name, '');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (value) {\n\t\t\t\tfor (name in value) {\n\t\t\t\t\tif (!oldValue || value[name] !== oldValue[name]) {\n\t\t\t\t\t\tsetStyle(dom.style, name, value[name]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Benchmark for comparison: https://esbench.com/bench/574c954bdb965b9a00965ac6\n\telse if (name[0] === 'o' && name[1] === 'n') {\n\t\tuseCapture =\n\t\t\tname !== (name = name.replace(/(PointerCapture)$|Capture$/i, '$1'));\n\n\t\t// Infer correct casing for DOM built-in events:\n\t\tif (\n\t\t\tname.toLowerCase() in dom ||\n\t\t\tname === 'onFocusOut' ||\n\t\t\tname === 'onFocusIn'\n\t\t)\n\t\t\tname = name.toLowerCase().slice(2);\n\t\telse name = name.slice(2);\n\n\t\tif (!dom._listeners) dom._listeners = {};\n\t\tdom._listeners[name + useCapture] = value;\n\n\t\tif (value) {\n\t\t\tif (!oldValue) {\n\t\t\t\tvalue._attached = eventClock;\n\t\t\t\tdom.addEventListener(\n\t\t\t\t\tname,\n\t\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\t\tuseCapture\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tvalue._attached = oldValue._attached;\n\t\t\t}\n\t\t} else {\n\t\t\tdom.removeEventListener(\n\t\t\t\tname,\n\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\tuseCapture\n\t\t\t);\n\t\t}\n\t} else {\n\t\tif (namespace == 'http://www.w3.org/2000/svg') {\n\t\t\t// Normalize incorrect prop usage for SVG:\n\t\t\t// - xlink:href / xlinkHref --> href (xlink:href was removed from SVG and isn't needed)\n\t\t\t// - className --> class\n\t\t\tname = name.replace(/xlink(H|:h)/, 'h').replace(/sName$/, 's');\n\t\t} else if (\n\t\t\tname != 'width' &&\n\t\t\tname != 'height' &&\n\t\t\tname != 'href' &&\n\t\t\tname != 'list' &&\n\t\t\tname != 'form' &&\n\t\t\t// Default value in browsers is `-1` and an empty string is\n\t\t\t// cast to `0` instead\n\t\t\tname != 'tabIndex' &&\n\t\t\tname != 'download' &&\n\t\t\tname != 'rowSpan' &&\n\t\t\tname != 'colSpan' &&\n\t\t\tname != 'role' &&\n\t\t\tname != 'popover' &&\n\t\t\tname in dom\n\t\t) {\n\t\t\ttry {\n\t\t\t\tdom[name] = value == null ? '' : value;\n\t\t\t\t// labelled break is 1b smaller here than a return statement (sorry)\n\t\t\t\tbreak o;\n\t\t\t} catch (e) {}\n\t\t}\n\n\t\t// aria- and data- attributes have no boolean representation.\n\t\t// A `false` value is different from the attribute not being\n\t\t// present, so we can't remove it. For non-boolean aria\n\t\t// attributes we could treat false as a removal, but the\n\t\t// amount of exceptions would cost too many bytes. On top of\n\t\t// that other frameworks generally stringify `false`.\n\n\t\tif (typeof value == 'function') {\n\t\t\t// never serialize functions as attribute values\n\t\t} else if (value != null && (value !== false || name[4] === '-')) {\n\t\t\tdom.setAttribute(name, name == 'popover' && value == true ? '' : value);\n\t\t} else {\n\t\t\tdom.removeAttribute(name);\n\t\t}\n\t}\n}\n\n/**\n * Create an event proxy function.\n * @param {boolean} useCapture Is the event handler for the capture phase.\n * @private\n */\nfunction createEventProxy(useCapture) {\n\t/**\n\t * Proxy an event to hooked event handlers\n\t * @param {PreactEvent} e The event object from the browser\n\t * @private\n\t */\n\treturn function (e) {\n\t\tif (this._listeners) {\n\t\t\tconst eventHandler = this._listeners[e.type + useCapture];\n\t\t\tif (e._dispatched == null) {\n\t\t\t\te._dispatched = eventClock++;\n\n\t\t\t\t// When `e._dispatched` is smaller than the time when the targeted event\n\t\t\t\t// handler was attached we know we have bubbled up to an element that was added\n\t\t\t\t// during patching the DOM.\n\t\t\t} else if (e._dispatched < eventHandler._attached) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (options.event) e = options.event(e);\n\t\t\treturn \"handleEvent\" in eventHandler ? eventHandler.handleEvent(e) : eventHandler(e);\n\t\t}\n\t};\n}\n\nconst eventProxy = createEventProxy(false);\nconst eventProxyCapture = createEventProxy(true);\n","import { enqueueRender } from './component';\n\nexport let i = 0;\n\nexport function createContext(defaultValue, contextId) {\n\tcontextId = '__cC' + i++;\n\n\tconst context = {\n\t\t_id: contextId,\n\t\t_defaultValue: defaultValue,\n\t\t/** @type {FunctionComponent} */\n\t\tConsumer(props, contextValue) {\n\t\t\t// return props.children(\n\t\t\t// \tcontext[contextId] ? context[contextId].props.value : defaultValue\n\t\t\t// );\n\t\t\treturn props.children(contextValue);\n\t\t},\n\t\t/** @type {FunctionComponent} */\n\t\tProvider(props) {\n\t\t\tif (!this.getChildContext) {\n\t\t\t\t/** @type {Set<Component> | null} */\n\t\t\t\tlet subs = new Set();\n\t\t\t\tlet ctx = {};\n\t\t\t\tctx[contextId] = this;\n\n\t\t\t\tthis.getChildContext = () => ctx;\n\n\t\t\t\tthis.componentWillUnmount = () => {\n\t\t\t\t\tsubs = null;\n\t\t\t\t};\n\n\t\t\t\tthis.shouldComponentUpdate = function (_props) {\n\t\t\t\t\tif (this.props.value !== _props.value) {\n\t\t\t\t\t\tsubs.forEach(c => {\n\t\t\t\t\t\t\tc._force = true;\n\t\t\t\t\t\t\tenqueueRender(c);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tthis.sub = c => {\n\t\t\t\t\tsubs.add(c);\n\t\t\t\t\tlet old = c.componentWillUnmount;\n\t\t\t\t\tc.componentWillUnmount = () => {\n\t\t\t\t\t\tif (subs) {\n\t\t\t\t\t\t\tsubs.delete(c);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (old) old.call(c);\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn props.children;\n\t\t}\n\t};\n\n\t// Devtools needs access to the context object when it\n\t// encounters a Provider. This is necessary to support\n\t// setting `displayName` on the context object instead\n\t// of on the component itself. See:\n\t// https://reactjs.org/docs/context.html#contextdisplayname\n\n\treturn (context.Provider._contextRef = context.Consumer.contextType =\n\t\tcontext);\n}\n","import { diff, unmount, applyRef } from './index';\nimport { createVNode, Fragment } from '../create-element';\nimport {\n\tEMPTY_OBJ,\n\tEMPTY_ARR,\n\tINSERT_VNODE,\n\tMATCHED,\n\tUNDEFINED\n} from '../constants';\nimport { isArray } from '../util';\nimport { getDomSibling } from '../component';\n\n/**\n * Diff the children of a virtual node\n * @param {PreactElement} parentDom The DOM element whose children are being\n * diffed\n * @param {ComponentChildren[]} renderResult\n * @param {VNode} newParentVNode The new virtual node whose children should be\n * diff'ed against oldParentVNode\n * @param {VNode} oldParentVNode The old virtual node whose children should be\n * diff'ed against newParentVNode\n * @param {object} globalContext The current context object - modified by\n * getChildContext\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array<PreactElement>} excessDomChildren\n * @param {Array<Component>} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {PreactElement} oldDom The current attached DOM element any new dom\n * elements should be placed around. Likely `null` on first render (except when\n * hydrating). Can be a sibling DOM element when diffing Fragments that have\n * siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n */\nexport function diffChildren(\n\tparentDom,\n\trenderResult,\n\tnewParentVNode,\n\toldParentVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating,\n\trefQueue\n) {\n\tlet i,\n\t\t/** @type {VNode} */\n\t\toldVNode,\n\t\t/** @type {VNode} */\n\t\tchildVNode,\n\t\t/** @type {PreactElement} */\n\t\tnewDom,\n\t\t/** @type {PreactElement} */\n\t\tfirstChildDom;\n\n\t// This is a compression of oldParentVNode!=null && oldParentVNode != EMPTY_OBJ && oldParentVNode._children || EMPTY_ARR\n\t// as EMPTY_OBJ._children should be `undefined`.\n\t/** @type {VNode[]} */\n\tlet oldChildren = (oldParentVNode && oldParentVNode._children) || EMPTY_ARR;\n\n\tlet newChildrenLength = renderResult.length;\n\n\tnewParentVNode._nextDom = oldDom;\n\tconstructNewChildrenArray(newParentVNode, renderResult, oldChildren);\n\toldDom = newParentVNode._nextDom;\n\n\tfor (i = 0; i < newChildrenLength; i++) {\n\t\tchildVNode = newParentVNode._children[i];\n\t\tif (childVNode == null) continue;\n\n\t\t// At this point, constructNewChildrenArray has assigned _index to be the\n\t\t// matchingIndex for this VNode's oldVNode (or -1 if there is no oldVNode).\n\t\tif (childVNode._index === -1) {\n\t\t\toldVNode = EMPTY_OBJ;\n\t\t} else {\n\t\t\toldVNode = oldChildren[childVNode._index] || EMPTY_OBJ;\n\t\t}\n\n\t\t// Update childVNode._index to its final index\n\t\tchildVNode._index = i;\n\n\t\t// Morph the old element into the new one, but don't append it to the dom yet\n\t\tdiff(\n\t\t\tparentDom,\n\t\t\tchildVNode,\n\t\t\toldVNode,\n\t\t\tglobalContext,\n\t\t\tnamespace,\n\t\t\texcessDomChildren,\n\t\t\tcommitQueue,\n\t\t\toldDom,\n\t\t\tisHydrating,\n\t\t\trefQueue\n\t\t);\n\n\t\t// Adjust DOM nodes\n\t\tnewDom = childVNode._dom;\n\t\tif (childVNode.ref && oldVNode.ref != childVNode.ref) {\n\t\t\tif (oldVNode.ref) {\n\t\t\t\tapplyRef(oldVNode.ref, null, childVNode);\n\t\t\t}\n\t\t\trefQueue.push(\n\t\t\t\tchildVNode.ref,\n\t\t\t\tchildVNode._component || newDom,\n\t\t\t\tchildVNode\n\t\t\t);\n\t\t}\n\n\t\tif (firstChildDom == null && newDom != null) {\n\t\t\tfirstChildDom = newDom;\n\t\t}\n\n\t\tif (\n\t\t\tchildVNode._flags & INSERT_VNODE ||\n\t\t\toldVNode._children === childVNode._children\n\t\t) {\n\t\t\toldDom = insert(childVNode, oldDom, parentDom);\n\t\t} else if (\n\t\t\ttypeof childVNode.type == 'function' &&\n\t\t\tchildVNode._nextDom !== UNDEFINED\n\t\t) {\n\t\t\t// Since Fragments or components that return Fragment like VNodes can\n\t\t\t// contain multiple DOM nodes as the same level, continue the diff from\n\t\t\t// the sibling of last DOM child of this child VNode\n\t\t\toldDom = childVNode._nextDom;\n\t\t} else if (newDom) {\n\t\t\toldDom = newDom.nextSibling;\n\t\t}\n\n\t\t// Eagerly cleanup _nextDom. We don't need to persist the value because it\n\t\t// is only used by `diffChildren` to determine where to resume the diff\n\t\t// after diffing Components and Fragments. Once we store it the nextDOM\n\t\t// local var, we can clean up the property. Also prevents us hanging on to\n\t\t// DOM nodes that may have been unmounted.\n\t\tchildVNode._nextDom = UNDEFINED;\n\n\t\t// Unset diffing flags\n\t\tchildVNode._flags &= ~(INSERT_VNODE | MATCHED);\n\t}\n\n\t// TODO: With new child diffing algo, consider alt ways to diff Fragments.\n\t// Such as dropping oldDom and moving fragments in place\n\t//\n\t// Because the newParentVNode is Fragment-like, we need to set it's\n\t// _nextDom property to the nextSibling of its last child DOM node.\n\t//\n\t// `oldDom` contains the correct value here because if the last child\n\t// is a Fragment-like, then oldDom has already been set to that child's _nextDom.\n\t// If the last child is a DOM VNode, then oldDom will be set to that DOM\n\t// node's nextSibling.\n\tnewParentVNode._nextDom = oldDom;\n\tnewParentVNode._dom = firstChildDom;\n}\n\n/**\n * @param {VNode} newParentVNode\n * @param {ComponentChildren[]} renderResult\n * @param {VNode[]} oldChildren\n */\nfunction constructNewChildrenArray(newParentVNode, renderResult, oldChildren) {\n\t/** @type {number} */\n\tlet i;\n\t/** @type {VNode} */\n\tlet childVNode;\n\t/** @type {VNode} */\n\tlet oldVNode;\n\n\tconst newChildrenLength = renderResult.length;\n\tlet oldChildrenLength = oldChildren.length,\n\t\tremainingOldChildren = oldChildrenLength;\n\n\tlet skew = 0;\n\n\tnewParentVNode._children = [];\n\tfor (i = 0; i < newChildrenLength; i++) {\n\t\t// @ts-expect-error We are reusing the childVNode variable to hold both the\n\t\t// pre and post normalized childVNode\n\t\tchildVNode = renderResult[i];\n\n\t\tif (\n\t\t\tchildVNode == null ||\n\t\t\ttypeof childVNode == 'boolean' ||\n\t\t\ttypeof childVNode == 'function'\n\t\t) {\n\t\t\tchildVNode = newParentVNode._children[i] = null;\n\t\t\tcontinue;\n\t\t}\n\t\t// If this newVNode is being reused (e.g. <div>{reuse}{reuse}</div>) in the same diff,\n\t\t// or we are rendering a component (e.g. setState) copy the oldVNodes so it can have\n\t\t// it's own DOM & etc. pointers\n\t\telse if (\n\t\t\ttypeof childVNode == 'string' ||\n\t\t\ttypeof childVNode == 'number' ||\n\t\t\t// eslint-disable-next-line valid-typeof\n\t\t\ttypeof childVNode == 'bigint' ||\n\t\t\tchildVNode.constructor == String\n\t\t) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tnull,\n\t\t\t\tchildVNode,\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\tnull\n\t\t\t);\n\t\t} else if (isArray(childVNode)) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tFragment,\n\t\t\t\t{ children: childVNode },\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\tnull\n\t\t\t);\n\t\t} else if (childVNode.constructor === UNDEFINED && childVNode._depth > 0) {\n\t\t\t// VNode is already in use, clone it. This can happen in the following\n\t\t\t// scenario:\n\t\t\t// const reuse = <div />\n\t\t\t// <div>{reuse}<span />{reuse}</div>\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tchildVNode.type,\n\t\t\t\tchildVNode.props,\n\t\t\t\tchildVNode.key,\n\t\t\t\tchildVNode.ref ? childVNode.ref : null,\n\t\t\t\tchildVNode._original\n\t\t\t);\n\t\t} else {\n\t\t\tchildVNode = newParentVNode._children[i] = childVNode;\n\t\t}\n\n\t\tconst skewedIndex = i + skew;\n\t\tchildVNode._parent = newParentVNode;\n\t\tchildVNode._depth = newParentVNode._depth + 1;\n\n\t\t// Temporarily store the matchingIndex on the _index property so we can pull\n\t\t// out the oldVNode in diffChildren. We'll override this to the VNode's\n\t\t// final index after using this property to get the oldVNode\n\t\tconst matchingIndex = (childVNode._index = findMatchingIndex(\n\t\t\tchildVNode,\n\t\t\toldChildren,\n\t\t\tskewedIndex,\n\t\t\tremainingOldChildren\n\t\t));\n\n\t\toldVNode = null;\n\t\tif (matchingIndex !== -1) {\n\t\t\toldVNode = oldChildren[matchingIndex];\n\t\t\tremainingOldChildren--;\n\t\t\tif (oldVNode) {\n\t\t\t\toldVNode._flags |= MATCHED;\n\t\t\t}\n\t\t}\n\n\t\t// Here, we define isMounting for the purposes of the skew diffing\n\t\t// algorithm. Nodes that are unsuspending are considered mounting and we detect\n\t\t// this by checking if oldVNode._original === null\n\t\tconst isMounting = oldVNode == null || oldVNode._original === null;\n\n\t\tif (isMounting) {\n\t\t\tif (matchingIndex == -1) {\n\t\t\t\tskew--;\n\t\t\t}\n\n\t\t\t// If we are mounting a DOM VNode, mark it for insertion\n\t\t\tif (typeof childVNode.type != 'function') {\n\t\t\t\tchildVNode._flags |= INSERT_VNODE;\n\t\t\t}\n\t\t} else if (matchingIndex !== skewedIndex) {\n\t\t\t// When we move elements around i.e. [0, 1, 2] --> [1, 0, 2]\n\t\t\t// --> we diff 1, we find it at position 1 while our skewed index is 0 and our skew is 0\n\t\t\t// we set the skew to 1 as we found an offset.\n\t\t\t// --> we diff 0, we find it at position 0 while our skewed index is at 2 and our skew is 1\n\t\t\t// this makes us increase the skew again.\n\t\t\t// --> we diff 2, we find it at position 2 while our skewed index is at 4 and our skew is 2\n\t\t\t//\n\t\t\t// this becomes an optimization question where currently we see a 1 element offset as an insertion\n\t\t\t// or deletion i.e. we optimize for [0, 1, 2] --> [9, 0, 1, 2]\n\t\t\t// while a more than 1 offset we see as a swap.\n\t\t\t// We could probably build heuristics for having an optimized course of action here as well, but\n\t\t\t// might go at the cost of some bytes.\n\t\t\t//\n\t\t\t// If we wanted to optimize for i.e. only swaps we'd just do the last two code-branches and have\n\t\t\t// only the first item be a re-scouting and all the others fall in their skewed counter-part.\n\t\t\t// We could also further optimize for swaps\n\t\t\tif (matchingIndex == skewedIndex - 1) {\n\t\t\t\tskew--;\n\t\t\t} else if (matchingIndex == skewedIndex + 1) {\n\t\t\t\tskew++;\n\t\t\t} else {\n\t\t\t\tif (matchingIndex > skewedIndex) {\n\t\t\t\t\tskew--;\n\t\t\t\t} else {\n\t\t\t\t\tskew++;\n\t\t\t\t}\n\n\t\t\t\t// Move this VNode's DOM if the original index (matchingIndex) doesn't\n\t\t\t\t// match the new skew index (i + new skew)\n\t\t\t\t// In the former two branches we know that it matches after skewing\n\t\t\t\tchildVNode._flags |= INSERT_VNODE;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove remaining oldChildren if there are any. Loop forwards so that as we\n\t// unmount DOM from the beginning of the oldChildren, we can adjust oldDom to\n\t// point to the next child, which needs to be the first DOM node that won't be\n\t// unmounted.\n\tif (remainingOldChildren) {\n\t\tfor (i = 0; i < oldChildrenLength; i++) {\n\t\t\toldVNode = oldChildren[i];\n\t\t\tif (oldVNode != null && (oldVNode._flags & MATCHED) === 0) {\n\t\t\t\tif (oldVNode._dom == newParentVNode._nextDom) {\n\t\t\t\t\tnewParentVNode._nextDom = getDomSibling(oldVNode);\n\t\t\t\t}\n\n\t\t\t\tunmount(oldVNode, oldVNode);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * @param {VNode} parentVNode\n * @param {PreactElement} oldDom\n * @param {PreactElement} parentDom\n * @returns {PreactElement}\n */\nfunction insert(parentVNode, oldDom, parentDom) {\n\t// Note: VNodes in nested suspended trees may be missing _children.\n\n\tif (typeof parentVNode.type == 'function') {\n\t\tlet children = parentVNode._children;\n\t\tfor (let i = 0; children && i < children.length; i++) {\n\t\t\tif (children[i]) {\n\t\t\t\t// If we enter this code path on sCU bailout, where we copy\n\t\t\t\t// oldVNode._children to newVNode._children, we need to update the old\n\t\t\t\t// children's _parent pointer to point to the newVNode (parentVNode\n\t\t\t\t// here).\n\t\t\t\tchildren[i]._parent = parentVNode;\n\t\t\t\toldDom = insert(children[i], oldDom, parentDom);\n\t\t\t}\n\t\t}\n\n\t\treturn oldDom;\n\t} else if (parentVNode._dom != oldDom) {\n\t\tif (oldDom && parentVNode.type && !parentDom.contains(oldDom)) {\n\t\t\toldDom = getDomSibling(parentVNode);\n\t\t}\n\t\tparentDom.insertBefore(parentVNode._dom, oldDom || null);\n\t\toldDom = parentVNode._dom;\n\t}\n\n\tdo {\n\t\toldDom = oldDom && oldDom.nextSibling;\n\t} while (oldDom != null && oldDom.nodeType === 8);\n\n\treturn oldDom;\n}\n\n/**\n * Flatten and loop through the children of a virtual node\n * @param {ComponentChildren} children The unflattened children of a virtual\n * node\n * @returns {VNode[]}\n */\nexport function toChildArray(children, out) {\n\tout = out || [];\n\tif (children == null || typeof children == 'boolean') {\n\t} else if (isArray(children)) {\n\t\tchildren.some(child => {\n\t\t\ttoChildArray(child, out);\n\t\t});\n\t} else {\n\t\tout.push(children);\n\t}\n\treturn out;\n}\n\n/**\n * @param {VNode} childVNode\n * @param {VNode[]} oldChildren\n * @param {number} skewedIndex\n * @param {number} remainingOldChildren\n * @returns {number}\n */\nfunction findMatchingIndex(\n\tchildVNode,\n\toldChildren,\n\tskewedIndex,\n\tremainingOldChildren\n) {\n\tconst key = childVNode.key;\n\tconst type = childVNode.type;\n\tlet x = skewedIndex - 1;\n\tlet y = skewedIndex + 1;\n\tlet oldVNode = oldChildren[skewedIndex];\n\n\t// We only need to perform a search if there are more children\n\t// (remainingOldChildren) to search. However, if the oldVNode we just looked\n\t// at skewedIndex was not already used in this diff, then there must be at\n\t// least 1 other (so greater than 1) remainingOldChildren to attempt to match\n\t// against. So the following condition checks that ensuring\n\t// remainingOldChildren > 1 if the oldVNode is not already used/matched. Else\n\t// if the oldVNode was null or matched, then there could needs to be at least\n\t// 1 (aka `remainingOldChildren > 0`) children to find and compare against.\n\t//\n\t// If there is an unkeyed functional VNode, that isn't a built-in like our Fragment,\n\t// we should not search as we risk re-using state of an unrelated VNode.\n\tlet shouldSearch =\n\t\t(typeof type !== 'function' || type === Fragment || key) &&\n\t\tremainingOldChildren >\n\t\t\t(oldVNode != null && (oldVNode._flags & MATCHED) === 0 ? 1 : 0);\n\n\tif (\n\t\toldVNode === null ||\n\t\t(oldVNode &&\n\t\t\tkey == oldVNode.key &&\n\t\t\ttype === oldVNode.type &&\n\t\t\t(oldVNode._flags & MATCHED) === 0)\n\t) {\n\t\treturn skewedIndex;\n\t} else if (shouldSearch) {\n\t\twhile (x >= 0 || y < oldChildren.length) {\n\t\t\tif (x >= 0) {\n\t\t\t\toldVNode = oldChildren[x];\n\t\t\t\tif (\n\t\t\t\t\toldVNode &&\n\t\t\t\t\t(oldVNode._flags & MATCHED) === 0 &&\n\t\t\t\t\tkey == oldVNode.key &&\n\t\t\t\t\ttype === oldVNode.type\n\t\t\t\t) {\n\t\t\t\t\treturn x;\n\t\t\t\t}\n\t\t\t\tx--;\n\t\t\t}\n\n\t\t\tif (y < oldChildren.length) {\n\t\t\t\toldVNode = oldChildren[y];\n\t\t\t\tif (\n\t\t\t\t\toldVNode &&\n\t\t\t\t\t(oldVNode._flags & MATCHED) === 0 &&\n\t\t\t\t\tkey == oldVNode.key &&\n\t\t\t\t\ttype === oldVNode.type\n\t\t\t\t) {\n\t\t\t\t\treturn y;\n\t\t\t\t}\n\t\t\t\ty++;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn -1;\n}\n","import {\n\tEMPTY_OBJ,\n\tMODE_HYDRATE,\n\tMODE_SUSPENDED,\n\tRESET_MODE,\n\tUNDEFINED\n} from '../constants';\nimport { BaseComponent, getDomSibling } from '../component';\nimport { Fragment } from '../create-element';\nimport { diffChildren } from './children';\nimport { setProperty } from './props';\nimport { assign, isArray, removeNode, slice } from '../util';\nimport options from '../options';\n\n/**\n * Diff two virtual nodes and apply proper changes to the DOM\n * @param {PreactElement} parentDom The parent of the DOM element\n * @param {VNode} newVNode The new virtual node\n * @param {VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object. Modified by\n * getChildContext\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array<PreactElement>} excessDomChildren\n * @param {Array<Component>} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {PreactElement} oldDom The current attached DOM element any new dom\n * elements should be placed around. Likely `null` on first render (except when\n * hydrating). Can be a sibling DOM element when diffing Fragments that have\n * siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n */\nexport function diff(\n\tparentDom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating,\n\trefQueue\n) {\n\t/** @type {any} */\n\tlet tmp,\n\t\tnewType = newVNode.type;\n\n\t// When passing through createElement it assigns the object\n\t// constructor as undefined. This to prevent JSON-injection.\n\tif (newVNode.constructor !== UNDEFINED) return null;\n\n\t// If the previous diff bailed out, resume creating/hydrating.\n\tif (oldVNode._flags & MODE_SUSPENDED) {\n\t\tisHydrating = !!(oldVNode._flags & MODE_HYDRATE);\n\t\toldDom = newVNode._dom = oldVNode._dom;\n\t\texcessDomChildren = [oldDom];\n\t}\n\n\tif ((tmp = options._diff)) tmp(newVNode);\n\n\touter: if (typeof newType == 'function') {\n\t\ttry {\n\t\t\tlet c, isNew, oldProps, oldState, snapshot, clearProcessingException;\n\t\t\tlet newProps = newVNode.props;\n\t\t\tconst isClassComponent =\n\t\t\t\t'prototype' in newType && newType.prototype.render;\n\n\t\t\t// Necessary for createContext api. Setting this property will pass\n\t\t\t// the context value as `this.context` just for this component.\n\t\t\ttmp = newType.contextType;\n\t\t\tlet provider = tmp && globalContext[tmp._id];\n\t\t\tlet componentContext = tmp\n\t\t\t\t? provider\n\t\t\t\t\t? provider.props.value\n\t\t\t\t\t: tmp._defaultValue\n\t\t\t\t: globalContext;\n\n\t\t\t// Get component and set it to `c`\n\t\t\tif (oldVNode._component) {\n\t\t\t\tc = newVNode._component = oldVNode._component;\n\t\t\t\tclearProcessingException = c._processingException = c._pendingError;\n\t\t\t} else {\n\t\t\t\t// Instantiate the new component\n\t\t\t\tif (isClassComponent) {\n\t\t\t\t\t// @ts-expect-error The check above verifies that newType is suppose to be constructed\n\t\t\t\t\tnewVNode._component = c = new newType(newProps, componentContext); // eslint-disable-line new-cap\n\t\t\t\t} else {\n\t\t\t\t\t// @ts-expect-error Trust me, Component implements the interface we want\n\t\t\t\t\tnewVNode._component = c = new BaseComponent(\n\t\t\t\t\t\tnewProps,\n\t\t\t\t\t\tcomponentContext\n\t\t\t\t\t);\n\t\t\t\t\tc.constructor = newType;\n\t\t\t\t\tc.render = doRender;\n\t\t\t\t}\n\t\t\t\tif (provider) provider.sub(c);\n\n\t\t\t\tc.props = newProps;\n\t\t\t\tif (!c.state) c.state = {};\n\t\t\t\tc.context = componentContext;\n\t\t\t\tc._globalContext = globalContext;\n\t\t\t\tisNew = c._dirty = true;\n\t\t\t\tc._renderCallbacks = [];\n\t\t\t\tc._stateCallbacks = [];\n\t\t\t}\n\n\t\t\t// Invoke getDerivedStateFromProps\n\t\t\tif (isClassComponent && c._nextState == null) {\n\t\t\t\tc._nextState = c.state;\n\t\t\t}\n\n\t\t\tif (isClassComponent && newType.getDerivedStateFromProps != null) {\n\t\t\t\tif (c._nextState == c.state) {\n\t\t\t\t\tc._nextState = assign({}, c._nextState);\n\t\t\t\t}\n\n\t\t\t\tassign(\n\t\t\t\t\tc._nextState,\n\t\t\t\t\tnewType.getDerivedStateFromProps(newProps, c._nextState)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toldProps = c.props;\n\t\t\toldState = c.state;\n\t\t\tc._vnode = newVNode;\n\n\t\t\t// Invoke pre-render lifecycle methods\n\t\t\tif (isNew) {\n\t\t\t\tif (\n\t\t\t\t\tisClassComponent &&\n\t\t\t\t\tnewType.getDerivedStateFromProps == null &&\n\t\t\t\t\tc.componentWillMount != null\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillMount();\n\t\t\t\t}\n\n\t\t\t\tif (isClassComponent && c.componentDidMount != null) {\n\t\t\t\t\tc._renderCallbacks.push(c.componentDidMount);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (\n\t\t\t\t\tisClassComponent &&\n\t\t\t\t\tnewType.getDerivedStateFromProps == null &&\n\t\t\t\t\tnewProps !== oldProps &&\n\t\t\t\t\tc.componentWillReceiveProps != null\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillReceiveProps(newProps, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t!c._force &&\n\t\t\t\t\t((c.shouldComponentUpdate != null &&\n\t\t\t\t\t\tc.shouldComponentUpdate(\n\t\t\t\t\t\t\tnewProps,\n\t\t\t\t\t\t\tc._nextState,\n\t\t\t\t\t\t\tcomponentContext\n\t\t\t\t\t\t) === false) ||\n\t\t\t\t\t\tnewVNode._original === oldVNode._original)\n\t\t\t\t) {\n\t\t\t\t\t// More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8\n\t\t\t\t\tif (newVNode._original !== oldVNode._original) {\n\t\t\t\t\t\t// When we are dealing with a bail because of sCU we have to update\n\t\t\t\t\t\t// the props, state and dirty-state.\n\t\t\t\t\t\t// when we are dealing with strict-equality we don't as the child could still\n\t\t\t\t\t\t// be dirtied see #3883\n\t\t\t\t\t\tc.props = newProps;\n\t\t\t\t\t\tc.state = c._nextState;\n\t\t\t\t\t\tc._dirty = false;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\t\tnewVNode._children.some(vnode => {\n\t\t\t\t\t\tif (vnode) vnode._parent = newVNode;\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (let i = 0; i < c._stateCallbacks.length; i++) {\n\t\t\t\t\t\tc._renderCallbacks.push(c._stateCallbacks[i]);\n\t\t\t\t\t}\n\t\t\t\t\tc._stateCallbacks = [];\n\n\t\t\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\t\t\tcommitQueue.push(c);\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak outer;\n\t\t\t\t}\n\n\t\t\t\tif (c.componentWillUpdate != null) {\n\t\t\t\t\tc.componentWillUpdate(newProps, c._nextState, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (isClassComponent && c.componentDidUpdate != null) {\n\t\t\t\t\tc._renderCallbacks.push(() => {\n\t\t\t\t\t\tc.componentDidUpdate(oldProps, oldState, snapshot);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tc.context = componentContext;\n\t\t\tc.props = newProps;\n\t\t\tc._parentDom = parentDom;\n\t\t\tc._force = false;\n\n\t\t\tlet renderHook = options._render,\n\t\t\t\tcount = 0;\n\t\t\tif (isClassComponent) {\n\t\t\t\tc.state = c._nextState;\n\t\t\t\tc._dirty = false;\n\n\t\t\t\tif (renderHook) renderHook(newVNode);\n\n\t\t\t\ttmp = c.render(c.props, c.state, c.context);\n\n\t\t\t\tfor (let i = 0; i < c._stateCallbacks.length; i++) {\n\t\t\t\t\tc._renderCallbacks.push(c._stateCallbacks[i]);\n\t\t\t\t}\n\t\t\t\tc._stateCallbacks = [];\n\t\t\t} else {\n\t\t\t\tdo {\n\t\t\t\t\tc._dirty = false;\n\t\t\t\t\tif (renderHook) renderHook(newVNode);\n\n\t\t\t\t\ttmp = c.render(c.props, c.state, c.context);\n\n\t\t\t\t\t// Handle setState called in render, see #2553\n\t\t\t\t\tc.state = c._nextState;\n\t\t\t\t} while (c._dirty && ++count < 25);\n\t\t\t}\n\n\t\t\t// Handle setState called in render, see #2553\n\t\t\tc.state = c._nextState;\n\n\t\t\tif (c.getChildContext != null) {\n\t\t\t\tglobalContext = assign(assign({}, globalContext), c.getChildContext());\n\t\t\t}\n\n\t\t\tif (isClassComponent && !isNew && c.getSnapshotBeforeUpdate != null) {\n\t\t\t\tsnapshot = c.getSnapshotBeforeUpdate(oldProps, oldState);\n\t\t\t}\n\n\t\t\tlet isTopLevelFragment =\n\t\t\t\ttmp != null && tmp.type === Fragment && tmp.key == null;\n\t\t\tlet renderResult = isTopLevelFragment ? tmp.props.children : tmp;\n\n\t\t\tdiffChildren(\n\t\t\t\tparentDom,\n\t\t\t\tisArray(renderResult) ? renderResult : [renderResult],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tnamespace,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\toldDom,\n\t\t\t\tisHydrating,\n\t\t\t\trefQueue\n\t\t\t);\n\n\t\t\tc.base = newVNode._dom;\n\n\t\t\t// We successfully rendered this VNode, unset any stored hydration/bailout state:\n\t\t\tnewVNode._flags &= RESET_MODE;\n\n\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\tcommitQueue.push(c);\n\t\t\t}\n\n\t\t\tif (clearProcessingException) {\n\t\t\t\tc._pendingError = c._processingException = null;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tnewVNode._original = null;\n\t\t\t// if hydrating or creating initial tree, bailout preserves DOM:\n\t\t\tif (isHydrating || excessDomChildren != null) {\n\t\t\t\tnewVNode._flags |= isHydrating\n\t\t\t\t\t? MODE_HYDRATE | MODE_SUSPENDED\n\t\t\t\t\t: MODE_SUSPENDED;\n\n\t\t\t\twhile (oldDom && oldDom.nodeType === 8 && oldDom.nextSibling) {\n\t\t\t\t\toldDom = oldDom.nextSibling;\n\t\t\t\t}\n\t\t\t\texcessDomChildren[excessDomChildren.indexOf(oldDom)] = null;\n\t\t\t\tnewVNode._dom = oldDom;\n\t\t\t} else {\n\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t}\n\t\t\toptions._catchError(e, newVNode, oldVNode);\n\t\t}\n\t} else if (\n\t\texcessDomChildren == null &&\n\t\tnewVNode._original === oldVNode._original\n\t) {\n\t\tnewVNode._children = oldVNode._children;\n\t\tnewVNode._dom = oldVNode._dom;\n\t} else {\n\t\tnewVNode._dom = diffElementNodes(\n\t\t\toldVNode._dom,\n\t\t\tnewVNode,\n\t\t\toldVNode,\n\t\t\tglobalContext,\n\t\t\tnamespace,\n\t\t\texcessDomChildren,\n\t\t\tcommitQueue,\n\t\t\tisHydrating,\n\t\t\trefQueue\n\t\t);\n\t}\n\n\tif ((tmp = options.diffed)) tmp(newVNode);\n}\n\n/**\n * @param {Array<Component>} commitQueue List of components\n * which have callbacks to invoke in commitRoot\n * @param {VNode} root\n */\nexport function commitRoot(commitQueue, root, refQueue) {\n\troot._nextDom = UNDEFINED;\n\n\tfor (let i = 0; i < refQueue.length; i++) {\n\t\tapplyRef(refQueue[i], refQueue[++i], refQueue[++i]);\n\t}\n\n\tif (options._commit) options._commit(root, commitQueue);\n\n\tcommitQueue.some(c => {\n\t\ttry {\n\t\t\t// @ts-expect-error Reuse the commitQueue variable here so the type changes\n\t\t\tcommitQueue = c._renderCallbacks;\n\t\t\tc._renderCallbacks = [];\n\t\t\tcommitQueue.some(cb => {\n\t\t\t\t// @ts-expect-error See above comment on commitQueue\n\t\t\t\tcb.call(c);\n\t\t\t});\n\t\t} catch (e) {\n\t\t\toptions._catchError(e, c._vnode);\n\t\t}\n\t});\n}\n\n/**\n * Diff two virtual nodes representing DOM element\n * @param {PreactElement} dom The DOM element representing the virtual nodes\n * being diffed\n * @param {VNode} newVNode The new virtual node\n * @param {VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array<PreactElement>} excessDomChildren\n * @param {Array<Component>} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n * @returns {PreactElement}\n */\nfunction diffElementNodes(\n\tdom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\tisHydrating,\n\trefQueue\n) {\n\tlet oldProps = oldVNode.props;\n\tlet newProps = newVNode.props;\n\tlet nodeType = /** @type {string} */ (newVNode.type);\n\t/** @type {any} */\n\tlet i;\n\t/** @type {{ __html?: string }} */\n\tlet newHtml;\n\t/** @type {{ __html?: string }} */\n\tlet oldHtml;\n\t/** @type {ComponentChildren} */\n\tlet newChildren;\n\tlet value;\n\tlet inputValue;\n\tlet checked;\n\n\t// Tracks entering and exiting namespaces when descending through the tree.\n\tif (nodeType === 'svg') namespace = 'http://www.w3.org/2000/svg';\n\telse if (nodeType === 'math')\n\t\tnamespace = 'http://www.w3.org/1998/Math/MathML';\n\telse if (!namespace) namespace = 'http://www.w3.org/1999/xhtml';\n\n\tif (excessDomChildren != null) {\n\t\tfor (i = 0; i < excessDomChildren.length; i++) {\n\t\t\tvalue = excessDomChildren[i];\n\n\t\t\t// if newVNode matches an element in excessDomChildren or the `dom`\n\t\t\t// argument matches an element in excessDomChildren, remove it from\n\t\t\t// excessDomChildren so it isn't later removed in diffChildren\n\t\t\tif (\n\t\t\t\tvalue &&\n\t\t\t\t'setAttribute' in value === !!nodeType &&\n\t\t\t\t(nodeType ? value.localName === nodeType : value.nodeType === 3)\n\t\t\t) {\n\t\t\t\tdom = value;\n\t\t\t\texcessDomChildren[i] = null;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dom == null) {\n\t\tif (nodeType === null) {\n\t\t\treturn document.createTextNode(newProps);\n\t\t}\n\n\t\tdom = document.createElementNS(\n\t\t\tnamespace,\n\t\t\tnodeType,\n\t\t\tnewProps.is && newProps\n\t\t);\n\n\t\t// we are creating a new node, so we can assume this is a new subtree (in\n\t\t// case we are hydrating), this deopts the hydrate\n\t\tif (isHydrating) {\n\t\t\tif (options._hydrationMismatch)\n\t\t\t\toptions._hydrationMismatch(newVNode, excessDomChildren);\n\t\t\tisHydrating = false;\n\t\t}\n\t\t// we created a new parent, so none of the previously attached children can be reused:\n\t\texcessDomChildren = null;\n\t}\n\n\tif (nodeType === null) {\n\t\t// During hydration, we still have to split merged text from SSR'd HTML.\n\t\tif (oldProps !== newProps && (!isHydrating || dom.data !== newProps)) {\n\t\t\tdom.data = newProps;\n\t\t}\n\t} else {\n\t\t// If excessDomChildren was not null, repopulate it with the current element's children:\n\t\texcessDomChildren = excessDomChildren && slice.call(dom.childNodes);\n\n\t\toldProps = oldVNode.props || EMPTY_OBJ;\n\n\t\t// If we are in a situation where we are not hydrating but are using\n\t\t// existing DOM (e.g. replaceNode) we should read the existing DOM\n\t\t// attributes to diff them\n\t\tif (!isHydrating && excessDomChildren != null) {\n\t\t\toldProps = {};\n\t\t\tfor (i = 0; i < dom.attributes.length; i++) {\n\t\t\t\tvalue = dom.attributes[i];\n\t\t\t\toldProps[value.name] = value.value;\n\t\t\t}\n\t\t}\n\n\t\tfor (i in oldProps) {\n\t\t\tvalue = oldProps[i];\n\t\t\tif (i == 'children') {\n\t\t\t} else if (i == 'dangerouslySetInnerHTML') {\n\t\t\t\toldHtml = value;\n\t\t\t} else if (!(i in newProps)) {\n\t\t\t\tif (\n\t\t\t\t\t(i == 'value' && 'defaultValue' in newProps) ||\n\t\t\t\t\t(i == 'checked' && 'defaultChecked' in newProps)\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tsetProperty(dom, i, null, value, namespace);\n\t\t\t}\n\t\t}\n\n\t\t// During hydration, props are not diffed at all (including dangerouslySetInnerHTML)\n\t\t// @TODO we should warn in debug mode when props don't match here.\n\t\tfor (i in newProps) {\n\t\t\tvalue = newProps[i];\n\t\t\tif (i == 'children') {\n\t\t\t\tnewChildren = value;\n\t\t\t} else if (i == 'dangerouslySetInnerHTML') {\n\t\t\t\tnewHtml = value;\n\t\t\t} else if (i == 'value') {\n\t\t\t\tinputValue = value;\n\t\t\t} else if (i == 'checked') {\n\t\t\t\tchecked = value;\n\t\t\t} else if (\n\t\t\t\t(!isHydrating || typeof value == 'function') &&\n\t\t\t\toldProps[i] !== value\n\t\t\t) {\n\t\t\t\tsetProperty(dom, i, value, oldProps[i], namespace);\n\t\t\t}\n\t\t}\n\n\t\t// If the new vnode didn't have dangerouslySetInnerHTML, diff its children\n\t\tif (newHtml) {\n\t\t\t// Avoid re-applying the same '__html' if it did not changed between re-render\n\t\t\tif (\n\t\t\t\t!isHydrating &&\n\t\t\t\t(!oldHtml ||\n\t\t\t\t\t(newHtml.__html !== oldHtml.__html &&\n\t\t\t\t\t\tnewHtml.__html !== dom.innerHTML))\n\t\t\t) {\n\t\t\t\tdom.innerHTML = newHtml.__html;\n\t\t\t}\n\n\t\t\tnewVNode._children = [];\n\t\t} else {\n\t\t\tif (oldHtml) dom.innerHTML = '';\n\n\t\t\tdiffChildren(\n\t\t\t\tdom,\n\t\t\t\tisArray(newChildren) ? newChildren : [newChildren],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tnodeType === 'foreignObject'\n\t\t\t\t\t? 'http://www.w3.org/1999/xhtml'\n\t\t\t\t\t: namespace,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\texcessDomChildren\n\t\t\t\t\t? excessDomChildren[0]\n\t\t\t\t\t: oldVNode._children && getDomSibling(oldVNode, 0),\n\t\t\t\tisHydrating,\n\t\t\t\trefQueue\n\t\t\t);\n\n\t\t\t// Remove children that are not part of any vnode.\n\t\t\tif (excessDomChildren != null) {\n\t\t\t\tfor (i = excessDomChildren.length; i--; ) {\n\t\t\t\t\tremoveNode(excessDomChildren[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// As above, don't diff props during hydration\n\t\tif (!isHydrating) {\n\t\t\ti = 'value';\n\t\t\tif (nodeType === 'progress' && inputValue == null) {\n\t\t\t\tdom.removeAttribute('value');\n\t\t\t} else if (\n\t\t\t\tinputValue !== UNDEFINED &&\n\t\t\t\t// #2756 For the <progress>-element the initial value is 0,\n\t\t\t\t// despite the attribute not being present. When the attribute\n\t\t\t\t// is missing the progress bar is treated as indeterminate.\n\t\t\t\t// To fix that we'll always update it when it is 0 for progress elements\n\t\t\t\t(inputValue !== dom[i] ||\n\t\t\t\t\t(nodeType === 'progress' && !inputValue) ||\n\t\t\t\t\t// This is only for IE 11 to fix <select> value not being updated.\n\t\t\t\t\t// To avoid a stale select value we need to set the option.value\n\t\t\t\t\t// again, which triggers IE11 to re-evaluate the select value\n\t\t\t\t\t(nodeType === 'option' && inputValue !== oldProps[i]))\n\t\t\t) {\n\t\t\t\tsetProperty(dom, i, inputValue, oldProps[i], namespace);\n\t\t\t}\n\n\t\t\ti = 'checked';\n\t\t\tif (checked !== UNDEFINED && checked !== dom[i]) {\n\t\t\t\tsetProperty(dom, i, checked, oldProps[i], namespace);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn dom;\n}\n\n/**\n * Invoke or update a ref, depending on whether it is a function or object ref.\n * @param {Ref<any> & { _unmount?: unknown }} ref\n * @param {any} value\n * @param {VNode} vnode\n */\nexport function applyRef(ref, value, vnode) {\n\ttry {\n\t\tif (typeof ref == 'function') {\n\t\t\tlet hasRefUnmount = typeof ref._unmount == 'function';\n\t\t\tif (hasRefUnmount) {\n\t\t\t\t// @ts-ignore TS doesn't like moving narrowing checks into variables\n\t\t\t\tref._unmount();\n\t\t\t}\n\n\t\t\tif (!hasRefUnmount || value != null) {\n\t\t\t\t// Store the cleanup function on the function\n\t\t\t\t// instance object itself to avoid shape\n\t\t\t\t// transitioning vnode\n\t\t\t\tref._unmount = ref(value);\n\t\t\t}\n\t\t} else ref.current = value;\n\t} catch (e) {\n\t\toptions._catchError(e, vnode);\n\t}\n}\n\n/**\n * Unmount a virtual node from the tree and apply DOM changes\n * @param {VNode} vnode The virtual node to unmount\n * @param {VNode} parentVNode The parent of the VNode that initiated the unmount\n * @param {boolean} [skipRemove] Flag that indicates that a parent node of the\n * current element is already detached from the DOM.\n */\nexport function unmount(vnode, parentVNode, skipRemove) {\n\tlet r;\n\tif (options.unmount) options.unmount(vnode);\n\n\tif ((r = vnode.ref)) {\n\t\tif (!r.current || r.current === vnode._dom) {\n\t\t\tapplyRef(r, null, parentVNode);\n\t\t}\n\t}\n\n\tif ((r = vnode._component) != null) {\n\t\tif (r.componentWillUnmount) {\n\t\t\ttry {\n\t\t\t\tr.componentWillUnmount();\n\t\t\t} catch (e) {\n\t\t\t\toptions._catchError(e, parentVNode);\n\t\t\t}\n\t\t}\n\n\t\tr.base = r._parentDom = null;\n\t}\n\n\tif ((r = vnode._children)) {\n\t\tfor (let i = 0; i < r.length; i++) {\n\t\t\tif (r[i]) {\n\t\t\t\tunmount(\n\t\t\t\t\tr[i],\n\t\t\t\t\tparentVNode,\n\t\t\t\t\tskipRemove || typeof vnode.type != 'function'\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!skipRemove) {\n\t\tremoveNode(vnode._dom);\n\t}\n\n\t// Must be set to `undefined` to properly clean up `_nextDom`\n\t// for which `null` is a valid value. See comment in `create-element.js`\n\tvnode._component = vnode._parent = vnode._dom = vnode._nextDom = UNDEFINED;\n}\n\n/** The `.render()` method for a PFC backing instance. */\nfunction doRender(props, state, context) {\n\treturn this.constructor(props, context);\n}\n","import { EMPTY_OBJ } from './constants';\nimport { commitRoot, diff } from './diff/index';\nimport { createElement, Fragment } from './create-element';\nimport options from './options';\nimport { slice } from './util';\n\n/**\n * Render a Preact virtual node into a DOM element\n * @param {ComponentChild} vnode The virtual node to render\n * @param {PreactElement} parentDom The DOM element to render into\n * @param {PreactElement | object} [replaceNode] Optional: Attempt to re-use an\n * existing DOM tree rooted at `replaceNode`\n */\nexport function render(vnode, parentDom, replaceNode) {\n\tif (options._root) options._root(vnode, parentDom);\n\n\t// We abuse the `replaceNode` parameter in `hydrate()` to signal if we are in\n\t// hydration mode or not by passing the `hydrate` function instead of a DOM\n\t// element..\n\tlet isHydrating = typeof replaceNode == 'function';\n\n\t// To be able to support calling `render()` multiple times on the same\n\t// DOM node, we need to obtain a reference to the previous tree. We do\n\t// this by assigning a new `_children` property to DOM nodes which points\n\t// to the last rendered tree. By default this property is not present, which\n\t// means that we are mounting a new tree for the first time.\n\tlet oldVNode = isHydrating\n\t\t? null\n\t\t: (replaceNode && replaceNode._children) || parentDom._children;\n\n\tvnode = ((!isHydrating && replaceNode) || parentDom)._children =\n\t\tcreateElement(Fragment, null, [vnode]);\n\n\t// List of effects that need to be called after diffing.\n\tlet commitQueue = [],\n\t\trefQueue = [];\n\tdiff(\n\t\tparentDom,\n\t\t// Determine the new vnode tree and store it on the DOM element on\n\t\t// our custom `_children` property.\n\t\tvnode,\n\t\toldVNode || EMPTY_OBJ,\n\t\tEMPTY_OBJ,\n\t\tparentDom.namespaceURI,\n\t\t!isHydrating && replaceNode\n\t\t\t? [replaceNode]\n\t\t\t: oldVNode\n\t\t\t\t? null\n\t\t\t\t: parentDom.firstChild\n\t\t\t\t\t? slice.call(parentDom.childNodes)\n\t\t\t\t\t: null,\n\t\tcommitQueue,\n\t\t!isHydrating && replaceNode\n\t\t\t? replaceNode\n\t\t\t: oldVNode\n\t\t\t\t? oldVNode._dom\n\t\t\t\t: parentDom.firstChild,\n\t\tisHydrating,\n\t\trefQueue\n\t);\n\n\t// Flush all queued effects\n\tcommitRoot(commitQueue, vnode, refQueue);\n}\n\n/**\n * Update an existing DOM element with data from a Preact virtual node\n * @param {ComponentChild} vnode The virtual node to render\n * @param {PreactElement} parentDom The DOM element to update\n */\nexport function hydrate(vnode, parentDom) {\n\trender(vnode, parentDom, hydrate);\n}\n","import { assign, slice } from './util';\nimport { createVNode } from './create-element';\nimport { UNDEFINED } from './constants';\n\n/**\n * Clones the given VNode, optionally adding attributes/props and replacing its\n * children.\n * @param {VNode} vnode The virtual DOM element to clone\n * @param {object} props Attributes/props to add when cloning\n * @param {Array<ComponentChildren>} rest Any additional arguments will be used\n * as replacement children.\n * @returns {VNode}\n */\nexport function cloneElement(vnode, props, children) {\n\tlet normalizedProps = assign({}, vnode.props),\n\t\tkey,\n\t\tref,\n\t\ti;\n\n\tlet defaultProps;\n\n\tif (vnode.type && vnode.type.defaultProps) {\n\t\tdefaultProps = vnode.type.defaultProps;\n\t}\n\n\tfor (i in props) {\n\t\tif (i == 'key') key = props[i];\n\t\telse if (i == 'ref') ref = props[i];\n\t\telse if (props[i] === UNDEFINED && defaultProps !== UNDEFINED) {\n\t\t\tnormalizedProps[i] = defaultProps[i];\n\t\t} else {\n\t\t\tnormalizedProps[i] = props[i];\n\t\t}\n\t}\n\n\tif (arguments.length > 2) {\n\t\tnormalizedProps.children =\n\t\t\targuments.length > 3 ? slice.call(arguments, 2) : children;\n\t}\n\n\treturn createVNode(\n\t\tvnode.type,\n\t\tnormalizedProps,\n\t\tkey || vnode.key,\n\t\tref || vnode.ref,\n\t\tnull\n\t);\n}\n","/**\n * Find the closest error boundary to a thrown error and call it\n * @param {object} error The thrown value\n * @param {VNode} vnode The vnode that threw the error that was caught (except\n * for unmounting when this parameter is the highest parent that was being\n * unmounted)\n * @param {VNode} [oldVNode]\n * @param {ErrorInfo} [errorInfo]\n */\nexport function _catchError(error, vnode, oldVNode, errorInfo) {\n\t/** @type {Component} */\n\tlet component,\n\t\t/** @type {ComponentType} */\n\t\tctor,\n\t\t/** @type {boolean} */\n\t\thandled;\n\n\tfor (; (vnode = vnode._parent); ) {\n\t\tif ((component = vnode._component) && !component._processingException) {\n\t\t\ttry {\n\t\t\t\tctor = component.constructor;\n\n\t\t\t\tif (ctor && ctor.getDerivedStateFromError != null) {\n\t\t\t\t\tcomponent.setState(ctor.getDerivedStateFromError(error));\n\t\t\t\t\thandled = component._dirty;\n\t\t\t\t}\n\n\t\t\t\tif (component.componentDidCatch != null) {\n\t\t\t\t\tcomponent.componentDidCatch(error, errorInfo || {});\n\t\t\t\t\thandled = component._dirty;\n\t\t\t\t}\n\n\t\t\t\t// This is an error boundary. Mark it as having bailed out, and whether it was mid-hydration.\n\t\t\t\tif (handled) {\n\t\t\t\t\treturn (component._pendingError = component);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\terror = e;\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow error;\n}\n","import { options as _options } from 'preact';\n\n/** @type {number} */\nlet currentIndex;\n\n/** @type {import('./internal').Component} */\nlet currentComponent;\n\n/** @type {import('./internal').Component} */\nlet previousComponent;\n\n/** @type {number} */\nlet currentHook = 0;\n\n/** @type {Array<import('./internal').Component>} */\nlet afterPaintEffects = [];\n\n// Cast to use internal Options type\nconst options = /** @type {import('./internal').Options} */ (_options);\n\nlet oldBeforeDiff = options._diff;\nlet oldBeforeRender = options._render;\nlet oldAfterDiff = options.diffed;\nlet oldCommit = options._commit;\nlet oldBeforeUnmount = options.unmount;\nlet oldRoot = options._root;\n\nconst RAF_TIMEOUT = 100;\nlet prevRaf;\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions._diff = vnode => {\n\tcurrentComponent = null;\n\tif (oldBeforeDiff) oldBeforeDiff(vnode);\n};\n\noptions._root = (vnode, parentDom) => {\n\tif (vnode && parentDom._children && parentDom._children._mask) {\n\t\tvnode._mask = parentDom._children._mask;\n\t}\n\n\tif (oldRoot) oldRoot(vnode, parentDom);\n};\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions._render = vnode => {\n\tif (oldBeforeRender) oldBeforeRender(vnode);\n\n\tcurrentComponent = vnode._component;\n\tcurrentIndex = 0;\n\n\tconst hooks = currentComponent.__hooks;\n\tif (hooks) {\n\t\tif (previousComponent === currentComponent) {\n\t\t\thooks._pendingEffects = [];\n\t\t\tcurrentComponent._renderCallbacks = [];\n\t\t\thooks._list.forEach(hookItem => {\n\t\t\t\tif (hookItem._nextValue) {\n\t\t\t\t\thookItem._value = hookItem._nextValue;\n\t\t\t\t}\n\t\t\t\thookItem._pendingArgs = hookItem._nextValue = undefined;\n\t\t\t});\n\t\t} else {\n\t\t\thooks._pendingEffects.forEach(invokeCleanup);\n\t\t\thooks._pendingEffects.forEach(invokeEffect);\n\t\t\thooks._pendingEffects = [];\n\t\t\tcurrentIndex = 0;\n\t\t}\n\t}\n\tpreviousComponent = currentComponent;\n};\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions.diffed = vnode => {\n\tif (oldAfterDiff) oldAfterDiff(vnode);\n\n\tconst c = vnode._component;\n\tif (c && c.__hooks) {\n\t\tif (c.__hooks._pendingEffects.length) afterPaint(afterPaintEffects.push(c));\n\t\tc.__hooks._list.forEach(hookItem => {\n\t\t\tif (hookItem._pendingArgs) {\n\t\t\t\thookItem._args = hookItem._pendingArgs;\n\t\t\t}\n\t\t\thookItem._pendingArgs = undefined;\n\t\t});\n\t}\n\tpreviousComponent = currentComponent = null;\n};\n\n// TODO: Improve typing of commitQueue parameter\n/** @type {(vnode: import('./internal').VNode, commitQueue: any) => void} */\noptions._commit = (vnode, commitQueue) => {\n\tcommitQueue.some(component => {\n\t\ttry {\n\t\t\tcomponent._renderCallbacks.forEach(invokeCleanup);\n\t\t\tcomponent._renderCallbacks = component._renderCallbacks.filter(cb =>\n\t\t\t\tcb._value ? invokeEffect(cb) : true\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tcommitQueue.some(c => {\n\t\t\t\tif (c._renderCallbacks) c._renderCallbacks = [];\n\t\t\t});\n\t\t\tcommitQueue = [];\n\t\t\toptions._catchError(e, component._vnode);\n\t\t}\n\t});\n\n\tif (oldCommit) oldCommit(vnode, commitQueue);\n};\n\n/** @type {(vnode: import('./internal').VNode) => void} */\noptions.unmount = vnode => {\n\tif (oldBeforeUnmount) oldBeforeUnmount(vnode);\n\n\tconst c = vnode._component;\n\tif (c && c.__hooks) {\n\t\tlet hasErrored;\n\t\tc.__hooks._list.forEach(s => {\n\t\t\ttry {\n\t\t\t\tinvokeCleanup(s);\n\t\t\t} catch (e) {\n\t\t\t\thasErrored = e;\n\t\t\t}\n\t\t});\n\t\tc.__hooks = undefined;\n\t\tif (hasErrored) options._catchError(hasErrored, c._vnode);\n\t}\n};\n\n/**\n * Get a hook's state from the currentComponent\n * @param {number} index The index of the hook to get\n * @param {number} type The index of the hook to get\n * @returns {any}\n */\nfunction getHookState(index, type) {\n\tif (options._hook) {\n\t\toptions._hook(currentComponent, index, currentHook || type);\n\t}\n\tcurrentHook = 0;\n\n\t// Largely inspired by:\n\t// * https://github.com/michael-klein/funcy.js/blob/f6be73468e6ec46b0ff5aa3cc4c9baf72a29025a/src/hooks/core_hooks.mjs\n\t// * https://github.com/michael-klein/funcy.js/blob/650beaa58c43c33a74820a3c98b3c7079cf2e333/src/renderer.mjs\n\t// Other implementations to look at:\n\t// * https://codesandbox.io/s/mnox05qp8\n\tconst hooks =\n\t\tcurrentComponent.__hooks ||\n\t\t(currentComponent.__hooks = {\n\t\t\t_list: [],\n\t\t\t_pendingEffects: []\n\t\t});\n\n\tif (index >= hooks._list.length) {\n\t\thooks._list.push({});\n\t}\n\n\treturn hooks._list[index];\n}\n\n/**\n * @template {unknown} S\n * @param {import('./index').Dispatch<import('./index').StateUpdater<S>>} [initialState]\n * @returns {[S, (state: S) => void]}\n */\nexport function useState(initialState) {\n\tcurrentHook = 1;\n\treturn useReducer(invokeOrReturn, initialState);\n}\n\n/**\n * @template {unknown} S\n * @template {unknown} A\n * @param {import('./index').Reducer<S, A>} reducer\n * @param {import('./index').Dispatch<import('./index').StateUpdater<S>>} initialState\n * @param {(initialState: any) => void} [init]\n * @returns {[ S, (state: S) => void ]}\n */\nexport function useReducer(reducer, initialState, init) {\n\t/** @type {import('./internal').ReducerHookState} */\n\tconst hookState = getHookState(currentIndex++, 2);\n\thookState._reducer = reducer;\n\tif (!hookState._component) {\n\t\thookState._value = [\n\t\t\t!init ? invokeOrReturn(undefined, initialState) : init(initialState),\n\n\t\t\taction => {\n\t\t\t\tconst currentValue = hookState._nextValue\n\t\t\t\t\t? hookState._nextValue[0]\n\t\t\t\t\t: hookState._value[0];\n\t\t\t\tconst nextValue = hookState._reducer(currentValue, action);\n\n\t\t\t\tif (currentValue !== nextValue) {\n\t\t\t\t\thookState._nextValue = [nextValue, hookState._value[1]];\n\t\t\t\t\thookState._component.setState({});\n\t\t\t\t}\n\t\t\t}\n\t\t];\n\n\t\thookState._component = currentComponent;\n\n\t\tif (!currentComponent._hasScuFromHooks) {\n\t\t\tcurrentComponent._hasScuFromHooks = true;\n\t\t\tlet prevScu = currentComponent.shouldComponentUpdate;\n\t\t\tconst prevCWU = currentComponent.componentWillUpdate;\n\n\t\t\t// If we're dealing with a forced update `shouldComponentUpdate` will\n\t\t\t// not be called. But we use that to update the hook values, so we\n\t\t\t// need to call it.\n\t\t\tcurrentComponent.componentWillUpdate = function (p, s, c) {\n\t\t\t\tif (this._force) {\n\t\t\t\t\tlet tmp = prevScu;\n\t\t\t\t\t// Clear to avoid other sCU hooks from being called\n\t\t\t\t\tprevScu = undefined;\n\t\t\t\t\tupdateHookState(p, s, c);\n\t\t\t\t\tprevScu = tmp;\n\t\t\t\t}\n\n\t\t\t\tif (prevCWU) prevCWU.call(this, p, s, c);\n\t\t\t};\n\n\t\t\t// This SCU has the purpose of bailing out after repeated updates\n\t\t\t// to stateful hooks.\n\t\t\t// we store the next value in _nextValue[0] and keep doing that for all\n\t\t\t// state setters, if we have next states and\n\t\t\t// all next states within a component end up being equal to their original state\n\t\t\t// we are safe to bail out for this specific component.\n\t\t\t/**\n\t\t\t *\n\t\t\t * @type {import('./internal').Component[\"shouldComponentUpdate\"]}\n\t\t\t */\n\t\t\t// @ts-ignore - We don't use TS to downtranspile\n\t\t\t// eslint-disable-next-line no-inner-declarations\n\t\t\tfunction updateHookState(p, s, c) {\n\t\t\t\tif (!hookState._component.__hooks) return true;\n\n\t\t\t\t/** @type {(x: import('./internal').HookState) => x is import('./internal').ReducerHookState} */\n\t\t\t\tconst isStateHook = x => !!x._component;\n\t\t\t\tconst stateHooks =\n\t\t\t\t\thookState._component.__hooks._list.filter(isStateHook);\n\n\t\t\t\tconst allHooksEmpty = stateHooks.every(x => !x._nextValue);\n\t\t\t\t// When we have no updated hooks in the component we invoke the previous SCU or\n\t\t\t\t// traverse the VDOM tree further.\n\t\t\t\tif (allHooksEmpty) {\n\t\t\t\t\treturn prevScu ? prevScu.call(this, p, s, c) : true;\n\t\t\t\t}\n\n\t\t\t\t// We check whether we have components with a nextValue set that\n\t\t\t\t// have values that aren't equal to one another this pushes\n\t\t\t\t// us to update further down the tree\n\t\t\t\tlet shouldUpdate = hookState._component.props !== p;\n\t\t\t\tstateHooks.forEach(hookItem => {\n\t\t\t\t\tif (hookItem._nextValue) {\n\t\t\t\t\t\tconst currentValue = hookItem._value[0];\n\t\t\t\t\t\thookItem._value = hookItem._nextValue;\n\t\t\t\t\t\thookItem._nextValue = undefined;\n\t\t\t\t\t\tif (currentValue !== hookItem._value[0]) shouldUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn prevScu\n\t\t\t\t\t? prevScu.call(this, p, s, c) || shouldUpdate\n\t\t\t\t\t: shouldUpdate;\n\t\t\t}\n\n\t\t\tcurrentComponent.shouldComponentUpdate = updateHookState;\n\t\t}\n\t}\n\n\treturn hookState._nextValue || hookState._value;\n}\n\n/**\n * @param {import('./internal').Effect} callback\n * @param {unknown[]} args\n * @returns {void}\n */\nexport function useEffect(callback, args) {\n\t/** @type {import('./internal').EffectHookState} */\n\tconst state = getHookState(currentIndex++, 3);\n\tif (!options._skipEffects && argsChanged(state._args, args)) {\n\t\tstate._value = callback;\n\t\tstate._pendingArgs = args;\n\n\t\tcurrentComponent.__hooks._pendingEffects.push(state);\n\t}\n}\n\n/**\n * @param {import('./internal').Effect} callback\n * @param {unknown[]} args\n * @returns {void}\n */\nexport function useLayoutEffect(callback, args) {\n\t/** @type {import('./internal').EffectHookState} */\n\tconst state = getHookState(currentIndex++, 4);\n\tif (!options._skipEffects && argsChanged(state._args, args)) {\n\t\tstate._value = callback;\n\t\tstate._pendingArgs = args;\n\n\t\tcurrentComponent._renderCallbacks.push(state);\n\t}\n}\n\n/** @type {(initialValue: unknown) => unknown} */\nexport function useRef(initialValue) {\n\tcurrentHook = 5;\n\treturn useMemo(() => ({ current: initialValue }), []);\n}\n\n/**\n * @param {object} ref\n * @param {() => object} createHandle\n * @param {unknown[]} args\n * @returns {void}\n */\nexport function useImperativeHandle(ref, createHandle, args) {\n\tcurrentHook = 6;\n\tuseLayoutEffect(\n\t\t() => {\n\t\t\tif (typeof ref == 'function') {\n\t\t\t\tref(createHandle());\n\t\t\t\treturn () => ref(null);\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = createHandle();\n\t\t\t\treturn () => (ref.current = null);\n\t\t\t}\n\t\t},\n\t\targs == null ? args : args.concat(ref)\n\t);\n}\n\n/**\n * @template {unknown} T\n * @param {() => T} factory\n * @param {unknown[]} args\n * @returns {T}\n */\nexport function useMemo(factory, args) {\n\t/** @type {import('./internal').MemoHookState<T>} */\n\tconst state = getHookState(currentIndex++, 7);\n\tif (argsChanged(state._args, args)) {\n\t\tstate._value = factory();\n\t\tstate._args = args;\n\t\tstate._factory = factory;\n\t}\n\n\treturn state._value;\n}\n\n/**\n * @param {() => void} callback\n * @param {unknown[]} args\n * @returns {() => void}\n */\nexport function useCallback(callback, args) {\n\tcurrentHook = 8;\n\treturn useMemo(() => callback, args);\n}\n\n/**\n * @param {import('./internal').PreactContext} context\n */\nexport function useContext(context) {\n\tconst provider = currentComponent.context[context._id];\n\t// We could skip this call here, but than we'd not call\n\t// `options._hook`. We need to do that in order to make\n\t// the devtools aware of this hook.\n\t/** @type {import('./internal').ContextHookState} */\n\tconst state = getHookState(currentIndex++, 9);\n\t// The devtools needs access to the context object to\n\t// be able to pull of the default value when no provider\n\t// is present in the tree.\n\tstate._context = context;\n\tif (!provider) return context._defaultValue;\n\t// This is probably not safe to convert to \"!\"\n\tif (state._value == null) {\n\t\tstate._value = true;\n\t\tprovider.sub(currentComponent);\n\t}\n\treturn provider.props.value;\n}\n\n/**\n * Display a custom label for a custom hook for the devtools panel\n * @type {<T>(value: T, cb?: (value: T) => string | number) => void}\n */\nexport function useDebugValue(value, formatter) {\n\tif (options.useDebugValue) {\n\t\toptions.useDebugValue(\n\t\t\tformatter ? formatter(value) : /** @type {any}*/ (value)\n\t\t);\n\t}\n}\n\n/**\n * @param {(error: unknown, errorInfo: import('preact').ErrorInfo) => void} cb\n * @returns {[unknown, () => void]}\n */\nexport function useErrorBoundary(cb) {\n\t/** @type {import('./internal').ErrorBoundaryHookState} */\n\tconst state = getHookState(currentIndex++, 10);\n\tconst errState = useState();\n\tstate._value = cb;\n\tif (!currentComponent.componentDidCatch) {\n\t\tcurrentComponent.componentDidCatch = (err, errorInfo) => {\n\t\t\tif (state._value) state._value(err, errorInfo);\n\t\t\terrState[1](err);\n\t\t};\n\t}\n\treturn [\n\t\terrState[0],\n\t\t() => {\n\t\t\terrState[1](undefined);\n\t\t}\n\t];\n}\n\n/** @type {() => string} */\nexport function useId() {\n\t/** @type {import('./internal').IdHookState} */\n\tconst state = getHookState(currentIndex++, 11);\n\tif (!state._value) {\n\t\t// Grab either the root node or the nearest async boundary node.\n\t\t/** @type {import('./internal.d').VNode} */\n\t\tlet root = currentComponent._vnode;\n\t\twhile (root !== null && !root._mask && root._parent !== null) {\n\t\t\troot = root._parent;\n\t\t}\n\n\t\tlet mask = root._mask || (root._mask = [0, 0]);\n\t\tstate._value = 'P' + mask[0] + '-' + mask[1]++;\n\t}\n\n\treturn state._value;\n}\n\n/**\n * After paint effects consumer.\n */\nfunction flushAfterPaintEffects() {\n\tlet component;\n\twhile ((component = afterPaintEffects.shift())) {\n\t\tif (!component._parentDom || !component.__hooks) continue;\n\t\ttry {\n\t\t\tcomponent.__hooks._pendingEffects.forEach(invokeCleanup);\n\t\t\tcomponent.__hooks._pendingEffects.forEach(invokeEffect);\n\t\t\tcomponent.__hooks._pendingEffects = [];\n\t\t} catch (e) {\n\t\t\tcomponent.__hooks._pendingEffects = [];\n\t\t\toptions._catchError(e, component._vnode);\n\t\t}\n\t}\n}\n\nlet HAS_RAF = typeof requestAnimationFrame == 'function';\n\n/**\n * Schedule a callback to be invoked after the browser has a chance to paint a new frame.\n * Do this by combining requestAnimationFrame (rAF) + setTimeout to invoke a callback after\n * the next browser frame.\n *\n * Also, schedule a timeout in parallel to the the rAF to ensure the callback is invoked\n * even if RAF doesn't fire (for example if the browser tab is not visible)\n *\n * @param {() => void} callback\n */\nfunction afterNextFrame(callback) {\n\tconst done = () => {\n\t\tclearTimeout(timeout);\n\t\tif (HAS_RAF) cancelAnimationFrame(raf);\n\t\tsetTimeout(callback);\n\t};\n\tconst timeout = setTimeout(done, RAF_TIMEOUT);\n\n\tlet raf;\n\tif (HAS_RAF) {\n\t\traf = requestAnimationFrame(done);\n\t}\n}\n\n// Note: if someone used options.debounceRendering = requestAnimationFrame,\n// then effects will ALWAYS run on the NEXT frame instead of the current one, incurring a ~16ms delay.\n// Perhaps this is not such a big deal.\n/**\n * Schedule afterPaintEffects flush after the browser paints\n * @param {number} newQueueLength\n * @returns {void}\n */\nfunction afterPaint(newQueueLength) {\n\tif (newQueueLength === 1 || prevRaf !== options.requestAnimationFrame) {\n\t\tprevRaf = options.requestAnimationFrame;\n\t\t(prevRaf || afterNextFrame)(flushAfterPaintEffects);\n\t}\n}\n\n/**\n * @param {import('./internal').HookState} hook\n * @returns {void}\n */\nfunction invokeCleanup(hook) {\n\t// A hook cleanup can introduce a call to render which creates a new root, this will call options.vnode\n\t// and move the currentComponent away.\n\tconst comp = currentComponent;\n\tlet cleanup = hook._cleanup;\n\tif (typeof cleanup == 'function') {\n\t\thook._cleanup = undefined;\n\t\tcleanup();\n\t}\n\n\tcurrentComponent = comp;\n}\n\n/**\n * Invoke a Hook's effect\n * @param {import('./internal').EffectHookState} hook\n * @returns {void}\n */\nfunction invokeEffect(hook) {\n\t// A hook call can introduce a call to render which creates a new root, this will call options.vnode\n\t// and move the currentComponent away.\n\tconst comp = currentComponent;\n\thook._cleanup = hook._value();\n\tcurrentComponent = comp;\n}\n\n/**\n * @param {unknown[]} oldArgs\n * @param {unknown[]} newArgs\n * @returns {boolean}\n */\nfunction argsChanged(oldArgs, newArgs) {\n\treturn (\n\t\t!oldArgs ||\n\t\toldArgs.length !== newArgs.length ||\n\t\tnewArgs.some((arg, index) => arg !== oldArgs[index])\n\t);\n}\n\n/**\n * @template Arg\n * @param {Arg} arg\n * @param {(arg: Arg) => any} f\n * @returns {any}\n */\nfunction invokeOrReturn(arg, f) {\n\treturn typeof f == 'function' ? f(arg) : f;\n}\n","const ENCODED_ENTITIES = /[\"&<]/;\n\n/** @param {string} str */\nexport function encodeEntities(str) {\n\t// Skip all work for strings with no entities needing encoding:\n\tif (str.length === 0 || ENCODED_ENTITIES.test(str) === false) return str;\n\n\tlet last = 0,\n\t\ti = 0,\n\t\tout = '',\n\t\tch = '';\n\n\t// Seek forward in str until the next entity char:\n\tfor (; i < str.length; i++) {\n\t\tswitch (str.charCodeAt(i)) {\n\t\t\tcase 34:\n\t\t\t\tch = '&quot;';\n\t\t\t\tbreak;\n\t\t\tcase 38:\n\t\t\t\tch = '&amp;';\n\t\t\t\tbreak;\n\t\t\tcase 60:\n\t\t\t\tch = '&lt;';\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcontinue;\n\t\t}\n\t\t// Append skipped/buffered characters and the encoded entity:\n\t\tif (i !== last) out += str.slice(last, i);\n\t\tout += ch;\n\t\t// Start the next seek/buffer after the entity's offset:\n\t\tlast = i + 1;\n\t}\n\tif (i !== last) out += str.slice(last, i);\n\treturn out;\n}\n","/** Normal hydration that attaches to a DOM tree but does not diff it. */\nexport const MODE_HYDRATE = 1 << 5;\n/** Signifies this VNode suspended on the previous render */\nexport const MODE_SUSPENDED = 1 << 7;\n/** Indicates that this node needs to be inserted while patching children */\nexport const INSERT_VNODE = 1 << 16;\n/** Indicates a VNode has been matched with another VNode in the diff */\nexport const MATCHED = 1 << 17;\n\n/** Reset all mode flags */\nexport const RESET_MODE = ~(MODE_HYDRATE | MODE_SUSPENDED);\n\nexport const UNDEFINED = undefined;\nexport const EMPTY_OBJ = /** @type {any} */ ({});\nexport const EMPTY_ARR = [];\nexport const IS_NON_DIMENSIONAL =\n\t/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;\n","import { options, Fragment } from 'preact';\nimport { encodeEntities } from './utils';\nimport { IS_NON_DIMENSIONAL } from '../../src/constants';\n\nlet vnodeId = 0;\n\nconst isArray = Array.isArray;\n\n/**\n * @fileoverview\n * This file exports various methods that implement Babel's \"automatic\" JSX runtime API:\n * - jsx(type, props, key)\n * - jsxs(type, props, key)\n * - jsxDEV(type, props, key, __source, __self)\n *\n * The implementation of createVNode here is optimized for performance.\n * Benchmarks: https://esbench.com/bench/5f6b54a0b4632100a7dcd2b3\n */\n\n/**\n * JSX.Element factory used by Babel's {runtime:\"automatic\"} JSX transform\n * @param {VNode['type']} type\n * @param {VNode['props']} props\n * @param {VNode['key']} [key]\n * @param {unknown} [isStaticChildren]\n * @param {unknown} [__source]\n * @param {unknown} [__self]\n */\nfunction createVNode(type, props, key, isStaticChildren, __source, __self) {\n\tif (!props) props = {};\n\t// We'll want to preserve `ref` in props to get rid of the need for\n\t// forwardRef components in the future, but that should happen via\n\t// a separate PR.\n\tlet normalizedProps = props,\n\t\tref,\n\t\ti;\n\n\tif ('ref' in props) {\n\t\tref = props.ref;\n\t\tdelete props.ref;\n\t}\n\n\t/** @type {VNode & { __source: any; __self: any }} */\n\tconst vnode = {\n\t\ttype,\n\t\tprops: normalizedProps,\n\t\tkey,\n\t\tref,\n\t\t_children: null,\n\t\t_parent: null,\n\t\t_depth: 0,\n\t\t_dom: null,\n\t\t_nextDom: undefined,\n\t\t_component: null,\n\t\tconstructor: undefined,\n\t\t_original: --vnodeId,\n\t\t_index: -1,\n\t\t_flags: 0,\n\t\t__source,\n\t\t__self\n\t};\n\n\t// If a Component VNode, check for and apply defaultProps.\n\t// Note: `type` is often a String, and can be `undefined` in development.\n\tif (typeof type === 'function' && (ref = type.defaultProps)) {\n\t\tfor (i in ref)\n\t\t\tif (typeof normalizedProps[i] === 'undefined') {\n\t\t\t\tnormalizedProps[i] = ref[i];\n\t\t\t}\n\t}\n\n\tif (options.vnode) options.vnode(vnode);\n\treturn vnode;\n}\n\n/**\n * Create a template vnode. This function is not expected to be\n * used directly, but rather through a precompile JSX transform\n * @param {string[]} templates\n * @param {Array<string | null | VNode>} exprs\n * @returns {VNode}\n */\nfunction jsxTemplate(templates, ...exprs) {\n\tconst vnode = createVNode(Fragment, { tpl: templates, exprs });\n\t// Bypass render to string top level Fragment optimization\n\tvnode.key = vnode._vnode;\n\treturn vnode;\n}\n\nconst JS_TO_CSS = {};\nconst CSS_REGEX = /[A-Z]/g;\n\n/**\n * Serialize an HTML attribute to a string. This function is not\n * expected to be used directly, but rather through a precompile\n * JSX transform\n * @param {string} name The attribute name\n * @param {*} value The attribute value\n * @returns {string}\n */\nfunction jsxAttr(name, value) {\n\tif (options.attr) {\n\t\tconst result = options.attr(name, value);\n\t\tif (typeof result === 'string') return result;\n\t}\n\n\tif (name === 'ref' || name === 'key') return '';\n\tif (name === 'style' && typeof value === 'object') {\n\t\tlet str = '';\n\t\tfor (let prop in value) {\n\t\t\tlet val = value[prop];\n\t\t\tif (val != null && val !== '') {\n\t\t\t\tconst name =\n\t\t\t\t\tprop[0] == '-'\n\t\t\t\t\t\t? prop\n\t\t\t\t\t\t: JS_TO_CSS[prop] ||\n\t\t\t\t\t\t\t(JS_TO_CSS[prop] = prop.replace(CSS_REGEX, '-$&').toLowerCase());\n\n\t\t\t\tlet suffix = ';';\n\t\t\t\tif (\n\t\t\t\t\ttypeof val === 'number' &&\n\t\t\t\t\t// Exclude custom-attributes\n\t\t\t\t\t!name.startsWith('--') &&\n\t\t\t\t\t!IS_NON_DIMENSIONAL.test(name)\n\t\t\t\t) {\n\t\t\t\t\tsuffix = 'px;';\n\t\t\t\t}\n\t\t\t\tstr = str + name + ':' + val + suffix;\n\t\t\t}\n\t\t}\n\t\treturn name + '=\"' + str + '\"';\n\t}\n\n\tif (\n\t\tvalue == null ||\n\t\tvalue === false ||\n\t\ttypeof value === 'function' ||\n\t\ttypeof value === 'object'\n\t) {\n\t\treturn '';\n\t} else if (value === true) return name;\n\n\treturn name + '=\"' + encodeEntities(value) + '\"';\n}\n\n/**\n * Escape a dynamic child passed to `jsxTemplate`. This function\n * is not expected to be used directly, but rather through a\n * precompile JSX transform\n * @param {*} value\n * @returns {string | null | VNode | Array<string | null | VNode>}\n */\nfunction jsxEscape(value) {\n\tif (\n\t\tvalue == null ||\n\t\ttypeof value === 'boolean' ||\n\t\ttypeof value === 'function'\n\t) {\n\t\treturn null;\n\t}\n\n\tif (typeof value === 'object') {\n\t\t// Check for VNode\n\t\tif (value.constructor === undefined) return value;\n\n\t\tif (isArray(value)) {\n\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\tvalue[i] = jsxEscape(value[i]);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t}\n\n\treturn encodeEntities('' + value);\n}\n\nexport {\n\tcreateVNode as jsx,\n\tcreateVNode as jsxs,\n\tcreateVNode as jsxDEV,\n\tFragment,\n\t// precompiled JSX transform\n\tjsxTemplate,\n\tjsxAttr,\n\tjsxEscape\n};\n","/** @jsxImportSource preact */\n\nexport const IconChat = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n)\n\nexport const IconX = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n)\n\nexport const IconArrowLeft = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\" />\n <polyline points=\"12 19 5 12 12 5\" />\n </svg>\n)\n\nexport const IconSend = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n)\n\nexport const IconPlus = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n)\n\nexport const IconPaperclip = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\" />\n </svg>\n)\n\nexport const IconDownload = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n)\n\nexport const IconFile = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n </svg>\n)\n","/** @jsxImportSource preact */\n\nimport { IconChat, IconX } from '../icons'\n\ninterface ChatBubbleProps {\n isOpen: boolean\n position: 'bottom-right' | 'bottom-left'\n unreadCount: number\n onClick: () => void\n}\n\nexport function ChatBubble({\n isOpen,\n position,\n unreadCount,\n onClick,\n}: ChatBubbleProps) {\n const posClass =\n position === 'bottom-left' ? 'bp-bubble--left' : 'bp-bubble--right'\n\n return (\n <button\n class={`bp-bubble ${posClass}`}\n onClick={onClick}\n aria-label={isOpen ? 'Close chat' : 'Open chat'}\n >\n {isOpen ? <IconX /> : <IconChat />}\n {!isOpen && unreadCount > 0 && (\n <span class=\"bp-bubble__badge\">\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n )}\n </button>\n )\n}\n","/** @jsxImportSource preact */\n\nimport type { ChannelInfo, Conversation } from '../../api/types'\nimport { IconPlus } from '../icons'\nimport type { Translations } from '../i18n'\n\ninterface ConversationListProps {\n conversations: Conversation[]\n channelInfo: ChannelInfo\n loading: boolean\n onSelect: (conversation: Conversation) => void\n onNew: () => void\n t: Translations\n}\n\nexport function ConversationList({\n conversations,\n channelInfo,\n loading,\n onSelect,\n onNew,\n t,\n}: ConversationListProps) {\n const hasOpen = conversations.some((c) => c.open)\n const canReopen = channelInfo.config.allowReopenConversation\n\n if (loading) {\n return (\n <div class=\"bp-loading\">\n <div class=\"bp-spinner\" />\n </div>\n )\n }\n\n return (\n <div class=\"bp-convlist\">\n {!hasOpen && (\n <div class=\"bp-convlist__new\">\n <button class=\"bp-convlist__new-btn\" onClick={onNew}>\n <IconPlus />\n {t.conversations.newConversation}\n </button>\n </div>\n )}\n\n <div class=\"bp-convlist__items\">\n {conversations.length === 0 ? (\n <div class=\"bp-convlist__empty\">{t.conversations.empty}</div>\n ) : (\n conversations.map((conv) => {\n const isClickable = conv.open || canReopen\n\n return (\n <button\n key={conv.id}\n class=\"bp-convlist__item\"\n onClick={() => isClickable && onSelect(conv)}\n disabled={!isClickable}\n >\n <div class=\"bp-convlist__item-top\">\n <span class=\"bp-convlist__item-title\">\n {channelInfo.name}\n </span>\n <span\n class={`bp-convlist__item-status ${conv.open ? 'bp-convlist__item-status--open' : 'bp-convlist__item-status--closed'}`}\n >\n {conv.open ? t.conversations.open : t.conversations.closed}\n </span>\n </div>\n <span class=\"bp-convlist__item-preview\">\n {conv.lastMessage?.content || t.conversations.noMessages}\n </span>\n </button>\n )\n })\n )}\n </div>\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useCallback, useRef } from 'preact/hooks'\n\nimport { IconFile, IconPaperclip, IconSend, IconX } from '../icons'\nimport type { Translations } from '../i18n'\n\nexport interface AttachedFile {\n file: File\n preview?: string\n}\n\ninterface MessageInputProps {\n value: string\n onChange: (value: string) => void\n onSend: () => void\n onFileSelect: (file: File) => void\n onFileRemove: () => void\n attachedFile: AttachedFile | null\n uploading: boolean\n disabled: boolean\n placeholder?: string\n t: Translations\n}\n\nexport function MessageInput({\n value,\n onChange,\n onSend,\n onFileSelect,\n onFileRemove,\n attachedFile,\n uploading,\n disabled,\n placeholder,\n t,\n}: MessageInputProps) {\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n onSend()\n }\n },\n [onSend]\n )\n\n const handleInput = useCallback(\n (e: Event) => {\n const target = e.target as HTMLTextAreaElement\n onChange(target.value)\n target.style.height = 'auto'\n target.style.height = `${Math.min(target.scrollHeight, 100)}px`\n },\n [onChange]\n )\n\n const handleAttachClick = useCallback(() => {\n fileInputRef.current?.click()\n }, [])\n\n const handleFileChange = useCallback(\n (e: Event) => {\n const input = e.target as HTMLInputElement\n const file = input.files?.[0]\n if (file) {\n onFileSelect(file)\n }\n input.value = ''\n },\n [onFileSelect]\n )\n\n const isImage = attachedFile?.file.type.startsWith('image/')\n const canSend = (value.trim() || attachedFile) && !disabled && !uploading\n\n return (\n <div class=\"bp-composer\">\n {attachedFile && (\n <div class=\"bp-composer__preview\">\n {isImage && attachedFile.preview ? (\n <img\n src={attachedFile.preview}\n alt={attachedFile.file.name}\n class=\"bp-composer__preview-thumb\"\n />\n ) : (\n <div class=\"bp-composer__preview-icon\">\n <IconFile />\n </div>\n )}\n <div class=\"bp-composer__preview-info\">\n <div class=\"bp-composer__preview-name\">\n {attachedFile.file.name}\n </div>\n <div class=\"bp-composer__preview-status\">\n {uploading ? t.chat.uploading : formatSize(attachedFile.file.size)}\n </div>\n </div>\n {!uploading && (\n <button\n class=\"bp-composer__preview-remove\"\n onClick={onFileRemove}\n aria-label=\"Remove file\"\n >\n <IconX />\n </button>\n )}\n </div>\n )}\n\n <div class=\"bp-composer__row\">\n <button\n class=\"bp-composer__attach\"\n onClick={handleAttachClick}\n disabled={disabled || uploading || !!attachedFile}\n aria-label={t.chat.attachFile}\n >\n <IconPaperclip />\n </button>\n\n <textarea\n ref={textareaRef}\n class=\"bp-composer__field\"\n value={value}\n onInput={handleInput}\n onKeyDown={handleKeyDown}\n placeholder={placeholder || t.chat.placeholder}\n disabled={disabled}\n rows={1}\n />\n\n <button\n class=\"bp-composer__send\"\n onClick={onSend}\n disabled={!canSend}\n aria-label=\"Send message\"\n >\n <IconSend />\n </button>\n </div>\n\n <input\n type=\"file\"\n ref={fileInputRef}\n onChange={handleFileChange}\n style={{ display: 'none' }}\n accept=\"image/*,video/mp4,audio/*,.pdf,.doc,.docx,.xls,.xlsx,.txt\"\n />\n </div>\n )\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n","/** @jsxImportSource preact */\n\nimport { useCallback, useEffect } from 'preact/hooks'\n\nimport { IconX } from '../icons'\n\ninterface ImageLightboxProps {\n src: string\n alt?: string\n onClose: () => void\n}\n\nexport function ImageLightbox({ src, alt, onClose }: ImageLightboxProps) {\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose()\n },\n [onClose]\n )\n\n useEffect(() => {\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [handleKeyDown])\n\n return (\n <div class=\"bp-lightbox\" onClick={onClose}>\n <button class=\"bp-lightbox__close\" onClick={onClose}>\n <IconX />\n </button>\n <img\n src={src}\n alt={alt || ''}\n class=\"bp-lightbox__img\"\n onClick={(e) => e.stopPropagation()}\n />\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport type { Message } from '../../api/types'\nimport { IconDownload, IconFile } from '../icons'\nimport type { Translations } from '../i18n'\n\ninterface MessageMediaProps {\n media: NonNullable<Message['media']>\n onImageClick: (src: string) => void\n t: Translations\n}\n\nexport function MessageMedia({ media, onImageClick, t }: MessageMediaProps) {\n const mimeType = (media.mimeType || '').toLowerCase()\n\n if (mimeType.startsWith('image/') || media.kind === 'image') {\n const thumbSrc = media.streamUrlData?.small || media.url\n const fullSrc = media.streamUrlData?.large || media.url\n return (\n <img\n src={thumbSrc}\n alt={media.name}\n class=\"bp-media-img\"\n onClick={() => onImageClick(fullSrc)}\n />\n )\n }\n\n if (mimeType.startsWith('video/')) {\n return (\n <video controls class=\"bp-media-video\" preload=\"metadata\">\n <source src={media.url} type={mimeType} />\n </video>\n )\n }\n\n return (\n <a\n href={media.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"bp-media-file\"\n download={media.name}\n >\n <div class=\"bp-media-file__icon\">\n <IconFile />\n </div>\n <span class=\"bp-media-file__name\">{media.name}</span>\n <span class=\"bp-media-file__download\">\n <IconDownload />\n </span>\n </a>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useEffect, useRef, useState } from 'preact/hooks'\n\nimport type { Message } from '../../api/types'\nimport type { Translations } from '../i18n'\nimport { ImageLightbox } from './ImageLightbox'\nimport { MessageMedia } from './MessageMedia'\n\ninterface MessageListProps {\n messages: Message[]\n loading: boolean\n t: Translations\n}\n\nexport function MessageList({ messages, loading, t }: MessageListProps) {\n const endRef = useRef<HTMLDivElement>(null)\n const [lightboxSrc, setLightboxSrc] = useState<string | null>(null)\n\n useEffect(() => {\n endRef.current?.scrollIntoView({ behavior: 'smooth' })\n }, [messages])\n\n if (loading) {\n return (\n <div class=\"bp-loading\">\n <div class=\"bp-spinner\" />\n </div>\n )\n }\n\n return (\n <div class=\"bp-messages\">\n {messages.map((msg) => (\n <MessageBubble\n key={msg.id}\n message={msg}\n onImageClick={setLightboxSrc}\n t={t}\n />\n ))}\n <div ref={endRef} />\n {lightboxSrc && (\n <ImageLightbox\n src={lightboxSrc}\n onClose={() => setLightboxSrc(null)}\n />\n )}\n </div>\n )\n}\n\nfunction MessageBubble({\n message,\n onImageClick,\n t,\n}: {\n message: Message\n onImageClick: (src: string) => void\n t: Translations\n}) {\n const isClient = message.role === 'client'\n const cls = isClient ? 'bp-msg bp-msg--client' : 'bp-msg bp-msg--agent'\n\n const time = new Date(message.createdAt).toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n })\n\n return (\n <div class={cls}>\n {!isClient && (\n <div class=\"bp-msg__avatar\">\n {message.user?.avatar?.url ? (\n <img\n src={message.user.avatar.url}\n alt={message.user.firstName || 'Agent'}\n />\n ) : (\n (message.user?.firstName?.[0] || 'A').toUpperCase()\n )}\n </div>\n )}\n <div class=\"bp-msg__body\">\n {message.media && (\n <MessageMedia\n media={message.media}\n onImageClick={onImageClick}\n t={t}\n />\n )}\n {message.content && (\n <div class=\"bp-msg__content\">{message.content}</div>\n )}\n <div class=\"bp-msg__time\">{time}</div>\n </div>\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useState } from 'preact/hooks'\n\nimport type { ChannelInfo } from '../../api/types'\nimport type { Translations } from '../i18n'\n\ninterface PreChatFormProps {\n channelInfo: ChannelInfo\n onSubmit: (data: { name?: string; email?: string }) => void\n loading: boolean\n t: Translations\n}\n\nexport function PreChatForm({\n channelInfo,\n onSubmit,\n loading,\n t,\n}: PreChatFormProps) {\n const [name, setName] = useState('')\n const [email, setEmail] = useState('')\n\n const { requireName, requireEmail, privacyPolicyUrl } = channelInfo.config\n\n const handleSubmit = (e: Event) => {\n e.preventDefault()\n onSubmit({\n name: name.trim() || undefined,\n email: email.trim() || undefined,\n })\n }\n\n const isValid =\n (!requireName || name.trim()) && (!requireEmail || email.trim())\n\n return (\n <form class=\"bp-prechat\" onSubmit={handleSubmit}>\n <div class=\"bp-prechat__title\">{t.prechat.title}</div>\n <div class=\"bp-prechat__desc\">{t.prechat.description}</div>\n\n {requireName && (\n <div class=\"bp-prechat__field\">\n <label class=\"bp-prechat__label\">{t.prechat.name}</label>\n <input\n class=\"bp-prechat__input\"\n type=\"text\"\n value={name}\n onInput={(e) => setName((e.target as HTMLInputElement).value)}\n placeholder={t.prechat.namePlaceholder}\n required\n />\n </div>\n )}\n\n {requireEmail && (\n <div class=\"bp-prechat__field\">\n <label class=\"bp-prechat__label\">{t.prechat.email}</label>\n <input\n class=\"bp-prechat__input\"\n type=\"email\"\n value={email}\n onInput={(e) => setEmail((e.target as HTMLInputElement).value)}\n placeholder={t.prechat.emailPlaceholder}\n required\n />\n </div>\n )}\n\n <button\n class=\"bp-prechat__submit\"\n type=\"submit\"\n disabled={!isValid || loading}\n >\n {loading ? t.prechat.loading : t.prechat.start}\n </button>\n\n {privacyPolicyUrl && (\n <div class=\"bp-prechat__privacy\">\n {t.prechat.privacyPrefix}{' '}\n <a href={privacyPolicyUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {t.prechat.privacyLink}\n </a>\n </div>\n )}\n </form>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useCallback, useEffect, useState } from 'preact/hooks'\n\nimport type { ApiClient } from '../../api/client'\nimport type {\n ChannelInfo,\n Conversation,\n Message,\n VisitorData,\n} from '../../api/types'\nimport type { RealtimeClient } from '../../realtime/ably-client'\nimport type { EventEmitter } from '../../utils/events'\nimport type { Storage } from '../../utils/storage'\nimport { IconArrowLeft, IconX } from '../icons'\nimport type { Translations } from '../i18n'\nimport { ConversationList } from './ConversationList'\nimport { MessageInput, type AttachedFile } from './MessageInput'\nimport { MessageList } from './MessageList'\nimport { PreChatForm } from './PreChatForm'\n\ntype View = 'prechat' | 'conversations' | 'chat'\n\ninterface ChatWindowProps {\n channelInfo: ChannelInfo\n apiClient: ApiClient\n realtimeClient: RealtimeClient\n storage: Storage\n events: EventEmitter\n visitor: VisitorData | null\n isAuthenticated: boolean\n position: 'bottom-right' | 'bottom-left'\n onClose: () => void\n t: Translations\n initialConversationId?: string | null\n}\n\nexport function ChatWindow({\n channelInfo,\n apiClient,\n realtimeClient,\n storage,\n events,\n visitor,\n isAuthenticated,\n position,\n onClose,\n t,\n initialConversationId,\n}: ChatWindowProps) {\n const [view, setView] = useState<View>('chat')\n const [conversation, setConversation] = useState<Conversation | null>(null)\n const [conversations, setConversations] = useState<Conversation[]>([])\n const [messages, setMessages] = useState<Message[]>([])\n const [inputValue, setInputValue] = useState('')\n const [loading, setLoading] = useState(true)\n const [sending, setSending] = useState(false)\n const [attachedFile, setAttachedFile] = useState<AttachedFile | null>(null)\n const [uploadedFileId, setUploadedFileId] = useState<string | null>(null)\n const [uploading, setUploading] = useState(false)\n\n const isOpen = conversation?.open !== false\n\n const allowViewHistory = channelInfo.config.allowViewHistory && isAuthenticated\n\n // Determine initial view\n useEffect(() => {\n const init = async () => {\n setLoading(true)\n try {\n if (allowViewHistory) {\n // History mode: load conversation list\n const convs = await apiClient.getVisitorConversations()\n setConversations(convs)\n\n if (initialConversationId) {\n const conv = convs.find((c) => c.id === initialConversationId)\n if (conv) {\n await openConversation(conv)\n return\n }\n }\n\n if (convs.length > 0) {\n setView('conversations')\n } else {\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n }\n } else {\n // No history: check localStorage for existing conversation\n const storedId =\n initialConversationId || storage.getConversationId()\n\n if (storedId) {\n try {\n const msgs = await apiClient.getMessages(storedId, { limit: 50 })\n setMessages(Array.isArray(msgs) ? msgs.reverse() : [])\n setConversation({ id: storedId, open: true } as Conversation)\n setView('chat')\n connectRealtime(storedId)\n } catch {\n storage.clear()\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n }\n } else {\n if (needsPreChat()) {\n setView('prechat')\n } else {\n await startNewConversation()\n }\n }\n }\n } catch (e) {\n console.error('[BaseportalChat] Error initializing:', e)\n } finally {\n setLoading(false)\n }\n }\n\n init()\n\n return () => {\n realtimeClient.unsubscribe()\n }\n }, [])\n\n const needsPreChat = useCallback((): boolean => {\n if (visitor?.name && visitor?.email) return false\n return (\n channelInfo.config.requireName || channelInfo.config.requireEmail\n )\n }, [channelInfo, visitor])\n\n const connectRealtime = useCallback(\n (convId: string) => {\n realtimeClient.subscribe(convId, {\n onMessage: (msg) => {\n setMessages((prev) => {\n if (prev.some((m) => m.id === msg.id)) {\n return prev.map((m) =>\n m.id === msg.id ? { ...m, ...msg } : m\n )\n }\n const withoutTemp = prev.filter(\n (m) =>\n !String(m.id).startsWith('temp-') ||\n m.content !== msg.content\n )\n return [...withoutTemp, msg]\n })\n events.emit('message:received', msg)\n },\n onConversationStatusUpdate: (conv) => {\n setConversation((prev) =>\n prev ? { ...prev, open: conv.open } : prev\n )\n if (!conv.open) {\n events.emit('conversation:closed', conv)\n }\n },\n })\n },\n [realtimeClient, events]\n )\n\n const openConversation = useCallback(\n async (conv: Conversation) => {\n setLoading(true)\n try {\n const msgs = await apiClient.getMessages(conv.id, { limit: 50 })\n setMessages(Array.isArray(msgs) ? msgs.reverse() : [])\n setConversation(conv)\n setView('chat')\n storage.setConversationId(conv.id)\n connectRealtime(conv.id)\n } catch (e) {\n console.error('[BaseportalChat] Error opening conversation:', e)\n } finally {\n setLoading(false)\n }\n },\n [apiClient, storage, connectRealtime]\n )\n\n const startNewConversation = useCallback(async () => {\n setLoading(true)\n try {\n const result = await apiClient.initConversation({\n name: visitor?.name,\n email: visitor?.email,\n })\n setConversation(result)\n setMessages(result.messages || [])\n setView('chat')\n storage.setConversationId(result.id)\n connectRealtime(result.id)\n events.emit('conversation:started', result)\n } catch (e) {\n console.error('[BaseportalChat] Error starting conversation:', e)\n } finally {\n setLoading(false)\n }\n }, [apiClient, visitor, storage, connectRealtime, events])\n\n const handlePreChatSubmit = useCallback(\n async (data: { name?: string; email?: string }) => {\n storage.setVisitor({ ...visitor, ...data })\n const result = await apiClient.initConversation(data)\n setConversation(result)\n setMessages(result.messages || [])\n setView('chat')\n storage.setConversationId(result.id)\n connectRealtime(result.id)\n events.emit('conversation:started', result)\n },\n [apiClient, visitor, storage, connectRealtime, events]\n )\n\n const handleFileSelect = useCallback(\n async (file: File) => {\n if (!conversation) return\n\n const MAX_SIZE = 25 * 1024 * 1024\n if (file.size > MAX_SIZE) {\n console.warn('[BaseportalChat] File too large')\n return\n }\n\n const preview = file.type.startsWith('image/')\n ? URL.createObjectURL(file)\n : undefined\n\n setAttachedFile({ file, preview })\n setUploading(true)\n\n try {\n const uploaded = await apiClient.uploadFile(conversation.id, file)\n setUploadedFileId(uploaded.id)\n } catch (e) {\n console.error('[BaseportalChat] Error uploading file:', e)\n setAttachedFile(null)\n if (preview) URL.revokeObjectURL(preview)\n } finally {\n setUploading(false)\n }\n },\n [apiClient, conversation]\n )\n\n const handleFileRemove = useCallback(() => {\n if (attachedFile?.preview) URL.revokeObjectURL(attachedFile.preview)\n setAttachedFile(null)\n setUploadedFileId(null)\n }, [attachedFile])\n\n const handleSend = useCallback(async () => {\n const content = inputValue.trim()\n if ((!content && !uploadedFileId) || !conversation || sending) return\n\n const tempId = `temp-${Date.now()}`\n const optimistic: Message = {\n id: tempId,\n content,\n role: 'client',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n\n const mediaId = uploadedFileId || undefined\n\n setInputValue('')\n setAttachedFile(null)\n setUploadedFileId(null)\n setSending(true)\n setMessages((prev) => [...prev, optimistic])\n\n try {\n const msg = await apiClient.sendMessage(conversation.id, {\n content: content || undefined,\n mediaId,\n })\n setMessages((prev) => prev.map((m) => (m.id === tempId ? msg : m)))\n events.emit('message:sent', msg)\n } catch (e) {\n console.error('[BaseportalChat] Error sending message:', e)\n setMessages((prev) => prev.filter((m) => m.id !== tempId))\n setInputValue(content)\n } finally {\n setSending(false)\n }\n }, [inputValue, uploadedFileId, conversation, sending, apiClient, events])\n\n const handleReopen = useCallback(async () => {\n if (!conversation) return\n try {\n const updated = await apiClient.reopenConversation(conversation.id)\n setConversation((prev) => prev ? { ...prev, open: updated.open ?? true } : prev)\n } catch (e) {\n console.error('[BaseportalChat] Error reopening conversation:', e)\n }\n }, [conversation, apiClient])\n\n const handleBack = useCallback(() => {\n if (allowViewHistory && view === 'chat') {\n realtimeClient.unsubscribe()\n setView('conversations')\n setConversation(null)\n setMessages([])\n apiClient.getVisitorConversations().then(setConversations).catch(() => {})\n } else {\n onClose()\n }\n }, [allowViewHistory, view, realtimeClient, apiClient, onClose])\n\n const posClass =\n position === 'bottom-left' ? 'bp-window--left' : 'bp-window--right'\n\n const headerTitle =\n view === 'conversations'\n ? t.conversations.title\n : channelInfo.name\n\n const showBack =\n (allowViewHistory && view === 'chat') || view === 'prechat'\n\n return (\n <div class={`bp-window ${posClass}`}>\n {/* Header */}\n <div class=\"bp-header\">\n <div class=\"bp-header__title\">\n {showBack && (\n <button class=\"bp-header__back\" onClick={handleBack}>\n <IconArrowLeft />\n </button>\n )}\n {headerTitle}\n </div>\n <button class=\"bp-header__close\" onClick={onClose}>\n <IconX />\n </button>\n </div>\n\n {/* Content */}\n {loading && view !== 'chat' ? (\n <div class=\"bp-loading\">\n <div class=\"bp-spinner\" />\n </div>\n ) : (\n <>\n {view === 'prechat' && (\n <PreChatForm\n channelInfo={channelInfo}\n onSubmit={handlePreChatSubmit}\n loading={loading}\n t={t}\n />\n )}\n\n {view === 'conversations' && (\n <ConversationList\n conversations={conversations}\n channelInfo={channelInfo}\n loading={loading}\n onSelect={openConversation}\n onNew={\n needsPreChat()\n ? () => setView('prechat')\n : startNewConversation\n }\n t={t}\n />\n )}\n\n {view === 'chat' && (\n <>\n <MessageList messages={messages} loading={loading} t={t} />\n {isOpen ? (\n <MessageInput\n value={inputValue}\n onChange={setInputValue}\n onSend={handleSend}\n onFileSelect={handleFileSelect}\n onFileRemove={handleFileRemove}\n attachedFile={attachedFile}\n uploading={uploading}\n disabled={sending || loading}\n placeholder={t.chat.placeholder}\n t={t}\n />\n ) : (\n <div class=\"bp-closed-banner\">\n <span class=\"bp-closed-banner__text\">{t.chat.closed}</span>\n {channelInfo.config.allowReopenConversation && (\n <button class=\"bp-closed-banner__reopen\" onClick={handleReopen}>\n {t.chat.reopen}\n </button>\n )}\n </div>\n )}\n {channelInfo.config.privacyPolicyUrl && (\n <div class=\"bp-privacy-footer\">\n <a\n href={channelInfo.config.privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t.prechat.privacyLink}\n </a>\n </div>\n )}\n </>\n )}\n </>\n )}\n </div>\n )\n}\n","/** @jsxImportSource preact */\n\nimport { useEffect, useState } from 'preact/hooks'\n\nimport type { ApiClient } from '../api/client'\nimport type { ChannelInfo, VisitorData } from '../api/types'\nimport type { RealtimeClient } from '../realtime/ably-client'\nimport type { EventEmitter } from '../utils/events'\nimport type { Storage } from '../utils/storage'\nimport { ChatBubble } from './components/ChatBubble'\nimport { ChatWindow } from './components/ChatWindow'\nimport type { Translations } from './i18n'\n\ninterface AppProps {\n channelInfo: ChannelInfo\n apiClient: ApiClient\n realtimeClient: RealtimeClient\n storage: Storage\n events: EventEmitter\n visitor: VisitorData | null\n isAuthenticated: boolean\n position: 'bottom-right' | 'bottom-left'\n hidden: boolean\n t: Translations\n // Controlled state from widget class\n isOpenRef: { current: boolean }\n setIsOpen: (open: boolean) => void\n}\n\nexport function App({\n channelInfo,\n apiClient,\n realtimeClient,\n storage,\n events,\n visitor,\n isAuthenticated,\n position,\n hidden,\n t,\n isOpenRef,\n setIsOpen,\n}: AppProps) {\n const [isOpen, setIsOpenState] = useState(isOpenRef.current)\n const [isHidden, setIsHidden] = useState(hidden)\n const [unreadCount] = useState(0)\n\n // Listen for external open/close/show/hide from SDK\n useEffect(() => {\n const onOpen = () => {\n setIsOpenState(true)\n isOpenRef.current = true\n setIsOpen(true)\n }\n const onClose = () => {\n setIsOpenState(false)\n isOpenRef.current = false\n setIsOpen(false)\n }\n const onShow = () => setIsHidden(false)\n const onHide = () => {\n setIsHidden(true)\n setIsOpenState(false)\n isOpenRef.current = false\n setIsOpen(false)\n }\n\n events.on('_open', onOpen)\n events.on('_close', onClose)\n events.on('show', onShow)\n events.on('hide', onHide)\n\n return () => {\n events.off('_open', onOpen)\n events.off('_close', onClose)\n events.off('show', onShow)\n events.off('hide', onHide)\n }\n }, [events, isOpenRef, setIsOpen])\n\n const handleToggle = () => {\n const next = !isOpen\n setIsOpenState(next)\n isOpenRef.current = next\n setIsOpen(next)\n events.emit(next ? 'open' : 'close')\n }\n\n const handleClose = () => {\n setIsOpenState(false)\n isOpenRef.current = false\n setIsOpen(false)\n events.emit('close')\n }\n\n return (\n <>\n {!isHidden && (\n <ChatBubble\n isOpen={isOpen}\n position={position}\n unreadCount={unreadCount}\n onClick={handleToggle}\n />\n )}\n {isOpen && (\n <ChatWindow\n channelInfo={channelInfo}\n apiClient={apiClient}\n realtimeClient={realtimeClient}\n storage={storage}\n events={events}\n visitor={visitor}\n isAuthenticated={isAuthenticated}\n position={position}\n onClose={handleClose}\n t={t}\n />\n )}\n </>\n )\n}\n","// CSS exported as a string to prevent tsup from extracting it to a separate file.\n// This ensures the CSS is inlined in the JS bundle.\nexport default `#baseportal-chat-widget {\n display: block;\n position: static;\n width: 0;\n height: 0;\n overflow: visible;\n padding: 0;\n margin: 0;\n border: none;\n\n --bp-primary: #6366f1;\n --bp-primary-contrast: #ffffff;\n --bp-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n 'Helvetica Neue', Arial, sans-serif;\n --bp-radius: 16px;\n --bp-radius-sm: 8px;\n --bp-bubble-size: 60px;\n --bp-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);\n --bp-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.1);\n --bp-gray-50: #f9fafb;\n --bp-gray-100: #f3f4f6;\n --bp-gray-200: #e5e7eb;\n --bp-gray-300: #d1d5db;\n --bp-gray-500: #6b7280;\n --bp-gray-700: #374151;\n --bp-gray-900: #111827;\n --bp-transition: 0.2s ease;\n}\n\n#baseportal-chat-widget *,\n#baseportal-chat-widget *::before,\n#baseportal-chat-widget *::after {\n box-sizing: border-box;\n}\n\n/* ===== Chat Bubble (FAB) ===== */\n.bp-bubble {\n pointer-events: auto;\n position: fixed;\n bottom: 24px;\n z-index: 2147483646;\n width: var(--bp-bubble-size);\n height: var(--bp-bubble-size);\n border-radius: 50%;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: var(--bp-shadow);\n transition: transform var(--bp-transition), box-shadow var(--bp-transition);\n font-family: var(--bp-font-family);\n font-size: 14px;\n line-height: 1.5;\n margin: 0;\n padding: 0;\n}\n\n.bp-bubble:hover {\n transform: scale(1.08);\n box-shadow: 0 6px 32px rgba(0, 0, 0, 0.2);\n}\n\n.bp-bubble--right {\n right: 24px;\n}\n\n.bp-bubble--left {\n left: 24px;\n}\n\n.bp-bubble svg {\n width: 28px;\n height: 28px;\n fill: currentColor;\n}\n\n.bp-bubble__badge {\n position: absolute;\n top: -2px;\n right: -2px;\n min-width: 20px;\n height: 20px;\n border-radius: 10px;\n background: #ef4444;\n color: #fff;\n font-size: 11px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 5px;\n}\n\n/* ===== Chat Window ===== */\n.bp-window {\n pointer-events: auto;\n position: fixed;\n bottom: 96px;\n z-index: 2147483647;\n width: 380px;\n height: 520px;\n border-radius: var(--bp-radius);\n background: #fff;\n box-shadow: var(--bp-shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: bp-slide-up 0.25s ease-out;\n font-family: var(--bp-font-family);\n font-size: 14px;\n line-height: 1.5;\n color: var(--bp-gray-900);\n}\n\n.bp-window--right {\n right: 24px;\n}\n\n.bp-window--left {\n left: 24px;\n}\n\n@keyframes bp-slide-up {\n from {\n opacity: 0;\n transform: translateY(16px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Mobile fullscreen */\n@media (max-width: 480px) {\n .bp-window {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n height: 100%;\n border-radius: 0;\n }\n}\n\n/* ===== Header ===== */\n.bp-header {\n padding: 16px;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n}\n\n.bp-header__title {\n font-size: 16px;\n font-weight: 600;\n color: inherit;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.bp-header__back,\n.bp-header__close {\n background: none;\n border: none;\n color: inherit;\n cursor: pointer;\n padding: 4px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background var(--bp-transition);\n}\n\n.bp-header__back:hover,\n.bp-header__close:hover {\n background: rgba(255, 255, 255, 0.15);\n}\n\n.bp-header__back svg,\n.bp-header__close svg {\n width: 18px;\n height: 18px;\n fill: currentColor;\n}\n\n/* ===== Message List ===== */\n.bp-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n background: var(--bp-gray-50);\n}\n\n.bp-messages::-webkit-scrollbar {\n width: 4px;\n}\n\n.bp-messages::-webkit-scrollbar-thumb {\n background: var(--bp-gray-300);\n border-radius: 2px;\n}\n\n/* ===== Message Bubble ===== */\n.bp-msg {\n display: flex;\n max-width: 80%;\n}\n\n.bp-msg--client {\n align-self: flex-end;\n flex-direction: row-reverse;\n}\n\n.bp-msg--agent {\n align-self: flex-start;\n}\n\n.bp-msg__avatar {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n margin-top: auto;\n}\n\n.bp-msg__avatar img {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n}\n\n.bp-msg__body {\n margin: 0 8px;\n}\n\n.bp-msg__content {\n padding: 10px 14px;\n border-radius: 16px;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.bp-msg--client .bp-msg__content {\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border-bottom-right-radius: 4px;\n}\n\n.bp-msg--agent .bp-msg__content {\n background: var(--bp-gray-100);\n color: var(--bp-gray-900);\n border-bottom-left-radius: 4px;\n}\n\n.bp-msg__time {\n font-size: 11px;\n color: var(--bp-gray-500);\n margin-top: 2px;\n padding: 0 4px;\n}\n\n.bp-msg--client .bp-msg__time {\n text-align: right;\n}\n\n/* ===== Composer (Message Input) ===== */\n.bp-composer {\n margin: 8px 12px 12px;\n border: 1px solid var(--bp-gray-200);\n border-radius: 12px;\n background: #fff;\n flex-shrink: 0;\n overflow: hidden;\n transition: border-color var(--bp-transition);\n}\n\n.bp-composer:focus-within {\n border-color: var(--bp-primary);\n}\n\n.bp-composer__preview {\n padding: 8px 12px;\n border-bottom: 1px solid var(--bp-gray-100);\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--bp-gray-50);\n}\n\n.bp-composer__preview-thumb {\n width: 40px;\n height: 40px;\n border-radius: 6px;\n object-fit: cover;\n flex-shrink: 0;\n}\n\n.bp-composer__preview-icon {\n width: 36px;\n height: 36px;\n border-radius: 6px;\n background: var(--bp-gray-100);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--bp-gray-500);\n}\n\n.bp-composer__preview-icon svg {\n width: 18px;\n height: 18px;\n}\n\n.bp-composer__preview-info {\n flex: 1;\n min-width: 0;\n}\n\n.bp-composer__preview-name {\n font-size: 12px;\n font-weight: 500;\n color: var(--bp-gray-700);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bp-composer__preview-status {\n font-size: 11px;\n color: var(--bp-gray-500);\n}\n\n.bp-composer__preview-remove {\n background: none;\n border: none;\n cursor: pointer;\n padding: 2px;\n color: var(--bp-gray-500);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.bp-composer__preview-remove svg {\n width: 14px;\n height: 14px;\n}\n\n.bp-composer__preview-remove:hover {\n color: var(--bp-gray-700);\n}\n\n.bp-composer__row {\n display: flex;\n align-items: flex-end;\n padding: 4px;\n}\n\n.bp-composer__attach {\n width: 32px;\n height: 32px;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--bp-gray-500);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border-radius: 6px;\n transition: color var(--bp-transition), background var(--bp-transition);\n}\n\n.bp-composer__attach:hover {\n color: var(--bp-primary);\n background: var(--bp-gray-50);\n}\n\n.bp-composer__attach:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.bp-composer__attach svg {\n width: 18px;\n height: 18px;\n}\n\n.bp-composer__field {\n flex: 1;\n border: none;\n padding: 6px 4px;\n font-size: 14px;\n font-family: inherit;\n line-height: 1.4;\n resize: none;\n outline: none;\n max-height: 100px;\n overflow-y: auto;\n color: var(--bp-gray-900);\n background: transparent;\n}\n\n.bp-composer__field::placeholder {\n color: var(--bp-gray-500);\n}\n\n.bp-composer__field:disabled {\n cursor: not-allowed;\n}\n\n.bp-composer__send {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: opacity var(--bp-transition);\n}\n\n.bp-composer__send:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.bp-composer__send svg {\n width: 16px;\n height: 16px;\n}\n\n/* ===== Message Media ===== */\n.bp-media-img {\n max-width: 100%;\n max-height: 240px;\n border-radius: 8px;\n cursor: pointer;\n display: block;\n object-fit: contain;\n}\n\n.bp-media-video {\n max-width: 100%;\n max-height: 240px;\n border-radius: 8px;\n display: block;\n}\n\n.bp-media-file {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--bp-gray-50);\n border-radius: 8px;\n text-decoration: none;\n color: var(--bp-gray-700);\n transition: background var(--bp-transition);\n}\n\n.bp-media-file:hover {\n background: var(--bp-gray-100);\n}\n\n.bp-media-file__icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n background: var(--bp-gray-200);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--bp-gray-500);\n}\n\n.bp-media-file__icon svg {\n width: 16px;\n height: 16px;\n}\n\n.bp-media-file__name {\n flex: 1;\n font-size: 13px;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.bp-media-file__download svg {\n width: 16px;\n height: 16px;\n color: var(--bp-primary);\n}\n\n/* ===== Image Lightbox ===== */\n.bp-lightbox {\n position: fixed;\n inset: 0;\n z-index: 2147483647;\n background: rgba(0, 0, 0, 0.85);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n}\n\n.bp-lightbox__img {\n max-width: 90vw;\n max-height: 90vh;\n object-fit: contain;\n border-radius: 4px;\n cursor: default;\n}\n\n.bp-lightbox__close {\n position: absolute;\n top: 16px;\n right: 16px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background var(--bp-transition);\n}\n\n.bp-lightbox__close:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n\n.bp-lightbox__close svg {\n width: 20px;\n height: 20px;\n}\n\n/* ===== Pre-Chat Form ===== */\n.bp-prechat {\n flex: 1;\n padding: 24px 16px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n overflow-y: auto;\n}\n\n.bp-prechat__title {\n font-size: 16px;\n font-weight: 600;\n color: var(--bp-gray-900);\n}\n\n.bp-prechat__desc {\n font-size: 13px;\n color: var(--bp-gray-500);\n}\n\n.bp-prechat__field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.bp-prechat__label {\n font-size: 13px;\n font-weight: 500;\n color: var(--bp-gray-700);\n}\n\n.bp-prechat__input {\n border: 1px solid var(--bp-gray-200);\n border-radius: var(--bp-radius-sm);\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n outline: none;\n transition: border-color var(--bp-transition);\n color: var(--bp-gray-900);\n background: #fff;\n}\n\n.bp-prechat__input:focus {\n border-color: var(--bp-primary);\n}\n\n.bp-prechat__submit {\n padding: 10px 20px;\n border-radius: var(--bp-radius-sm);\n background: var(--bp-primary);\n color: var(--bp-primary-contrast);\n border: none;\n font-size: 14px;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: opacity var(--bp-transition);\n}\n\n.bp-prechat__submit:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.bp-prechat__privacy {\n font-size: 12px;\n color: var(--bp-gray-500);\n text-align: center;\n margin-top: auto;\n}\n\n.bp-prechat__privacy a {\n color: var(--bp-primary);\n text-decoration: underline;\n}\n\n/* ===== Conversation List ===== */\n.bp-convlist {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n.bp-convlist__new {\n padding: 12px 16px;\n border-bottom: 1px solid var(--bp-gray-200);\n}\n\n.bp-convlist__new-btn {\n width: 100%;\n padding: 10px 16px;\n border-radius: var(--bp-radius-sm);\n background: rgba(99, 102, 241, 0.08);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n font-family: inherit;\n color: var(--bp-primary);\n transition: background var(--bp-transition);\n}\n\n.bp-convlist__new-btn svg {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n}\n\n.bp-convlist__new-btn:hover {\n background: rgba(99, 102, 241, 0.15);\n}\n\n.bp-convlist__items {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n\n.bp-convlist__item {\n width: 100%;\n padding: 12px;\n border-radius: var(--bp-radius-sm);\n background: none;\n border: none;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n gap: 4px;\n text-align: left;\n font-family: inherit;\n transition: background var(--bp-transition);\n color: var(--bp-gray-900);\n}\n\n.bp-convlist__item:hover {\n background: var(--bp-gray-50);\n}\n\n.bp-convlist__item:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.bp-convlist__item-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.bp-convlist__item-title {\n font-size: 14px;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n.bp-convlist__item-status {\n font-size: 11px;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n flex-shrink: 0;\n}\n\n.bp-convlist__item-status--open {\n background: #dcfce7;\n color: #166534;\n}\n\n.bp-convlist__item-status--closed {\n background: var(--bp-gray-100);\n color: var(--bp-gray-500);\n}\n\n.bp-convlist__item-preview {\n font-size: 13px;\n color: var(--bp-gray-500);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bp-convlist__empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--bp-gray-500);\n font-size: 14px;\n}\n\n/* ===== Closed conversation banner ===== */\n.bp-closed-banner {\n padding: 14px 16px;\n border-top: 1px solid var(--bp-gray-200);\n background: var(--bp-gray-50);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.bp-closed-banner__text {\n font-size: 13px;\n color: var(--bp-gray-500);\n}\n\n.bp-closed-banner__reopen {\n background: none;\n border: none;\n padding: 0;\n font-size: 13px;\n font-weight: 500;\n font-family: inherit;\n color: var(--bp-primary);\n cursor: pointer;\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.bp-closed-banner__reopen:hover {\n opacity: 0.8;\n}\n\n/* ===== Privacy footer ===== */\n.bp-privacy-footer {\n padding: 4px 16px 8px;\n text-align: center;\n font-size: 11px;\n color: var(--bp-gray-500);\n flex-shrink: 0;\n}\n\n.bp-privacy-footer a {\n color: var(--bp-primary);\n text-decoration: underline;\n}\n\n/* ===== Loading ===== */\n.bp-loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.bp-spinner {\n width: 32px;\n height: 32px;\n border: 3px solid var(--bp-gray-200);\n border-top-color: var(--bp-primary);\n border-radius: 50%;\n animation: bp-spin 0.6s linear infinite;\n}\n\n@keyframes bp-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n/* ===== Hidden ===== */\n.bp-hidden {\n display: none !important;\n}\n` as string\n","import { render, h } from 'preact'\n\nimport type { ApiClient } from '../api/client'\nimport type { ChannelInfo, VisitorData } from '../api/types'\nimport type { RealtimeClient } from '../realtime/ably-client'\nimport type { EventEmitter } from '../utils/events'\nimport type { Storage } from '../utils/storage'\nimport { App } from './App'\nimport type { Translations } from './i18n'\nimport widgetCSS from './styles/widget-css'\n\ninterface MountOptions {\n channelInfo: ChannelInfo\n apiClient: ApiClient\n realtimeClient: RealtimeClient\n storage: Storage\n events: EventEmitter\n visitor: VisitorData | null\n isAuthenticated: boolean\n position: 'bottom-right' | 'bottom-left'\n hidden: boolean\n t: Translations\n container?: HTMLElement\n isOpenRef: { current: boolean }\n setIsOpen: (open: boolean) => void\n}\n\nlet styleElement: HTMLStyleElement | null = null\nlet hostElement: HTMLElement | null = null\n\nexport function mount(options: MountOptions): void {\n // Inject styles into document head (once)\n if (!styleElement) {\n styleElement = document.createElement('style')\n styleElement.id = 'baseportal-chat-styles'\n styleElement.textContent = widgetCSS\n document.head.appendChild(styleElement)\n }\n\n // Create host element directly on body — no shadow DOM\n hostElement = document.createElement('div')\n hostElement.id = 'baseportal-chat-widget'\n const target = options.container || document.body\n target.appendChild(hostElement)\n\n // Apply primary color as CSS variable\n const primaryColor =\n options.channelInfo.theme?.primaryColor || '#6366f1'\n const contrastColor = getContrastColor(primaryColor)\n hostElement.style.setProperty('--bp-primary', primaryColor)\n hostElement.style.setProperty('--bp-primary-contrast', contrastColor)\n\n // Render Preact app\n render(\n h(App, {\n channelInfo: options.channelInfo,\n apiClient: options.apiClient,\n realtimeClient: options.realtimeClient,\n storage: options.storage,\n events: options.events,\n visitor: options.visitor,\n isAuthenticated: options.isAuthenticated,\n position: options.position,\n hidden: options.hidden,\n t: options.t,\n isOpenRef: options.isOpenRef,\n setIsOpen: options.setIsOpen,\n }),\n hostElement\n )\n}\n\nexport function unmount(): void {\n if (hostElement) {\n render(null, hostElement)\n hostElement.remove()\n hostElement = null\n }\n if (styleElement) {\n styleElement.remove()\n styleElement = null\n }\n}\n\nexport function updateTheme(primaryColor: string): void {\n if (!hostElement) return\n hostElement.style.setProperty('--bp-primary', primaryColor)\n hostElement.style.setProperty(\n '--bp-primary-contrast',\n getContrastColor(primaryColor)\n )\n}\n\nfunction getContrastColor(hex: string): string {\n const r = parseInt(hex.slice(1, 3), 16)\n const g = parseInt(hex.slice(3, 5), 16)\n const b = parseInt(hex.slice(5, 7), 16)\n const luminance =\n (0.299 * r + 0.587 * g + 0.114 * b) / 255\n return luminance > 0.5 ? '#000000' : '#ffffff'\n}\n","export type EventCallback = (...args: any[]) => void\n\nexport class EventEmitter {\n private listeners = new Map<string, Set<EventCallback>>()\n\n on(event: string, callback: EventCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(callback)\n }\n\n off(event: string, callback: EventCallback): void {\n this.listeners.get(event)?.delete(callback)\n }\n\n emit(event: string, ...args: any[]): void {\n this.listeners.get(event)?.forEach((cb) => {\n try {\n cb(...args)\n } catch (e) {\n console.error(`[BaseportalChat] Error in ${event} handler:`, e)\n }\n })\n }\n\n removeAllListeners(): void {\n this.listeners.clear()\n }\n}\n","import type { VisitorData } from '../api/types'\n\ninterface StoredData {\n conversationId?: string\n visitor?: VisitorData\n}\n\nexport class Storage {\n private prefix: string\n\n constructor(channelToken: string, email?: string) {\n this.prefix = email\n ? `bp_chat_${channelToken}_${email}`\n : `bp_chat_${channelToken}`\n }\n\n get(): StoredData {\n try {\n const raw = localStorage.getItem(this.prefix)\n return raw ? JSON.parse(raw) : {}\n } catch {\n return {}\n }\n }\n\n set(data: Partial<StoredData>): void {\n try {\n const current = this.get()\n localStorage.setItem(this.prefix, JSON.stringify({ ...current, ...data }))\n } catch {\n // localStorage unavailable (private browsing, etc.)\n }\n }\n\n getConversationId(): string | undefined {\n return this.get().conversationId\n }\n\n setConversationId(id: string): void {\n this.set({ conversationId: id })\n }\n\n getVisitor(): VisitorData | undefined {\n return this.get().visitor\n }\n\n setVisitor(visitor: VisitorData): void {\n this.set({ visitor })\n }\n\n clear(): void {\n try {\n localStorage.removeItem(this.prefix)\n } catch {\n // ignore\n }\n }\n}\n","import { ApiClient } from './api/client'\nimport type { BaseportalChatConfig, ChannelInfo, VisitorData } from './api/types'\nimport { RealtimeClient } from './realtime/ably-client'\nimport { getTranslations } from './ui/i18n'\nimport { mount, unmount, updateTheme } from './ui/mount'\nimport { EventCallback, EventEmitter } from './utils/events'\nimport { Storage } from './utils/storage'\n\nconst DEFAULT_API_URL = 'https://api.baseportal.io'\n\nexport class BaseportalChat {\n private config: Required<\n Pick<BaseportalChatConfig, 'channelToken' | 'apiUrl' | 'position' | 'locale'>\n > &\n BaseportalChatConfig\n private apiClient: ApiClient\n private realtimeClient: RealtimeClient\n private storage: Storage\n private events = new EventEmitter()\n private channelInfo: ChannelInfo | null = null\n private visitor: VisitorData | null = null\n private isAuthenticated = false\n private isOpenRef = { current: false }\n private hidden: boolean\n private mounted = false\n\n constructor(config: BaseportalChatConfig) {\n this.config = {\n ...config,\n apiUrl: config.apiUrl || DEFAULT_API_URL,\n position: config.position || 'bottom-right',\n locale: config.locale || 'pt',\n }\n\n this.hidden = config.hideOnLoad || false\n this.visitor = config.visitor || null\n this.isAuthenticated = !!config.visitor?.email\n\n this.apiClient = new ApiClient(\n this.config.channelToken,\n this.config.apiUrl\n )\n\n if (this.isAuthenticated && this.visitor?.email) {\n this.apiClient.setVisitorIdentity(this.visitor.email, this.visitor.hash)\n }\n\n this.storage = new Storage(\n this.config.channelToken,\n this.isAuthenticated ? this.visitor?.email : undefined\n )\n\n this.realtimeClient = new RealtimeClient(this.apiClient)\n\n // Restore visitor from storage\n if (!this.visitor) {\n this.visitor = this.storage.getVisitor() || null\n }\n\n this.init()\n }\n\n private async init(): Promise<void> {\n try {\n this.channelInfo = await this.apiClient.getChannelInfo()\n\n // Apply theme: SDK config > channel theme > default\n const primaryColor =\n this.config.theme?.primaryColor ||\n this.channelInfo.theme?.primaryColor ||\n '#6366f1'\n\n const t = getTranslations(this.config.locale)\n\n mount({\n channelInfo: this.channelInfo,\n apiClient: this.apiClient,\n realtimeClient: this.realtimeClient,\n storage: this.storage,\n events: this.events,\n visitor: this.visitor,\n isAuthenticated: this.isAuthenticated,\n position: this.config.position,\n hidden: this.hidden,\n t,\n container: this.config.container,\n isOpenRef: this.isOpenRef,\n setIsOpen: (open: boolean) => {\n this.isOpenRef.current = open\n },\n })\n\n // Override theme if needed\n if (primaryColor !== '#6366f1') {\n updateTheme(primaryColor)\n }\n\n this.mounted = true\n this.events.emit('ready')\n } catch (e) {\n console.error('[BaseportalChat] Failed to initialize:', e)\n }\n }\n\n // --- Visibility ---\n\n open(): void {\n if (!this.mounted) return\n this.events.emit('_open')\n this.events.emit('open')\n }\n\n close(): void {\n if (!this.mounted) return\n this.events.emit('_close')\n this.events.emit('close')\n }\n\n toggle(): void {\n if (this.isOpenRef.current) {\n this.close()\n } else {\n this.open()\n }\n }\n\n show(): void {\n this.hidden = false\n this.events.emit('show')\n }\n\n hide(): void {\n this.hidden = true\n this.events.emit('hide')\n }\n\n isOpen(): boolean {\n return this.isOpenRef.current\n }\n\n // --- Visitor ---\n\n identify(visitor: {\n email: string\n name?: string\n hash: string\n metadata?: Record<string, string>\n }): void {\n this.visitor = visitor\n this.isAuthenticated = true\n this.apiClient.setVisitorIdentity(visitor.email, visitor.hash)\n this.storage = new Storage(this.config.channelToken, visitor.email)\n this.storage.setVisitor(visitor)\n this.events.emit('identified', visitor)\n\n // Remount with new state\n if (this.mounted) {\n this.remount()\n }\n }\n\n updateVisitor(data: {\n name?: string\n metadata?: Record<string, string>\n }): void {\n if (this.visitor) {\n this.visitor = { ...this.visitor, ...data }\n this.storage.setVisitor(this.visitor)\n }\n }\n\n clearVisitor(): void {\n this.visitor = null\n this.isAuthenticated = false\n this.apiClient.clearVisitorIdentity()\n this.storage.clear()\n this.storage = new Storage(this.config.channelToken)\n this.realtimeClient.unsubscribe()\n\n if (this.mounted) {\n this.remount()\n }\n }\n\n // --- Actions ---\n\n sendMessage(content: string): void {\n // Implemented via events - App listens\n this.events.emit('_sendMessage', content)\n }\n\n setConversationId(id: string): void {\n this.events.emit('_setConversationId', id)\n }\n\n newConversation(): void {\n this.events.emit('_newConversation')\n }\n\n // --- Config ---\n\n setTheme(theme: { primaryColor?: string }): void {\n if (theme.primaryColor) {\n updateTheme(theme.primaryColor)\n }\n }\n\n setPosition(position: 'bottom-right' | 'bottom-left'): void {\n this.config.position = position\n if (this.mounted) {\n this.remount()\n }\n }\n\n setLocale(locale: 'pt' | 'en' | 'es'): void {\n this.config.locale = locale\n if (this.mounted) {\n this.remount()\n }\n }\n\n // --- Events ---\n\n on(event: string, callback: EventCallback): void {\n this.events.on(event, callback)\n }\n\n off(event: string, callback: EventCallback): void {\n this.events.off(event, callback)\n }\n\n // --- Lifecycle ---\n\n destroy(): void {\n this.realtimeClient.unsubscribe()\n this.events.removeAllListeners()\n unmount()\n this.mounted = false\n }\n\n private remount(): void {\n unmount()\n this.mounted = false\n this.init()\n }\n}\n"],"mappings":"gxDAAAA,EAAA,CAAA,EAAAC,EAAAD,EAAA,CAAA,UAAA,IAAAE,EAAA,SAAA,IAAAC,GAAA,KAAA,IAAAC,GAAA,QAAA,IAAAC,GAAA,QAAA,IAAAC,GAAA,gCAAA,IAAAC,EAAA,CAAA,EAAAC,EAAA,QAAAC,EAAAT,CAAA,ECiBA,IAAqBU,EAArB,KAA8B,CAwB9B,EC/BIC,EAAe,OAAO,OAAW,IAAc,OAAS,OAAO,OAAW,IAAc,OAAS,KAUrG,SAASC,EAAIC,EAAqBC,EAAgB,CAChD,MAAO,GAAGD,CAAW,GAAG,SAASC,EAAQ,EAAI,EAAG,GAAG,CACrD,CAEA,SAASC,GAAWC,EAA4B,CAC9C,OAAON,EAAS,OAAO,cACnB,SAAUO,EAAc,CACtB,IAAMC,EAAO,IAAI,KACjBF,EACEJ,EAAIM,EAAK,SAAS,CAAC,EACjB,IACAN,EAAIM,EAAK,WAAW,CAAC,EACrB,IACAN,EAAIM,EAAK,WAAW,CAAC,EACrB,IACAN,EAAIM,EAAK,gBAAgB,EAAG,CAAC,EAC7B,IACAD,CACJ,CACF,EACA,SAAUA,EAAa,CACrBD,EAAOC,CAAG,CACZ,CACN,CAEA,IAAME,GAAoB,IAA4B,CA7CtD,IAAAC,EA8CE,IAAIC,EACAC,EAGJ,OAAI,QAAOF,EAAAT,GAAc,UAAd,KAAA,OAAAS,EAAuB,MAAQ,YACxCC,EAAgB,YAAaE,EAAiB,CAC5C,QAAQ,IAAI,MAAM,QAASA,CAAI,CACjC,EAEAD,EAAc,QAAQ,KAClB,YAAaC,EAAiB,CAC5B,QAAQ,KAAK,MAAM,QAASA,CAAI,CAClC,EACAF,GAGJA,EAAgBC,EAAc,UAAY,CAAC,EAGtC,CAACD,EAAeC,CAAW,EAAE,IAAIP,EAAU,CACpD,EAEMS,GAAN,MAAMA,EAAO,CA4BX,aAAc,CA6Bd,KAAA,WAAa,CAACC,EAAqBR,IAAgB,CACjD,KAAK,mBAAmB,GAAGQ,CAAW,2DAA2DR,CAAG,EAAE,CACxG,EAsBA,KAAA,UAAaS,GACJA,GAAS,KAAK,SAGvB,KAAA,OAAS,CAACA,EAA8BC,IAAkC,CACpED,IAAU,SAAW,KAAK,SAAWA,GACrCC,IAAY,SAAW,KAAK,WAAa,KAAK,gBAAkBA,EACtE,EA3DE,KAAK,SAAWH,GAAO,gBACvB,KAAK,WAAaA,GAAO,kBACzB,KAAK,gBAAkBA,GAAO,sBAChC,CAXA,OAAO,iBAAkB,CACvB,GAAM,CAACI,EAAYC,CAAe,EAAIV,GAAkB,EACxD,KAAK,kBAAoBS,EACzB,KAAK,uBAAyBC,EAC9B,KAAK,cAAgB,IAAIL,EAC3B,CAqBA,OAAO,iBAAiBR,EAAgBU,EAAkBI,EAAgBC,EAAkB,CAC1Ff,EAAO,UAAUU,EAAOI,EAAQC,CAAO,CACzC,CAEQ,UAAUL,EAAkBI,EAAgBC,EAAkB,CAChE,KAAK,UAAUL,CAAK,IACrBA,IAAU,EAAkB,KAAK,gBAAkB,KAAK,YAAY,SAAWI,EAAS,KAAOC,EAASL,CAAK,CAElH,CAMA,oBAAoBM,EAAiBC,EAAiB,CACpD,KAAK,mBACH,SAASD,CAAO,0CAA0CC,CAAO,wCAAwCA,CAAO,iBAAiBD,CAAO,yCAC1I,CACF,CAEA,cAAcE,EAAmBF,EAAiBC,EAAiB,CACjE,KAAK,mBACH,KAAKC,CAAS,eAAUF,CAAO,mCAAmCC,CAAO,wCAAwCA,CAAO,iBAAiBD,CAAO,yCAClJ,CACF,CAEA,mBAAmBD,EAAiB,CAC9B,KAAK,UAAU,CAAe,GAChC,KAAK,gBAAgB,+BAA+BA,CAAO,GAAI,CAAe,CAElF,CAYF,EAzFMP,GACW,gBAA6B,EADxCA,GAUY,SAAsB,EAVlCA,GAWY,UAAuB,EAXnCA,GAYY,UAAuB,EAZnCA,GAaY,UAAuB,EAbnCA,GAcY,UAAuB,EAdnCA,GAwCG,UAAY,CAACR,EAAgBU,EAAkBI,EAAgBC,IAAqB,CACzFP,GAAK,iBAAiBR,EAAQU,EAAOI,EAAQC,CAAO,CACtD,EA1CF,IAAMI,GAANX,GA2FOY,EAAQD,GC/JfE,GAAA,CAAA,EAAApC,EAAAoC,GAAA,CAAA,OAAA,IAAAC,GAAA,QAAA,IAAAC,GAAA,eAAA,IAAAC,GAAA,eAAA,IAAAC,GAAA,WAAA,IAAAC,GAAA,eAAA,IAAAC,GAAA,UAAA,IAAAC,GAAA,aAAA,IAAAC,GAAA,eAAA,IAAAC,GAAA,oBAAA,IAAAC,GAAA,YAAA,IAAAC,GAAA,gBAAA,IAAAC,EAAA,aAAA,IAAAC,GAAA,cAAA,IAAAC,GAAA,KAAA,IAAAC,GAAA,yBAAA,IAAAC,GAAA,cAAA,IAAAC,GAAA,WAAA,IAAAC,GAAA,WAAA,IAAAC,GAAA,YAAA,IAAAC,GAAA,0BAAA,IAAAC,GAAA,sBAAA,IAAAC,GAAA,gBAAA,IAAAC,GAAA,qBAAA,IAAAC,GAAA,aAAA,IAAAC,GAAA,SAAA,IAAAC,GAAA,YAAA,IAAAC,GAAA,aAAA,IAAAC,EAAA,UAAA,IAAAC,GAAA,QAAA,IAAAC,GAAA,8BAAA,IAAAC,GAAA,MAAA,IAAAC,GAAA,SAAA,IAAAC,GAAA,UAAA,IAAAC,EAAA,oBAAA,IAAAC,GAAA,MAAA,IAAAC,EAAA,iBAAA,IAAAC,GAAA,kBAAA,IAAAC,GAAA,aAAA,IAAAC,GAAA,aAAA,IAAAC,GAAA,cAAA,IAAAC,GAAA,wBAAA,IAAAC,GAAA,SAAA,IAAAC,GAAA,cAAA,IAAAC,GAAA,YAAA,IAAAC,EAAA,mBAAA,IAAAC,GAAA,iBAAA,IAAAC,EAAA,CAAA,ECWA,SAASC,GAASC,EAAmC,CACnD,IAAIC,EAAS,IAAMD,EAAI,YAAY,KACnC,OAAIA,EAAI,UAASC,GAAU,KAAOD,EAAI,SAClCA,EAAI,aAAYC,GAAU,gBAAkBD,EAAI,YAChDA,EAAI,OAAMC,GAAU,UAAYD,EAAI,MACpCA,EAAI,QAAOC,GAAU,WAAmBtB,EAAaqB,EAAI,KAAK,GAC9DA,EAAI,MAAQ,EAAEA,EAAI,SAAWA,EAAI,QAAQ,QAAQ,cAAc,EAAI,MAAKC,GAAU,SAAWD,EAAI,KAAO,KAC5GC,GAAU,IACHA,CACT,CAcA,IAAqBrF,EAArB,MAAqBsF,WAAkB,KAAkD,CAMvF,YAAYzD,EAAiB0D,EAAcC,EAAoBC,EAAoC,CACjG,MAAM5D,CAAO,EACT,OAAO,OAAO,eAAmB,KACnC,OAAO,eAAe,KAAMyD,GAAU,SAAS,EAEjD,KAAK,KAAOC,EACZ,KAAK,WAAaC,EAClB,KAAK,MAAQC,CACf,CAEA,UAAmB,CACjB,OAAON,GAAS,IAAI,CACtB,CAEA,OAAO,WAAWO,EAA4C,CAC5D,GAAM,CAAE,QAAA7D,EAAS,KAAA0D,EAAM,WAAAC,CAAW,EAAIE,EACtC,GAAI,OAAO7D,GAAY,UAAY,OAAO0D,GAAS,UAAY,OAAOC,GAAe,SACnF,MAAM,IAAI,MAAM,2CAA6ChF,EAAS,OAAO,QAAQkF,CAAM,CAAC,EAE9F,IAAML,EAAS,OAAO,OAAO,IAAIC,GAAUzD,EAAS0D,EAAMC,CAAU,EAAGE,CAAM,EAC7E,OAAIL,EAAO,MAAQ,CAACA,EAAO,OACzBA,EAAO,KAAO,8BAAgCA,EAAO,MAEhDA,CACT,CACF,EAEaM,GAAN,MAAMC,WAAyB,KAAmC,CAMvE,YAAY/D,EAAiB0D,EAAqBC,EAAqBC,EAAoC,CACzG,MAAM5D,CAAO,EACT,OAAO,OAAO,eAAmB,KACnC,OAAO,eAAe,KAAM+D,GAAiB,SAAS,EAExD,KAAK,KAAOL,EACZ,KAAK,WAAaC,EAClB,KAAK,MAAQC,CACf,CAEA,UAAmB,CACjB,OAAON,GAAS,IAAI,CACtB,CAEA,OAAO,WAAWO,EAA0D,CAC1E,GAAM,CAAE,QAAA7D,EAAS,KAAA0D,EAAM,WAAAC,CAAW,EAAIE,EACtC,GACE,OAAO7D,GAAY,UAClB,CAAOsC,GAAMoB,CAAI,GAAK,OAAOA,GAAS,UACtC,CAAOpB,GAAMqB,CAAU,GAAK,OAAOA,GAAe,SAEnD,MAAM,IAAI,MAAM,kDAAoDhF,EAAS,OAAO,QAAQkF,CAAM,CAAC,EAErG,IAAML,EAAS,OAAO,OAAO,IAAIO,GAAiB/D,EAAS0D,EAAMC,CAAU,EAAGE,CAAM,EACpF,OAAIL,EAAO,MAAQ,CAACA,EAAO,OACzBA,EAAO,KAAO,8BAAgCA,EAAO,MAEhDA,CACT,CACF,EDjGA,SAASQ,GAAWC,EAAmC,CACrD,OAAO,KAAK,MAAM,KAAK,OAAO,EAAIA,EAAS,MAAM,CACnD,CASO,SAASvB,EACdwB,KACG1E,EACsB,CACzB,QAAS2E,EAAI,EAAGA,EAAI3E,EAAK,OAAQ2E,IAAK,CACpC,IAAMC,EAAS5E,EAAK2E,CAAC,EACrB,GAAI,CAACC,EACH,MAGF,QAAWC,KAAOD,EACZ,OAAO,UAAU,eAAe,KAAKA,EAAQC,CAAG,IAClDH,EAAOG,CAAG,EAAKD,EAAmCC,CAAG,EAG3D,CACA,OAAOH,CACT,CAQO,SAAS7C,GAAkCiD,EAAwD,CACxG,OAAO5B,EAAM,CAAC,EAAG4B,CAA8B,CACjD,CAOO,SAAS5C,GAAY6C,EAAyC,CACnE,OAAIjC,GAAMiC,CAAG,EACJ,CAAC,EAEN,MAAM,QAAQA,CAAG,EACZA,EAEF,CAACA,CAAG,CACb,CAEO,SAAShC,GAASiC,EAA4C,CACnE,OAAO,OAAO,UAAU,SAAS,KAAKA,CAAE,GAAK,iBAC/C,CAOO,SAASpC,GAAQoC,EAAkD,CACxE,QAAWC,KAAQD,EAAI,MAAO,GAC9B,MAAO,EACT,CAOO,SAASlC,GAAMoC,EAAuC,CAC3D,OAAOA,GAAO,IAChB,CASO,SAAS5B,GAAa0B,EAAsD,CACjF,IAAMhB,EAAS,IAAI,OACnB,QAAWiB,KAAQD,EAAIhB,EAAOiB,CAAI,EAAID,EAAGC,CAAI,EAC7C,OAAOjB,CACT,CAWO,SAASZ,GACd4B,EACAG,EACyB,CACzB,MAAMC,CAAE,CAAC,CACTA,EAAE,UAAYJ,EACd,IAAMhB,EAAS,IAAIoB,EACnB,OAAID,GAAejC,EAAMc,EAAQmB,CAAa,EACvCnB,CACT,CASO,IAAMxB,GAAW,SAAU6C,EAAWC,EAAqB,CAChE,GAAInG,EAAS,OAAO,SAAU,CAC5BA,EAAS,OAAO,SAASkG,EAAMC,CAAS,EACxC,MACF,CACAD,EAAK,OAASC,EACdD,EAAK,UAAYjC,GAAkBkC,EAAU,UAAW,CAAE,YAAaD,CAAK,CAAC,CAC/E,EAQO,SAASzD,GAAcoD,EAA6BO,EAAuB,CAChF,QAAWZ,KAAKK,EACd,GAAIA,EAAGL,CAAC,GAAKY,EAAK,MAAO,GAE3B,MAAO,EACT,CAEO,SAAS5C,GAA+B6C,EAAeR,EAAsC,CAClG,OAAO,MAAM,QAAQA,CAAE,EAAI1D,GAAakE,EAAKR,CAAE,EAAIzD,GAAeiE,EAAKR,CAAE,CAC3E,CAEO,SAAS1D,GAAgBmE,EAAgBC,EAA0B,CACxE,IAAM1B,EAAS,CAAC,EAChB,QAAS,EAAI,EAAG,EAAIyB,EAAK,OAAQ,IAAK,CACpC,IAAME,EAASF,EAAK,CAAC,EACjBC,EAAK,QAAQC,CAAM,GAAK,IAAI3B,EAAO,KAAK2B,CAAM,CACpD,CACA,OAAO3B,CACT,CAEO,SAASzC,GAAiCiE,EAAeR,EAAsC,CACpG,IAAMhB,EAAS,CAAC,EAChB,QAAS,EAAI,EAAG,EAAIwB,EAAI,OAAQ,IAAK,CACnC,IAAMG,EAASH,EAAI,CAAC,EAChBG,KAAUX,GAAIhB,EAAO,KAAK2B,CAAM,CACtC,CACA,OAAO3B,CACT,CAEO,SAASvC,GAAegE,EAAgBC,EAA0B,CACvE,IAAM1B,EAAS,CAAC,EAChB,QAAS,EAAI,EAAG,EAAIyB,EAAK,OAAQ,IAAK,CACpC,IAAMG,EAAUH,EAAK,CAAC,EAClBC,EAAK,QAAQE,CAAO,GAAK,IAAI5B,EAAO,KAAK4B,CAAO,CACtD,CACA,OAAO5B,CACT,CAEO,SAAS5C,GAAkBoE,EAAeD,EAAiB,CAChE,IAAMM,EAAML,EAAI,QAAQD,CAAG,EACrBO,EAAMD,GAAO,GACnB,OAAIC,GAAKN,EAAI,OAAOK,EAAK,CAAC,EACnBC,CACT,CAEO,SAASpE,EAAmB8D,EAAeD,EAAkB,CAClE,IAAMQ,EAASP,EAAI,MAAM,EACzB,OAAApE,GAAe2E,EAAQR,CAAG,EACnBQ,CACT,CASO,SAAS/C,EAAUgC,EAA6BgB,EAAkC,CACvF,IAAMhC,EAAS,CAAC,EAChB,QAAWiB,KAAQD,EACbgB,GAAW,CAAC,OAAO,UAAU,eAAe,KAAKhB,EAAIC,CAAI,GAC7DjB,EAAO,KAAKiB,CAAI,EAElB,OAAOjB,CACT,CASO,SAASL,EAAeqB,EAAuBgB,EAAwB,CAC5E,IAAMhC,EAAS,CAAC,EAChB,QAAWiB,KAAQD,EACbgB,GAAW,CAAC,OAAO,UAAU,eAAe,KAAKhB,EAAIC,CAAI,GAC7DjB,EAAO,KAAKgB,EAAGC,CAAI,CAAC,EAEtB,OAAOjB,CACT,CAEO,SAAS7B,GAA0B6C,EAA6BiB,EAAkC,CACvG,QAAWhB,KAAQD,EACb,OAAO,UAAU,eAAe,KAAKA,EAAIC,CAAI,GAAKD,EAAGC,CAAI,GAC3DgB,EAAGhB,CAAI,CAGb,CAEO,SAASjE,GAAQwE,EAAqCP,EAAuB,CAClF,GAAIO,EAAI,SAAW,EACjB,MAAO,GAET,IAAMU,EAAQV,EAAI,CAAC,EAAEP,CAAI,EACzB,OAAOO,EAAI,MAAM,SAAUW,EAAM,CAC/B,OAAOA,EAAKlB,CAAI,IAAMiB,CACxB,CAAC,CACH,CAEO,IAAKnF,IAAAA,IACVA,EAAA,QAAU,UACVA,EAAA,KAAO,OAFGA,IAAAA,IAAA,CAAA,CAAA,EAKL,SAASS,GAAuBgE,EAAkB,CACvD,OAAOA,EAAI,OAAOhB,GAAWgB,CAAG,EAAG,CAAC,EAAE,CAAC,CACzC,CAEO,SAAS9B,GAAc0C,EAAgD,CAC5E,IAAMC,EAAQ,CAAC,EACf,GAAID,EACF,QAAWvB,KAAOuB,EAAQC,EAAM,KAAK,mBAAmBxB,CAAG,EAAI,IAAM,mBAAmBuB,EAAOvB,CAAG,CAAC,CAAC,EAEtG,OAAOwB,EAAM,OAAS,IAAMA,EAAM,KAAK,GAAG,EAAI,EAChD,CAEO,SAASlD,GAAiBmD,EAAuC,CACtE,IAAIC,EACEC,EAAS,sBACTxC,EAAiC,CAAC,EAExC,KAAQuC,EAAQC,EAAO,KAAKF,CAAK,GAAItC,EAAO,mBAAmBuC,EAAM,CAAC,CAAC,CAAC,EAAI,mBAAmBA,EAAM,CAAC,CAAC,EAEvG,OAAOvC,CACT,CAEO,SAASnB,GAA8BkB,EAAmD,CAC/F,OAAO,OAAOA,GAAO,UAAYA,IAAQ,OAASA,aAAepF,GAAaoF,aAAeO,GAC/F,CAEO,SAAS5B,EAAaqB,EAAsB,CA9QnD,IAAAlE,EAAA4G,EA+QE,OACE1C,aAAe,SACdlE,EAAAkE,GAAmB,cAAnB,KAAA,OAAAlE,EAAgC,QAAS,eACzC4G,EAAA1C,GAA0B,cAA1B,KAAA,OAAA0C,EAAuC,QAAS,mBAEzC1C,EAAc,SAAS,EAC1B5E,EAAS,OAAO,QAAQ4E,CAAG,CACpC,CAEO,SAAStB,GAAYiE,EAAuB,CACjD,OAAIvH,EAAS,YAAY,SAASuH,CAAI,EAC5BA,EAAa,SAAS,EACrB,OAAOA,GAAS,SAClBA,EAEAvH,EAAS,OAAO,QAAQuH,CAAI,CAEvC,CAGO,SAAS3E,GAAc4E,EAA+B,CAC3D,GAAIxH,EAAS,YAAY,SAASwH,CAAI,EACpC,OAAOxH,EAAS,YAAY,WAAWwH,CAAI,EAE7C,GAAI,OAAOA,GAAS,SAClB,OAAOxH,EAAS,OAAO,eAAewH,CAAI,EAE5C,MAAM,IAAI,MAAM,4EAA8E,OAAOA,CAAI,CAC3G,CAEO,SAAShF,IAAuB,CACrC,OAAO,OAAO,KAAK,OAAO,CAAC,EAAE,OAAO,CAAC,CACvC,CAKO,IAAM0B,GAAe,MAAOuD,GAAsC,CACvE,IAAMC,EAAS,MAAM1H,EAAS,OAAO,qBAAqByH,CAAQ,EAClE,OAAOzH,EAAS,YAAY,aAAa0H,CAAM,CACjD,EAGO,SAAS1F,GAAcqE,EAAesB,EAAqB,CAChE,IAAMC,EAAW,KAAK,IAAID,EAAGtB,EAAI,MAAM,EACrCwB,EAAaxB,EAAI,MAAM,EACvBxB,EAAmB,CAAC,EACtB,QAASW,EAAI,EAAGA,EAAIoC,EAAUpC,IAC5BX,EAAO,KAAKxC,GAAoBwF,CAAU,CAAC,EAE7C,OAAOhD,CACT,CAKO,SAASJ,GACdqD,EACAC,EACA,CACAD,EACG,KAAMjD,GAAW,CAChBkD,IAAW,KAAMlD,CAAA,CACnB,CAAC,EACA,MAAOD,GAAiB,CAEvBmD,IAAWnD,CAAA,CACb,CAAC,CACL,CAEO,SAAS/B,GAAc0E,EAAeS,EAAyBC,EAA2B,CAC/F,OAAIA,GAAU,WACPD,GACH3D,GAAwB,SAAS,EAE5B2D,EAAQ,OAAOT,CAAc,GAG/B,KAAK,MAAM,OAAOA,CAAI,CAAC,CAChC,CAEO,SAASzE,GAAWyE,EAAeS,EAAyBC,EAAkC,CACnG,OAAIA,GAAU,WACPD,GACH3D,GAAwB,SAAS,EAE5B2D,EAAQ,OAAOT,EAAM,EAAI,GAG3B,KAAK,UAAUA,CAAI,CAC5B,CAEO,SAASzF,GAAeuE,EAAmC,CAChE,OAAOA,EAAI,IAAI,SAAUI,EAAS,CAChC,OAAOA,GAAWA,EAAQ,YAAY,CACxC,CAAC,CACH,CAEO,SAAS1E,GAAesE,EAAmC,CAChE,OAAOA,EAAI,IAAI,SAAUI,EAAS,CAChC,OAAOA,GAAWA,EAAQ,YAAY,CACxC,CAAC,CACH,CAEO,SAASxD,GAAsBiF,EAAe,CACnD,OAAO,KAAK,KAAKA,EAAQ,GAAK,EAAG,CAAC,CACpC,CAEO,SAAS/E,IAAuB,CACrC,MAAO,GAAI,KAAK,OAAO,EAAI,EAC7B,CAYO,SAASC,GAAa+E,EAAwBC,EAAsB,CACzE,OAAOD,EAAiBlF,GAAsBmF,CAAY,EAAIjF,GAAqB,CACrF,CAEO,SAASD,IAAkB,CAChC,OAAI,OAAO,OAAW,IACb,OAGL,OAAO,OAAW,IACb,OAGF,IACT,CAEO,SAASkB,GAAcqB,EAAiCF,EAAiC,CAC9F,OACE,OAAO,KAAKE,CAAM,EAAE,MAAOC,GAAQD,EAAOC,CAAG,IAAMH,EAAOG,CAAG,CAAC,GAC9D,OAAO,KAAKH,CAAM,EAAE,MAAOG,GAAQH,EAAOG,CAAG,IAAMD,EAAOC,CAAG,CAAC,CAElE,CAEO,SAAS5B,GAAoBuE,EAAc,CAUhD,IAAMC,EAAQ,+BACRlB,EAAQiB,EAAK,MAAMC,CAAK,EAC9B,GAAI,CAAClB,GAAS,CAACA,EAAM,QAAUA,EAAM,OAAS,EAC5C,MAAM,IAAI5H,EAAU,qBAAsB,IAAK,KAAK,EAGtD,GAAI4H,EAAO,CAAC,EACV,MAAM,IAAI5H,EAAU,sCAAsC4H,EAAM,CAAC,CAAC,WAAY,IAAK,KAAK,EAG1F,MAAO,CACL,eAAgBA,EAAM,CAAC,GAAK,GAC5B,YAAaA,EAAM,CAAC,CACtB,CACF,CAEO,SAAS9C,GAASiE,EAAa,CACpC,IAAMC,EAAcxI,EAAS,YACvByI,EAAaD,EAAY,WAAWD,CAAG,EAC7C,OAAOC,EAAY,aAAaC,CAAU,CAC5C,CAEO,SAASvG,GAAUwG,EAAUC,EAAU,CAC5C,OACED,EAAE,SAAWC,EAAE,QACfD,EAAE,MAAM,SAAUtC,EAAK,EAAG,CACxB,OAAOA,IAAQuC,EAAE,CAAC,CACpB,CAAC,CAEL,CAEO,SAAShG,GAAyBiG,EAA6C,CACpF,OAAO,IAAIpJ,EAAU,GAAGoJ,CAAU,uBAAwB,MAAO,GAAG,CACtE,CAEO,SAASvE,GAAwBuE,EAAyC,CAC/E,MAAMjG,GAAyBiG,CAAU,CAC3C,CAEA,eAAsBlE,GAAoBoD,EAAqBe,EAAU,IAAMjE,EAAM,kBAA+B,CAClH,IAAMkE,EAAI,IAAItJ,EAAUoF,EAAK,IAAO,GAAG,EACvC,OAAO,QAAQ,KAAK,CAACkD,EAAS,IAAI,QAAW,CAACiB,EAAUC,IAAW,WAAW,IAAMA,EAAOF,CAAC,EAAGD,CAAO,CAAC,CAAC,CAAC,CAC3G,CEjdE,IAAAI,GAAW,QCSTC,GAAQ,WAAaD,GA8CnBE,GAAW,CACf,YAAa,GACb,UAAW,eACX,cAAe,mBACf,eAAgB,CACd,sBACA,sBACA,sBACA,sBACA,qBACF,EACA,KAAM,GACN,SAAU,IACV,SAAU,CAER,yBAA0B,KAC1B,sBAAuB,IAEvB,mBAAoB,IACpB,qBAAsB,KACtB,oBAAqB,KACrB,qBAAsB,IAEtB,mBAAoB,KACpB,uBAAwB,IACxB,YAAa,IACb,wBAAyB,IACzB,qBAAsB,GACxB,EACA,kBAAmB,EACnB,eAAgB,MAEhB,QAAAF,GACA,gBAAiB,EACjB,MAAAC,GACA,QAAAE,GACA,QAAAC,GACA,cAAAC,GACA,yBAAAC,GACA,iBAAAC,GACA,SAAAC,GACA,UAAAC,GACA,iBAAAC,GACA,iBAAAC,GACA,kBAAAC,GACA,mBAAAC,EACF,EAEO,SAASV,GAAQW,EAAwBC,EAAsBC,EAAsB,CAC1F,OAAIA,EAAID,EAAQA,GAAQD,EAAQ,UAAYA,EAAQ,cAAiBC,GAAQD,EAAQ,aAChFC,EAAOA,GAAQD,EAAQ,SAErBC,CACT,CAEO,SAASX,GAAQU,EAAwBG,EAAmC,CACjF,OAAOA,GAAOH,EAAQ,IAAMA,EAAQ,QAAUA,EAAQ,IACxD,CAEO,SAAST,GAAcS,EAAgC,CAC5D,OAAOA,EAAQ,IAAM,WAAa,SACpC,CAGO,SAASR,GAAyBY,EAA+B,CACtE,MAAO,CACLA,EAAc,gCACdA,EAAc,gCACdA,EAAc,gCACdA,EAAc,gCACdA,EAAc,+BAChB,CACF,CAEO,SAASX,GAAiBO,EAA4C,CAC3E,IAAMK,EAAgBL,EAAQ,cAC5BM,EACE,OAAON,EAAQ,kBAAsB,IAAcA,EAAQ,kBAAoBZ,GAAS,kBAE5F,OAAOiB,EAAsBpI,GAAWoI,EAAeC,CAAiB,EAAI,CAAC,CAC/E,CAEO,SAASZ,GAASM,EAAkCE,EAAwB,CACjF,IAAMK,EAAQ,CAACP,EAAQ,QAAQ,EAAE,OAAOP,GAAiBO,CAAO,CAAC,EACjE,OAAOE,EAAKK,EAAM,IAAKN,GAASZ,GAAQW,EAASC,EAAM,EAAI,CAAC,EAAIM,CAClE,CAEA,SAASZ,GAAUM,EAAoB,CACrC,GAAI,OAAOA,GAAS,SAClB,MAAM,IAAIxK,EAAU,gCAAkC,OAAOwK,EAAM,IAAO,GAAG,EAE/E,GAAI,CAACA,EAAK,OACR,MAAM,IAAIxK,EAAU,+BAAgC,IAAO,GAAG,CAElE,CAEA,SAAS+K,GAAgBR,EAAwBS,EAAqBL,EAAqB7J,EAAwB,CACjH,OAAIyJ,EAAQ,aAAqBA,EAAQ,aAGrCA,EAAQ,UACVrI,EAAO,UACLpB,EACAoB,EAAO,UACP,4BACA,uBACEqI,EAAQ,SACR,8DACAA,EAAQ,SACR,0EACJ,EACOA,EAAQ,UAEVS,EAAarB,GAAS,cAAgBgB,EAAc,IAAMhB,GAAS,aAC5E,CAEA,SAASsB,GAAYV,EAAwB,CAE3C,IAAMW,EAAmC,CAAC,EAC1C,QAAW5E,KAAQqD,GAAS,SAC1BuB,EAAS5E,CAAI,EAAKiE,EAAmCjE,CAAI,GAAMqD,GAAS,SAAoCrD,CAAI,EAElH,OAAO4E,CACT,CAEO,SAASC,GAAeZ,EAAgC,CAC7D,IAAIa,EAAWzB,GAAS,MACxB,GAAIY,EAAQ,OACV,QAASb,KAASa,EAAQ,OACxBa,GAAY,IAAM1B,EAAQ,IAAMa,EAAQ,OAAOb,CAAK,EAGxD,OAAO0B,CACT,CAEO,SAASjB,GACdI,EACAc,EACAC,EACAxK,EACAyK,EACe,CACf,GAAIhB,IAAY,OAAW,CACzB,IAAMxJ,EAAMsK,EACR,GAAGC,CAAqB,8FACxB,GAAGA,CAAqB,oDAC5B,MAAApJ,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,GAAGoJ,CAAqB,KAAMvK,CAAG,EACtE,IAAI,MAAMA,CAAG,CACrB,CAEA,IAAIyK,EAEJ,GAAI,OAAOjB,GAAY,SACrB,GAAIA,EAAQ,QAAQ,GAAG,GAAK,GAAI,CAC9B,GAAI,CAACc,EAAiB,CACpB,IAAMtK,EAAM,GAAGuK,CAAqB,uLACpC,MAAApJ,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,GAAGoJ,CAAqB,KAAMvK,CAAG,EACtE,IAAI,MAAMA,CAAG,CACrB,CAEAyK,EAAa,CAAE,MAAOjB,CAAQ,CAChC,KAAO,CACL,GAAI,CAACc,EAAiB,CACpB,IAAMtK,EAAM,GAAGuK,CAAqB,yLACpC,MAAApJ,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,GAAGoJ,CAAqB,KAAMvK,CAAG,EACtE,IAAI,MAAMA,CAAG,CACrB,CAEAyK,EAAa,CAAE,IAAKjB,CAAQ,CAC9B,MAEAiB,EAAajB,EAGf,OAAIgB,IACFC,EAAaC,EAAAC,EAAA,CAAA,EAAKF,CAAA,EAAL,CAAiB,QAASE,EAAAA,EAAA,CAAA,EAAKH,CAAA,EAA4BC,EAAW,OAAA,CAAU,CAAA,GAGxFA,CACT,CAEO,SAASpB,GACdG,EACA/B,EACA1H,EACyB,CACzB,IAAM6K,EAAc7K,GAAUoB,EAAO,cAEjC,OAAOqI,EAAQ,SAAY,YAAcA,EAAQ,gBAAkB,KACrErI,EAAO,UACLyJ,EACAzJ,EAAO,UACP,4BACA,wHACF,EACAqI,EAAQ,QAAU,QAGd,kBAAmBA,IAGvBA,EAAQ,cAAgB,CAACA,EAAQ,SAG7B,kBAAmBA,IAAUA,EAAQ,cAAgB,IAG3D,IAAMI,EAAeJ,EAAQ,aAAe,OAAOA,EAAQ,WAAW,EAAE,YAAY,GAAMZ,GAAS,YAC7FqB,EAAa,CAACL,GAAeA,IAAgB,aAE/C,CAACJ,EAAQ,eAAiB,CAACA,EAAQ,UAAY,CAACA,EAAQ,cAAgB,CAACA,EAAQ,MAAQ,CAACA,EAAQ,UACpGA,EAAQ,cAAgBS,EAAarB,GAAS,eAAiBI,GAAyBY,CAAW,GAGrG,IAAMiB,EAAWrB,EAAQ,WAAaS,EAAarB,GAAS,UAAYgB,EAAc,IAAMhB,GAAS,WAC/FkC,EAAed,GAAgBR,EAASS,EAAYL,EAAagB,CAAW,GAEjFpB,EAAQ,eAAiB,CAAC,GAAG,OAAOqB,EAAUC,CAAY,EAAE,QAAQ3B,EAAS,EAE9EK,EAAQ,KAAOA,EAAQ,MAAQZ,GAAS,KACxCY,EAAQ,QAAUA,EAAQ,SAAWZ,GAAS,SACxC,QAASY,IAAUA,EAAQ,IAAM,IAEvC,IAAMW,EAAWD,GAAYV,CAAO,EAEhC/B,EACE,sBAAuB+B,EACzBA,EAAQ,kBAAoB/J,EAAS,OAAO,gBAAkB+J,EAAQ,kBAEtEA,EAAQ,kBAAoB/J,EAAS,OAAO,aAG9C+J,EAAQ,kBAAoB,GAG9B,IAAMuB,EAAkC,CAAC,EACrCvB,EAAQ,WACVuB,EAAQ,iBAAiB,EAAItL,EAAS,YAAY,aAAaA,EAAS,YAAY,WAAW+J,EAAQ,QAAQ,CAAC,GAG5G,6BAA8BA,IAClCA,EAAQ,yBAA2B,IAGrC,IAAIwB,EAA0B,KAC1BC,EAAuBzB,EAAQ,qBACnC,GAAIA,EAAQ,qBAAsB,CAChC,GAAI,CAAC0B,EAAKC,CAAE,EAAI3B,EAAQ,qBAAqB,MAAM,GAAG,EACtDwB,EAA0BG,EAAW1H,GAAiB0H,CAAE,EAAI,CAAC,EACzDD,EAAI,QAAQ,KAAK,IAAM,KACzBA,EAAM,WAAaA,GAErBD,EAAuBC,CACzB,CAEA,IAAIE,EAAyB5B,EAAQ,uBACrC,OAAI4B,GAA0BA,EAAuB,QAAQ,KAAK,IAAM,KACtEA,EAAyB,SAAWA,GAG/BV,EAAAC,EAAA,CAAA,EACFnB,CAAA,EADE,CAEL,aAAAsB,EACA,SAAAD,EACA,eAAgBrB,EAAQ,gBAAkBZ,GAAS,eACnD,SAAAuB,EACA,wBAAAa,EACA,qBAAAC,EACA,uBAAAG,EACA,QAAAL,CACF,CAAA,CACF,CAEO,SAASM,GAAwBC,EAAqCvL,EAAgByJ,EAA0B,CACrH,IAAM+B,EAAiB/B,GAAW,CAAC,EACnC,GAAI+B,EAAe,OAAQ,CACpBD,GAAcxH,GAAwB,QAAQ,EACnD,IAAM0H,EAASF,EAAO,UAAUC,EAAe,OAAQxL,CAAM,EAC7DwL,EAAe,OAASC,EAAO,aAC/BD,EAAe,cAAgBC,EAAO,MACxC,KAAW,WAAYD,IAGrBA,EAAe,OAAS,OACxBA,EAAe,cAAgB,MAEjC,OAAOA,CACT,CAEA,IAAME,GAAe,CACnB,KAAM,mBACN,IAAK,kBACL,KAAM,YACN,QAAS,wBACT,KAAM,YACR,EAOMC,GAAkD,CACtD,OAAA,OACA,gBAAiB9C,GAAS,eAC5B,EAEO,SAASU,GACdE,EACA,CACE,OAAA9B,EAASgE,GAAsB,OAC/B,gBAAAC,EAAkBD,GAAsB,eAC1C,EAAoB,CAAC,EACG,CAExB,MAAO,CACL,OAFaD,GAAa/D,CAAM,EAGhC,iBAAkBiE,EAAgB,SAAS,EAC3C,aAAcvB,GAAeZ,CAAO,CACtC,CACF,CAEO,SAASD,GACdC,EACA,CACE,OAAA9B,EAASgE,GAAsB,OAC/B,gBAAAC,EAAkBD,GAAsB,eAC1C,EAAoB,CAAC,EACG,CACxB,IAAIE,EAGJ,MAAO,CACL,OAHcA,EAAcH,GAAa/D,CAAM,EAI/C,eAAgBkE,EAChB,iBAAkBD,EAAgB,SAAS,EAC3C,aAAcvB,GAAeZ,CAAO,CACtC,CACF,CAEA,IAAOqC,EAAQjD,GAER,SAASkD,GAAYC,EAA6B,CACvD,OAAO,OAAO,OAAOnD,GAAUmD,CAAgB,CACjD,CC7XA,IAAMC,GAAN,MAAMC,EAAe,CAIX,YACWlM,EACjBmM,EACA,CAFiB,KAAA,OAAAnM,EAGjB,KAAK,QAAWmM,GAA0C,CAAC,CAC7D,CAEQ,KAAK7H,EAAwBC,EAAkB,CACrD,QAAW2B,KAAU,KAAK,QACxB,GAAIA,EACF,GAAI,CACFA,EAAO5B,EAAKC,CAAM,CACpB,OAASiE,EAAG,CACVpH,EAAO,UACL,KAAK,OACLA,EAAO,UACP,wCACA,yBAA2BoH,EAAI,aAAgBA,EAAY,KAC7D,CACF,CAGN,CAEA,QAAQjI,EAAwC,CAC9C,KAAK,QAAQ,KAAK,GAAGA,CAAI,CAC3B,CAEA,eAA4B,CAC1B,OAAO,IAAI,QAAQ,CAAC6L,EAAS1D,IAAW,CACtC,KAAK,KAAK,CAACpE,EAAKC,IAAW,CACzBD,EAAMoE,EAAOpE,CAAG,EAAI8H,EAAQ7H,CAAO,CACrC,CAAC,CACH,CAAC,CACH,CAEA,WAAWA,EAAW,CACpB,KAAK,KAAK,KAAMA,CAAM,CACxB,CAEA,UAAUD,EAAgB,CACxB,KAAK,KAAKA,CAAG,CACf,CAEA,OAAO,OAAUtE,EAAgBmM,EAA0E,CACzG,IAAME,EAAW,IAAIH,GAAYlM,EAAQmM,CAAO,EAChD,OAAO,OAAO,OAAO,CAAC7H,EAAwBC,IAAe8H,EAAS,KAAK/H,EAAKC,CAAM,EAAG,CACvF,KAAOiC,GAA4B6F,EAAS,KAAK7F,CAAE,EACnD,cAAe,IAAM6F,EAAS,cAAc,EAC5C,WAAa9H,GAAc8H,EAAS,WAAW9H,CAAM,EACrD,UAAYD,GAAmB+H,EAAS,UAAU/H,CAAG,CACvD,CAAC,CACH,CACF,EAEOgI,GAAQL,GChFVM,IAAAA,IACHA,EAAA,IAAM,MACNA,EAAA,OAAS,SACTA,EAAA,KAAO,OACPA,EAAA,IAAM,MACNA,EAAA,MAAQ,QALLA,IAAAA,IAAA,CAAA,CAAA,EAQEC,EAAQD,GCRVE,IAAAA,IACHA,EAAAA,EAAA,QAAU,GAAA,EAAV,UACAA,EAAAA,EAAA,UAAY,GAAA,EAAZ,YACAA,EAAAA,EAAA,WAAa,GAAA,EAAb,aACAA,EAAAA,EAAA,aAAe,GAAA,EAAf,eACAA,EAAAA,EAAA,UAAY,GAAA,EAAZ,YACAA,EAAAA,EAAA,eAAiB,GAAA,EAAjB,iBACAA,EAAAA,EAAA,oBAAsB,GAAA,EAAtB,sBAPGA,IAAAA,IAAA,CAAA,CAAA,EAUE,SAASC,GAAchI,EAAoB,CAChD,OAAOA,GAAc,KAA2BA,EAAa,GAC/D,CAEA,IAAOiI,GAAQF,GCOTG,GAAmB,KAAK,IAAI,EAAG,EAAE,EACvC,SAASC,IAAS,CAChB,OAAQ,SAAW,KAAK,MAAM,KAAK,OAAO,EAAI,IAAI,GAAG,MAAM,GAAG,CAChE,CAEA,SAASC,GAAWC,EAA4C,CAC9D,MAAO,CAAC,CAAEA,EAAwB,UACpC,CAGA,SAASC,GAA2B1I,EAAU,CAC5C,OAAWlB,GAA8BkB,CAAG,GAIvCA,EAAI,OACHA,EAAI,aAAe,IACrBA,EAAI,KAAO,OAEXA,EAAI,KAAO,MAEXA,EAAI,WAAa,MAGdA,GAZE,IAAIpF,EAAgB+D,EAAaqB,CAAG,EAAGA,EAAI,MAAQ,MAAOA,EAAI,YAAc,GAAG,CAa1F,CAEA,IAAI2I,GAAO,CAACC,EAAc9H,IAAwB,CAChD,IAAM8C,EAAcxI,EAAS,YAEvByI,EAAaD,EAAY,WAAWgF,CAAI,EACxCC,EAAYjF,EAAY,WAAW9C,CAAG,EAEtCgI,EAASlF,EAAY,WAAWC,EAAYgF,CAAS,EAE3D,OAAOjF,EAAY,aAAakF,CAAM,CACxC,EAEA,SAASC,GAAKC,EAAqD,CACjE,GAAI,CAACA,EAAY,MAAO,GAEpB,OAAOA,GAAc,WAAUA,EAAa,KAAK,MAAMA,CAAU,GAErE,IAAMC,EAAgD,OAAO,OAAO,IAAI,EAClEC,EAAajK,EAAU+J,EAA6C,EAAI,EAC9E,GAAI,CAACE,EAAM,MAAO,GAClBA,EAAK,KAAK,EACV,QAAS,EAAI,EAAG,EAAIA,EAAK,OAAQ,IAC/BD,EAAeC,EAAK,CAAC,CAAC,EAAKF,EAA6CE,EAAK,CAAC,CAAC,EAAE,KAAK,EAExF,OAAO,KAAK,UAAUD,CAAc,CACtC,CAEA,SAASE,GAA8BC,EAA0B1N,EAAgB,CAC/E,GAAI0N,EAAY,aACdtM,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,SAAU,oCAAoC,UAChFsM,EAAY,QACrBtM,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,SAAU,+BAA+B,UAC3EsM,EAAY,IACrBtM,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,SAAU,2CAA2C,UACvFsM,EAAY,aACrBtM,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,SAAU,2CAA2C,MAC3F,CACL,IAAMnB,EAAM,2DACZ,MAAAmB,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,SAAUnB,CAAG,EAClD,IAAI,MAAMA,CAAG,CACrB,CACF,CAEA,SAAS0N,GAAgBlE,EAAwB,CAC/C,MAAO,iBAAkBA,GAAW,CAACA,EAAQ,YAC/C,CAGO,SAASmE,GAAanE,EAAwB,CACnD,OACEA,EAAQ,cACP,CAACkE,GAAgBlE,CAAO,IAAMA,EAAQ,cAAgBA,EAAQ,SAAWA,EAAQ,OAASA,EAAQ,aAEvG,CAGA,SAASoE,GAAapE,EAAwB,CAC5C,MAAO,CAACA,EAAQ,KAAO,CAACA,EAAQ,cAAgB,CAACA,EAAQ,OAC3D,CAEA,IAAIqE,GAAO,EACX,SAASC,IAAoB,CAC3B,OAAOD,IACT,CAYA,IAAME,GAAN,KAAW,CAaT,YAAYjB,EAAoBtD,EAAwB,CAOtD,GAdF,KAAA,YAA2B,CAAC,EAQ1B,KAAK,OAASsD,EACd,KAAK,YAActD,EAAQ,oBAAsB,CAAC,EAElD,KAAK,sBAAwB,KAC7B,KAAK,uBAAyB,KAE1BmE,GAAanE,CAAO,EAElBoE,GAAapE,CAAO,GACtBrI,EAAO,UACL,KAAK,OACLA,EAAO,UACP,SACA,wLACF,EAEF,KAAK,kBAAkBqI,EAAQ,mBAAwCA,CAAO,EAC9EgE,GAA8B,KAAK,YAAa,KAAK,MAAM,MACtD,CAEL,GAAI,CAAChE,EAAQ,IAAK,CAChB,IAAMxJ,EACJ,8HACF,MAAAmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,SAAUnB,CAAG,EACvD,IAAIf,EAAUe,EAAK,MAAO,GAAG,CACrC,CACAmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,SAAU,6BAA6B,EACvF,KAAK,kBAAkBqI,CAAO,CAChC,CACF,CAEA,IAAI,QAAiB,CACnB,OAAO,KAAK,OAAO,MACrB,CAuFA,MAAM,UACJwE,EACAP,EAC2B,CAG3B,GAAIA,GAAeA,EAAY,KAAO,KAAK,YAAY,MAAQA,EAAY,IACzE,MAAM,IAAIxO,EAAU,sDAAuD,MAAO,GAAG,EAGvF,GAAI,CACF,IAAIgP,EAAe,MAAM,KAAK,eAAeD,GAAe,KAAMP,GAAe,IAAI,EAOrF,OAAIZ,GAAW,KAAK,MAAM,EACjB,IAAI,QAAQ,CAACV,EAAS1D,IAAW,CACrC,KAAK,OAAwB,WAAW,kBAAkB,cACzDwF,EACA,CAAC5J,EAAc4J,IAAqC5J,EAAMoE,EAAOpE,CAAG,EAAI8H,EAAQ8B,CAAa,CAC/F,CACF,CAAC,EAEMA,CAEX,OAAS5J,EAAK,CACZ,MAAK,KAAK,OAAwB,YAAeA,EAAkB,aAAeqI,GAAgB,WAI/F,KAAK,OAAwB,WAAW,kBAAkB,wBAAwBrI,CAAgB,EAE/FA,CACR,CACF,CAKA,MAAM,eACJ2J,EACAP,EAC2B,CAE3B,KAAK,aAAe,KAKpB,KAAK,kBAAkBO,EAAaP,CAAW,EAE/CD,GAA8B,KAAK,YAAa,KAAK,MAAM,EAE3D,GAAI,CACF,OAAO,KAAK,4BAA4B,EAAI,CAC9C,QAAA,CAEE,OAAO,KAAK,YAAY,UACxB,OAAO,KAAK,YAAY,SAC1B,CACF,CAyEA,MAAM,aAAaQ,EAAsCP,EAAsD,CAE7G,IAAMS,EAAsBT,GAAe,KAAK,YAC1CU,EAAsBH,GAAqB7L,GAAK,KAAK,WAAW,EAIlEiM,EAQFtB,EAAS,KAAK,OAEhB,GAAIoB,EAAoB,aACtB/M,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,sBAAuB,oCAAoC,EAC3GiN,EAAuBF,EAAoB,qBAClCA,EAAoB,QAC7B/M,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,sBAAuB,+BAA+B,EACtGiN,EAAuB,CAAC1H,EAAQ2H,IAAO,CACrC,IAAMC,EAAoB9K,EACxB,CAAE,OAAQ,8BAA+B,EACzC0K,EAAoB,WACtB,EACMK,EAAUL,EAAoB,YAAcA,EAAoB,WAAW,YAAY,IAAM,OAC/FM,EAEEC,EAAWP,EAAoB,QAAS,QAAQ,GAAG,EACrDO,EAAW,KACbD,EAAyB/K,GAAiByK,EAAoB,QAAS,MAAMO,CAAQ,CAAC,EACtFP,EAAoB,QAAUA,EAAoB,QAAS,MAAM,EAAGO,CAAQ,EACvEF,IAEHL,EAAoB,WAAmB1K,EACrCgL,EACAN,EAAoB,UACtB,IAIJ,IAAMQ,EAAmBlL,EAAM,CAAC,EAAG0K,EAAoB,YAAc,CAAC,EAAGxH,CAAM,EACzEiI,EAA0BrK,GAA0B,CApblE,IAAAnE,EAAA4G,EAqbU,IAAIC,GAAQ7G,EAAAmE,EAAO,OAAP,KAAAnE,EAAe,KAEvByL,EAA6B,KACjC,GAAItH,EAAO,MACTnD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,2CACA,mBAA2B6B,EAAasB,EAAO,KAAK,CACtD,MACK,CACL,IAAMsK,IAA6B7H,EAAAzC,EAAO,QAAS,cAAc,IAA9B,KAAAyC,EAAmC,KAClE,MAAM,QAAQ6H,EAA0B,EAE1ChD,EAAcgD,GAA2B,KAAK,IAAI,EAElDhD,EAAcgD,GAEhBzN,EAAO,UACL,KAAK,OACLA,EAAO,UACP,2CACA,2BAA6ByK,EAAc,WAAmB7I,GAAYiE,CAAI,CAChF,CACF,CACA,GAAI1C,EAAO,MAAO,CAChB+J,EAAG/J,EAAO,MAAO,IAAI,EACrB,MACF,CACA,GAAIA,EAAO,SAAU,CACnB+J,EAAG,KAAMrH,CAAwC,EACjD,MACF,CAEA,GADIvH,EAAS,YAAY,SAASuH,CAAI,IAAGA,EAAOA,EAAK,SAAS,GAC1D,CAAC4E,EAAa,CAChByC,EAAG,IAAIpP,EAAU,oDAAqD,MAAO,GAAG,EAAG,IAAI,EACvF,MACF,CACA,IAAM4P,EAAOjD,EAAY,QAAQ,kBAAkB,EAAI,GACrDqB,GAAOrB,EAAY,QAAQ,YAAY,EAAI,IAAMA,EAAY,QAAQ,iBAAiB,EAAI,GAC5F,GAAI,CAACiD,GAAQ,CAAC5B,GAAM,CAClBoB,EACE,IAAIpP,EACF,oDACE2M,EACA,qEACF,MACA,GACF,EACA,IACF,EACA,MACF,CACA,GAAIiD,EAAM,CACR,GAAK7H,EAAgB,OAAS2F,GAAkB,CAC9C0B,EAAG,IAAIpP,EAAU,iDAAkD,MAAO,GAAG,EAAG,IAAI,EACpF,MACF,CACA,GAAI,CACF+H,EAAO,KAAK,MAAMA,CAAc,CAClC,OAASuB,GAAG,CACV8F,EACE,IAAIpP,EACF,uDAA0DsJ,GAAY,QACtE,MACA,GACF,EACA,IACF,EACA,MACF,CACF,CACA8F,EAAG,KAAMrH,EAA0C4E,CAAW,CAChE,EAYA,GAXAzK,EAAO,UACL,KAAK,OACLA,EAAO,UACP,2CACA,yBACE+M,EAAoB,QACpB,aACA,KAAK,UAAUQ,CAAU,EACzB,cACCH,EAAU,OAAS,MACxB,EACIA,EAAS,CAEX,IAAMxD,EAAUuD,GAAe,CAAC,EAChCvD,EAAQ,cAAc,EAAI,oCAC1B,IAAM/D,EAAahD,GAAc0K,CAAU,EAAE,MAAM,CAAC,EAC9CxK,GACJ,KAAK,OAAO,KAAK,MACfqI,EAAY,KACZ2B,EAAoB,QACpBnD,EACA/D,EACAwH,CACF,EACA,CAACnK,EAAUC,IAELqK,EADJtK,GAE2BC,CADG,CAElC,CACF,MACQJ,GACJ,KAAK,OAAO,KAAK,MAAMqI,EAAY,IAAK2B,EAAoB,QAAUI,GAAe,CAAC,EAAG,KAAMI,CAAU,EACzG,CAACrK,EAAUC,IAELqK,EADJtK,GAE2BC,CADG,CAElC,CAEJ,UACS4J,EAAoB,IAC7B/M,EAAO,UACL,KAAK,OACLA,EAAO,UACP,sBACA,2CACF,EACAiN,EAAuB,CAAC1H,EAAQ2H,IAAO,CAC/BnK,GAAmB,KAAK,mBAAmBwC,EAAQwH,CAAmB,EAAG,CAAC7J,EAAKC,IACnF+J,EAAGhK,EAAkCC,GAAU,IAAI,CACrD,CACF,MACK,CACL,IAAMtE,EACJ,+GACF,MAAAmB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,SACA,+KACF,EACM,IAAIlC,EAAUe,EAAK,MAAO,GAAG,CACrC,CAGI,eAAiBmO,IAClBA,EAA4C,WAAaf,GACvDe,EAA4C,UAC/C,GAEF,IAAMW,EAAe,CACnBC,EACAC,IACG,CACH,IAAMC,EAAUF,EAAkB,QAChCG,EAAO,SAAWD,EAAU,gBAC5BE,EAAW,SAAU1F,EAAc,CACjC,OAAOqD,EAAO,QAAQrD,CAAI,EAAIyF,CAChC,EAEIE,EAAiBvD,EAAS,mBAAmB,KAAK,OAAO,OAAO,EAClEqC,EAAoB,gBAAsB1K,EAAM4L,EAAgBlB,EAAoB,cAAc,EACtG/M,EAAO,UACL,KAAK,OACLA,EAAO,UACP,mCACA,mBAAqB+N,EAAO,mBAAqB,KAAK,UAAUH,CAAiB,CACnF,EACM7K,GACJ,KAAK,OAAO,KAAK,GAAGqI,EAAY,KAAM4C,EAAUC,EAAgB,KAAK,UAAUL,CAAiB,EAAG,IAAI,EACvG,CAAC1K,EAAUC,IACTD,EACI2K,EAAQ3K,CAAG,EACX2K,EAAQ1K,EAAQ,MAAOA,EAAQ,KAA+CA,EAAQ,QAAQ,CACtG,CACF,EAEA,OAAO,IAAI,QAAQ,CAAC6H,EAAS1D,IAAW,CACtC,IAAI4G,EAAqC,GACvCC,EAAgB,KAAK,OAAO,QAAQ,SAAS,uBAC7CC,EAA8B,WAAW,IAAM,CAC7CF,EAAqC,GACrC,IAAMrP,EAAM,0CAA4CsP,EAAgB,IAAO,WAC/EnO,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,sBAAuBnB,CAAG,EAC1EyI,EAAO,IAAIxJ,EAAUe,EAAK,MAAO,GAAG,CAAC,CACvC,EAAGsP,CAAa,EAElBlB,EAAsBD,EAAqB,CAAC9J,EAAKmL,EAAuB5D,IAAgB,CACtF,GAAIyD,EAAoC,OAGxC,GAFA,aAAaE,CAA2B,EAEpClL,EAAK,CACPlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,sBACA,oDAA4D6B,EAAaqB,CAAG,CAC9E,EACAoE,EAAOsE,GAA2B1I,CAAG,CAAC,EACtC,MACF,CAEA,GAAI,OAAOmL,GAA0B,SAAU,CACzCA,EAAsB,SAAW,EACnC/G,EAAO,IAAIxJ,EAAU,wBAAyB,MAAO,GAAG,CAAC,EAChDuQ,EAAsB,OAAS7C,GACxClE,EACE,IAAIxJ,EACF,mDAAqDuQ,EAAsB,OAAS,UACpF,MACA,GACF,CACF,EACSA,IAA0B,aAAeA,IAA0B,OAE5E/G,EAAO,IAAIxJ,EAAU,0CAA2C,MAAO,GAAG,CAAC,EAE3EuQ,EAAsB,CAAC,IAAM,KAC7B,EAAE5D,GAAeA,EAAY,QAAQ,iBAAiB,EAAI,IAE1DnD,EACE,IAAIxJ,EACF,2GACA,MACA,GACF,CACF,EAEAkN,EAAQ,CAAE,MAAOqD,CAAsB,CAAqB,EAE9D,MACF,CACA,GAAI,OAAOA,GAA0B,UAAYA,IAA0B,KAAM,CAC/E,IAAMxP,EACJ,+GACA,OAAOwP,EACTrO,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,sBAAuBnB,CAAG,EAC1EyI,EAAO,IAAIxJ,EAAUe,EAAK,MAAO,GAAG,CAAC,EACrC,MACF,CACA,IAAMyP,EAAa,KAAK,UAAUD,CAAqB,EAAE,OACzD,GAAIC,EAAa9C,IAAoB,CAACuB,EAAoB,uBAAwB,CAChFzF,EACE,IAAIxJ,EACF,6EAA+EwQ,EAAa,UAC5F,MACA,GACF,CACF,EACA,MACF,CACA,GAAI,WAAYD,EAAuB,CAErCrD,EAAQqD,CAAqB,EAC7B,MACF,CACA,GAAI,EAAE,YAAaA,GAAwB,CACzC,IAAMxP,EACJ,kHACFmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,sBAAuBnB,CAAG,EAC1EyI,EAAO,IAAIxJ,EAAUe,EAAK,MAAO,GAAG,CAAC,EACrC,MACF,CAEA8O,EAAaU,EAAuB,CAACnL,EAAKqL,EAAeC,IAAa,CACpE,GAAItL,EAAK,CACPlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,sBACA,gDAAwD6B,EAAaqB,CAAG,CAC1E,EACAoE,EAAOsE,GAA2B1I,CAAG,CAAC,EACtC,MACF,CACKsL,IAAUD,EAAgB,KAAK,MAAMA,CAAuB,GACjEvO,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,kBAAmB,gBAAgB,EACnFgL,EAAQuD,CAAiC,CAC3C,CAAC,CACH,CAAC,CACH,CAAC,CACH,CAmCA,MAAM,mBAAmB1B,EAAqCP,EAA6C,CAEzGA,EAAcA,GAAe,KAAK,YAClCO,EAAcA,GAAqB7L,GAAsB,KAAK,WAAW,EAEzE,IAAMgD,EAAMsI,EAAY,IACxB,GAAI,CAACtI,EACH,MAAM,IAAIlG,EAAU,mBAAoB,MAAO,GAAG,EAEpD,IAAM2Q,EAAWzK,EAAI,MAAM,GAAG,EAC5B8J,EAAUW,EAAS,CAAC,EACpBC,EAAYD,EAAS,CAAC,EAExB,GAAI,CAACC,EACH,MAAM,IAAI5Q,EAAU,wBAAyB,MAAO,GAAG,EAGzD,GAAI+O,EAAY,WAAa,GAC3B,MAAM,IAAI/O,EAAU,yCAAqC,MAAO,GAAG,EAGjE,eAAgB+O,IAClBA,EAAY,WAAaZ,GAAKY,EAAY,UAAU,GAGtD,IAAM8B,EAA2CtM,EAAM,CAAE,QAAAyL,CAAiB,EAAGjB,CAAW,EACtF+B,EAAW/B,EAAY,UAAY,GACnCgC,EAAMhC,EAAY,KAAO,GACzBX,EAAaW,EAAY,YAAc,GAEpC8B,EAAQ,YACXA,EAAQ,UAAY,MAAM,KAAK,aAAarC,GAAeA,EAAY,SAAS,GAQlF,IAAMwC,EAAQH,EAAQ,QAAUA,EAAQ,MAAQlD,GAAO,GACrDsD,EAAYJ,EAAQ,UAEhBK,EACJL,EAAQ,QAAU;EAAOE,EAAM;EAAO3C,EAAa;EAAO0C,EAAW;EAAOG,EAAY;EAAOD,EAAQ;EAOzG,OAAAH,EAAQ,IAAMA,EAAQ,KAAO9C,GAAKmD,EAAUN,CAAS,EAErD1O,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,yBAA0B,0BAA0B,EAE7F2O,CACT,CAMA,MAAM,eAAiD,CACrD,GAAI,KAAK,QAAU,QAAS,MAAO,CAAE,IAAK,KAAK,GAAK,EAC/C,CACH,IAAI7B,EAAe,MAAM,KAAK,4BAA4B,EAAK,EAC/D,GAAI,CAACA,EACH,MAAM,IAAI,MAAM,qFAAqF,EAEvG,MAAO,CAAE,aAAcA,EAAa,KAAM,CAC5C,CACF,CAMA,MAAM,gBAAkD,CACtD,GAAI,KAAK,QAAU,QACjB,MAAO,CAAE,cAAe,SAAW,KAAK,QAAS,EAC5C,CACL,IAAMA,EAAe,MAAM,KAAK,4BAA4B,EAAK,EACjE,GAAI,CAACA,EACH,MAAM,IAAI,MAAM,qFAAqF,EAEvG,MAAO,CAAE,cAAe,UAAkBlK,GAASkK,EAAa,KAAK,CAAE,CACzE,CACF,CAQA,MAAM,aAAamC,EAAqC,CACtD,MAAI,CAAC,KAAK,gBAAgB,IAAMA,GAAa,KAAK,YAAY,WACrD,KAAK,OAAO,KAAK,EAEjB,KAAK,wBAAwB,CAExC,CAEA,yBAA0B,CACxB,OAAO,KAAK,IAAI,GAAK,KAAK,OAAO,kBAAoB,EACvD,CAEA,iBAAkB,CAChB,OAAO,KAAK,OAAO,mBAAqB,IAC1C,CAEA,kBAAkB3C,EAA0B,CAC1C,KAAK,OAAS,QACd,KAAK,IAAMA,EAAY,IACvB,KAAK,SAAiB1J,GAAS0J,EAAY,GAAa,EACxD,KAAK,YAAcA,GAAe,CAAC,EAC/B,aAAcA,GAChB,KAAK,iBAAiBA,EAAY,QAAQ,CAE9C,CAEA,kBAAkBO,EAAqCP,EAAiC,CACtF,KAAK,OAAS,QAEVO,IAIF,KAAK,YAAcA,GAGjBP,IAEEA,EAAY,QAEdA,EAAY,aACV,OAAOA,EAAY,OAAU,SACxB,CAAE,MAAOA,EAAY,KAAM,EAC5BA,EAAY,OAGhBA,EAAY,eACd,KAAK,aAAeA,EAAY,cAG9B,aAAcA,GAChB,KAAK,iBAAiBA,EAAY,QAAQ,EAG5C,KAAK,YAAcA,EAEvB,CAIA,MAAM,4BAA4B4C,EAAoD,CACpF,IAAMC,EAAQ,KAAK,aAEnB,GAAIA,EAAO,CACT,GAAI,KAAK,uBAAuBA,EAAM,QAAQ,EAE5C,MAAM,IAAIrR,EACR,uCAAyCqR,EAAM,SAAW,2BAA6B,KAAK,SAAW,IACvG,MACA,GACF,EAKF,GAAI,CAAC,KAAK,gBAAgB,GAAK,CAACA,EAAM,SAAWA,EAAM,SAAW,KAAK,wBAAwB,EAC7F,OAAAnP,EAAO,UACL,KAAK,OACLA,EAAO,UACP,kBACA,iCAAmCmP,EAAM,OAC3C,EACOA,EAGTnP,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,kBAAmB,wBAAwB,EAC3F,KAAK,aAAe,IACtB,CAEA,IAAMoG,GACJ,KAAK,yBAA2B,KAAK,uBAAyB8E,GAAY,OAAO,KAAK,MAAM,IAC5F,cAAc,EAChB,GAAI,KAAK,wBAA0B,MAAQ,CAACgE,EAC1C,OAAO9I,EAIT,IAAMgJ,EAAkB,KAAK,sBAAwBzC,GAAkB,EAEnE4B,EACFc,EAAgC,KAClC,GAAI,CACFd,EAAgB,MAAM,KAAK,aAAa,KAAK,YAAa,KAAK,WAAW,CAC5E,OAASrL,EAAK,CACZmM,EAAcnM,CAChB,CAEA,GAAK,KAAK,sBAAmCkM,EAC3C,OAAApP,EAAO,UACL,KAAK,OACLA,EAAO,UACP,qCACA,2DACF,EACOoG,EAGT,KAAK,sBAAwB,KAC7B,IAAMkJ,EAAc,KAAK,uBAEzB,OADA,KAAK,uBAAyB,KAC1BD,GACFC,GAAa,UAAUD,CAAA,EAChBjJ,IAETkJ,GAAa,WAAY,KAAK,aAAef,CAAA,EAEtCnI,EACT,CAGA,iBAAiBwI,EAA8B,CAC7C,GAAM,OAAOA,GAAa,UAAYA,IAAa,KAEnD,IAAWA,IAAa,IACtB,MAAM,IAAI9Q,EACR,8SACA,MACA,GACF,EACK,CACL,IAAMoF,EAAM,KAAK,sBAAsB0L,CAAQ,EAC/C,GAAI1L,EAAK,MAAMA,CACjB,MAVE,OAAM,IAAIpF,EAAU,2CAA4C,MAAO,GAAG,CAW9E,CAGA,sBAAsB8Q,EAA8B,CAClD,GAAI,KAAK,uBAAuBA,CAAQ,EAAG,CAGzC,IAAM/P,EAAM,4CAA8C,KAAK,SAAW,eAAiB+P,EACrF1L,EAAM,IAAIpF,EAAUe,EAAK,MAAO,GAAG,EACzC,OAAAmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAAgCnB,CAAG,EAC5EqE,CACT,KAGE,aAAK,SAAW,KAAK,YAAY,SAAW0L,EACrC,IAEX,CAEA,uBAAuBW,EAAwC,CAC7D,MAAO,CAAC,EACN,KAAK,UACL,KAAK,WAAa,KAClBA,GACAA,IAAkB,KAClB,KAAK,WAAaA,EAEtB,CAEA,OAAO,WAAWC,EAA0B,CAC1C,OAAOA,EAAM,MAAQA,EAAM,MAAQ,OAASA,EAAM,KAAO,KAC3D,CAEA,aACEC,EACApH,EACgC,CAChC,OAAO,KAAK,OAAO,KAAK,aAAaoH,EAAYpH,CAAO,CAC1D,CACF,EAEOqH,GAAQ9C,GCp8BR,SAAS+C,GAAYpK,EAAoC,CAC9D,IAAMqK,EAAa,CAAC,EACpB,GAAIrK,EACF,QAAWsK,KAAUtK,EACnBqK,EAAW,KAAKC,EAAS,IAAMtK,EAAOsK,CAAM,CAAC,EAGjD,OAAOD,EAAW,KAAK,GAAG,CAC5B,CAEO,SAASE,GAAgB/F,EAAaxE,EAAoC,CAC/E,OAAOwE,GAAOxE,EAAS,IAAM,IAAMoK,GAAYpK,CAAM,CACvD,CAEA,SAASwK,GACP5M,EACA6M,EACAjG,EACAxE,EACA3G,EACA,CACIuE,EAAO,MACTnD,EAAO,iBACLpB,EACAoB,EAAO,UACP,QAAUgQ,EAAS,KACnB,mBAAqBF,GAAgB/F,EAAKxE,CAAM,EAAI,YAAoB1D,EAAasB,EAAO,KAAK,CACnG,EAEAnD,EAAO,iBACLpB,EACAoB,EAAO,UACP,QAAUgQ,EAAS,KACnB,aACEF,GAAgB/F,EAAKxE,CAAM,EAC3B,cACAoK,GAAYxM,EAAO,OAA8B,EACjD,iBACAA,EAAO,WACP,UACC7E,EAAS,YAAY,SAAS6E,EAAO,IAAI,EACtC,cAAgB7E,EAAS,YAAY,aAAa6E,EAAO,IAAI,EAC7D,KAAOA,EAAO,KACtB,CAEJ,CAEA,SAAS8M,GAAWD,EAAqBjG,EAAalE,EAA0BN,EAAuB3G,EAAgB,CACjHA,EAAO,UAAUoB,EAAO,SAAS,GACnCA,EAAO,iBACLpB,EACAoB,EAAO,UACP,QAAUgQ,EAAS,KACnB,YACEF,GAAgB/F,EAAKxE,CAAM,EAC3B,UACCjH,EAAS,YAAY,SAASuH,CAAI,EAAI,cAAgBvH,EAAS,YAAY,aAAauH,CAAI,EAAI,KAAOA,EAC5G,CAEJ,CAEO,IAAMqK,GAAN,KAAW,CAIhB,YAA6BvE,EAAqB,CAArB,KAAA,OAAAA,EAC3B,KAAK,aAAe,IAAIrN,EAAS,KAAKqN,CAAM,EAE5C,KAAK,kBAAoB,KAAK,aAAa,kBACvC,IAAM,KAAK,aAAa,kBAAmB,EAC3C,MACN,CAEA,IAAI,QAAiB,CArIvB,IAAA3M,EAAA4G,EAsII,OAAOA,GAAA5G,EAAA,KAAK,SAAL,KAAA,OAAAA,EAAa,SAAb,KAAA4G,EAAuB5F,EAAO,aACvC,CAEA,IAAI,qBAAsB,CACxB,OAAO,KAAK,aAAa,mBAC3B,CAEA,IAAI,qBAAsB,CACxB,OAAO,KAAK,aAAa,mBAC3B,CAEA,UAAU2L,EAAoB,CAI5B,IAAMwE,EAAcxE,EAAwB,WAC1CyE,EAAiBD,GAAcA,EAAW,kBAAkB,KAE9D,OAAIC,EACK,CAACA,CAAc,EAAE,OAAO1F,EAAS,iBAAiBiB,EAAO,OAAO,CAAC,EAGnEjB,EAAS,SAASiB,EAAO,OAAO,CACzC,CAKA,MAAM,GACJqE,EACAjC,EACAnE,EACA/D,EACAN,EACwB,CACxB,GAAI,CAEF,IAAMoG,EAAS,KAAK,OACpB,GAAI,CAACA,EACH,MAAO,CAAE,MAAO,IAAI7N,EAAU,gCAAiC,IAAO,GAAG,CAAE,EAG7E,IAAMuS,EACJ,OAAOtC,GAAS,WACZA,EACA,SAAUzF,EAAc,CACtB,OAAOqD,EAAO,QAAQrD,CAAI,EAAIyF,CAChC,EAEAuC,EAAkB3E,EAAO,iBAC/B,GAAI2E,EACF,GAAIA,EAAgB,WAAa,KAAK,IAAI,EAAG,CAE3C,IAAMnN,EAAS,MAAM,KAAK,MAAM6M,EAAQK,EAAYC,EAAgB,IAAI,EAAG1G,EAAS/D,EAAMN,CAAM,EAChG,OAAIpC,EAAO,OAAS,KAAK,aAAa,eAAeA,EAAO,KAAuB,GAEjFwI,EAAO,iBAAmB,KACnB,KAAK,GAAGqE,EAAQjC,EAAMnE,EAAS/D,EAAMN,CAAM,GAE7CpC,CACT,MAEEwI,EAAO,iBAAmB,KAI9B,IAAM/C,EAAQ,KAAK,UAAU+C,CAAM,EAGnC,GAAI/C,EAAM,SAAW,EACnB,OAAO,KAAK,MAAMoH,EAAQK,EAAYzH,EAAM,CAAC,CAAC,EAAGgB,EAAS/D,EAAMN,CAAM,EAGxE,IAAIgL,EAAiC,KAC/BC,EAAW,MAAOC,EAA+BC,IAAuD,CAC5G,IAAMpI,EAAOmI,EAAe,MAAM,EAClCF,EAAoBA,GAAqB,IAAI,KAC7C,IAAMpN,EAAS,MAAM,KAAK,MAAM6M,EAAQK,EAAY/H,CAAc,EAAGsB,EAAS/D,EAAMN,CAAM,EAC1F,OAAIpC,EAAO,OAAS,KAAK,aAAa,eAAeA,EAAO,KAAuB,GAAKsN,EAAe,OAEjF,KAAK,IAAI,EAAIF,EAAkB,QAAQ,EACzC5E,EAAO,QAAQ,SAAS,qBACjC,CACL,MAAO,IAAI7N,EACT,8EAA8E6N,EAAO,QAAQ,SAAS,oBAAoB,WAC1H,MACA,GACF,CACF,EAGK6E,EAASC,EAAgB,EAAI,GAElCC,IAEF/E,EAAO,iBAAmB,CACxB,KAAArD,EACA,WAAY,KAAK,IAAI,EAAIqD,EAAO,QAAQ,SAAS,oBACnD,GAEKxI,EACT,EACA,OAAOqN,EAAS5H,CAAK,CACvB,OAAS1F,EAAK,CAEZ,MAAO,CAAE,MAAO,IAAIpF,EAAU,gCAAsC+D,EAAaqB,CAAG,CAAC,GAAI,IAAK,GAAK,CAAE,CACvG,CACF,CAKA,MAAM,MACJ8M,EACAjG,EACAH,EACA/D,EACAN,EACwB,CACxB,GAAI,CACF0K,GAAWD,EAAQjG,EAAKlE,EAAMN,EAAQ,KAAK,MAAM,EAEjD,IAAMpC,EAAS,MAAM,KAAK,aAAa,MAAM6M,EAAQjG,EAAKH,EAAS/D,EAAMN,CAAM,EAE/E,OAAI,KAAK,OAAO,UAAUvF,EAAO,SAAS,GACxC+P,GAAU5M,EAAQ6M,EAAQjG,EAAKxE,EAAQ,KAAK,MAAM,EAG7CpC,CACT,OAASD,EAAK,CAEZ,MAAO,CAAE,MAAO,IAAIpF,EAAU,mCAAyC+D,EAAaqB,CAAG,CAAC,GAAI,IAAK,GAAK,CAAE,CAC1G,CACF,CACF,EC5OMyN,GAAN,KAAiB,CAmBf,YAAYtI,EAAwB,CA6HpC,KAAA,SAAW/J,EACX,KAAA,UAAYR,EACZ,KAAA,OAASkC,EACT,KAAA,SAAW0K,EACX,KAAA,MAAQzK,GApLV,IAAAjB,EAAA4G,EAAAgL,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAoDI,KAAK,uCAAwCjS,EAAAqJ,EAAQ,UAAR,KAAArJ,EAAmB,KAEhE,KAAK,OAAS,IAAIgB,EAClB,KAAK,OAAO,OAAOqI,EAAQ,SAAUA,EAAQ,UAAU,EACvDrI,EAAO,UACL,KAAK,OACLA,EAAO,UACP,eACA,kCAAoC1B,EAAS,OAAO,QAAQ+J,CAAO,CACrE,EAEA,KAAK,UAAWuI,GAAAhL,EAAAyC,EAAQ,UAAR,KAAA,OAAAzC,EAAiB,UAAjB,KAAAgL,EAA4B,KAC5C,IAAMM,EAAiB,KAAK,QAAUxG,EAAS,iBAAiBrC,EAAS,KAAK,SAAU,KAAK,MAAM,EAGnG,GAAI6I,EAAc,IAAK,CACrB,IAAMC,EAAWD,EAAc,IAAI,MAAM,wBAAwB,EACjE,GAAI,CAACC,EAAU,CACb,IAAMtS,EAAM,wBACZ,MAAAmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,eAAgBnB,CAAG,EAC7D,IAAIf,EAAUe,EAAK,MAAO,GAAG,CACrC,CACAqS,EAAc,QAAUC,EAAS,CAAC,EAClCD,EAAc,UAAYC,EAAS,CAAC,CACtC,CAEA,GAAI,aAAcD,EAChB,GAAM,OAAOA,EAAc,UAAa,UAAYA,EAAc,WAAa,MACH,GACnEA,EAAc,WAAa,IAClC,MAAM,IAAIpT,EACR,qLACA,MACA,GACF,MANA,OAAM,IAAIA,EAAU,2CAA4C,MAAO,GAAG,EAS9EkC,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,eAAgB,sBAAwB0K,EAAS,OAAO,EAExG,KAAK,iBAAmB,KAExB,KAAK,iBAAmB,KACxB,KAAK,KAAO,IAAIwF,GAAK,IAAI,EACzB,KAAK,KAAO,IAAIR,GAAK,KAAMwB,CAAa,EAExC,KAAK,OAAQL,EAAAxI,EAAQ,UAAR,MAAAwI,EAAiB,KAAO,IAAIxI,EAAQ,QAAQ,KAAK,IAAI,EAAI,KACtE,KAAK,SAAU0I,GAAAD,EAAAzI,EAAQ,UAAR,KAAA,OAAAyI,EAAiB,SAAjB,KAAAC,EAA2B,KAC1C,KAAK,yBAA0BE,GAAAD,EAAA3I,EAAQ,UAAR,KAAA,OAAA2I,EAAiB,sBAAjB,KAAAC,EAAwC,IACzE,CAEA,IAAI,MAAa,CACf,OAAK,KAAK,OACRtO,GAAwB,MAAM,EAEzB,KAAK,KACd,CAEA,IAAI,wBAAuD,CACzD,OAAK,KAAK,yBACRA,GAAwB,qBAAqB,EAExC,KAAK,uBACd,CAEA,IAAI,UAAW,CACb,OAAO,KAAK,KAAK,QACnB,CAEA,IAAI,MAAO,CACT,OAAO,KAAK,KAAK,IACnB,CAEA,IAAI,QAAS,CA5Hf,IAAA3D,EA6HI,OAAI,GAACA,EAAA,KAAK,QAAQ,UAAb,MAAAA,EAAsB,OAAQ,CAAC,KAAK,KAAK,cAC5C2D,GAAwB,MAAM,EAE3B,KAAK,UACR,KAAK,QAAU,KAAK,KAAK,YAAY,KAAK,IAAI,GAEzC,KAAK,OACd,CAEA,QAAQ2F,EAAc,CACpB,OAAOoC,EAAS,cAAc,KAAK,OAAO,EAAIpC,EAAO,IAAMoC,EAAS,QAAQ,KAAK,QAAS,EAAK,CACjG,CAEA,MAAM,MAAMnF,EAAwD,CAClE,OAAO,KAAK,KAAK,MAAMA,CAAM,CAC/B,CAEA,MAAM,KAAKA,EAAyC,CAClD,OAAO,KAAK,KAAK,KAAKA,CAAM,CAC9B,CAEA,MAAM,QACJyK,EACAjC,EACAxG,EACAhC,EACAM,EACAuL,EACyC,CACzC,OAAO,KAAK,KAAK,QAAQpB,EAAQjC,EAAMxG,EAAShC,EAAQM,EAAMuL,CAAa,CAC7E,CAEA,aACEC,EACiF,CACjF,OAAO,KAAK,KAAK,aAAaA,CAAW,CAC3C,CAEA,cAAcC,EAAkD,CAC9D,OAAO,KAAK,KAAK,cAAcA,CAAQ,CACzC,CAEA,OAAOC,EAAiC,CACtC,KAAK,OAAO,OAAOA,EAAW,MAAOA,EAAW,OAAO,CACzD,CAYF,EArJMZ,GA2IG,SAAWrS,EAYpB,IAAOkT,GAAQb,GCnITc,GAAN,MAAMC,EAAc,CAUlB,QAAwB,CA9D1B,IAAA1S,EAAA4G,EAAAgL,EA+DI,MAAO,CACL,GAAI,KAAK,GACT,aAAc,KAAK,aACnB,SAAU,KAAK,SACf,WAAY,KAAK,WACjB,SAAU,KAAK,SACf,SAAU,KAAK,SACf,oBAAqB,KAAK,oBAC1B,KAAM,CACJ,WAAW5R,EAAA,KAAK,OAAL,KAAA,OAAAA,EAAW,UACtB,OAAO4G,EAAA,KAAK,OAAL,KAAA,OAAAA,EAAW,MAClB,OAAOgL,EAAA,KAAK,OAAL,KAAA,OAAAA,EAAW,KACpB,CACF,CACF,CAEA,UAAmB,CA/ErB,IAAA5R,EAAA4G,EAAAgL,EAAAC,EAgFI,IAAI1N,EAAS,iBACb,OAAI,KAAK,KAAIA,GAAU,QAAU,KAAK,IAClC,KAAK,WAAUA,GAAU,cAAgB,KAAK,UAC9C,KAAK,aAAYA,GAAU,gBAAkB,KAAK,YAClD,KAAK,WAAUA,GAAU,cAAgB,KAAK,UAC9C,KAAK,WAAUA,GAAU,cAAgB,KAAK,UAC9C,KAAK,sBAAqBA,GAAU,yBAA2B,KAAK,UAAU,KAAK,mBAAmB,IACtGnE,EAAA,KAAK,OAAL,MAAAA,EAAW,YAAWmE,GAAU,oBAAsB,KAAK,UAAU,KAAK,KAAK,SAAS,IACxFyC,EAAA,KAAK,OAAL,MAAAA,EAAW,QAAOzC,GAAU,gBAAkB,KAAK,KAAK,QACxDyN,EAAA,KAAK,OAAL,MAAAA,EAAW,QAAOzN,GAAU,gBAAkB,KAAK,UAAU,KAAK,KAAK,KAAK,IAC5E0N,EAAA,KAAK,OAAL,MAAAA,EAAW,WAAU1N,GAAU,mBAAqB,KAAK,KAAK,UAClEA,GAAU,IACHA,CACT,CAEA,OAAO,cAAc0C,EAAeS,EAAyBC,EAAuB,CAClF,OAAanF,GAAWyE,EAAMS,EAASC,CAAM,CAC/C,CAEA,OAAO,iBACLV,EACAS,EACAC,EACiC,CAKjC,OAJIA,IACFV,EAAa1E,GAAW0E,EAAMS,EAASC,CAAM,GAG3C,MAAM,QAAQV,CAAI,EACb6L,GAAc,gBAAgB7L,CAAI,EAElC6L,GAAc,WAAW7L,CAAI,CAExC,CAEA,OAAO,WAAWrC,EAAgD,CAChE,OAAAA,EAAO,MAAQA,EAAO,OAAS1F,EAAU,WAAW0F,EAAO,KAAgC,EACpF,OAAO,OAAO,IAAIkO,GAAiBlO,CAAM,CAClD,CAEA,OAAO,gBAAgBmO,EAAoC,CACzD,OAAO,OAAO,OAAO,IAAID,GAAiBC,CAAM,CAClD,CAEA,OAAO,gBAAgBnO,EAAyD,CAC9E,IAAMgD,EAAQhD,EAAO,OACnBL,EAAS,IAAI,MAAMqD,CAAK,EAC1B,QAAS1C,EAAI,EAAGA,EAAI0C,EAAO1C,IAAKX,EAAOW,CAAC,EAAI4N,GAAc,WAAWlO,EAAOM,CAAC,CAAC,EAC9E,OAAOX,CACT,CACF,EAEOyO,GAAQH,GCzHf,eAAeI,GACblG,EACA/B,EACArE,EACAuM,EAC4B,CAC5B,GAAInG,EAAO,KAAK,oBAAqB,CACnC,IAAMwB,EAAc,MAAMxB,EAAO,KAAK,eAAe,EACrD,OAAOmG,EAAiBzP,EAAM8K,EAAcvD,CAAO,EAAGrE,CAAM,CAC9D,KAAO,CACL,IAAMgI,EAAa,MAAM5B,EAAO,KAAK,cAAc,EACnD,OAAOmG,EAAWlI,EAAevH,EAAMkL,EAAahI,CAAM,CAAC,CAC7D,CACF,CAEA,SAASwM,GACP5O,EACAmD,EACAC,EACmB,CACnB,GAAIpD,EAAO,KAAO,CAACA,EAAO,KACxB,MAAO,CAAE,IAAKA,EAAO,GAAI,EAG3B,GAAIA,EAAO,aAAeoI,GAAgB,UACxC,OAAOhC,EAAAC,EAAA,CAAA,EAAKrG,CAAA,EAAL,CAAa,KAAM,CAAC,EAAU,SAAU,EAAK,CAAA,EAGtD,IAAI0C,EAAO1C,EAAO,KAElB,GAAI,CAACA,EAAO,SACV,GAAI,CACF0C,EAAa1E,GAAW0E,EAAMS,EAASC,CAAM,CAC/C,OAASa,EAAG,CACV,OAAUpF,GAA8BoF,CAAC,EAChC,CAAE,IAAKA,CAAE,EAET,CAAE,IAAK,IAAI3D,GAAuB5B,EAAauF,CAAC,EAAG,IAAI,CAAE,CAEpE,CAGF,GAAI,CAACvB,EACH,MAAO,CAAE,IAAK,IAAIpC,GAAiB,yCAA0C,IAAI,CAAE,EAGrF,GAAM,CAAE,WAAYuO,EAAmB,SAAAC,EAAU,QAASC,CAAe,EAAIrM,EAE7E,GAAImM,IAAsB,OAExB,OAAOzI,EAAAC,EAAA,CAAA,EAAKrG,CAAA,EAAL,CAAa,KAAA0C,EAAM,SAAU,EAAK,CAAA,EAG3C,GAAImM,EAAoB,KAAOA,GAAqB,IAAK,CAEvD,IAAIG,EAAcF,GAAYA,EAAS,OAAU9O,EAAO,IACxD,OAAKgP,IACHA,EAAa,IAAI,MAAM,yBAA2BtM,CAAI,EACtDsM,EAAW,WAAaH,GAEnB,CAAE,IAAKG,EAAY,KAAMF,EAAU,QAASC,EAAgB,SAAU,GAAM,WAAYF,CAAkB,CACnH,CAEA,MAAO,CAAE,IAAK7O,EAAO,IAAK,KAAM8O,EAAU,QAASC,EAAgB,SAAU,GAAM,WAAYF,CAAkB,CACnH,CAEA,SAASjC,GACP5M,EACA6M,EACAjC,EACAxI,EACA3G,EACA,CACIuE,EAAO,IACTnD,EAAO,UACLpB,EACAoB,EAAO,UACP,YAAcgQ,EAAS,KACvB,mBAAqBF,GAAqB/B,EAAMxI,CAAM,EAAI,YAAoB1D,EAAasB,EAAO,GAAG,CACvG,EAEAnD,EAAO,UACLpB,EACAoB,EAAO,UACP,YAAcgQ,EAAS,KACvB,aACEF,GAAqB/B,EAAMxI,CAAM,EACjC,cACAoK,GAAYxM,EAAO,OAA8B,EACjD,iBACAA,EAAO,WACP,YACC7E,EAAS,YAAY,SAAS6E,EAAO,IAAI,EACtC,cAAgB7E,EAAS,YAAY,aAAa6E,EAAO,IAAI,EAC7D,KAAO7E,EAAS,OAAO,QAAQ6E,EAAO,IAAI,EAClD,CAEJ,CAgBA,IAAMiP,GAAN,MAAMC,EAAS,CAsBb,aAAa,IACX1G,EACAoC,EACAnE,EACArE,EACA+M,EACAC,EACkD,CAClD,OAAOF,GAAS,GAAGjH,EAAY,IAAKO,EAAQoC,EAAM,KAAMnE,EAASrE,EAAQ+M,EAAUC,GAAc,EAAK,CACxG,CAuBA,aAAa,OACX5G,EACAoC,EACAnE,EACArE,EACA+M,EACAC,EACkD,CAClD,OAAOF,GAAS,GAAGjH,EAAY,OAAQO,EAAQoC,EAAM,KAAMnE,EAASrE,EAAQ+M,EAAUC,CAAU,CAClG,CAyBA,aAAa,KACX5G,EACAoC,EACAlI,EACA+D,EACArE,EACA+M,EACAC,EACkD,CAClD,OAAOF,GAAS,GAAGjH,EAAY,KAAMO,EAAQoC,EAAMlI,EAAM+D,EAASrE,EAAQ+M,EAAUC,CAAU,CAChG,CAyBA,aAAa,MACX5G,EACAoC,EACAlI,EACA+D,EACArE,EACA+M,EACAC,EACkD,CAClD,OAAOF,GAAS,GAAGjH,EAAY,MAAOO,EAAQoC,EAAMlI,EAAM+D,EAASrE,EAAQ+M,EAAUC,CAAU,CACjG,CAyBA,aAAa,IACX5G,EACAoC,EACAlI,EACA+D,EACArE,EACA+M,EACAC,EACkD,CAClD,OAAOF,GAAS,GAAGjH,EAAY,IAAKO,EAAQoC,EAAMlI,EAAM+D,EAASrE,EAAQ+M,EAAUC,CAAU,CAC/F,CAEA,aAAa,GACXvC,EACArE,EACAoC,EACAlI,EACA+D,EACArE,EACA+M,EACAC,EACkD,CAC9CD,KACD/M,EAASA,GAAU,CAAC,GAAG,SAAc+M,GAGxC,IAAM1T,EAAS+M,EAAO,OAEtB,eAAe6G,EAEb5I,EACArE,EAC4B,CA1TlC,IAAAvG,EA2TM,GAAIJ,EAAO,UAAUoB,EAAO,SAAS,EAAG,CACtC,IAAIyS,EAAc5M,EAClB,KAAI7G,EAAA4K,EAAQ,cAAc,IAAtB,KAAA,OAAA5K,EAAyB,QAAQ,SAAA,GAAa,EAChD,GAAI,CACG2M,EAAO,UACJhJ,GAAwB,SAAS,EAEzC8P,EAAc9G,EAAO,SAAS,OAAO9F,CAAc,CACrD,OAAS6M,EAAW,CAClB1S,EAAO,UACLpB,EACAoB,EAAO,UACP,YAAcgQ,EAAS,KACvB,mCAA2CnO,EAAa6Q,CAAS,CACnE,CACF,CAEF1S,EAAO,UACLpB,EACAoB,EAAO,UACP,YAAcgQ,EAAS,KACvB,YAAcF,GAAqB/B,EAAMxI,CAAM,EAAI,WAAakN,CAClE,CACF,CAEA,IAAME,EAAa,MAAMhH,EAAO,KAAK,GAAGqE,EAAQjC,EAAMnE,EAAS/D,EAAMN,CAAM,EAE3E,OAAIoN,EAAW,OAASjD,GAAK,WAAWiD,EAAW,KAAkB,GAEnE,MAAMhH,EAAO,KAAK,UAAU,KAAM,IAAI,EAE/BkG,GAAgBlG,EAAQ/B,EAASrE,EAAQiN,CAAS,GAGpD,CACL,IAAKG,EAAW,MAChB,KAAMA,EAAW,KACjB,QAASA,EAAW,QACpB,SAAUA,EAAW,SACrB,WAAYA,EAAW,UACzB,CACF,CAEA,IAAIxP,EAAS,MAAM0O,GAAmBlG,EAAQ/B,EAASrE,EAAQiN,CAAS,EAUxE,GARIF,IACFnP,EAAS4O,GAAW5O,EAAQwI,EAAO,SAAU2G,CAAQ,GAGnD1T,EAAO,UAAUoB,EAAO,SAAS,GACnC+P,GAAU5M,EAAQ6M,EAAQjC,EAAMxI,EAAQ3G,CAAM,EAG5C2T,EAAY,CACd,GAAIpP,EAAO,IACT,MAAMA,EAAO,IACR,CACL,IAAM8O,EAAqFzI,EAAA,CAAA,EAAKrG,CAAA,EAChG,cAAO8O,EAAS,IACTA,CACT,CACF,CAEA,OAAO9O,CACT,CACF,EAEOyP,GAAQR,GCpXf,SAASS,GAAaC,EAAiB,CACrC,IAAMC,EAAWD,EAAQ,MAAM,mBAAmB,EAClD,OAAOC,GAAYA,EAAS,CAAC,GAAWzQ,GAAiByQ,EAAS,CAAC,CAAC,CACtE,CAEA,SAASC,GAAcC,EAAoC,CACrD,OAAOA,GAAc,WAAUA,EAAaA,EAAW,MAAM,GAAG,GAEpE,IAAMC,EAAoD,CAAC,EAC3D,QAASpP,EAAI,EAAGA,EAAImP,EAAW,OAAQnP,IAAK,CAC1C,IAAMqP,EAAYF,EAAWnP,CAAC,EAAE,MAAM,4BAA4B,EAClE,GAAIqP,EAAW,CACb,IAAM5N,EAASsN,GAAaM,EAAU,CAAC,CAAC,EACpC5N,IAAQ2N,EAAUC,EAAU,CAAC,CAAC,EAAI5N,EACxC,CACF,CACA,OAAO2N,CACT,CAEA,SAASE,GAAclQ,EAAwB2C,EAAewN,EAAkB,CAK9E,MAAO,EAAEA,IAAWxN,GAAQ,OAAO3C,EAAI,MAAS,UAClD,CAEA,IAAMoQ,GAAN,KAAwB,CAQtB,YACE3H,EACAoC,EACAnE,EACA0I,EACAiB,EACAC,EACA,CACA,KAAK,OAAS7H,EACd,KAAK,KAAOoC,EACZ,KAAK,QAAUnE,EACf,KAAK,SAAW0I,GAAY,KAC5B,KAAK,YAAciB,EACnB,KAAK,yBAA2BC,GAA4B,EAC9D,CAEA,IAAI,QAAiB,CACnB,OAAO,KAAK,OAAO,MACrB,CAEA,MAAM,IAAYjO,EAA0D,CAC1E,IAAMpC,EAAS,MAAMyP,GAAS,IAAQ,KAAK,OAAQ,KAAK,KAAM,KAAK,QAASrN,EAAQ,KAAK,SAAU,EAAK,EACxG,OAAO,KAAK,WAAWpC,CAAM,CAC/B,CAEA,MAAM,OAAeoC,EAA0D,CAC7E,IAAMpC,EAAS,MAAMyP,GAAS,OAAW,KAAK,OAAQ,KAAK,KAAM,KAAK,QAASrN,EAAQ,KAAK,SAAU,EAAK,EAC3G,OAAO,KAAK,WAAWpC,CAAM,CAC/B,CAEA,MAAM,KAAaoC,EAA4BM,EAAwD,CACrG,IAAM1C,EAAS,MAAMyP,GAAS,KAAS,KAAK,OAAQ,KAAK,KAAM/M,EAAM,KAAK,QAASN,EAAQ,KAAK,SAAU,EAAK,EAC/G,OAAO,KAAK,WAAWpC,CAAM,CAC/B,CAEA,MAAM,IAAYoC,EAA4BM,EAAwD,CACpG,IAAM1C,EAAS,MAAMyP,GAAS,IAAQ,KAAK,OAAQ,KAAK,KAAM/M,EAAM,KAAK,QAASN,EAAQ,KAAK,SAAU,EAAK,EAC9G,OAAO,KAAK,WAAWpC,CAAM,CAC/B,CAEA,MAAM,MAAcoC,EAA4BM,EAAwD,CACtG,IAAM1C,EAAS,MAAMyP,GAAS,MAAU,KAAK,OAAQ,KAAK,KAAM/M,EAAM,KAAK,QAASN,EAAQ,KAAK,SAAU,EAAK,EAChH,OAAO,KAAK,WAAWpC,CAAM,CAC/B,CAEA,MAAM,WAAcA,EAAwD,CAC1E,GAAIA,EAAO,KAAOiQ,GAAcjQ,EAAO,IAAKA,EAAO,KAAM,KAAK,wBAAwB,EACpF,MAAAnD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,iCACA,4CAAoD6B,EAAasB,EAAO,GAAG,CAC7E,EACMA,EAAO,IAGf,IAAIsQ,EAAOR,EAAYC,EAEvB,GAAI,CACFO,EACEtQ,EAAO,YAAcoI,GAAgB,UACjC,CAAC,EACD,MAAM,KAAK,YAAYpI,EAAO,KAAMA,EAAO,SAAW,CAAC,EAAGA,EAAO,QAAQ,CACjF,OAASiE,EAAG,CAGV,MAAMjE,EAAO,KAAOiE,CACtB,CAMA,OAJIjE,EAAO,UAAY8P,EAAa9P,EAAO,QAAQ,MAAWA,EAAO,QAAQ,QAC3E+P,EAAYF,GAAcC,CAAU,GAGlC,KAAK,yBACA,IAAIS,GACT,KACAD,EACAtQ,EAAO,SAAW,CAAC,EACnBA,EAAO,WACP+P,EACA/P,EAAO,GACT,EAEO,IAAIwQ,GAAgB,KAAMF,EAAOP,CAAS,CAErD,CACF,EAEaS,GAAN,KAAyB,CAS9B,YAAYC,EAA6BH,EAAYP,EAAiC,CACpF,KAAK,SAAWU,EAChB,KAAK,MAAQH,EAEb,IAAMI,EAAO,KACTX,IACE,UAAWA,IACb,KAAK,MAAQ,gBAAkB,CAC7B,OAAOW,EAAK,IAAIX,EAAU,KAAK,CACjC,GAEE,YAAaA,IACf,KAAK,QAAU,gBAAkB,CAC/B,OAAOW,EAAK,IAAIX,EAAU,OAAO,CACnC,GAEF,KAAK,KAAO,gBAAkB,CAC5B,MAAI,SAAUA,EACLW,EAAK,IAAIX,EAAU,IAAI,EAEvB,IAEX,EAEA,KAAK,QAAU,UAAY,CACzB,MAAO,SAAUA,CACnB,EACA,KAAK,OAAS,IAAM,CAzK1B,IAAAlU,EA0KQ,MAAO,GAACA,EAAA,KAAK,UAAL,MAAAA,EAAA,KAAA,IAAA,EACV,EAEJ,CAIA,MAAM,IAAIuG,EAA0C,CAClD,IAAMN,EAAM,KAAK,SACX9B,EAAS,MAAMyP,GAAS,IAAO3N,EAAI,OAAQA,EAAI,KAAMA,EAAI,QAASM,EAAQN,EAAI,SAAU,EAAK,EACnG,OAAOA,EAAI,WAAW9B,CAAM,CAC9B,CACF,EAEauQ,GAAN,cAAuCC,EAAmB,CAO/D,YACEC,EACAH,EACA7J,EACAtG,EACA4P,EACAhQ,EACA,CACA,MAAM0Q,EAAUH,EAAOP,CAAS,EAChC,KAAK,WAAa5P,EAClB,KAAK,QAAUA,EAAa,KAAOA,GAAc,IACjD,KAAK,QAAUsG,EACf,KAAK,UAAY1G,GAAOA,EAAI,KAC5B,KAAK,aAAeA,GAAOA,EAAI,OACjC,CAEA,QAAS,CACP,MAAO,CACL,MAAO,KAAK,MACZ,WAAY,KAAK,WACjB,QAAS,KAAK,QACd,QAAS,KAAK,QACd,UAAW,KAAK,UAChB,aAAc,KAAK,YACrB,CACF,CACF,EAEO4Q,GAAQR,GClNTS,GAAN,MAAMA,EAAwB,CAS5B,QAAwC,CACtC,MAAO,CACL,QAAS,KAAK,QACd,SAAU,KAAK,SACf,SAAU,KAAK,QACjB,CACF,CAEA,UAAmB,CACjB,IAAI5Q,EAAS,2BACb,OAAI,KAAK,UAASA,GAAU,aAAe,KAAK,SAC5C,KAAK,WAAUA,GAAU,cAAgB,KAAK,UAC9C,KAAK,WAAUA,GAAU,cAAgB,KAAK,UAClDA,GAAU,IACHA,CACT,CAIA,OAAO,iBACL0C,EACAS,EACAC,EACqD,CAKrD,OAJIA,IACFV,EAAa1E,GAAW0E,EAAMS,EAASC,CAAM,GAG3C,MAAM,QAAQV,CAAI,EACbkO,GAAwB,gBAAgBlO,CAAI,EAE5CkO,GAAwB,WAAWlO,CAAI,CAElD,CAEA,OAAO,WAAWrC,EAA0D,CAC1E,OAAO,OAAO,OAAO,IAAIuQ,GAA2BvQ,CAAM,CAC5D,CAEA,OAAO,gBAAgBA,EAAmE,CACxF,IAAMgD,EAAQhD,EAAO,OACnBL,EAAS,IAAI,MAAMqD,CAAK,EAC1B,QAAS1C,EAAI,EAAGA,EAAI0C,EAAO1C,IAAKX,EAAOW,CAAC,EAAIiQ,GAAwB,WAAWvQ,EAAOM,CAAC,CAAC,EACxF,OAAOX,CACT,CACF,EAtDM4Q,GA0BG,cAAsB3S,GA1B/B,IAAM4S,GAAND,GAwDOE,GAAQD,GChDTE,GAAN,KAAW,CAMT,YAAYvI,EAAoB,CAvBlC,IAAA3M,EAwBI,KAAK,OAAS2M,EACd,KAAK,MAAQ,IAAIwI,GAAMxI,CAAM,EACzBrN,EAAS,OAAO,QAAQU,EAAA2M,EAAO,QAAQ,UAAf,MAAA3M,EAAwB,QAClD,KAAK,aAAe,IAAI2M,EAAO,QAAQ,QAAQ,KAAK,uBAAuBA,CAAM,EACjF,KAAK,YAAcA,EAAO,QAAQ,QAAQ,KAAK,mBAAmBiG,EAAa,EAEnF,CAEA,MAAM,SAASwC,EAAqCC,EAAoC,CACtF,MAAM,IAAI,QAAc,CAACrJ,EAAS1D,IAAW,CAjCjD,IAAAtI,EAkCM,GAAI,GAACA,EAAA,KAAK,OAAO,QAAQ,UAApB,MAAAA,EAA6B,MAAM,CACtCsI,EAAarG,GAAyB,MAAM,CAAC,EAC7C,MACF,CACA,GAAI,CAAC,KAAK,aAAc,CACtBqG,EAAO,IAAIxJ,EAAU,mEAAoE,IAAO,GAAG,CAAC,EACpG,MACF,CACA,GAAI,KAAK,aAAa,kBAAmB,CACvCwJ,EAAO,IAAIxJ,EAAU,iCAAkC,IAAO,GAAG,CAAC,EAClE,MACF,CACA,KAAK,aAAa,kBAAqBoF,GAAmB,CACxD,GAAIA,EAAK,CACPoE,EAAOpE,CAAG,EACV,MACF,CACA8H,EAAQ,CACV,EACA,KAAK,aAAa,qBAAuBqJ,EACzC,KAAK,aAAa,YAChB,IAAI,KAAK,OAAO,QAAQ,QAAQ,KAAK,eAAe,KAAK,aAAcD,CAAgB,CACzF,CACF,CAAC,CACH,CAEA,MAAM,WAAWE,EAAwC,CACvD,MAAM,IAAI,QAAc,CAACtJ,EAAS1D,IAAW,CA7DjD,IAAAtI,EA8DM,GAAI,GAACA,EAAA,KAAK,OAAO,QAAQ,UAApB,MAAAA,EAA6B,MAAM,CACtCsI,EAAarG,GAAyB,MAAM,CAAC,EAC7C,MACF,CACA,GAAI,CAAC,KAAK,aAAc,CACtBqG,EAAO,IAAIxJ,EAAU,mEAAoE,IAAO,GAAG,CAAC,EACpG,MACF,CACA,GAAI,KAAK,aAAa,oBAAqB,CACzCwJ,EAAO,IAAIxJ,EAAU,mCAAoC,IAAO,GAAG,CAAC,EACpE,MACF,CACA,KAAK,aAAa,oBAAuBoF,GAAmB,CAC1D,GAAIA,EAAK,CACPoE,EAAOpE,CAAG,EACV,MACF,CACA8H,EAAQ,CACV,EACA,KAAK,aAAa,YAChB,IAAI,KAAK,OAAO,QAAQ,QAAQ,KAAK,iBAAiB,KAAK,aAAcsJ,CAAkB,CAC7F,CACF,CAAC,CACH,CACF,EAEMH,GAAN,KAAY,CAKV,YAAYxI,EAAoB,CAC9B,KAAK,OAASA,EACd,KAAK,oBAAsB,IAAI4I,GAAoB5I,CAAM,EACzD,KAAK,qBAAuB,IAAI6I,GAAqB7I,CAAM,CAC7D,CAEA,MAAM,QAAQ8I,EAAgBC,EAA6B,CACzD,IAAM/I,EAAS,KAAK,OACdpF,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OAC5B/B,EAAUc,EAAS,mBAAmBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAChEhB,EAAS,CAAC,EACNM,EAAaxD,EAAM,CAAE,UAAAoS,CAAqB,EAAGC,CAAO,EAEpDrS,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEvCA,EAAO,QAAQ,cAAoBtJ,EAAMkD,EAAQ,CAAE,SAAU,MAAO,CAAC,EAEzE,IAAMoP,EAAoBvT,GAAWyE,EAAM8F,EAAO,SAAUpF,CAAM,EAClE,MAAMqM,GAAS,KAAKjH,EAAQ,gBAAiBgJ,EAAa/K,EAASrE,EAAQ,KAAM,EAAI,CACvF,CACF,EAEMgP,GAAN,KAA0B,CAGxB,YAAY5I,EAAoB,CAC9B,KAAK,OAASA,CAChB,CAEA,MAAM,KAAKgG,EAAqC,CAC9C,IAAMhG,EAAS,KAAK,OACd9F,EAAO+L,GAAc,WAAWD,CAAM,EACtCpL,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OAC5B/B,EAAUc,EAAS,mBAAmBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAChEhB,EAAS,CAAC,EAENlD,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEvCA,EAAO,QAAQ,cAAoBtJ,EAAMkD,EAAQ,CAAE,SAAU,MAAO,CAAC,EAEzE,IAAMoP,EAAoBvT,GAAWyE,EAAM8F,EAAO,SAAUpF,CAAM,EAC5D0L,EAAW,MAAMW,GAAS,IAC9BjH,EACA,6BAA+B,mBAAmBgG,EAAO,EAAE,EAC3DgD,EACA/K,EACArE,EACA,KACA,EACF,EAEA,OAAOqM,GAAc,iBACnBK,EAAS,KACTtG,EAAO,SACPsG,EAAS,SAAW,OAAY1L,CAClC,CACF,CAEA,MAAM,IAAIqO,EAAgD,CACxD,IAAMjJ,EAAS,KAAK,OAClBpF,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB/B,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAC/DsO,EAAWD,EAAkB,IAAMA,EAErC,GAAI,OAAOC,GAAa,UAAY,CAACA,EAAS,OAC5C,MAAM,IAAI/W,EACR,uFACA,IACA,GACF,EAGIuE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAE3C,IAAMsG,EAAW,MAAMW,GAAS,IAC9BjH,EACA,6BAA+B,mBAAmBkJ,CAAQ,EAC1DjL,EACA,CAAC,EACD,KACA,EACF,EAEA,OAAOgI,GAAc,iBACnBK,EAAS,KACTtG,EAAO,SACPsG,EAAS,SAAW,OAAY1L,CAClC,CACF,CAEA,MAAM,KAAKhB,EAAgD,CACzD,IAAMoG,EAAS,KAAK,OAClBpF,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB2G,EAAW,KAAK,OAAO,KAAK,oBAAsB,OAAY/L,EAC9DqD,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAE3D,OAAAlE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEpC,IAAImI,GAAkBnI,EAAQ,4BAA6B/B,EAAS0I,EAAU,eACnFzM,EACA+D,EACA4E,EACA,CACA,OAAOoD,GAAc,iBACnB/L,EACA8F,EAAO,SACP6C,EAAW,OAAYjI,CACzB,CACF,CAAC,EAAE,IAAIhB,CAAM,CACf,CAEA,MAAM,OAAOqP,EAAuC,CAClD,IAAMjJ,EAAS,KAAK,OAClBpF,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB/B,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAC/DhB,EAAS,CAAC,EACVsP,EAAWD,EAAkB,IAAMA,EAErC,GAAI,OAAOC,GAAa,UAAY,CAACA,EAAS,OAC5C,MAAM,IAAI/W,EACR,0FACA,IACA,GACF,EAGIuE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEvCA,EAAO,QAAQ,cAAoBtJ,EAAMkD,EAAQ,CAAE,SAAU,MAAO,CAAC,EAEzE,MAAMqN,GAAS,OACbjH,EACA,6BAA+B,mBAAmBkJ,CAAQ,EAC1DjL,EACArE,EACA,KACA,EACF,CACF,CAEA,MAAM,YAAYA,EAA4B,CAC5C,IAAMoG,EAAS,KAAK,OAClBpF,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB/B,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAE3DlE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEvCA,EAAO,QAAQ,cAAoBtJ,EAAMkD,EAAQ,CAAE,SAAU,MAAO,CAAC,EAEzE,MAAMqN,GAAS,OAAUjH,EAAQ,4BAA6B/B,EAASrE,EAAQ,KAAM,EAAI,CAC3F,CACF,EAEMiP,GAAN,MAAMM,EAAqB,CAGzB,YAAYnJ,EAAoB,CAmEhC,KAAA,OAASmJ,GAAqB,UAAU,YAlEtC,KAAK,OAASnJ,CAChB,CAEA,MAAM,KAAKoJ,EAAyE,CAClF,IAAMpJ,EAAS,KAAK,OACd9F,EAAOoO,GAAwB,WAAWc,CAAY,EACtDxO,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OAC5B/B,EAAUc,EAAS,mBAAmBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAChEhB,EAAS,CAAC,EAENlD,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEvCA,EAAO,QAAQ,cAAoBtJ,EAAMkD,EAAQ,CAAE,SAAU,MAAO,CAAC,EAEzE,IAAMoP,EAAoBvT,GAAWyE,EAAM8F,EAAO,SAAUpF,CAAM,EAC5D0L,EAAW,MAAMW,GAAS,KAC9BjH,EACA,6BACAgJ,EACA/K,EACArE,EACA,KACA,EACF,EAEA,OAAO0O,GAAwB,iBAC7BhC,EAAS,KACTtG,EAAO,SACPsG,EAAS,SAAW,OAAY1L,CAClC,CACF,CAEA,MAAM,KAAKhB,EAAgD,CACzD,IAAMoG,EAAS,KAAK,OAClBpF,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB2G,EAAW,KAAK,OAAO,KAAK,oBAAsB,OAAY/L,EAC9DqD,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAE3D,OAAAlE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEpC,IAAImI,GAAkBnI,EAAQ,6BAA8B/B,EAAS0I,EAAU,eACpFzM,EACA+D,EACA4E,EACA,CACA,OAAOyF,GAAwB,iBAC7BpO,EACA8F,EAAO,SACP6C,EAAW,OAAYjI,CACzB,CACF,CAAC,EAAE,IAAIhB,CAAM,CACf,CAEA,MAAM,YAAYA,EAA4B,CAC5C,IAAMoG,EAAS,KAAK,OAClBpF,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB/B,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAE3DlE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEvCA,EAAO,QAAQ,cAAoBtJ,EAAMkD,EAAQ,CAAE,SAAU,MAAO,CAAC,EAEzE,MAAMqN,GAAS,OAAUjH,EAAQ,6BAA8B/B,EAASrE,EAAQ,KAAM,EAAI,CAC5F,CAKA,MAAM,aAAaA,EAAgD,CACjE,IAAMoG,EAAS,KAAK,OAClBpF,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB2G,EAAW,KAAK,OAAO,KAAK,oBAAsB,OAAY/L,EAC9DqD,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAE3D,OAAAlE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEvCA,EAAO,QAAQ,cAAoBtJ,EAAMkD,EAAQ,CAAE,SAAU,MAAO,CAAC,EAElE,IAAIuO,GAAkBnI,EAAQ,iBAAkB/B,EAAS0I,EAAU,eAAgBzM,EAAM+D,EAAS4E,EAAU,CACjH,IAAMwG,EACJ,CAACxG,GAAYjI,EAAepF,GAAW0E,EAAM8F,EAAO,SAAUpF,CAAM,EAAIV,EAG1E,QAAS/B,EAAI,EAAGA,EAAIkR,EAAW,OAAQlR,IACrCkR,EAAWlR,CAAC,EAAI,OAAOkR,EAAWlR,CAAC,CAAC,EAEtC,OAAOkR,CACT,CAAC,EAAE,IAAIzP,CAAM,CACf,CACF,EAEO0P,GAAQf,GCtUTgB,GAA0C,CAC9C,gBACA,iBACA,iBACA,iBACA,oBACA,oBACA,gBACF,EAEMC,GAAmB,IAAI,IAA+BD,GAAmB,IAAI,CAACxV,EAAQ0V,IAAU,CAAC1V,EAAQ0V,CAAK,CAAC,CAAC,EAEhHC,GAA0B,IAAI,IAClCH,GAAmB,IAAI,CAACxV,EAAQ0V,IAAU,CAACA,EAAO1V,CAAM,CAAC,CAC3D,EAEA,SAAS4V,GAAsBC,EAAqD,CAClF,OAAOF,GAAwB,IAAIE,CAAY,CACjD,CAEA,SAASC,GAAsBC,EAAuD,CACpF,OAAOA,EAAgBN,GAAiB,IAAIM,CAAa,EAAI,MAC/D,CA2BA,SAASC,GAAiBC,EAA4F,CACpH,MAAI,CAACA,GAAW,CAAEA,EAAoC,eAC7C,CACL,eAAgBA,EAChB,QAAS,CAAC,EACV,2BAA4B,MAC9B,EAEKA,CACT,CAEO,SAASC,GACdzL,EACAvL,EACAyJ,EACgB,CAChB,GAAIA,GAAWA,EAAQ,OAAQ,CACxB8B,GAAcxH,GAAwB,QAAQ,EACnD,IAAM0H,EAASF,EAAO,UAAU9B,EAAQ,OAAQzJ,CAAM,EACtD,MAAO,CACL,OAAQyL,EAAO,aACf,cAAeA,EAAO,MACxB,CACF,CACA,OAAOhC,GAAW,CAAC,CACrB,CAEA,SAASwN,GAAehX,EAAc,CACpC,IAAIiX,EAAO,EACX,OAAIjX,EAAI,OACNiX,GAAQjX,EAAI,KAAK,QAEfA,EAAI,WACNiX,GAAQjX,EAAI,SAAS,QAEnBA,EAAI,SACNiX,GAAQ,KAAK,UAAUjX,EAAI,MAAM,EAAE,QAEjCA,EAAI,OACNiX,GAAc5U,GAAcrC,EAAI,IAAI,GAE/BiX,CACT,CAEA,eAAsBC,GACpBnX,EACAuL,EACA6L,EACAC,EACkB,CAClB,IAAMpX,EAAMqX,GAAiBF,CAAO,EAC9B3N,EAAUuN,GAAuBzL,EAAQvL,EAAQqX,GAAgB,IAAI,EAG3E,GAAI,CACF,MAAME,GAAOtX,EAAKwJ,CAAO,CAC3B,OAASjB,EAAG,CACVpH,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,wBAA0BoH,EAAY,SAAS,CAAC,CAC7F,CACA,OAAOvI,CACT,CAEA,eAAsBuX,GACpBxX,EACAuL,EACAkM,EACAhO,EACoB,CACpB,OAAO,QAAQ,IACbgO,EAAa,IAAI,SAAUL,EAAS,CAClC,OAAOD,GAAYnX,EAAQuL,EAAQ6L,EAAS3N,CAAO,CACrD,CAAC,CACH,CACF,CAIA,eAAsBiO,GAAaN,EAA8BO,EAAoC,CACnG,IAAM1X,EAAMqX,GAAiBF,CAAO,EACpC,GAAI,CACF,MAAMG,GAAOtX,EAAK0X,EAAQ,cAAc,CAC1C,OAASnP,EAAG,CACVpH,EAAO,UAAUuW,EAAQ,OAAQvW,EAAO,UAAW,yBAA2BoH,EAAY,SAAS,CAAC,CACtG,CACA,OAAOvI,CACT,CAEA,eAAsB2X,GAAkBH,EAAqCE,EAAsC,CACjH,OAAO,QAAQ,IACbF,EAAa,IAAI,SAAUL,EAAS,CAClC,OAAOM,GAAaN,EAASO,CAAO,CACtC,CAAC,CACH,CACF,CAEA,eAAeE,GAA6C5X,EAAQwJ,EAAoC,CACtG,IAAIvC,EAAOjH,EAAI,KACb6X,EAAW7X,EAAI,SACfwL,EAAShC,EAAQ,cAEnBqO,EAAWA,EAAWA,EAAW,IAAM,GAClCpY,EAAS,YAAY,SAASwH,CAAI,IACrCA,EAAOxH,EAAS,YAAY,WAAW,OAAOwH,CAAI,CAAC,EACnD4Q,EAAWA,EAAW,UAExB,IAAMC,EAAa,MAAMtM,EAAO,QAAQvE,CAAI,EAC5C,OAAAjH,EAAI,KAAO8X,EACX9X,EAAI,SAAW6X,EAAW,UAAYrM,EAAO,UACtCxL,CACT,CAEA,eAAsB+X,GAA4C/X,EAAQwJ,EAAoC,CAC5G,IAAMvC,EAAOjH,EAAI,KAIjB,GAAI,EAFF,OAAOiH,GAAQ,UAAYxH,EAAS,YAAY,SAASwH,CAAI,GAAKA,IAAS,MAAQA,IAAS,QAG5F,GAAU5D,GAAS4D,CAAI,GAAK,MAAM,QAAQA,CAAI,EAC5CjH,EAAI,KAAO,KAAK,UAAUiH,CAAI,EAC9BjH,EAAI,SAAWA,EAAI,SAAWA,EAAI,SAAW,QAAU,WAEvD,OAAM,IAAIf,EAAU,2BAA4B,MAAO,GAAG,EAI9D,OAAIuK,GAAW,MAAQA,EAAQ,OACtBoO,GAAQ5X,EAAKwJ,CAAO,EAEpBxJ,CAEX,CAEA,eAAsBgY,GAAYC,EAA0BzO,EAAiD,CAC3G,OAAO,QAAQ,IAAIyO,EAAS,IAAKnX,GAAYiX,GAAOjX,EAAS0I,CAAO,CAAC,CAAC,CACxE,CAEO,IAAM0O,GAAkB3V,GAE/B,eAAsB+U,GACpBxW,EACAqX,EACe,CACf,IAAMrB,EAAUD,GAAiBsB,CAAY,EAEzCC,EAActX,EAAQ,KACpB+W,EAAW/W,EAAQ,SACzB,GAAI+W,EAAU,CACZ,IAAMQ,EAASR,EAAS,MAAM,GAAG,EAC7BS,EACFC,EAAqBF,EAAO,OAC5BpR,EAAOnG,EAAQ,KAEb0X,EAAQ,GACZ,GAAI,CACF,MAAQF,EAA6BC,GAAsB,GAAG,CAE5D,IAAM1R,EAAQwR,EAAO,EAAEE,CAAkB,EAAE,MAAM,uBAAuB,EACxE,GAAI,CAAC1R,EAAO,MAEZ,OADA2R,EAAQ3R,EAAM,CAAC,EACP2R,EAAO,CACb,IAAK,SACHvR,EAAOxH,EAAS,YAAY,aAAa,OAAOwH,CAAI,CAAC,EACjDqR,GAA8BD,EAAO,SACvCD,EAAcnR,GAEhB,SACF,IAAK,QACHA,EAAOxH,EAAS,YAAY,WAAWwH,CAAI,EAC3C,SACF,IAAK,OACHA,EAAO,KAAK,MAAMA,CAAI,EACtB,SACF,IAAK,SACH,GACE6P,EAAQ,gBAAkB,MAC1BA,EAAQ,eAAe,QACvBA,EAAQ,eAAe,cACvB,CACA,IAAM2B,EAAiB5R,EAAM,CAAC,EAC5B2E,EAASsL,EAAQ,eAAe,cAElC,GAAI2B,GAAkBjN,EAAO,UAC3B,MAAM,IAAI,MAAM,yEAAyE,EAE3FvE,EAAO,MAAMuE,EAAO,QAAQvE,CAAI,EAChC,QACF,KACE,OAAM,IAAI,MAAM,qDAAqD,EAEzE,IAAK,SACH,GAAI,CAAC6P,EAAQ,SAAW,CAACA,EAAQ,QAAQ,OACvC,MAAM,IAAI7X,EAAU,wEAAyE,MAAO,GAAG,EAEzG,GAAI,OAAO,WAAe,IACxB,MAAM,IAAIA,EACR,+EACA,MACA,GACF,EAEF,GAAI,CACF,IAAIyZ,EAAY5B,EAAQ,2BACpB,OAAO4B,GAAc,WACvBA,EAAYjZ,EAAS,YAAY,WAAWiZ,CAAS,GAIvD,IAAMC,EAAkBlZ,EAAS,YAAY,SAASiZ,CAAmB,EACzEzR,EAAOxH,EAAS,YAAY,SAASwH,CAAI,EAEzCA,EAAOxH,EAAS,YAAY,wBAAwBqX,EAAQ,QAAQ,OAAO,OAAO7P,EAAM0R,CAAe,CAAC,EACxGP,EAAcnR,CAChB,OAASsB,EAAG,CACV,MAAM,IAAItJ,EAAU,mCAAqCsJ,EAAG,MAAO,GAAG,CACxE,CACA,SACF,QACE,MAAM,IAAI,MAAM,kBAAkB,CACtC,CACF,CACF,OAASA,EAAG,CACV,IAAMlE,EAAMkE,EACZ,MAAM,IAAItJ,EACR,wBAA0BuZ,EAAQ,qCAAkCnU,EAAI,QAAU,SAClFA,EAAI,MAAQ,MACZ,GACF,CACF,QAAA,CACEvD,EAAQ,SACLwX,GAAyC,EAAI,KAAOD,EAAO,MAAM,EAAGC,CAA0B,EAAE,KAAK,GAAG,EAC3GxX,EAAQ,KAAOmG,CACjB,CACF,CACA6P,EAAQ,2BAA6BsB,CACvC,CAEO,SAASQ,GAAWjU,EAAsC,CAC/D,OAAO,OAAO,OAAO,IAAIkU,GAAWlU,CAAM,CAC5C,CAEO,SAAS0S,GAAiB1S,EAAsC,CACrE,IAAM9D,EAAS4V,GAAsB9R,EAAO,MAAgB,GAAKA,EAAO,OAClEyB,EAAM,OAAO,OAAO,IAAIyS,GAAWnO,EAAAC,EAAA,CAAA,EAAKhG,CAAA,EAAL,CAAa,OAAA9D,CAAO,CAAA,CAAC,EAC9D,OAAAuF,EAAI,aAAa,EACVA,CACT,CAEO,SAAS0S,GAAgBnU,EAA0C,CACxE,OAAOA,EAAO,IAAIiU,EAAU,CAC9B,CAIO,SAASG,GAAgBd,EAA6B,CAC3D,IAAIjY,EACFgZ,EAAQ,EACV,QAAS,EAAI,EAAG,EAAIf,EAAS,OAAQ,IACnCjY,EAAMiY,EAAS,CAAC,EAChBe,GAAShZ,EAAI,OAASA,EAAI,KAAOgX,GAAehX,CAAG,GAErD,OAAOgZ,CACT,CAEA,IAAMH,GAAN,KAAc,CAuBZ,QAAS,CAIP,IAAIhB,EAAW,KAAK,SAChB5Q,EAAO,KAAK,KAChB,OAAIA,GAAQxH,EAAS,YAAY,SAASwH,CAAI,IACxC,UAAU,OAAS,GAErB4Q,EAAWA,EAAWA,EAAW,UAAY,SAC7C5Q,EAAOxH,EAAS,YAAY,aAAawH,CAAI,GAK7CA,EAAOxH,EAAS,YAAY,SAASwH,CAAI,GAGtC,CACL,KAAM,KAAK,KACX,GAAI,KAAK,GACT,SAAU,KAAK,SACf,aAAc,KAAK,aACnB,cAAe,KAAK,cACpB,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,OAAQ0P,GAAsB,KAAK,MAA2B,GAAK,KAAK,OACxE,UAAW,KAAK,UAChB,QAAS,KAAK,QACd,UAAW,KAAK,UAChB,QAAS,KAAK,QACd,UAAW,KAAK,UAChB,SAAAkB,EACA,KAAA5Q,CACF,CACF,CAEA,cAAe,CACT,KAAK,SAAW,mBAEd,KAAK,SAAW,CAAC,KAAK,SACxB,KAAK,OAAS,KAAK,SAGjB,KAAK,WAAa,CAAC,KAAK,YAC1B,KAAK,UAAY,KAAK,WAG5B,CAEA,UAAmB,CACjB,IAAI3C,EAAS,WACb,OAAI,KAAK,OAAMA,GAAU,UAAY,KAAK,MACtC,KAAK,KAAIA,GAAU,QAAU,KAAK,IAClC,KAAK,YAAWA,GAAU,eAAiB,KAAK,WAChD,KAAK,WAAUA,GAAU,cAAgB,KAAK,UAC9C,KAAK,eAAcA,GAAU,kBAAoB,KAAK,cACtD,KAAK,WAAUA,GAAU,cAAgB,KAAK,UAC9C,KAAK,SAAQA,GAAU,aAAe,KAAK,UAAU,KAAK,MAAM,GAChE,KAAK,OACH,OAAO,KAAK,MAAQ,SAAUA,GAAU,UAAY,KAAK,KACpD7E,EAAS,YAAY,SAAS,KAAK,IAAI,EAC9C6E,GAAU,mBAAqB7E,EAAS,YAAY,aAAa,KAAK,IAAI,EACvE6E,GAAU,iBAAmB,KAAK,UAAU,KAAK,IAAI,GAExD,KAAK,SAAQA,GAAU,YAAc,KAAK,UAAU,KAAK,MAAM,GAE/D,KAAK,SAAQA,GAAU,YAAc,KAAK,QAC1C,KAAK,SAAQA,GAAU,YAAc,KAAK,QAC1C,KAAK,UAASA,GAAU,aAAe,KAAK,SAC5C,KAAK,YAAWA,GAAU,eAAiB,KAAK,WAChD,KAAK,UAASA,GAAU,aAAe,KAAK,SAC5C,KAAK,YAAWA,GAAU,eAAiB,KAAK,WAChD,KAAK,YAAWA,GAAU,eAAiB,KAAK,UAAU,KAAK,SAAS,GAC5EA,GAAU,IACHA,CACT,CACF,EAEO2U,GAAQJ,GClaTK,GAAU,CAAC,SAAU,UAAW,QAAS,QAAS,QAAQ,EAIhE,SAASC,GAAcC,EAAsB,CAC3C,OAAOF,GAAQ,QAAQE,CAAY,CACrC,CAEA,eAAsBlC,GACpBnX,EACAuL,EACA6L,EACAC,EAC0B,CAC1B,IAAMpX,EAAMqX,GAAiBF,CAAO,EAC9B3N,EAAUuN,GAAuBzL,EAAQvL,EAAQqX,GAAgB,IAAI,EAG3E,GAAI,CACF,MAAME,GAAOtX,EAAKwJ,GAAW,CAAC,CAAC,CACjC,OAASjB,EAAG,CACVpH,EAAO,UAAUpB,EAAQoB,EAAO,UAAW,gCAAkCoH,EAAY,SAAS,CAAC,CACrG,CACA,OAAOvI,CACT,CAEA,eAAsBuX,GACpBxX,EACAuL,EACAkM,EACAhO,EAC4B,CAC5B,OAAO,QAAQ,IACbgO,EAAa,IAAI,SAAUL,EAAS,CAClC,OAAOD,GAAYnX,EAAQuL,EAAQ6L,EAAS3N,CAAO,CACrD,CAAC,CACH,CACF,CAIA,eAAsBiO,GAAaN,EAAsCO,EAA4C,CACnH,IAAM1X,EAAMqX,GAAiBF,CAAO,EACpC,GAAI,CACF,MAAMG,GAAOtX,EAAK0X,EAAQ,cAAc,CAC1C,OAASnP,EAAG,CACVpH,EAAO,UAAUuW,EAAQ,OAAQvW,EAAO,UAAW,iCAAmCoH,EAAY,SAAS,CAAC,CAC9G,CACA,OAAOvI,CACT,CAEA,eAAsB2X,GACpBH,EACAE,EAC4B,CAC5B,OAAO,QAAQ,IACbF,EAAa,IAAI,SAAUL,EAAS,CAClC,OAAOM,GAAaN,EAASO,CAAO,CACtC,CAAC,CACH,CACF,CAEO,SAASkB,GAAWjU,EAAsD,CAC/E,OAAO,OAAO,OAAO,IAAI0U,GAAmB1U,CAAM,CACpD,CAEO,SAAS0S,GAAiB1S,EAAsD,CACrF,IAAM9D,EAASqY,GAAQvU,EAAO,MAAM,EACpC,OAAO,OAAO,OAAO,IAAI0U,GAAmB3O,EAAAC,EAAA,CAAA,EAAKhG,CAAA,EAAL,CAAa,OAAA9D,CAAO,CAAA,CAAC,CACnE,CAGO,IAAMyW,GAASA,GAEf,SAASwB,GAAgBnU,EAA0D,CACxF,OAAOA,EAAO,IAAIiU,EAAU,CAC9B,CAEO,SAASU,GAASrS,EAA4B,CACnD,OAAIA,aAAgBoS,GACXpS,EAEF2R,GAAW,CAChB,KAAA3R,CACF,CAAC,CACH,CAIA,IAAMoS,GAAN,KAAsB,CAgBpB,eAAyB,CACvB,MAAI,CAAC,KAAK,IAAM,CAAC,KAAK,aACb,GAEF,KAAK,GAAG,UAAU,KAAK,aAAa,OAAQ,CAAC,IAAM,KAAK,YACjE,CAGA,SAAsE,CACpE,GAAI,CAAC,KAAK,GAAI,MAAM,IAAI,MAAM,oDAAoD,EAClF,IAAM1S,EAAQ,KAAK,GAAG,MAAM,GAAG,EAC/B,MAAO,CACL,aAAcA,EAAM,CAAC,EACrB,UAAW,SAASA,EAAM,CAAC,EAAG,EAAE,EAChC,MAAO,SAASA,EAAM,CAAC,EAAG,EAAE,CAC9B,CACF,CAMA,QAOE,CAIA,IAAIM,EAAO,KAAK,KACZ4Q,EAAW,KAAK,SACpB,OAAI5Q,GAAQxH,EAAS,YAAY,SAASwH,CAAI,IACxC,UAAU,OAAS,GAErB4Q,EAAWA,EAAWA,EAAW,UAAY,SAC7C5Q,EAAOxH,EAAS,YAAY,aAAawH,CAAI,GAK7CA,EAAOxH,EAAS,YAAY,SAASwH,CAAI,GAGtC,CACL,GAAI,KAAK,GACT,SAAU,KAAK,SAEf,OAAQkS,GAAc,KAAK,MAAgB,EAC3C,KAAAlS,EACA,SAAA4Q,EACA,OAAQ,KAAK,MACf,CACF,CAEA,UAAmB,CACjB,IAAIvT,EAAS,mBACb,OAAAA,GAAU,YAAc,KAAK,OACzB,KAAK,KAAIA,GAAU,QAAU,KAAK,IAClC,KAAK,YAAWA,GAAU,eAAiB,KAAK,WAChD,KAAK,WAAUA,GAAU,cAAgB,KAAK,UAC9C,KAAK,eAAcA,GAAU,kBAAoB,KAAK,cACtD,KAAK,WAAUA,GAAU,cAAgB,KAAK,UAC9C,KAAK,OACH,OAAO,KAAK,MAAQ,SAAUA,GAAU,UAAY,KAAK,KACpD7E,EAAS,YAAY,SAAS,KAAK,IAAI,EAC9C6E,GAAU,mBAAqB7E,EAAS,YAAY,aAAa,KAAK,IAAI,EACvE6E,GAAU,iBAAmB,KAAK,UAAU,KAAK,IAAI,GAExD,KAAK,SACPA,GAAU,YAAc,KAAK,UAAU,KAAK,MAAM,GAEpDA,GAAU,IACHA,CACT,CACF,EAEOiV,GAAQF,GC7LTG,GAAN,KAAmB,CAGjB,YAAY9B,EAAsB,CAChC,KAAK,QAAUA,CACjB,CAEA,IAAI,QAAiB,CACnB,OAAO,KAAK,QAAQ,MACtB,CAEA,MAAM,IAAIhR,EAAwD,CAChEvF,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,qBAAsB,aAAe,KAAK,QAAQ,IAAI,EACtG,IAAM2L,EAAS,KAAK,QAAQ,OAC1BpF,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB2G,EAAW,KAAK,QAAQ,OAAO,KAAK,oBAAsB,OAAY/L,EACtEqD,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAE3D,OAAAlE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEpC,IAAImI,GACTnI,EACA,KAAK,QAAQ,OAAO,KAAK,cAAc,SAAS,IAAI,EACpD/B,EACA0I,EACA,MAAOzM,EAAM+D,EAAS4E,IAAa,CACjC,IAAM8J,EAAyC9J,EAC1C3I,EACK1E,GAAW0E,EAAM8F,EAAO,SAAUpF,CAAM,EAElD,OAAOiQ,GAAkB8B,EAAS,KAAK,OAAO,CAChD,CACF,EAAE,IAAI/S,CAAM,CACd,CAEA,MAAM,QAAQA,EAAwD,CACpE,OAAAvF,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,yBAA0B,aAAe,KAAK,QAAQ,IAAI,EACnG,KAAK,QAAQ,OAAO,KAAK,cAAc,QAAQ,KAAMuF,CAAM,CACpE,CACF,EAEOgT,GAAQF,GC1BTG,GAAuB,EAE7B,SAASC,GAAY3B,EAA0B,CAC7C,OAAOA,EAAS,MAAM,SAAUnX,EAAkB,CAChD,MAAO,CAACA,EAAQ,EAClB,CAAC,CACH,CAEA,IAAM+Y,GAAN,KAAkB,CAOhB,YAAY/M,EAAkBhF,EAAcyD,EAAiC,CArC/E,IAAApL,EAAA4G,EAsCI5F,EAAO,UAAU2L,EAAO,OAAQ3L,EAAO,UAAW,gBAAiB,mBAAqB2G,CAAI,EAC5F,KAAK,KAAOA,EACZ,KAAK,OAASgF,EACd,KAAK,SAAW,IAAI4M,GAAa,IAAI,EACrC,KAAK,eAAiBrO,IAAwBlL,EAAA2M,EAAO,UAAP,KAAA3M,EAAkB,KAAM,KAAK,OAAQoL,CAAc,GAC7FxE,EAAA+F,EAAO,QAAQ,UAAf,MAAA/F,EAAwB,OAC1B,KAAK,MAAQ,IAAI+F,EAAO,QAAQ,QAAQ,KAAK,YAAY,IAAI,EAEjE,CAEA,IAAI,MAAO,CACT,OAAK,KAAK,OACFhJ,GAAwB,MAAM,EAE/B,KAAK,KACd,CAEA,IAAI,QAAiB,CACnB,OAAO,KAAK,OAAO,MACrB,CAEA,WAAW0F,EAAgC,CA3D7C,IAAArJ,EA4DI,KAAK,eAAiBkL,IAAwBlL,EAAA,KAAK,OAAO,UAAZ,KAAAA,EAAuB,KAAM,KAAK,OAAQqJ,CAAO,CACjG,CAEA,MAAM,QAAQ9C,EAAqE,CACjF,OAAAvF,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,wBAAyB,aAAe,KAAK,IAAI,EAC1F,KAAK,OAAO,KAAK,aAAa,QAAQ,KAAMuF,CAAM,CAC3D,CAEA,MAAM,WAAWpG,EAA4B,CAC3C,IAAMkG,EAAQlG,EAAK,CAAC,EAClBwZ,EAASxZ,EAAK,CAAC,EACb2X,EACAvR,EAEJ,GAAI,OAAOF,GAAU,UAAYA,IAAU,KAEzCyR,EAAW,CAACW,GAAkB,CAAE,KAAMpS,EAAO,KAAMsT,CAAO,CAAC,CAAC,EAC5DpT,EAASpG,EAAK,CAAC,UACA+C,GAASmD,CAAK,EAC7ByR,EAAW,CAACW,GAAkBpS,CAAK,CAAC,EACpCE,EAASpG,EAAK,CAAC,UACN,MAAM,QAAQkG,CAAK,EAC5ByR,EAAWa,GAAwBtS,CAAK,EACxCE,EAASpG,EAAK,CAAC,MAEf,OAAM,IAAIrB,EACR,gGACA,MACA,GACF,EAGGyH,IAEHA,EAAS,CAAC,GAGZ,IAAMoG,EAAS,KAAK,OAClBtD,EAAUsD,EAAO,QACjBpF,EAAS8B,EAAQ,kBAAA,UAAA,OACjBuQ,EAA2BjN,EAAO,QAAQ,yBAC1C/B,EAAUc,EAAS,mBAAmBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAIlE,GAFMlE,EAAMuH,EAASvB,EAAQ,OAAO,EAEhCuQ,GAA4BH,GAAY3B,CAAQ,EAAG,CACrD,IAAM+B,EAAY,MAAYrW,GAAagW,EAAoB,EAC/D1B,EAAS,QAAQ,SAAUnX,EAASyV,EAAO,CACzCzV,EAAQ,GAAKkZ,EAAY,IAAMzD,EAAM,SAAS,CAChD,CAAC,CACH,CAEA,MAAMyB,GAAoBC,EAAU,KAAK,cAA+B,EAGxE,IAAMhB,EAAO8B,GAAgBd,CAAQ,EACnCgC,EAAiBzQ,EAAQ,eAC3B,GAAIyN,EAAOgD,EACT,MAAM,IAAIhb,EACR,yEACEgY,EACA,oBACAgD,EACA,UACF,MACA,GACF,EAGF,MAAM,KAAK,SAAS/B,GAAiBD,EAAUnL,EAAO,SAAUpF,CAAM,EAAGqD,EAASrE,CAAM,CAC1F,CAEA,MAAM,SAASoP,EAAiC/K,EAAiCrE,EAA4B,CAC3G,MAAMqN,GAAS,KACb,KAAK,OACL,KAAK,OAAO,KAAK,aAAa,SAAS,IAAI,EAAI,YAC/C+B,EACA/K,EACArE,EACA,KACA,EACF,CACF,CAEA,MAAM,QAAsC,CAC1C,OAAO,KAAK,OAAO,KAAK,aAAa,OAAO,IAAI,CAClD,CACF,EAEOwT,GAAQL,GC5ITM,GAAN,MAAMC,EAAM,CAQV,YAAYzV,EAAsB,CAChC,KAAK,QAAWA,GAAUA,EAAO,SAAY,OAC7C,KAAK,OAAUA,GAAUA,EAAO,QAAW,OAC3C,KAAK,MAASA,GAAUA,EAAO,OAAU,OACzC,KAAK,WAAcA,GAAUA,EAAO,YAAe,OACnD,KAAK,KAAQA,GAAUA,EAAO,MAAS,OACvC,KAAK,WAAcA,GAAUA,EAAO,YAAe,MACrD,CAEA,OAAO,WAAWA,EAA4B,CAC5C,OAAO,IAAIyV,GAAMzV,CAAM,CACzB,CACF,EAEO0V,GAAQF,GCfFG,GAAN,KAAuB,CAC5B,OAAO,SAAS5C,EAAwC,CACtD,MAAO,aAAe,mBAAmBA,EAAQ,IAAI,CACvD,CAEA,OAAO,QACLA,EACAhR,EACmC,CACnC,IAAMoG,EAAS4K,EAAQ,OACrBhQ,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB2G,EAAWiE,EAAQ,OAAO,KAAK,oBAAsB,OAAYhQ,EACjEqD,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAE3D,OAAAlE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEpC,IAAImI,GAAkBnI,EAAQ,KAAK,SAAS4K,CAAO,EAAI,YAAa3M,EAAS0I,EAAU,eAC5FzM,EACA+D,EACA4E,EACA,CACA,IAAM8J,EAAiC9J,EAClC3I,EACK1E,GAAW0E,EAAM8F,EAAO,SAAUpF,CAAM,EAElD,OAAOiQ,GAAkB8B,EAAS/B,CAAO,CAC3C,CAAC,EAAE,IAAIhR,CAAiC,CAC1C,CAEA,aAAa,OAAOgR,EAAqE,CACvF,IAAMhQ,EAASgQ,EAAQ,OAAO,QAAQ,kBAAA,UAAA,OAChC3M,EAAUc,EAAS,mBAAmB6L,EAAQ,OAAO,QAAS,CAAE,OAAAhQ,CAAO,CAAC,EAW9E,OATiB,MAAMqM,GAAS,IAC9B2D,EAAQ,OACR,KAAK,SAASA,CAAO,EACrB3M,EACA,CAAC,EACDrD,EACA,EACF,GAEgB,IAClB,CACF,ECpDa6S,GAAN,KAAwB,CAC7B,OAAO,SAASC,EAA2C,CACzD,OAAOF,GAAiB,SAASE,EAAS,OAAO,EAAI,WACvD,CAEA,aAAa,QACXA,EACA9T,EAC2C,CAC3C,IAAMoG,EAAS0N,EAAS,QAAQ,OAC9B9S,EAASoF,EAAO,QAAQ,kBAAA,UAAA,OACxB2G,EAAW+G,EAAS,QAAQ,OAAO,KAAK,oBAAsB,OAAY9S,EAC1EqD,EAAUc,EAAS,kBAAkBiB,EAAO,QAAS,CAAE,OAAApF,CAAO,CAAC,EAE3D,OAAAlE,EAAMuH,EAAS+B,EAAO,QAAQ,OAAO,EAEpC,IAAImI,GACTnI,EACA,KAAK,SAAS0N,CAAQ,EAAI,WAC1BzP,EACA0I,EACA,MAAOzM,EAAM+D,EAAS4E,IAAa,CACjC,IAAM8J,EAAyC9J,EAC1C3I,EACK1E,GAAW0E,EAAM8F,EAAO,SAAUpF,CAAM,EAElD,OAAOiQ,GAAkB8B,EAASe,EAAS,OAAO,CACpD,CACF,EAAE,IAAI9T,CAAM,CACd,CACF,ECFa+T,GAAN,KAAW,CAYhB,YAAY3N,EAAoB,CAPhC,KAAS,aAAewN,GACxB,KAAS,cAAgBC,GAGzB,KAAA,SAAWxG,GACX,KAAA,cAAgBhB,GAGd,KAAK,OAASjG,EACd,KAAK,SAAW,IAAI4N,GAAS,KAAK,MAAM,EACxC,KAAK,KAAO,IAAItE,GAAK,KAAK,MAAM,CAClC,CAEA,MAAM,MAAM1P,EAAwD,CAClE,IAAMqE,EAAUc,EAAS,kBAAkB,KAAK,OAAO,OAAO,EAC5DnE,EAAS,KAAK,OAAO,QAAQ,kBAAA,UAAA,OAC7B+L,EAAW,KAAK,OAAO,KAAK,oBAAsB,OAAY/L,EAE1D,OAAAlE,EAAMuH,EAAS,KAAK,OAAO,QAAQ,OAAO,EAEzC,IAAIkK,GAAkB,KAAK,OAAQ,SAAUlK,EAAS0I,EAAU,SAAUzM,EAAM+D,EAAS4E,EAAU,CACxG,IAAMgL,EAAchL,EAAW3I,EAAO,KAAK,MAAMA,CAAc,EAC/D,QAAS/B,EAAI,EAAGA,EAAI0V,EAAY,OAAQ1V,IAAK0V,EAAY1V,CAAC,EAAIoV,GAAM,WAAWM,EAAY1V,CAAC,CAAC,EAC7F,OAAO0V,CACT,CAAC,EAAE,IAAIjU,CAAgC,CACzC,CAEA,MAAM,KAAKA,EAAyC,CAClD,IAAMqE,EAAUc,EAAS,kBAAkB,KAAK,OAAO,OAAO,EAC1D,KAAK,OAAO,QAAQ,SAAerI,EAAMuH,EAAS,KAAK,OAAO,QAAQ,OAAO,EACjF,IAAM6P,EAAWnR,GACR,KAAK,OAAO,QAAQA,CAAI,EAAI,QAGjC,CAAE,MAAAkH,EAAO,KAAA3J,EAAM,SAAA2I,CAAS,EAAI,MAAM,KAAK,OAAO,KAAK,GACrDpD,EAAY,IACZqO,EACA7P,EACA,KACArE,CACF,EAEA,GAAIiK,EACF,MAAMA,EAEHhB,IAAU3I,EAAO,KAAK,MAAMA,CAAc,GAC/C,IAAM/G,EAAQ+G,EAAkB,CAAC,EACjC,GAAI,CAAC/G,EACH,MAAM,IAAIhB,EAAU,yDAA0D,IAAO,GAAG,EAG1F,YAAK,OAAO,iBAAmBgB,EAAO,KAAK,IAAI,EACxCA,CACT,CAEA,MAAM,QACJkR,EACAjC,EACAxG,EACAhC,EACAM,EACAuL,EACyC,CAvG7C,IAAApS,EAwGI,GAAM,CAAC0a,EAASC,EAASpT,CAAM,EACzB,KAAK,OAAO,QAAQ,mBACjB,KAAK,OAAO,UACT5D,GAAwB,SAAS,EAElC,CAAC,KAAK,OAAO,SAAS,OAAQ,KAAK,OAAO,SAAS,OAAA,SAA4B,GAE/E,CAAC,KAAK,UAAW,KAAK,MAAA,MAAwB,EAGnD2P,EAAW,KAAK,OAAO,KAAK,oBAAsB,OAAY/L,EACpEhB,EAASA,GAAU,CAAC,EACpB,IAAMqU,EAAU5J,EAAO,YAAY,EAC7BpG,EACJgQ,GAAW,MACPlP,EAAS,kBAAkB,KAAK,OAAO,QAAS,CAAE,OAAAnE,EAAQ,gBAAiBgB,CAAQ,CAAC,EACpFmD,EAAS,mBAAmB,KAAK,OAAO,QAAS,CAAE,OAAAnE,EAAQ,gBAAiBgB,CAAQ,CAAC,EAEvF,OAAO1B,GAAS,WAClBA,GAAO7G,EAAA0a,EAAQ7T,CAAI,IAAZ,KAAA7G,EAAiB,MAEpBqD,EAAMuH,EAAS,KAAK,OAAO,QAAQ,OAAO,EAC5CwH,GACI/O,EAAMuH,EAASwH,CAAa,EAEpC,IAAMyI,EAAoB,IAAI/F,GAC5B,KAAK,OACL/F,EACAnE,EACA0I,EACA,eAAgBwH,EAASlQ,EAAS4E,EAAU,CAC1C,OAAanN,GAAYmN,EAAWsL,EAAUH,EAAQG,CAA0B,CAAC,CACnF,EACgC,EAClC,EAEA,GAAI,CAACxb,EAAS,KAAK,QAAQ,SAASsb,CAAO,EACzC,MAAM,IAAI9b,EAAU,sBAAwB8b,EAAS,MAAO,GAAG,EAGjE,OAAItb,EAAS,KAAK,gBAAgB,SAASsb,CAAO,EACzCC,EAAkBD,CAA2B,EAAErU,EAAQM,CAAmB,EAI1EgU,EAAkBD,CAA+C,EAAErU,CAAM,CAIpF,CAEA,MAAM,aACJ8L,EACiF,CACjF,IAAI0I,EACAC,EACA,MAAM,QAAQ3I,CAAW,GAC3B0I,EAAiB1I,EACjB2I,EAAiB,KAEjBD,EAAiB,CAAC1I,CAAW,EAC7B2I,EAAiB,IAGnB,IAAMzT,EAAS,KAAK,OAAO,QAAQ,kBAAA,UAAA,OACjCqD,EAAUc,EAAS,mBAAmB,KAAK,OAAO,QAAS,CAAE,OAAAnE,CAAO,CAAC,EAEnE,KAAK,OAAO,QAAQ,SAAelE,EAAMuH,EAAS,KAAK,OAAO,QAAQ,OAAO,EAEjF,IAAM+K,EAAoBvT,GAAW2Y,EAAgB,KAAK,OAAO,SAAUxT,CAAM,EAE3E0L,EAAW,MAAMW,GAAS,KAAK,KAAK,OAAQ,YAAa+B,EAAa/K,EAAS,CAAC,EAAG,KAAM,EAAI,EAE7FqQ,EACJhI,EAAS,SAAWA,EAAS,KAAa9Q,GAAW8Q,EAAS,KAAM,KAAK,OAAO,SAAU1L,CAAM,EAIlG,OAAIyT,EACKC,EAAa,CAAC,EAEdA,CAEX,CAEA,MAAM,cAAc3I,EAAkD,CACpE,IAAM/K,EAAS,KAAK,OAAO,QAAQ,kBAAA,UAAA,OACjCqD,EAAUc,EAAS,mBAAmB,KAAK,OAAO,QAAS,CAAE,OAAAnE,CAAO,CAAC,EAEnE,KAAK,OAAO,QAAQ,SAAelE,EAAMuH,EAAS,KAAK,OAAO,QAAQ,OAAO,EAEjF,IAAMsQ,EAAgB5I,EAAS,KAAK,GAAG,EAEjCW,EAAW,MAAMW,GAAS,IAAI,KAAK,OAAQ,YAAahJ,EAAS,CAAE,SAAUsQ,CAAc,EAAG,KAAM,EAAI,EAE9G,OACEjI,EAAS,SAAWA,EAAS,KAAa9Q,GAAW8Q,EAAS,KAAM,KAAK,OAAO,SAAU1L,CAAM,CAEpG,CAEA,MAAM,aACJkJ,EACApH,EACgC,CAChC,GAAImE,GAAa,KAAK,OAAO,OAAO,EAClC,MAAM,IAAI1O,EAAU,6CAA8C,MAAO,GAAG,EAG9E,IAAMgQ,EAAU,KAAK,OAAO,QAAQ,QAEhCqM,EAAkB9R,GAAW,CAAC,EAE5B0R,EAAiBvQ,EAAA,CACrB,QAASiG,EAAW,IAAK2K,GAAc,GAAGA,EAAU,IAAI,IAAIA,EAAU,KAAK,EAAE,CAAA,EAC1ED,CAAA,EAGC5T,EAAS,KAAK,OAAO,QAAQ,kBAAA,UAAA,OACjCqD,EAAUc,EAAS,mBAAmB,KAAK,OAAO,QAAS,CAAE,OAAAnE,CAAO,CAAC,EAEnE,KAAK,OAAO,QAAQ,SAAelE,EAAMuH,EAAS,KAAK,OAAO,QAAQ,OAAO,EAEjF,IAAM+K,EAAoBvT,GAAW2Y,EAAgB,KAAK,OAAO,SAAUxT,CAAM,EAE3E0L,EAAW,MAAMW,GAAS,KAC9B,KAAK,OACL,SAAS9E,CAAO,gBAChB6G,EACA/K,EACA,CAAC,EACD,KACA,EACF,EAEA,OACEqI,EAAS,SAAWA,EAAS,KAAa9Q,GAAW8Q,EAAS,KAAM,KAAK,OAAO,SAAU1L,CAAM,CAEpG,CACF,EAEMgT,GAAN,KAAe,CAIb,YAAY5N,EAAoB,CAC9B,KAAK,OAASA,EACd,KAAK,IAAM,OAAO,OAAO,IAAI,CAC/B,CAEA,IAAIhF,EAAcyD,EAAiC,CACjDzD,EAAO,OAAOA,CAAI,EAClB,IAAI4P,EAAU,KAAK,IAAI5P,CAAI,EAC3B,OAAK4P,EAEMnM,GACTmM,EAAQ,WAAWnM,CAAc,EAFjC,KAAK,IAAIzD,CAAI,EAAI4P,EAAU,IAAIwC,GAAY,KAAK,OAAQpS,EAAMyD,CAAc,EAKvEmM,CACT,CAIA,QAAQ5P,EAAc,CACpB,OAAO,KAAK,IAAI,OAAOA,CAAI,CAAC,CAC9B,CACF,ECnQa0T,GAAN,cAAuB7I,EAAW,CASvC,YAAYnJ,EAAkC,CAC5C,MAAMqC,EAAS,iBAAiBrC,EAAS,GAAO,WAAYrI,EAAO,cAAe,CAAE,KAAAsZ,EAAK,CAAC,CAAC,CAC7F,CACF,ECeagB,GAA0C,CAAE,KAAAhB,EAAK,ECjBjDiB,GAAN,cAA6BzC,EAAQ,CAC1C,aAAa,YAAY9B,EAAkBC,EAAqD,CAC9F,OAAOF,GAAY/V,EAAO,cAAe1B,EAAS,OAAQ0X,EAAgCC,CAAY,CACxG,CAEA,aAAa,iBAAiBI,EAA8BhO,EAAkD,CAC5G,OAAO+N,GAAiBpW,EAAO,cAAe1B,EAAS,OAAQ+X,EAAuChO,CAAO,CAC/G,CAGA,OAAO,WAAW7E,EAAsC,CACtD,OAAOiU,GAAWjU,CAAM,CAC1B,CAGA,OAAO,iBAAiBA,EAAsC,CAC5D,OAAO0S,GAAiB1S,CAAM,CAChC,CAGA,aAAa,OAA4C3E,EAAQwJ,EAAoC,CACnG,OAAOuO,GAAO/X,EAAKwJ,CAAO,CAC5B,CAGA,aAAa,OACX1I,EACAqX,EACe,CACf,OAAOb,GAAOxW,EAASqX,CAAY,CACrC,CACF,ECtCawD,GAAN,cAAqCpC,EAAgB,CAC1D,aAAa,YAAYpC,EAAkBC,EAA6D,CACtG,OAAOF,GAAY/V,EAAO,cAAe1B,EAAS,OAAQ0X,EAAwCC,CAAY,CAChH,CAEA,aAAa,iBACXI,EACAhO,EAC4B,CAC5B,OAAO+N,GACLpW,EAAO,cACP1B,EAAS,OACT+X,EACAhO,CACF,CACF,CAEA,OAAO,WAAW7E,EAAsD,CACtE,OAAOiU,GAAWjU,CAAM,CAC1B,CACF,ECpBaiX,GAAN,MAAMA,WAAoBJ,EAAS,CAExC,YAAYhS,EAAkC,CAhBhD,IAAArJ,EAAA4G,EAkBI,GAAI,CADY6U,GAAY,SAE1B,MAAM,IAAI,MAAM,gDAAgD,EAGlE,MACE/P,EAAS,iBAAiBrC,EAAS,GAAM,OAAQrI,EAAO,cAAeuJ,EAAAC,EAAA,CAAA,EAClE8Q,EAAA,EADkE,CAErE,QAAQtb,EAAAyb,GAAY,SAAZ,KAAAzb,EAAsB,OAC9B,SAAS4G,EAAA6U,GAAY,WAAZ,KAAA7U,EAAwB,MACnC,CAAA,CAAC,CACH,CACF,CAGA,WAAW,QAAS,CAClB,GAAI,KAAK,UAAY,KACnB,MAAM,IAAI,MAAM,wDAAwD,EAG1E,OAAO,KAAK,OACd,CACA,WAAW,OAAO8U,EAAkC,CAClD,KAAK,QAAUA,CACjB,CASF,EApCaD,GAiBI,QAAkC,KAjBtCA,GA6BJ,QAAUF,GA7BNE,GA8BJ,gBAAkBD,GA9BdC,GAgCJ,SAA2B,KAhCvBA,GAmCJ,MAAQvK,GAnCV,IAAMlS,GAANyc,GCTP,SAASE,GAAa/b,EAAgBgc,EAA8BC,EAAoB1b,EAAiB,CACvG,GAAI,CACF0b,EAAS,MAAMD,EAAWzb,CAAI,CAChC,OAASiI,EAAG,CACVpH,EAAO,UACLpB,EACAoB,EAAO,UACP,sBACA,kCAAoCoH,EAAI,cAAgBA,GAAMA,EAAY,MAC5E,CACF,CACF,CAQA,SAAS0T,GAAeC,EAAsBF,EAAoBG,EAAsB,CACtF,IAAIC,EACA7F,EACA8F,EAEJ,QAASC,EAAuB,EAAGA,EAAuBJ,EAAgB,OAAQI,IAMhF,GALAF,EAAYF,EAAgBI,CAAoB,EAC5CH,IACFC,EAAYA,EAAUD,CAAW,GAG/B,MAAM,QAAQC,CAAS,EAAG,CAC5B,MAAQ7F,EAAQ6F,EAAU,QAAQJ,CAAQ,KAAO,IAC/CI,EAAU,OAAO7F,EAAO,CAAC,EAIvB4F,GAAeC,EAAU,SAAW,GACtC,OAAOF,EAAgBI,CAAoB,EAAEH,CAAW,CAE5D,SAAiB9Y,GAAS+Y,CAAS,EAEjC,IAAKC,KAAaD,EACZ,OAAO,UAAU,eAAe,KAAKA,EAAWC,CAAS,GAAK,MAAM,QAAQD,EAAUC,CAAS,CAAC,GAClGJ,GAAe,CAACG,CAAS,EAAGJ,EAAUK,CAAS,CAKzD,CAEA,IAAME,GAAN,KAAmB,CAMjB,YAAqBxc,EAAgB,CAAhB,KAAA,OAAAA,EACnB,KAAK,IAAM,CAAC,EACZ,KAAK,OAAS,OAAO,OAAO,IAAI,EAChC,KAAK,QAAU,CAAC,EAChB,KAAK,WAAa,OAAO,OAAO,IAAI,CACtC,CAeA,MAAMO,EAAiB,CACrB,GAAIA,EAAK,SAAW,EAAG,CACrB,IAAM0b,EAAW1b,EAAK,CAAC,EACvB,GAAI,OAAO0b,GAAa,WACtB,KAAK,IAAI,KAAKA,CAAQ,MAEtB,OAAM,IAAI,MAAM,0CAA4Cvc,EAAS,OAAO,QAAQa,CAAI,CAAC,CAE7F,CACA,GAAIA,EAAK,SAAW,EAAG,CACrB,GAAM,CAACkc,EAAOR,CAAQ,EAAI1b,EAC1B,GAAI,OAAO0b,GAAa,WACtB,MAAM,IAAI,MAAM,0CAA4Cvc,EAAS,OAAO,QAAQa,CAAI,CAAC,EAE3F,GAAU8C,GAAMoZ,CAAK,EACnB,KAAK,IAAI,KAAKR,CAAQ,UACb,MAAM,QAAQQ,CAAK,EAC5BA,EAAM,QAASH,GAAc,CAC3B,KAAK,GAAGA,EAAWL,CAAQ,CAC7B,CAAC,MACI,CACL,GAAI,OAAOQ,GAAU,SACnB,MAAM,IAAI,MAAM,0CAA4C/c,EAAS,OAAO,QAAQa,CAAI,CAAC,GAEzE,KAAK,OAAOkc,CAAK,IAAM,KAAK,OAAOA,CAAK,EAAI,CAAC,IACrD,KAAKR,CAAQ,CACzB,CACF,CACF,CAmBA,OAAO1b,EAAiB,CACtB,GAAIA,EAAK,QAAU,GAAY8C,GAAM9C,EAAK,CAAC,CAAC,GAAW8C,GAAM9C,EAAK,CAAC,CAAC,EAAI,CACtE,KAAK,IAAM,CAAC,EACZ,KAAK,OAAS,OAAO,OAAO,IAAI,EAChC,KAAK,QAAU,CAAC,EAChB,KAAK,WAAa,OAAO,OAAO,IAAI,EACpC,MACF,CACA,GAAM,CAACmc,EAAUC,CAAS,EAAIpc,EAC1B0b,EAA4B,KAC5BQ,EAAiB,KACrB,GAAIlc,EAAK,SAAW,GAAK,CAACoc,EACpB,OAAOD,GAAa,WAEtBT,EAAWS,EAEXD,EAAQC,MAGL,CACL,GAAI,OAAOC,GAAc,WACvB,MAAM,IAAI,MAAM,yCAA2Cjd,EAAS,OAAO,QAAQa,CAAI,CAAC,EAE1F,CAACkc,EAAOR,CAAQ,EAAI,CAACS,EAAUC,CAAS,CAC1C,CAEA,GAAIV,GAAkB5Y,GAAMoZ,CAAK,EAAG,CAClCP,GAAe,CAAC,KAAK,IAAK,KAAK,OAAQ,KAAK,QAAS,KAAK,UAAU,EAAGD,CAAQ,EAC/E,MACF,CAEA,GAAI,MAAM,QAAQQ,CAAK,EAAG,CACxBA,EAAM,QAASH,GAAc,CAC3B,KAAK,IAAIA,EAAWL,CAAQ,CAC9B,CAAC,EACD,MACF,CAGA,GAAI,OAAOQ,GAAU,SACnB,MAAM,IAAI,MAAM,yCAA2C/c,EAAS,OAAO,QAAQa,CAAI,CAAC,EAEtF0b,EACFC,GAAe,CAAC,KAAK,OAAQ,KAAK,UAAU,EAAGD,EAAUQ,CAAK,GAE9D,OAAO,KAAK,OAAOA,CAAK,EACxB,OAAO,KAAK,WAAWA,CAAK,EAEhC,CAOA,UAAUA,EAAe,CACvB,GAAIA,EAAO,CACT,IAAMJ,EAAY,KAAK,OAAOI,CAAK,GAAK,CAAC,EACzC,OAAI,KAAK,WAAWA,CAAK,GAAG,MAAM,UAAU,KAAK,MAAMJ,EAAW,KAAK,WAAWI,CAAK,CAAC,EACjFJ,EAAU,OAASA,EAAY,IACxC,CACA,OAAO,KAAK,IAAI,OAAS,KAAK,IAAM,IACtC,CAOA,KAAKI,KAAkBlc,EAAiC,CACtD,IAAMyb,EAAY,CAAE,MAAAS,CAAM,EACpBJ,EAAwB,CAAC,EAE3B,KAAK,QAAQ,SACf,MAAM,UAAU,KAAK,MAAMA,EAAW,KAAK,OAAO,EAClD,KAAK,QAAU,CAAC,GAEd,KAAK,IAAI,QACX,MAAM,UAAU,KAAK,MAAMA,EAAW,KAAK,GAAG,EAEhD,IAAMO,EAAsB,KAAK,WAAWH,CAAK,EAC7CG,IACF,MAAM,UAAU,KAAK,MAAMP,EAAWO,CAAmB,EACzD,OAAO,KAAK,WAAWH,CAAK,GAE9B,IAAMI,EAAkB,KAAK,OAAOJ,CAAK,EACrCI,GACF,MAAM,UAAU,KAAK,MAAMR,EAAWQ,CAAe,EAGvDR,EAAU,QAASJ,GAAa,CAC9BF,GAAa,KAAK,OAAQC,EAAWC,EAAU1b,CAAI,CACrD,CAAC,CACH,CAqBA,QAAQA,EAAuC,CAC7C,IAAMuc,EAAWvc,EAAK,OACtB,GAAIuc,IAAa,GAAMA,IAAa,GAAK,OAAOvc,EAAK,CAAC,GAAM,WAAa,CACvE,IAAMkc,EAAQlc,EAAK,CAAC,EACpB,OAAO,IAAI,QAAS6L,GAAY,CAC9B,KAAK,KAAKqQ,EAAmCrQ,CAAO,CACtD,CAAC,CACH,CAEA,GAAM,CAACsQ,EAAUC,CAAS,EAAIpc,EAC9B,GAAIA,EAAK,SAAW,GAAK,OAAOmc,GAAa,WAC3C,KAAK,QAAQ,KAAKA,CAAQ,UACXrZ,GAAMqZ,CAAQ,EAAG,CAChC,GAAI,OAAOC,GAAc,WACvB,MAAM,IAAI,MAAM,0CAA4Cjd,EAAS,OAAO,QAAQa,CAAI,CAAC,EAE3F,KAAK,QAAQ,KAAKoc,CAAS,CAC7B,SAAW,MAAM,QAAQD,CAAQ,EAAG,CAClC,IAAMzH,EAAO,KACP8H,EAAkB,UAAqB,CAC3C,IAAMC,EAAY,MAAM,UAAU,MAAM,KAAK,SAAS,EAItD,GAHAN,EAAS,QAAQ,SAAUJ,EAAW,CACpCrH,EAAK,IAAIqH,EAAWS,CAAe,CACrC,CAAC,EACG,OAAOJ,GAAc,WACvB,MAAM,IAAI,MAAM,0CAA4Cjd,EAAS,OAAO,QAAQa,CAAI,CAAC,EAE3Foc,EAAU,MAAM,KAAMK,CAAS,CACjC,EACAN,EAAS,QAAQ,SAAUJ,EAAW,CACpCrH,EAAK,GAAGqH,EAAWS,CAAe,CACpC,CAAC,CACH,KAAO,CACL,GAAI,OAAOL,GAAa,SACtB,MAAM,IAAI,MAAM,0CAA4Chd,EAAS,OAAO,QAAQa,CAAI,CAAC,EAE3F,IAAM8b,EAAY,KAAK,WAAWK,CAAQ,IAAM,KAAK,WAAWA,CAAQ,EAAI,CAAC,GAC7E,GAAIC,EAAW,CACb,GAAI,OAAOA,GAAc,WACvB,MAAM,IAAI,MAAM,0CAA4Cjd,EAAS,OAAO,QAAQa,CAAI,CAAC,EAE3F8b,EAAU,KAAKM,CAAS,CAC1B,CACF,CACF,CAOA,MAAM,UAAUM,EAAqBC,EAAsB,CACzD,GAAI,OAAOD,GAAgB,UAAY,OAAOC,GAAiB,SAC7D,MAAM,IAAI,MAAM,kDAAkD,EAEpE,OAAID,IAAgBC,EACX,KAEA,KAAK,KAAKD,CAAW,CAEhC,CACF,EAEOE,GAAQX,GChSFrD,EAAU,CACrB,UAAW,EACX,IAAK,EACL,KAAM,EACN,QAAS,EACT,UAAW,EACX,WAAY,EACZ,aAAc,EACd,MAAO,EACP,OAAQ,EACR,MAAO,EACP,OAAQ,GACR,SAAU,GACV,OAAQ,GACR,SAAU,GACV,SAAU,GACV,QAAS,GACT,KAAM,GACN,KAAM,GACN,SAAU,EACZ,EAEaiE,GAAuB,CAAC,EACrC,OAAO,KAAKjE,CAAO,EAAE,QAAQ,SAAUpR,EAAM,CAC3CqV,GAAYjE,EAAsCpR,CAAI,CAAC,EAAIA,CAC7D,CAAC,EAED,IAAMsV,GAAmC,CAEvC,aAAc,EACd,YAAa,EACb,QAAS,EACT,UAAW,GACX,cAAe,GAEf,SAAU,MACV,QAAS,GAAK,GACd,UAAW,GAAK,GAChB,mBAAoB,GAAK,EAC3B,EACMC,GAAY,OAAO,KAAKD,EAAK,EACnCA,GAAM,SAAWA,GAAM,SAAWA,GAAM,QAAUA,GAAM,UAAYA,GAAM,mBAE1E,SAASE,GAAcC,EAAuB,CAC5C,IAAMjZ,EAAS,CAAC,EAChB,GAAIiZ,EACF,QAAStY,EAAI,EAAGA,EAAIsY,EAAM,OAAQtY,IAChCX,EAAO,KAAKiZ,EAAMtY,CAAC,EAAE,SAAS,CAAC,EAGnC,MAAO,KAAOX,EAAO,KAAK,IAAI,EAAI,IACpC,CAEO,IAAMkZ,GAAe,CAAC,WAAY,UAAW,YAAa,oBAAoB,EAExEtF,GAAkB3V,GAExB,SAASkb,GACdC,EACAjW,EACAkW,EACAjW,EACiB,CACjB,IAAMkW,EAAqBtb,GAAoCob,EAAYjW,EAASC,CAAM,EAC1F,OAAOmW,GAAiBD,EAAcD,CAAqB,CAC7D,CAEO,SAASE,GACdD,EACAD,EACiB,CACjB,IAAMhN,EAAQiN,EAAa,MACvBjN,IACFiN,EAAa,MAAQ3e,EAAU,WAAW0R,CAAkB,GAG9D,IAAIsH,EACA2F,EAAa,WAEf3F,EADW2F,EAAa,SACV,IAAKE,GAAMzG,GAAwByG,CAAC,CAAC,GAGrD,IAAItD,EACJ,OAAImD,GAAyBC,EAAa,WAExCpD,EADWoD,EAAa,SACV,IAAKG,GAAOJ,EAAsB,gCAAgCI,CAAE,CAAC,GAG9E,OAAO,OAAO,IAAIC,GAAmBtT,EAAAC,EAAA,CAAA,EAAKiT,CAAA,EAAL,CAAmB,SAAApD,EAAU,SAAAvC,CAAS,CAAA,CAAC,CACrF,CAKO,SAAS3Y,GAAsCse,EAAwD,CAC5G,OAAOC,GAAiBD,EAAc,CACpC,0BAAAhF,GACA,gCAAAE,GACA,gCAAAzB,EACF,CAAC,CACH,CAEO,SAASuB,GAAWjU,EAAkC,CAC3D,OAAO,OAAO,OAAO,IAAIqZ,GAAmBrZ,CAAM,CACpD,CAEO,SAASsZ,GAAUje,EAAU2d,EAA6D,CAC/F,IAAIrZ,EAAS,mBACTtE,EAAI,SAAW,SAAWsE,GAAU,YAAc6Y,GAAWnd,EAAI,MAAM,GAAKA,EAAI,QAEpF,IAAMke,EAAmB,CAAC,KAAM,UAAW,gBAAiB,eAAgB,QAAS,YAAa,WAAW,EACzGC,EACJ,QAASC,EAAc,EAAGA,EAAcF,EAAiB,OAAQE,IAC/DD,EAAYD,EAAiBE,CAAW,EACpCpe,EAAIme,CAAS,IAAM,SAAW7Z,GAAU,KAAO6Z,EAAY,IAAMne,EAAIme,CAAS,GASpF,GANIne,EAAI,WAAUsE,GAAU,cAAgBgZ,GAAcxE,GAAwB9Y,EAAI,QAAQ,CAAC,GAC3FA,EAAI,UAAY2d,IAClBrZ,GAAU,cAAgBgZ,GAAcK,EAAsB,gCAAgC3d,EAAI,QAAQ,CAAC,GACzGA,EAAI,QAAOsE,GAAU,WAAarF,EAAU,WAAWe,EAAI,KAAK,EAAE,SAAS,GAC3EA,EAAI,MAAQA,EAAI,KAAK,cAAasE,GAAU,WAAatE,EAAI,KAAK,aAClEA,EAAI,QAAOsE,GAAU,WAAa+Y,GAAU,OAAOrd,EAAI,OAAO,EAAE,KAAK,GAAG,GACxEA,EAAI,OAAQ,CACd,IAAIqe,EAAoB,GAClB5b,GAA0BzC,EAAI,OAAQ,SAAUuF,EAAc,CAC9D8Y,EAAkB,OAAS,IAC7BA,GAAqB,MAEvBA,GAAqB9Y,EAAO,IAAMvF,EAAI,OAAOuF,CAAI,CACnD,CAAC,EACG8Y,EAAkB,OAAS,IAC7B/Z,GAAU,aAAe+Z,EAAoB,IAEjD,CACA,OAAA/Z,GAAU,IACHA,CACT,CAEA,IAAM0Z,GAAN,KAAsB,CAAtB,aAAA,CAiBE,KAAA,QAAWM,IACA,KAAK,MAAmBlB,GAAMkB,CAAI,GAAK,CAClD,CAEA,QAAQA,EAA+B,CACrC,OAAQ,KAAK,MAAS,KAAK,MAAmBlB,GAAMkB,CAAI,CAC1D,CAEA,SAA8B,CAC5B,OAAO,KAAK,OAAS,KAAK,MAAQlB,GAAM,QAC1C,CAEA,mBAAmBmB,EAAgC,CACjDA,EAAM,QAASC,GAAS,KAAK,QAAQA,CAAI,CAAC,CAC5C,CAEA,sBAA6C,CAC3C,IAAMD,EAAkB,CAAC,EACzB,OAAAf,GAAa,QAASgB,GAAS,CACzB,KAAK,QAAQA,CAAI,GACnBD,EAAM,KAAKC,CAAI,CAEnB,CAAC,EACMD,EAAM,OAAS,EAAIA,EAAQ,MACpC,CACF,EAEOE,GAAQT,GCnMTU,GAAN,cAA2BxB,EAAa,CAGtC,YAAYnd,EAAgB,CAC1B,MAAMA,CAAM,EACZ,KAAK,SAAW,CAAC,CACnB,CAEA,OAAgB,CACd,OAAO,KAAK,SAAS,MACvB,CAEA,KAAKe,EAA+B,CAClC,KAAK,SAAS,KAAKA,CAAO,CAC5B,CAEA,OAAoC,CAClC,OAAO,KAAK,SAAS,MAAM,CAC7B,CAEA,MAAuB,CACrB,OAAO,KAAK,SAAS,KAAK,SAAS,OAAS,CAAC,CAC/C,CAEA,SAA4B,CAC1B,OAAO,KAAK,SAAS,MAAM,CAC7B,CAEA,OAAOmX,EAAuC,CAC5C,KAAK,SAAS,KAAK,MAAM,KAAK,SAAUA,CAAQ,CAClD,CAEA,QAAQA,EAAuC,CAC7C,KAAK,SAAS,QAAQ,MAAM,KAAK,SAAUA,CAAQ,CACrD,CAEA,iBAAiB0G,EAAgBhX,EAAetD,EAA8B,CAC5ElD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,kCACA,YAAcwd,EAAS,aAAehX,CACxC,EACAtD,EAAMA,GAAO,KACb,IAAM4T,EAAW,KAAK,SACtB,GAAIA,EAAS,SAAW,EACtB,MAAM,IAAI,MAAM,oFAAoF,EAEtG,IAAMzR,EAAQyR,EAAS,CAAC,EACxB,GAAIzR,EAAO,CACT,IAAMoY,EAAcpY,EAAM,QAAQ,UAC5BqY,EAAYF,EAAShX,EAC3B,GAAIkX,EAAYD,EAAa,CAC3B,IAAME,EAAmB7G,EAAS,OAAO,EAAG4G,EAAYD,CAAW,EACnE,QAAW9d,KAAWge,EACnBhe,EAAQ,SAAsBuD,CAAG,CAEtC,CACI4T,EAAS,QAAU,GAAG,KAAK,KAAK,MAAM,CAC5C,CACF,CAEA,oBAAoB5T,EAAsB,CACxC,KAAK,iBAAiB,EAAG,OAAO,kBAAoB,OAAO,UAAWA,CAAG,CAC3E,CAEA,oBAA2B,CACzB,QAASrE,KAAO,KAAK,SACnBA,EAAI,cAAgB,EAExB,CAEA,OAAc,CACZmB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,uBACA,YAAc,KAAK,SAAS,OAAS,WACvC,EACA,KAAK,SAAW,CAAC,EACjB,KAAK,KAAK,MAAM,CAClB,CACF,EAEO4d,GAAQL,GChFFM,GAAN,KAAqB,CAO1B,YAAYle,EAA0B0G,EAAwB,CAC5D,KAAK,QAAU1G,EACf,KAAK,SAAW0G,EAChB,KAAK,OAAS,GACd,IAAM3G,EAASC,EAAQ,OACvB,KAAK,cAAgB,GACrB,KAAK,YAAcD,GAAUqY,EAAQ,SAAWrY,GAAUqY,EAAQ,QACpE,CACF,EAEM+F,GAAN,cAAuB/B,EAAa,CAIlC,YAAYgC,EAAsB,CAChC,MAAMA,EAAU,MAAM,EACtB,KAAK,UAAYA,EACjB,KAAK,aAAe,IAAIH,GAAa,KAAK,MAAM,EAChDG,EAAU,GAAG,MAAO,CAACP,EAAgBhX,IAAkB,CACrD,KAAK,MAAMgX,EAAQhX,CAAK,CAC1B,CAAC,EACDuX,EAAU,GAAG,OAAQ,CAACP,EAAgBhX,EAAetD,IAAmB,CACtE,KAAK,OAAOsa,EAAQhX,EAAOtD,CAAG,CAChC,CAAC,CACH,CAEA,MAAMsa,EAAgBhX,EAAqB,CACzCxG,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,mBAAoB,YAAcwd,EAAS,aAAehX,CAAK,EAC/G,KAAK,aAAa,iBAAiBgX,EAAQhX,CAAK,CAClD,CAEA,OAAOgX,EAAgBhX,EAAetD,EAAsB,CAC1DlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,oBACA,YAAcwd,EAAS,aAAehX,EAAQ,WAAmB3E,EAAaqB,CAAG,CACnF,EACKA,IACHA,EAAM,IAAIpF,EAAU,iDAAkD,MAAO,GAAG,GAElF,KAAK,aAAa,iBAAiB0f,EAAQhX,EAAOtD,CAAG,CACvD,CAEA,SAAS2X,EAA6B,CACpC,IAAMmD,EAAe,KAAK,aAC1B,GAAIA,EAAa,MAAM,IAAM,EAAG,CAC9BnD,EAAS,EACT,MACF,CACAmD,EAAa,KAAK,OAAQnD,CAAQ,CACpC,CAEA,KAAKoD,EAAsC,CACrCA,EAAe,aACjB,KAAK,aAAa,KAAKA,CAAc,EAEnC,KAAK,OAAO,UAAUje,EAAO,SAAS,GACxCA,EAAO,iBACL,KAAK,OACLA,EAAO,UACP,kBACA,gBACE8c,GAAyBmB,EAAe,QAAS,KAAK,UAAU,kBAAkB,SAAS,iBAAiB,CAChH,EAEFA,EAAe,cAAgB,GAC/B,KAAK,UAAU,KAAKA,EAAe,OAAO,CAC5C,CAEA,cAA0B,CACxB,OAAO,KAAK,SACd,CAEA,oBAAuC,CACrC,OAAO,KAAK,aAAa,QAAQ,CACnC,CAEA,sBAA6B,CAC3B,OAAO,KAAK,aAAa,MAAM,CACjC,CAEA,QAAe,CACb,IAAMF,EAAY,KAAK,UACvB,KAAK,SAAS,UAAY,CACxBA,EAAU,WAAW,CACvB,CAAC,CACH,CACF,EAEOG,GAAQJ,GCxGTK,GAAN,KAA4B,CAM1B,YAAYC,EAAmBC,EAAkBC,EAAyBC,EAA4B,CACpG,KAAK,SAAWH,EAChB,KAAK,QAAUC,EACXC,IAAS,KAAK,QAAUA,GACxBC,IAAQ,KAAK,OAASA,EAC5B,CACF,EAEOC,GAAQL,GCdTM,GAAuB,CAC3B,aAAc,MACd,UAAW,MACX,OAAQ,IACR,QAAS,MACT,OAAQ,MACR,uBAAwB,MACxB,oBAAqB,KACvB,EAEMC,GAAmB,CACvB,aAAc,IACZ5gB,EAAU,WAAW,CACnB,WAAY,IACZ,KAAM2gB,GAAqB,aAC3B,QAAS,8CACX,CAAC,EACH,UAAW,IACT3gB,EAAU,WAAW,CACnB,WAAY,IACZ,KAAM2gB,GAAqB,UAC3B,QAAS,kCACX,CAAC,EACH,OAAQ,IACN3gB,EAAU,WAAW,CACnB,WAAY,IACZ,KAAM2gB,GAAqB,OAC3B,QAAS,6CACX,CAAC,EACH,QAAS,IACP3gB,EAAU,WAAW,CACnB,WAAY,IACZ,KAAM2gB,GAAqB,QAC3B,QAAS,oBACX,CAAC,EACH,OAAQ,IACN3gB,EAAU,WAAW,CACnB,WAAY,IACZ,KAAM2gB,GAAqB,OAC3B,QAAS,mBACX,CAAC,EACH,qBAAsB,IACpB3gB,EAAU,WAAW,CACnB,WAAY,IACZ,KAAM2gB,GAAqB,uBAC3B,QAAS,2BACX,CAAC,EACH,kBAAmB,IACjB3gB,EAAU,WAAW,CACnB,WAAY,IACZ,KAAM2gB,GAAqB,uBAC3B,QAAS,wBACX,CAAC,CACL,EAEO,SAASE,GAAYzb,EAAgB,CAC1C,MAAI,CAACA,EAAI,YAAc,CAACA,EAAI,MAAQA,EAAI,YAAc,IAC7C,GAEF,OAAO,OAAOub,EAAoB,EAAE,SAASvb,EAAI,IAAI,CAC9D,CAEA,IAAO0b,GAAQF,GChCTG,GAAepH,GAA0B,CAAE,OAAQM,EAAQ,KAAM,CAAC,EAClE+G,GAAoBrH,GAA0B,CAAE,OAAQM,EAAQ,UAAW,CAAC,EAanEgH,GAAf,cAAiChD,EAAa,CAa5C,YAAYiD,EAAsCC,EAAY1Z,EAAyB2Z,EAA6B,CAClH,MAAMF,EAAkB,MAAM,EAC1BE,IACF3Z,EAAO,OAAS,OAChBA,EAAO,WAAa,IAEtB,KAAK,kBAAoByZ,EACzB,KAAK,KAAOC,EACZ,KAAK,OAAS1Z,EACd,KAAK,SAAWA,EAAO,QAAQ,SAC/B,KAAK,OAASA,EAAO,OACrB,KAAK,YAAc,GACnB,KAAK,WAAa,GAClB,KAAK,WAAa,GAClB,KAAK,gBAAkB,KACvB,KAAK,UAAY,KACjB,KAAK,aAAe,IACtB,CAKA,SAAgB,CAAC,CAEjB,OAAc,CACR,KAAK,aACP,KAAK,aAAa,EAEpB,KAAK,OAAO,SAAUqZ,GAAiB,OAAO,CAAC,CACjD,CAEA,WAAW1b,EAA+B,CAGpC,KAAK,aACP,KAAK,kBAAkB,EAEzB,KAAK,OAAO,eAAgBA,GAAO0b,GAAiB,aAAa,CAAC,CACpE,CAEA,KAAK1b,EAAsB,CAErB,KAAK,aACP,KAAK,kBAAkB,EAEzB,KAAK,OAAO,SAAUA,GAAO0b,GAAiB,OAAO,CAAC,CACxD,CAEA,OAAOvD,EAAenY,EAA+B,CA3GvD,IAAAlE,EA4GQ,KAAK,aAIT,KAAK,WAAa,GAClB,KAAK,YAAc,GACnB,KAAK,gBAAkB,KACvB,cAAaA,EAAA,KAAK,YAAL,KAAAA,EAAkB,MAAS,EACxC,KAAK,UAAY,KACjB,KAAK,KAAKqc,EAAOnY,CAAG,EACpB,KAAK,QAAQ,EACf,CAEA,kBAAkBvD,EAAgC,CAgBhD,OAfI,KAAK,OAAO,UAAUK,EAAO,SAAS,GACxCA,EAAO,iBACL,KAAK,OACLA,EAAO,UACP,gCACA,eACE,KAAK,UACL,KACA8c,GAAyBnd,EAAS,KAAK,kBAAkB,SAAS,iBAAiB,EACnF,oBACA,KAAK,kBAAkB,YAC3B,EAEF,KAAK,WAAW,EAERA,EAAQ,OAAQ,CACtB,KAAKoY,EAAQ,UACX/X,EAAO,iBACL,KAAK,OACLA,EAAO,UACP,gCACA,KAAK,UAAY,8BAAgC,KAAK,kBAAkB,YAC1E,EACA,KAAK,KAAK,YAAaL,EAAQ,EAAE,EACjC,MACF,KAAKoY,EAAQ,UACX,KAAK,UAAUpY,CAAO,EACtB,KAAK,KAAK,YAAaA,EAAQ,MAAOA,EAAQ,aAAcA,EAAQ,kBAAmBA,CAAO,EAC9F,MACF,KAAKoY,EAAQ,OACX,KAAK,QAAQpY,CAAO,EACpB,MACF,KAAKoY,EAAQ,aACX,KAAK,aAAapY,CAAO,EACzB,MACF,KAAKoY,EAAQ,IACX,KAAK,KAAK,MAAOpY,EAAQ,UAAWA,EAAQ,KAAK,EACjD,MACF,KAAKoY,EAAQ,KACX,KAAK,KAAK,OAAQpY,EAAQ,UAAWA,EAAQ,MAAOA,EAAQ,KAAK,EACjE,MACF,KAAKoY,EAAQ,KACX,KAAK,kBAAkB,iBAAiBpY,EAAS,IAAI,EACrD,MACF,KAAKoY,EAAQ,SAEX,MACF,KAAKA,EAAQ,KACLhV,GAAmB,KAAK,KAAK,UAAU,EAAIG,GAA0B,CACrEA,GACFlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,gCACA,uEAA+E6B,EAAaqB,CAAG,CACjG,CAEJ,CAAC,EACD,MACF,KAAK6U,EAAQ,MAWX,GAVA/X,EAAO,UACL,KAAK,OACLA,EAAO,UACP,gCACA,yCACE,KAAK,kBAAkB,aACvB,WACA1B,EAAS,OAAO,QAAQqB,EAAQ,KAAK,GACpCA,EAAQ,QAAU,cAAgBA,EAAQ,QAAU,GACzD,EACIA,EAAQ,UAAY,OAAW,CACjC,KAAK,aAAaA,CAAO,EACzB,KACF,CAEA,KAAK,kBAAkB,iBAAiBA,EAAS,IAAI,EACrD,MACF,QAEE,KAAK,kBAAkB,iBAAiBA,EAAS,IAAI,CACzD,CACF,CAEA,UAAUA,EAAgC,CAExC,GADA,KAAK,YAAc,GACf,CAACA,EAAQ,kBACX,MAAM,IAAI,MAAM,2EAA2E,EAE7F,IAAMwf,EAAkBxf,EAAQ,kBAAkB,gBAC9Cwf,IACF,KAAK,gBAAkBA,EAAkB,KAAK,SAAS,uBACvD,KAAK,WAAW,EAGpB,CAEA,aAAaxf,EAAgC,CAG3C,IAAMuD,EAAMvD,GAAWA,EAAQ,MAC/BK,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,SAAiB6B,EAAaqB,CAAG,CAAC,EAC9G,KAAK,OAAO,eAAgBA,CAAG,CACjC,CAEA,aAAavD,EAAgC,CAI3C,IAAMuD,EAAMvD,GAAWA,EAAQ,MAC/BK,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,SAAiB6B,EAAaqB,CAAG,CAAC,EAC9G,KAAK,OAAO,SAAUA,CAAG,CAC3B,CAEA,QAAQvD,EAAgC,CACtC,IAAMuD,EAAMvD,GAAWA,EAAQ,MAC/BK,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,sBAAuB,SAAiB6B,EAAaqB,CAAG,CAAC,EACzG,KAAK,OAAO,SAAUA,CAAG,CAC3B,CAEA,cAAqB,CACnBlD,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,EAAE,EAC9E,KAAK,KAAK6e,EAAY,CACxB,CAEA,mBAA0B,CACxB7e,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,gCAAiC,EAAE,EACnF,KAAK,KAAK8e,EAAiB,CAC7B,CAEA,KAAKM,EAAkB,CACrB,IAAMvgB,EAAuC,CAAE,OAAQkZ,EAAQ,SAAU,EACrEqH,IAAIvgB,EAAI,GAAKugB,GACjB,KAAK,KAAK3H,GAA0B5Y,CAAG,CAAC,CAC1C,CAEA,SAAgB,CACdmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,sBAAuB,EAAE,EACzE,KAAK,WAAa,GAClB,KAAK,IAAI,CACX,CAEA,YAAmB,CACZ,KAAK,kBAGV,KAAK,aAAe,KAAK,kBAAkB,aAAe,KAAK,IAAI,EACnE,KAAK,aAAa,KAAK,gBAAkB,GAAG,EAC9C,CAEA,aAAamH,EAAuB,CAC7B,KAAK,YACR,KAAK,UAAY,WAAW,IAAM,CAChC,KAAK,kBAAkB,CACzB,EAAGA,CAAO,EAEd,CAEA,mBAA0B,CACxB,GAAI,CAAC,KAAK,cAAgB,CAAC,KAAK,gBAC9B,MAAM,IAAI,MAAM,qEAAqE,EAEvF,KAAK,UAAY,KACjB,IAAMkY,EAAY,KAAK,IAAI,EAAI,KAAK,aAC9BC,EAAgB,KAAK,gBAAkBD,EAC7C,GAAIC,GAAiB,EAAG,CACtB,IAAMzgB,EAAM,qCAAuCwgB,EAAY,sCAC/Drf,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,gCAAiCnB,CAAG,EACpF,KAAK,WAAW,IAAIf,EAAUe,EAAK,MAAO,GAAG,CAAC,CAChD,MACE,KAAK,aAAaygB,EAAgB,GAAG,CAEzC,CAEA,OAAO,WACLC,EACAP,EACAC,EACAO,EACAnZ,EACW,CACX,IAAM0X,EAAY,IAAIwB,EAAcP,EAAmBC,EAAMO,CAAe,EAExEC,EAEEC,EAAU,SAAmCxc,EAAgB,CACjE,aAAauc,CAAqB,EAClCpZ,EAAS,CAAE,MAAO,KAAK,MAAO,MAAOnD,CAAI,CAAC,CAC5C,EAEMyc,EAAyBX,EAAkB,QAAQ,SAAS,uBAClE,OAAAS,EAAwB,WAAW,IAAM,CACvC1B,EAAU,IAAI,CAAC,aAAc,eAAgB,QAAQ,CAAC,EACtDA,EAAU,QAAQ,EAClB2B,EAAQ,KACN,CAAE,MAAO,cAAe,EACxB,IAAI5hB,EAAU,0DAA2D,IAAO,GAAG,CACrF,CACF,EAAG6hB,CAAsB,EAEzB5B,EAAU,GAAG,CAAC,SAAU,cAAc,EAAG2B,CAAO,EAChD3B,EAAU,GAAG,aAAc,UAAY,CACrC/d,EAAO,UACLgf,EAAkB,OAClBhf,EAAO,UACP,yBACA,oBAAsB+d,CACxB,EACA,aAAa0B,CAAqB,EAClC1B,EAAU,IAAI,CAAC,SAAU,cAAc,EAAG2B,CAAO,EACjDrZ,EAAS,KAAM0X,CAAS,CAC1B,CAAC,EACDA,EAAU,QAAQ,EACXA,CACT,CAIA,OAAO,aAAuB,CAC5B,MAAM,IAAIjgB,EAAU,4CAA6C,IAAO,GAAG,CAC7E,CACF,EAEO8hB,GAAQb,GCxVEc,IAAAA,GAAV,CACQA,EAAA,UAAY,aACZA,EAAA,MAAQ,QACRA,EAAA,WAAa,aAAA,GAHXA,KAAAA,GAAA,CAAA,EAAA,EC0BjB,IAAIthB,GAAe,OAAO,OAAW,IAAc,OAAS,OAAO,OAAW,IAAc,OAAS,KAE/FuhB,GAAiB,IAAG,CA5B1B,IAAA9gB,EA4B6B,OAAA,OAAOV,EAAS,WAAe,OAAeU,EAAAV,EAAS,aAAT,KAAA,OAAAU,EAAqB,eAAA,EAC1F+gB,GAAqB,IAAG,CA7B9B,IAAA/gB,EA6BiC,OAAA,OAAOV,EAAS,WAAe,OAAeU,EAAAV,EAAS,aAAT,KAAA,OAAAU,EAAqB,iBAAA,EAC9FghB,GAAO,UAAY,CAAC,EACpBC,GAA0B,4BAEhC,SAASC,GAAWC,EAAuBlc,EAAsBmc,EAAiB,CAChF,IAAI1gB,EASJ,GARIygB,EAAK,UAAYlc,EAAI,UAIpBvE,EAASygB,EAAK,UAAYpI,EAAQ,UAAYrY,IAAWqY,EAAQ,SAIlErY,IAAWuE,EAAI,OAEjB,MAAO,GAET,IAAMoc,EAAO3gB,IAAWqY,EAAQ,SAAW,WAAa,WACtDuI,EAAYH,EAA6BE,CAAI,EAAE,OAAQpc,EAA4Boc,CAAI,CAAC,EAU1F,OATSzI,GAAgB0I,CAAQ,EACtBF,GAIP,CAAOjgB,GAAQmgB,EAAU,UAAU,GAKrC,CAACA,EAAS,MAAM,SAAUzhB,EAAc,CACtC,MAAO,CAACA,EAAI,EACd,CAAC,EAGM,IAGRshB,EAA6BE,CAAI,EAAIC,EAC/B,GACT,CAQA,SAASC,GAAkBC,EAAyE,CAClG,GAAI,CACF,OAAO,KAAK,MAAMA,CAAqB,CACzC,MAAY,CACV,OAAO,IACT,CACF,CAEO,IAAMC,GAAN,KAAsB,CAS3B,YAAYpY,EAAkCC,EAAqB+U,EAAcqD,EAAwB,CACvG,KAAK,QAAUrY,EACf,KAAK,KAAOC,EACZ,KAAK,KAAO+U,EACZ,KAAK,cAAgBqD,EACrB,KAAK,OAASrY,EAAQ,kBAAA,UAAA,MACxB,CAEA,iBAAiBkF,EAA6D,CAC5E,IAAMhI,EAASgI,EAAmBvM,GAAKuM,CAAU,EAAI,CAAC,EAChDlF,EAAU,KAAK,QACrB,OAAQ,KAAK,KAAM,CACjB,IAAK,SACH9C,EAAO,OAAS,KAAK,cACrB,MACF,IAAK,UAAW,CACd,IAAMob,EAAkBJ,GAAkBlY,EAAQ,OAAO,EACrDsY,IACFpb,EAAO,QAAUob,EAAgB,eAEnC,KACF,CACA,QACF,CACA,OAAItY,EAAQ,WAAa,SACvB9C,EAAO,SAAW8C,EAAQ,UAExBA,EAAQ,eAAiB,KAC3B9C,EAAO,KAAO,SAEZ,KAAK,SAAW,SAClBA,EAAO,OAAS,KAAK,QAEnB,KAAK,SAAW,SAClBA,EAAO,OAAS,KAAK,QAEnB,KAAK,aAAe,SACtBA,EAAO,WAAa,KAAK,YAE3BA,EAAO,EAAImF,EAAS,gBACpBnF,EAAO,MAAQ0D,GAAe,KAAK,OAAO,EACtCZ,EAAQ,kBAAoB,QACxBhG,EAAMkD,EAAQ8C,EAAQ,eAAe,EAEtC9C,CACT,CAEA,UAAmB,CACjB,IAAIpC,EAAS,SAAW,KAAK,KAC7B,OAAI,KAAK,OACPA,GAAU,SAAW,KAAK,MAExB,KAAK,gBACPA,GAAU,kBAAoB,KAAK,eAEjC,KAAK,SACPA,GAAU,WAAa,KAAK,QAE9BA,GAAU,IAEHA,CACT,CACF,EAaMyd,GAAN,MAAMC,WAA0B9E,EAAa,CA2C3C,YAAY+E,EAAwBzY,EAAkC,CACpE,MAAMyY,EAAS,MAAM,EA3CvB,KAAA,oBAAqE,CAAC,EA6BtE,KAAA,uBAAiC,EACjC,KAAA,4BAKI,CAAE,aAAc,GAAO,MAAO,CAAC,CAAE,EASnC,KAAK,SAAWA,EAChB,KAAK,eAAe,EACpB,KAAK,QAAUzY,EACf,IAAMW,EAAWX,EAAQ,SAInB0Y,EAAoB/X,EAAS,wBAA0BA,EAAS,uBA2GtE,GA1GA,KAAK,OAAS,CACZ,YAAa,CACX,MAAO,cACP,SAAU,GACV,YAAa,GACb,WAAY,GACZ,UAAW,cACb,EACA,WAAY,CACV,MAAO,aACP,SAAU,GACV,YAAa,GACb,WAAY,GACZ,WAAY+X,EACZ,UAAW,cACb,EACA,UAAW,CACT,MAAO,YACP,SAAU,GACV,YAAa,GACb,WAAY,GACZ,UAAW,cACb,EACA,aAAc,CACZ,MAAO,eACP,SAAU,GACV,YAAa,GACb,WAAY,GACZ,WAAY/X,EAAS,yBACrB,UAAW,cACb,EACA,UAAW,CACT,MAAO,YACP,SAAU,GACV,YAAa,GACb,WAAY,GACZ,WAAYA,EAAS,sBACrB,UAAW,WACb,EACA,QAAS,CACP,MAAO,UACP,SAAU,GACV,YAAa,GACb,WAAY,GACZ,WAAYA,EAAS,uBACrB,UAAW,QACb,EACA,OAAQ,CAAE,MAAO,SAAU,SAAU,GAAM,YAAa,GAAO,WAAY,GAAO,UAAW,QAAS,EACtG,OAAQ,CAAE,MAAO,SAAU,SAAU,GAAM,YAAa,GAAO,WAAY,GAAO,UAAW,QAAS,CACxG,EACA,KAAK,MAAQ,KAAK,OAAO,YACzB,KAAK,YAAc,KAEnB,KAAK,eAAiB,IAAI4U,GAAa,KAAK,MAAM,EAClD,KAAK,UAAY,EACjB,KAAK,kBAAoB,OACzB,KAAK,aAAe,OACpB,KAAK,cAAgB,OACrB,KAAK,mBAAqB5U,EAAS,mBACnC,KAAK,gBAAkB,KAEvB,KAAK,WAAmBlH,GAAUuG,EAAQ,YAAcqC,EAAS,kBAAmB,KAAK,mBAAmB,EAC5G,KAAK,oBAAsB,KAEvB,KAAK,WAAW,SAASmV,GAAe,SAAS,IACnD,KAAK,4BAA8B,IAEjC,KAAK,WAAW,SAASA,GAAe,UAAU,EACpD,KAAK,cAAgBA,GAAe,WAC3B,KAAK,WAAW,SAASA,GAAe,KAAK,IACtD,KAAK,cAAgBA,GAAe,OAGtC,KAAK,UAAYnV,EAAS,SAASrC,CAAO,EAC1C,KAAK,QAAUqC,EAAS,SAASrC,EAAS,EAAI,EAC9C,KAAK,eAAiB,KACtB,KAAK,KAAO,KACZ,KAAK,yBAA2B,KAChC,KAAK,aAAe,KACpB,KAAK,kBAAoB,GACzB,KAAK,eAAiB,EACtB,KAAK,cAAgB,KACrB,KAAK,mBAAqB,KAC1B,KAAK,qBAAuB,KAC5B,KAAK,mBAAqB,GAE1BrI,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAAgC,SAAS,EACzFA,EAAO,UACL,KAAK,OACLA,EAAO,UACP,+BACA,4BAA8BqI,EAAQ,YAAcqC,EAAS,mBAAqB,GACpF,EACA1K,EAAO,UACL,KAAK,OACLA,EAAO,UACP,+BACA,2BAA6B,KAAK,WAAa,GACjD,EACAA,EAAO,UACL,KAAK,OACLA,EAAO,UACP,+BACA,iBAAmB,KAAK,UAAY,GACtC,EAEI,CAAC,KAAK,WAAW,OAAQ,CAC3B,IAAMnB,EAAM,oCACZ,MAAAmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAAgCnB,CAAG,EAC7E,IAAI,MAAMA,CAAG,CACrB,CAEA,IAAMmiB,EAAmB1iB,EAAS,OAAO,iBACrC0iB,IAEEjB,GAAmB,GAAK,OAAO1X,EAAQ,SAAY,YACrD2Y,EAAiB,eAAgB,KAAK,kBAAkB,KAAK,IAAI,CAAC,EAGhE3Y,EAAQ,gBAAkB,IAC5B2Y,EAAiB,eAAgB,IAAM,CACrChhB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,+BACA,mFACF,EACA,KAAK,aAAa,CAAE,MAAO,SAAU,CAAC,CACxC,CAAC,EAIHghB,EAAiB,SAAU,IAAM,CAlWvC,IAAAhiB,EAmWY,KAAK,OAAS,KAAK,OAAO,cAAgB,KAAK,OAAS,KAAK,OAAO,WACtEgB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,4DACA,yBACF,EACA,KAAK,aAAa,CAAE,MAAO,YAAa,CAAC,GAChC,KAAK,OAAS,KAAK,OAAO,cAEnChB,EAAA,KAAK,mBAAL,MAAAA,EAAuB,IAAA,EACvB,KAAK,wBAAwB,EAE7B,KAAK,aAAa,EAEtB,CAAC,EAEDgiB,EAAiB,UAAW,IAAM,CAC5B,KAAK,OAAS,KAAK,OAAO,YAC5BhhB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,6DACA,gCACF,EAIA,KAAK,wBAAwB,EAEjC,CAAC,EAEL,CAOA,OAAO,oBAAoBihB,EAAqD,CAC9E,IAAMC,EAA4B,CAAE,oBAAqB,CAAC,CAAE,EAC5D,YAAK,eAAeD,EAA2BC,CAAO,EAC/CA,EAAQ,mBACjB,CAEA,OAAe,eAAeD,EAAqDC,EAA2B,CAC5G,IAAMC,EAAkB3X,EAAAA,EAAA,CAAA,EAAKlL,EAAS,WAAW,sBAAA,EAA2B2iB,CAAA,EAE5E,CAACpB,GAAe,UAAW,GAAGvhB,EAAS,WAAW,KAAK,EAAE,QAAS8iB,GAAkB,CAClF,IAAMrD,EAAYoD,EAAgBC,CAAa,EAC3CrD,GAAaA,EAAU,YAAY,IACrCmD,EAAQ,oBAAoBE,CAAa,EAAIrD,EAEjD,CAAC,CACH,CAEA,gBAAiB,CACf8C,GAAkB,eAAe,KAAK,SAAS,oCAAqC,IAAI,CAC1F,CAEA,sBAAsBvY,EAAqB+U,EAA+B,CACxE,OAAO,IAAIoD,GAAgB,KAAK,QAASnY,EAAM+U,EAAM,KAAK,aAAa,CACzE,CAEA,mBAAmBhX,EAA0B,EACvBgb,GAAqB,CACvC,GAAI,KAAK,cAAe,CACtBA,EAAO,QAAQ,EACf,MACF,CAEA,GAAI,OAAO,KAAK,QAAQ,SAAY,SAAU,CAC5CA,EAAO,SAAS,EAChB,MACF,CAEA,IAAMC,EAAY,KAAK,QAAQ,QAC7BC,EAAkB,KAAK,sBAAsB,EAC7CC,EAAsB,KAAK,oBAAoB,EACjD,GAAID,GAAmB,OAAOD,GAAc,WAAY,CACtDthB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,yCACA,2FACEwhB,EACA,GACJ,EACAF,EAAUC,EAAkBE,GAA4B,CAClDA,GACF,KAAK,QAAQ,QAAUF,EAAgB,YACvCF,EAAO,SAAS,GAEhBA,EAAO,OAAO,CAElB,CAAC,EACD,MACF,CACAA,EAAO,OAAO,CAChB,GAEYhE,GAAiB,CAC3B,IAAMmC,EAAkB,KAAK,sBAAsB,KAAMnC,CAAI,EAC7D,GAAIA,IAAS,UAAW,CACtBrd,EAAO,UACL,KAAK,OACLA,EAAO,UACP,yCACA,oDAAsD,KAAK,QAAQ,OACrE,EACA,IAAM2gB,EAAkBJ,GAAkB,KAAK,QAAQ,OAAO,EAC1DI,IACF,KAAK,UAAYA,EAAgB,UAErC,MACE3gB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,yCACA,sBAAwBwf,EAAgB,SAAS,CACnD,EAEFnZ,EAASmZ,CAAe,CAC1B,CAAC,CACH,CAQA,cAAcA,EAAkCkC,EAA0Brb,EAA0B,CAClGrG,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,oCAAqC,UAAY0hB,CAAS,EAE1G,KAAK,kBAAoB9B,GAAU,WACjC,KAAK,oBAAoB8B,CAAS,EAClC,KACA,KAAK,SAAS,KACdlC,EACA,CAACrN,EAAwD4L,IAA0B,CACjF,IAAM4D,EAAQ,KAAK,MACnB,GAAIA,GAAS,KAAK,OAAO,SAAWA,GAAS,KAAK,OAAO,QAAUA,GAAS,KAAK,OAAO,OAAQ,CAC1F5D,IACF/d,EAAO,UACL,KAAK,OACLA,EAAO,UACP,oCACA,cAAgB2hB,EAAM,MAAQ,oDAAsD5D,CACtF,EACAA,EAAU,MAAM,GAElB1X,EAAS,EAAI,EACb,MACF,CAEA,GAAI8L,EAAY,CACdnS,EAAO,UACL,KAAK,OACLA,EAAO,UACP,oCACA,aAAe0hB,EAAY,IAAMvP,EAAW,MAAQ,UAAYA,EAAW,MAAM,SAAS,CAC5F,EAMEzC,GAAK,WAAWyC,EAAW,KAAK,GAChC,EAAE,KAAK,aAAezC,GAAK,WAAW,KAAK,WAAwB,IAEnE,KAAK,YAAcyC,EAAW,MAExBpP,GAAmB,KAAK,SAAS,KAAK,eAAe,KAAM,IAAI,EAAIG,GAA0B,CACjG,GAAIA,EAAK,CACP,KAAK,wBAAwBA,CAAG,EAChC,MACF,CACA,KAAK,cAAcsc,EAAiBkC,EAAWrb,CAAQ,CACzD,CAAC,GACQ8L,EAAW,QAAU,UAE9B,KAAK,YAAY,CAAE,MAAO,SAAU,MAAOA,EAAW,KAAM,CAAC,EAC7D9L,EAAS,EAAI,GACJ8L,EAAW,QAAU,iBACzBwM,GAAYxM,EAAW,KAAK,EAM/B9L,EAAS,EAAK,GAJd,KAAK,YAAY,CAAE,MAAO,KAAK,OAAO,WAAW,UAAqB,MAAO8L,EAAW,KAAM,CAAC,EAC/F9L,EAAS,EAAI,IAMjB,MACF,CAEArG,EAAO,UACL,KAAK,OACLA,EAAO,UACP,oCACA,oBAAsB0hB,EAAY,mBACpC,EACA,KAAK,oBAAoB3D,EAAwByB,CAAe,EAChEnZ,EAAS,KAAM0X,CAAS,CAC1B,CACF,CACF,CAQA,oBAAoBA,EAAsByB,EAAwC,CAChF,IAAMnC,EAAOmC,EAAgB,KAC7Bxf,EAAO,UACL,KAAK,OACLA,EAAO,UACP,0CACA,eAAiB+d,EAAY,YAAcV,CAC7C,EAEA,KAAK,iBAAmBU,EAExB,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAEhCA,EAAU,KAAK,YAAa,CAACvO,EAAkBoS,EAAsBC,IAA2C,CAC9G,KAAK,kBAAkBrS,EAAOuO,EAAW6D,EAAcC,CAAiB,EAEpExE,IAAS,WAAa,KAAK,QAAQ,UAGrC,OAAO,KAAK,QAAQ,QACpB,KAAK,oBAAoB,EAE7B,CAAC,EAED,IAAMxJ,EAAO,KACbkK,EAAU,GAAG,CAAC,eAAgB,SAAU,QAAQ,EAAG,SAAmCvO,EAAkB,CACtGqE,EAAK,oBAAoBkK,EAAW,KAAK,MAAOvO,CAAK,CACvD,CAAC,EAED,KAAK,KAAK,oBAAqBuO,CAAS,CAC1C,CAUA,kBACEvO,EACAuO,EACA6D,EACAC,EACS,CACT7hB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,wCACA,eAAiB+d,CACnB,EACIvO,GACFxP,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,wCAAyC,WAAawP,CAAK,EAEzGoS,GACF5hB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,wCACA,mBAAqB4hB,CACvB,EAEEC,GACF7hB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,wCACA,wBAA0B,KAAK,UAAU6hB,CAAiB,CAC5D,EAGF,KAAK,2BAA2B9D,CAAS,EAIzC,IAAM+D,EAAgB,KAAK,MACzBC,EAAiB,KAAK,OAAO,UAAU,MAOzC,GANA/hB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,wCACA,mBAAqB8hB,EAAc,KACrC,EAEEA,EAAc,OAAS,KAAK,OAAO,QAAQ,OAC3CA,EAAc,OAAS,KAAK,OAAO,OAAO,OAC1CA,EAAc,OAAS,KAAK,OAAO,OAAO,MAE1C,OAAA9hB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,wCACA,wCACF,EACA+d,EAAU,WAAW,EACd,GAMT,GAHA,OAAO,KAAK,iBAGR,CAACA,EAAU,YACb,OAAA/d,EAAO,UACL,KAAK,OACLA,EAAO,UACP,wCACA,mCAAqC+d,EAAY,6CACnD,EACO,GAKT,IAAMiE,EAAyB,KAAK,eACpC,KAAK,eAAiB,IAAI9D,GAASH,CAAS,EAC5C,KAAK,KAAOA,EAAU,OAAO,KAE7B,IAAM2C,EAAgBmB,EAAkB,cAsCxC,GArCInB,GAAiB,KAAK,eAAiBA,GACzC,KAAK,cAAckB,EAAcC,EAAmB,CAAC,CAACrS,CAAK,EAQ7D,KAAK,0BAA0BqS,EAAmB9D,CAAS,EAC3Dzf,EAAS,OAAO,SAAS,IAAM,CAC7Byf,EAAU,GACR,YACA,CAACkE,EAAyBC,EAAuBL,IAA2C,CAC1F,KAAK,0BAA0BA,EAAmB9D,CAAS,EAC3D,KAAK,KAAK,SAAU,IAAIS,GAAsBuD,EAAgBA,EAAgB,KAAME,CAAY,CAAC,CACnG,CACF,CACF,CAAC,EAIGH,EAAc,QAAU,KAAK,OAAO,UAAU,MAC5CtS,IACF,KAAK,YAAc,KAAK,SAAS,WAAW,YAAcA,EAC1D,KAAK,KAAK,SAAU,IAAIgP,GAAsBuD,EAAgBA,EAAgB,KAAMvS,CAAK,CAAC,IAG5F,KAAK,YAAY,CAAE,MAAO,YAAa,MAAAA,CAAa,CAAC,EACrD,KAAK,YAAc,KAAK,SAAS,WAAW,YAAcA,GAAS,MAKrE,KAAK,KAAK,mBAAoBuO,CAAS,EAGnCiE,EAmBF,GAlBIA,EAAuB,aAAa,MAAM,EAAI,GAKhDhiB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,wCACA,2CACEgiB,EAAuB,UAAU,UACjC,gBACAjE,EAAU,UACV,oBACAiE,EAAuB,aAAa,MAAM,EAC1C,yBACJ,EAEEA,EAAuB,YAAcjE,EAAW,CAClD,IAAMlf,EACJ,yHACAkf,EAAU,UACV,aACA,IAAI,MAAM,EAAE,MACd/d,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,wCAAyCnB,CAAG,CAC9F,MACEmjB,EAAuB,OAAO,EAIlC,MAAO,EACT,CAOA,oBAAoBjE,EAAsB4D,EAAenS,EAAwB,CAC/E,IAAM2S,EAAkB,KAAK,eAC3BC,EAAYD,GAAmBA,EAAgB,aAAa,IAAMpE,EAClEsE,EAAatE,IAAc,KAAK,iBAChCuE,EAAqC,KAAK,mCAAmC,EAmD/E,GAjDAtiB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,0CACA,eAAiB+d,CACnB,EACA/d,EAAO,UACL,KAAK,OACLA,EAAO,UACP,0CACA,WACE2hB,GACCS,EAAY,eAAiBC,EAAa,gBAAkB,KAC5DC,EAAqC,GAAK,kDAC/C,EACI9S,GAASA,EAAM,SACjBxP,EAAO,UACL,KAAK,OACLA,EAAO,UACP,0CACA,aAAewP,EAAM,OACvB,EAEE4S,IACFpiB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,0CACA,oCACG,KAAK,eAA4B,aAAa,MAAM,EACrD,mBACJ,EACA,KAAK,qBAAsBmiB,EAA6B,mBAAmB,CAAC,EAE3EA,EAA6B,qBAAqB,EACnD,KAAK,eAAiB,KAAK,KAAO,MAGpC,KAAK,KAAK,qBAAsBpE,CAAS,EAYtCqE,GAAaE,GACbF,GAAaT,IAAU,UACxBA,IAAU,UACTQ,IAAoB,MAAQE,EAC7B,CAWA,GAAIV,IAAU,gBAAkBnS,GAAUA,EAAM,WAAwB,KAAO,KAAK,UAAU,OAAS,EAAG,CACxG,KAAK,6BAA6B,EAClC,KAAK,kBAAoB,GAEzB,KAAK,YAAY,CAAE,MAAAmS,EAAc,MAAAnS,EAAc,iBAAkB,EAAK,CAAC,EACvE,MACF,CAGA,IAAM+S,EAAqBZ,IAAU,UAAYjS,GAAK,WAAWF,CAAK,EAAI,eAAiBmS,EAC3F,KAAK,YAAY,CAAE,MAAOY,EAAoB,MAAA/S,CAAa,CAAC,EAC5D,MACF,CACF,CAKA,oCAA8C,CAC5C,MAAO,CAAC,KAAK,kBAAoB,CAAC,KAAK,iBAAiB,WAC1D,CAEA,cAAcoS,EAAsBC,EAAwCW,EAAoC,CAM9G,IAAMC,EAAa,KAAK,cACNA,GAAcA,IAAeb,GAC5B,CAACa,GAAcD,KAEhCxiB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,oCAAqC,qBAAqB,EAC1G,KAAK,UAAY,EAGjB,KAAK,eAAe,mBAAmB,GAErC,KAAK,eAAiB4hB,GACxB5hB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,oCACA,qDACF,EAEF,KAAK,SAAS,WAAW,GAAK,KAAK,aAAe4hB,EAClD,KAAK,SAAS,WAAW,IAAM,KAAK,cAAgBC,EAAkB,aACxE,CAEA,iBAAwB,CACtB,KAAK,SAAS,WAAW,GAAK,KAAK,aAAe,OAClD,KAAK,SAAS,WAAW,IAAM,KAAK,cAAgB,OACpD,KAAK,UAAY,EACjB,KAAK,oBAAoB,CAC3B,CAEA,mBAAmC,CAEjC,OAAK,KAAK,cAIH,KAAK,UAAU,CACpB,cAAe,KAAK,cACpB,UAAW,KAAK,UAChB,eAAgB,KAAK,SAAS,SAAS,eAAe,CACxD,CAAC,EAPQ,IAQX,CAEA,+BAAsC,CACpC,GAAI,CAAC,KAAK,cAAgB,CAAC,KAAK,aAC9B,OAGF,IAAMxC,EAAY,KAAK,IAAI,EAAI,KAAK,aAChCA,EAAY,KAAK,mBAAsB,KAAK,kBAC9Crf,EAAO,UACL,KAAK,OACLA,EAAO,UACP,oDACA,yCAA2Cqf,EAAY,qCACzD,EACA,KAAK,gBAAgB,EACrB,KAAK,OAAO,WAAW,UAAY,YAEvC,CAMA,mBAA0B,CACxB,GAAIU,GAAmB,EAAG,CACxB,IAAMS,EAAc,KAAK,kBAAkB,EACvCA,GACF,KAAK,sBAAsB,CACzB,YAAAA,EACA,eAAgB,KAAK,IAAI,EACzB,SAAUjiB,GAAa,SACvB,SAAU,KAAK,SAAS,KAAK,QAC/B,CAAC,CAEL,CACF,CAMA,qBAA4B,CAC1B,KAAK,wBAAwB,CAC/B,CAMA,UAAuC,CACrC,GAAI,KAAK,YAAa,CAGpB,IAAMmkB,EAAWjf,GAAiB,WAAW,KAAK,WAAW,EAC7D,OAAAif,EAAS,MAAQ,KAAK,YACfA,CACT,CAEA,OAAO,KAAK,cAAc,CAC5B,CAEA,eAA2B,CAv8B7B,IAAA1jB,EAAA4G,EAw8BI,OAAQA,GAAA5G,EAAA4f,IAAqD,KAAK,MAAM,KAAA,IAAhE,KAAA,OAAAhZ,EAAA,KAAA5G,CAAAA,CACV,CAEA,aAA8B,CAC5B,OAAO,KAAK,MAAM,aAAe,KAAK,MAAM,UAC9C,CAEA,iBAAiB2jB,EAA0C,CACzD,IAAMjjB,EAAS,mBACTC,EAAUgjB,EAAY,SAAWA,EAAY,OAAS,aAAeA,EAAY,OAAS,IAC5FA,EAAY,UAAY,SAC1B3iB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAWN,EAAQC,CAAO,EAE/DK,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAWN,EAAQC,CAAO,EAEjEK,EAAO,UACL,KAAK,OACLA,EAAO,UACP,qCACA,sBACE2iB,EAAY,QACZ,eACCA,EAAY,QAAWA,EAAY,OAAqB,QAC7D,EACA,IAAMC,EAAY,KAAK,MAAQ,KAAK,OAAOD,EAAY,OAAiB,EACpEA,EAAY,SACd,KAAK,YAAcA,EAAY,OAE/B,KAAK,SAAS,WAAW,YAAcA,EAAY,SAEjDC,EAAS,UAAYA,EAAS,QAAU,cAI1C,KAAK,gBAAgB,EAEvB,KAAK,KAAK,kBAAmBD,CAAW,CAC1C,CAMA,qBAAqBE,EAAwC,CAC3D7iB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,2CACA,oBAAsB6iB,EAAgB,KACxC,EAEI,KAAK,kBACP7iB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,2CACA,gCACF,EACA,aAAa,KAAK,eAAyB,GAG7C,KAAK,gBAAkB,WAAW,IAAM,CAClC,KAAK,kBACP,KAAK,gBAAkB,KACvBA,EAAO,UACL,KAAK,OACLA,EAAO,UACP,qBAAuB6iB,EAAgB,MAAQ,iBAC/C,yBAA2BA,EAAgB,SAC7C,EACA,KAAK,YAAY,CAAE,MAAOA,EAAgB,SAAoB,CAAC,EAEnE,EAAGA,EAAgB,UAAU,CAC/B,CAEA,uBAA8B,CAC5B7iB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,4CAA6C,EAAE,EAC3F,KAAK,kBACP,aAAa,KAAK,eAAyB,EAC3C,KAAK,gBAAkB,KAE3B,CAEA,mBAA0B,CACpB,KAAK,eACT,KAAK,aAAe,WAAW,IAAM,CAC/B,KAAK,eACP,KAAK,aAAe,KACpBA,EAAO,UACL,KAAK,OACLA,EAAO,UACP,0CACA,iCACF,EACA,KAAK,OAAO,WAAW,UAAY,YACnC,KAAK,YAAY,CAAE,MAAO,WAAY,CAAC,EAE3C,EAAG,KAAK,kBAAkB,EAC5B,CAEA,kBAAkB2hB,EAAqB,CACjCA,IAAU,gBAAkBA,IAAU,aAAeA,IAAU,cAAc,KAAK,mBAAmB,CAC3G,CAEA,oBAA2B,CACzB,KAAK,OAAO,WAAW,UAAY,eAC/B,KAAK,eACP,aAAa,KAAK,YAAsB,EACxC,KAAK,aAAe,KAExB,CAEA,gBAAgBmB,EAAwB,CACtC,KAAK,WAAa,WAAW,IAAM,CACjC9iB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,wCAAyC,UAAU,EACnG,KAAK,WAAa,KAClB,KAAK,aAAa,CAAE,MAAO,YAAa,CAAC,CAC3C,EAAG8iB,CAAQ,CACb,CAEA,kBAAyB,CACnB,KAAK,aACP,aAAa,KAAK,UAA4B,EAC9C,KAAK,WAAa,KAEtB,CAEA,yBAA0B,CACxB,KAAK,mBAAqB,WAAW,IAAM,CACzC9iB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,yCACA,uBACF,EACA,KAAK,oBAAoB,EACtB,KAAK,IAAM,CACVA,EAAO,UACL,KAAK,OACLA,EAAO,UACP,yCACA,iCACF,EACA,KAAK,cAAgB,EACvB,CAAC,EACA,MAAM,IAAM,CACXA,EAAO,UACL,KAAK,OACLA,EAAO,UACP,yCACA,8BACF,EACA,KAAK,cAAgB,EACvB,CAAC,EACC,KAAK,SAAS,KAAK,mBACf+C,GAAmB,KAAK,SAAS,KAAK,kBAAkB,EAAG,CAACG,EAAK6f,IAAiB,CAClF7f,GAAO,CAAC6f,GACV/iB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,yCACA,gCACF,EACA,KAAK,2BAA2B,EAChC,KAAK,YAAY,CACf,MAAO,eACP,MAAO,IAAIlC,EAAU,0CAA2C,MAAO,GAAG,CAC5E,CAAC,GAEDkC,EAAO,UACL,KAAK,OACLA,EAAO,UACP,yCACA,mCACF,CAEJ,CAAC,CAEL,EAAG,KAAK,QAAQ,SAAS,oBAAoB,CAC/C,CAEA,0BAA2B,CACrB,KAAK,qBACP,aAAa,KAAK,kBAAkB,EACpC,KAAK,mBAAqB,KAE9B,CAEA,0BAA0Bwf,EAAkC,CAC1D,KAAK,qBAAuB,WAAW,IAAM,CAroCjD,IAAAxgB,EAAA4G,EAsoCW,KAAK,gBACR5F,EAAO,UACL,KAAK,OACLA,EAAO,UACP,4CACA,6CAA+C,KAAK,cAAgB,wBAA0B,GAChG,EACI,KAAK,eACP,KAAK,mBAAqB,IAC1BhB,EAAA,KAAK,oBAAL,MAAAA,EAAwB,QAAA,GACxB4G,EAAA,KAAK,mBAAL,MAAAA,EAAuB,QAAA,EACvB,KAAK,YAAY4Z,EAAiB,EAAE,KAAK,cAAc,GAGvDxf,EAAO,UACL,KAAK,OACLA,EAAO,UACP,4CACA,iFACF,EAGN,EAAG,KAAK,QAAQ,SAAS,uBAAuB,CAClD,CAEA,4BAA6B,CACvB,KAAK,uBACP,aAAa,KAAK,oBAAoB,EACtC,KAAK,qBAAuB,KAEhC,CAEA,YAAYgjB,EAAkC,CAtqChD,IAAAhkB,EAAA4G,EAuqCI,IAAM+b,EAAQqB,EAAU,MAUlBC,EACJtB,IAAU,iBACT,KAAK,QAAU,KAAK,OAAO,WAC1BqB,EAAU,kBACT,KAAK,QAAU,KAAK,OAAO,YAC1BA,EAAU,OACVtT,GAAK,WAAWsT,EAAU,KAAK,GAC/B,EAAE,KAAK,aAAetT,GAAK,WAAW,KAAK,WAAwB,IAwBzE,GAtBA1P,EAAO,UACL,KAAK,OACLA,EAAO,UACP,kCACA,cAAgB2hB,GAASsB,EAAmB,sCAAwC,GACtF,EAEItB,GAAS,KAAK,MAAM,QAIxB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,kBAAkBqB,EAAU,KAAK,GAElCrB,IAAU,aAAeA,IAAU,eACrC,KAAK,uBAAyB,GAI5B,KAAK,MAAM,UAAU,OAGzB,IAAMiB,EAAW,KAAK,OAAOI,EAAU,KAAK,EAExCE,EAAaN,EAAS,WACtBA,EAAS,QAAU,iBACrB,KAAK,yBACLM,EAAmBxhB,GAAakhB,EAAS,WAAsB,KAAK,sBAAsB,GAG5F,IAAMO,EAAS,IAAI3E,GACjB,KAAK,MAAM,MACXoE,EAAS,MACTM,EACAF,EAAU,SAAUpd,GAAA5G,EAAA4f,IAA8DgE,EAAS,KAAA,IAAvE,KAAA,OAAAhd,EAAA,KAAA5G,CAAAA,EACtB,EAEA,GAAIikB,EAAkB,CACpB,IAAMG,EAAgB,IAAM,CACtB,KAAK,QAAU,KAAK,OAAO,eAC7B,KAAK,yBAA2B,KAAK,IAAI,EACzC,KAAK,aAAa,CAAE,MAAO,YAAa,CAAC,EAE7C,EACM/D,EAAY,KAAK,0BAA4B,KAAK,IAAI,EAAI,KAAK,yBAA2B,EAC5FA,GAAaA,EAAY,KAC3Brf,EAAO,UACL,KAAK,OACLA,EAAO,UACP,kCACA,mCACEqf,EACA,4BACC,IAAOA,GACR,wBACJ,EACA,WAAW+D,EAAe,IAAO/D,CAAS,GAE1C/gB,EAAS,OAAO,SAAS8kB,CAAa,CAE1C,MAAWzB,IAAU,gBAAkBA,IAAU,cAC/C,KAAK,gBAAgBuB,CAAoB,GAKtCvB,IAAU,gBAAkB,CAACsB,GAAqBtB,IAAU,aAAeiB,EAAS,WAGvFtkB,EAAS,OAAO,SAAS,IAAM,CAC7B,KAAK,wBAAwB,CAC/B,CAAC,EAGCqjB,GAAS,aAAe,CAAC,KAAK,gBAChC3hB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,kCACA,yFACF,EAIF,KAAK,iBAAiBmjB,CAAM,EACxB,KAAK,MAAM,WACb,KAAK,mBAAmB,EACd,KAAK,MAAM,cACrB,KAAK,SAAS,SAAS,gCAAgCxB,EAAOwB,EAAO,MAAM,EAC3E,KAAK,mBAAmBA,EAAO,MAAmB,EAEtD,CAEA,aAAaxU,EAAoB,CA1xCnC,IAAA3P,EAAA4G,EA2xCI,IAAM+b,EAAQhT,EAAQ,MAmBtB,GAlBA3O,EAAO,UACL,KAAK,OACLA,EAAO,UACP,mCACA,oBAAsB2hB,EAAQ,oBAAsB,KAAK,MAAM,KACjE,EACIA,GAAS,KAAK,MAAM,QAGxB,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EAGtB,KAAK,kBAAkBA,CAAK,EAExBA,GAAS,cAAgB,KAAK,MAAM,OAAS,cAC7CA,GAAS,WAAa,KAAK,MAAM,OAAS,SAAU,OAExD,IAAMiB,EAAW,KAAK,OAAOjB,CAAK,EAChCwB,EAAS,IAAI3E,GACX,KAAK,MAAM,MACXoE,EAAS,MACT,KACAjU,EAAQ,SAAU/I,GAAA5G,EAAA4f,IAA8DgE,EAAS,KAAA,IAAvE,KAAA,OAAAhd,EAAA,KAAA5G,CAAAA,EACpB,EAEF,KAAK,iBAAiBmkB,CAAM,EAExBxB,GAAS,cACXrjB,EAAS,OAAO,SAAS,IAAM,CAC7B,KAAK,aAAa,CACpB,CAAC,EAECqjB,GAAS,WACX,KAAK,UAAU,CAEnB,CAEA,cAAqB,CACnB,GAAI,KAAK,QAAU,KAAK,OAAO,WAAY,CACzC3hB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,mCACA,mDAAqD,KAAK,MAAM,KAClE,EACA,MACF,CAEA,IAAMif,EAAO,KAAK,SAAS,KAQrBoE,EAAe,EAAE,KAAK,eAEtBC,EAAU,IAAM,CACpB,KAAK,8BAA8B,EACnC,KAAK,mBAAoB9D,GAAqC,CAC5D,GAAIA,EAAgB,OAAS,WAAaA,EAAgB,QAAQ,QAAS,CACzE,IAAMmB,EAAkBJ,GAAkBf,EAAgB,QAAQ,OAAO,EACrEmB,GACF,KAAK,SAAS,SAAS,gBAAgBA,EAAgB,cAAc,CAEzE,CAEI0C,IAAiB,KAAK,gBAG1B,KAAK,YAAY7D,EAAiB6D,CAAY,CAChD,CAAC,CACH,EAMA,GAJArjB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,mCAAoC,qBAAqB,EACzG,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,KAAK,OAAO,UAAU,EAE5Cif,EAAK,SAAW,QAClBqE,EAAQ,MACH,CACL,IAAMC,EAAUrgB,GAA0B,CACpCmgB,IAAiB,KAAK,iBAGtBngB,EACF,KAAK,wBAAwBA,CAAG,EAEhCogB,EAAQ,EAEZ,EACI,KAAK,aAAe5T,GAAK,WAAW,KAAK,WAAwB,EAE7D3M,GAAmBkc,EAAK,eAAe,KAAM,IAAI,EAAGsE,CAAM,EAE1DxgB,GAAmBkc,EAAK,4BAA4B,EAAK,EAAGsE,CAAM,CAE5E,CACF,CAkBA,YAAY/D,EAAkC6D,EAA4B,CACxE,IAAM1B,EAAQ,KAAK,MAAM,MACzB,GAAIA,IAAU,KAAK,OAAO,WAAW,MAAO,CAI1C3hB,EAAO,UACL,KAAK,OAELA,EAAO,UACP,kCACA,mDAAqD2hB,CACvD,EACA,MACF,CAEA,IAAM6B,EAAsB,KAAK,uBAAuB,EAGpDA,GAAuBA,IAAwB,KAAK,eAAiB,KAAK,6BAC5E,KAAK,oBAAoB,EACtB,KAAK,IAAM,CACV,KAAK,6BAA6B,EAC9B,KAAK,QAAU,KAAK,OAAO,aAC7BxjB,EAAO,UACL,KAAK,OAELA,EAAO,UACP,mCACA,yEAA2E,KAAK,aAClF,EACA,KAAK,wBAAwB,EAC7B,KAAK,UAAUwf,EAAiB,EAAE,KAAK,cAAc,EAEzD,CAAC,EACA,MAAMQ,EAAI,EAIZwD,GAAuBA,IAAwB,KAAK,eACpD,KAAK,eAAiB,CAAC,KAAK,4BAE7B,KAAK,YAAYhE,EAAiB6D,CAAY,EAE9C,KAAK,UAAU7D,EAAiB6D,CAAY,CAEhD,CAeA,UAAU7D,EAAkC6D,EAAsB,CAChErjB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAA+B,EAC/E,KAAK,cAAgB,KACrB,KAAK,mBAAqB,GAC1B,KAAK,wBAAwB,EAC7B,KAAK,0BAA0Bwf,CAAe,EAE9C,KAAK,0BAA0B,aAAcA,EAAiB,GAAM6D,EAAc,IACzE,KAAK,gBAAkB,IAAS,CAAC,KAAK,kBAC9C,CACH,CAEA,YAAY7D,EAAkC6D,EAAsB,CAClErjB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,iCAAiC,EAC7E,KAAK,cACP,KAAK,0BAA0B,KAAK,cAAewf,EAAiB,GAAO6D,EAAc,IAAM,EAAI,EAEnG,KAAK,YAAY,CACf,MAAO,eACP,MAAO,IAAIvlB,EAAU,4BAA6B,IAAO,GAAG,CAC9D,CAAC,CAEL,CAEA,0BACEsjB,EACA5B,EACAjX,EACA8a,EACAI,EACM,CACNzjB,EAAO,UACL,KAAK,OAELA,EAAO,UACP,gDACAohB,CACF,EACA,IAAMsC,EAAUxgB,GAA2B,CACzC,KAAK,YAAY,CAAE,MAAO,KAAK,OAAO,WAAW,UAAqB,MAAOA,CAAI,CAAC,CACpF,EAEMuN,EAAiBlI,EAAK,KAAK,QAAQ,MAAM,EAAI,KAAK,UAAU,MAAM,EAElEob,EAAgB,CAACC,EAAgB7F,IAAyB,CAC9D,GAAIsF,IAAiB,KAAK,eAG1B,IAAI,CAACI,EAAe,EAAG,CACjB1F,GACFA,EAAU,QAAQ,EAEpB,MACF,CACI,CAACA,GAAa,CAAC6F,GACjBC,EAAiB,EAErB,EAGMvb,EAAOmI,EAAe,MAAM,EAClC,GAAI,CAACnI,EAAM,CACTob,EAAO,IAAI5lB,EAAU,wCAAyC,MAAO,GAAG,CAAC,EACzE,MACF,CACA0hB,EAAgB,KAAOlX,EAGvB,IAAMub,EAAmB,IAAM,CAE7B,GAAI,CAACpT,EAAe,OAAQ,CAC1BiT,EAAO,IAAI5lB,EAAU,wDAAyD,MAAO,GAAG,CAAC,EACzF,MACF,CAIA,GAAI,CAAC,KAAK,SAAS,KAAK,kBAAmB,CACzC4lB,EAAO,IAAIjgB,GAAiB,iDAAkD,KAAM,GAAG,CAAC,EACxF,MACF,CACMV,GACJ,KAAK,SAAS,KAAK,kBAAkB,EACrC,CAACG,EAAwB6f,IAA2B,CAClD,GAAIM,IAAiB,KAAK,gBAGrBI,EAAe,EAIpB,IAAIvgB,EAAK,CACPwgB,EAAOxgB,CAAG,EACV,MACF,CACA,GAAI,CAAC6f,EAAc,CAEjBW,EAAO,IAAI5lB,EAAU,0CAA2C,MAAO,GAAG,CAAC,EAC3E,MACF,CAIA0hB,EAAgB,KAAa7e,GAAoB8P,CAAc,EAC/D,KAAK,cAAc+O,EAAiB4B,EAAeuC,CAAa,EAClE,CACF,CACF,EAEA,GAAI,KAAK,mBAAqBlT,EAAe,OAAQ,CACnD,KAAK,kBAAoB,GACzBoT,EAAiB,EACjB,MACF,CAEA,KAAK,cAAcrE,EAAiB4B,EAAeuC,CAAa,CAClE,CAEA,WAAkB,CAChB3jB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,gCAAiC,oBAAoB,EACrG,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,KAAK,OAAO,OAAO,EAEzC,KAAK,mBACPA,EAAO,UACL,KAAK,OAELA,EAAO,UACP,gCACA,8BAAgC,KAAK,gBACvC,EACA,KAAK,iBAAiB,MAAM,GAG1B,KAAK,iBACPA,EAAO,UACL,KAAK,OAELA,EAAO,UACP,gCACA,6BAA+B,KAAK,eAAe,aAAa,CAClE,EACA,KAAK,eAAe,aAAa,EAAE,MAAM,GAK3C,KAAK,YAAY,CAAE,MAAO,QAAS,CAAC,CACtC,CAEA,cAAc8M,EAAgCzG,EAA0B,CAvmD1E,IAAArH,EAwmDI,OAAQ,KAAK,MAAM,MAAO,CACxB,IAAK,YAAa,CAChBgB,EAAO,UACL,KAAK,OAELA,EAAO,UACP,oCACA,0CACF,EAGA,IAAM8jB,GAAkB9kB,EAAA,KAAK,iBAAL,KAAA,OAAAA,EAAqB,aAAA,EACzC8kB,GAAmBA,EAAgB,eACrCA,EAAgB,cAAchX,CAAY,EAG5C,IAAMiX,EAAUtM,GAA0B,CACxC,OAAQM,EAAQ,KAChB,KAAM,CACJ,YAAajL,EAAa,KAC5B,CACF,CAAC,EACD,KAAK,KAAKiX,CAAO,EAKjB,IAAMC,EAAkB,IAAM,CAC5B,KAAK,IAAIC,CAAe,EACxB5d,EAAS,KAAMyG,CAAY,CAC7B,EACMmX,EAAmBtB,GAAuC,CAC1DA,EAAY,UAAY,WAC1B,KAAK,IAAIqB,CAAe,EACxB,KAAK,IAAIC,CAAe,EACxB5d,EAASsc,EAAY,QAAU,KAAK,cAAc,CAAC,EAEvD,EACA,KAAK,KAAK,oBAAqBqB,CAAe,EAC9C,KAAK,GAAG,kBAAmBC,CAAe,EAC1C,KACF,CAEA,IAAK,aACHjkB,EAAO,UACL,KAAK,OAELA,EAAO,UACP,oCACA,wFACF,EACA,KAAK,wBAAwB,EAG/B,QAAS,CACPA,EAAO,UACL,KAAK,OAELA,EAAO,UACP,oCACA,uBAAyB,KAAK,MAAM,MAAQ,4CAC9C,EACA,IAAM6a,EAAY8H,GAAuC,CACvD,OAAQA,EAAY,QAAS,CAC3B,IAAK,YACH,KAAK,IAAI9H,CAAQ,EACjBxU,EAAS,KAAMyG,CAAY,EAC3B,MACF,IAAK,SACL,IAAK,SACL,IAAK,YACH,KAAK,IAAI+N,CAAQ,EACjBxU,EAASsc,EAAY,QAAU,KAAK,cAAc,CAAC,EACnD,MACF,QAEE,KACJ,CACF,EACA,KAAK,GAAG,kBAAmB9H,CAAQ,EAC/B,KAAK,MAAM,QAAU,aAGvB,KAAK,aAAa,EAElB,KAAK,aAAa,CAAE,MAAO,YAAa,CAAC,CAE7C,CACF,CACF,CAEA,yBAAgC,CAC9B7a,EAAO,UACL,KAAK,OAELA,EAAO,UACP,8CACA,8BACF,EAGA,KAAK,iBAED,KAAK,mBACPA,EAAO,UACL,KAAK,OAELA,EAAO,UACP,8CACA,oCAAsC,KAAK,gBAC7C,EACA,KAAK,iBAAiB,WAAW,GAEnC,OAAO,KAAK,iBAER,KAAK,oBACPA,EAAO,UACL,KAAK,OAELA,EAAO,UACP,8CACA,qCAAuC,KAAK,gBAC9C,EACA,KAAK,kBAAkB,WAAW,GAEpC,OAAO,KAAK,iBAER,KAAK,iBACPA,EAAO,UACL,KAAK,OAELA,EAAO,UACP,8CACA,mCAAqC,KAAK,eAAe,aAAa,CACxE,EACA,KAAK,eAAe,aAAa,EAAE,WAAW,EAIlD,CAMA,KAAKnB,EAAsBqlB,EAAsB7d,EAA8B,CAC7EA,EAAWA,GAAY2Z,GACvB,IAAM2B,EAAQ,KAAK,MAEnB,GAAIA,EAAM,WAAY,CACpB3hB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,eAAe,EAC3F,KAAK,SAAS,IAAI6d,GAAehf,EAAKwH,CAAQ,CAAC,EAC/C,MACF,CAEA,GAAI,EADgB6d,GAAcvC,EAAM,aACtB,CAChB,IAAMze,EAAM,mCAAqCghB,EAAa,eAAiBvC,EAAM,MACrF3hB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4BkD,CAAG,EAC/EmD,EAAS,KAAK,aAAe,IAAIvI,EAAUoF,EAAK,IAAO,GAAG,CAAC,EAC3D,MACF,CACI,KAAK,OAAO,UAAUlD,EAAO,SAAS,GACxCA,EAAO,UACL,KAAK,OAELA,EAAO,UACP,2BACA,iBAAmB8c,GAAyBje,EAAK,KAAK,SAAS,iBAAiB,CAClF,EAEF,KAAK,MAAMA,EAAKwH,CAAQ,CAC1B,CAEA,SAAS4X,EAAsC,CAC7C,IAAMpf,EAAMof,EAAe,QAGvBA,EAAe,aAAe,CAACA,EAAe,gBAChDpf,EAAI,UAAY,KAAK,aAEvB,GAAI,CACD,KAAK,eAA4B,KAAKof,CAAc,CACvD,OAAS7W,EAAG,CACVpH,EAAO,UACL,KAAK,OAELA,EAAO,UACP,+BACA,6CAAgDoH,EAAY,KAC9D,CACF,CACF,CAEA,MAAMvI,EAAsBwH,EAA6B,CACvDrG,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,4BAA6B,gBAAgB,EAC7F,IAAMmkB,EAAa,KAAK,eAAe,KAAK,EACtC/D,EAAU,KAAK,QAAQ,eAIzB+D,GAAc,CAACA,EAAW,eAAiBjE,GAAWiE,EAAW,QAAStlB,EAAKuhB,CAAO,GACnF+D,EAAW,SACdA,EAAW,SAAWjZ,GAAY,OAAO,KAAK,OAAQ,CAACiZ,EAAW,QAAQ,CAAC,EAC3EA,EAAW,OAAS,IAErBA,EAAW,SAAuC,KAAK9d,CAAQ,GAEhE,KAAK,eAAe,KAAK,IAAIwX,GAAehf,EAAKwH,CAAQ,CAAC,CAE9D,CAEA,oBAA2B,CACzBrG,EAAO,UACL,KAAK,OAELA,EAAO,UACP,yCACA,WAAa,KAAK,eAAe,MAAM,EAAI,kBAC7C,EACA,IAAIie,EACJ,KAAQA,EAAiB,KAAK,eAAe,MAAM,GAAI,KAAK,SAASA,CAAc,CACrF,CAEA,qBAAqBmG,EAA8C,CAC7DA,GAAmBA,EAAgB,SACrCpkB,EAAO,UACL,KAAK,OAELA,EAAO,UACP,2CACA,YAAcokB,EAAgB,OAAS,mBACzC,EACA,KAAK,eAAe,QAAQA,CAAe,EAE/C,CAEA,mBAAmBlhB,EAAsB,CACvC,IAAMmhB,EAAY,KAAK,eAAe,MAAM,EACxCA,EAAY,IACdrkB,EAAO,UACL,KAAK,OAELA,EAAO,UACP,yCACA,WAAaqkB,EAAY,2BAAmCxiB,EAAaqB,CAAG,CAC9E,EACA,KAAK,eAAe,oBAAoBA,CAAG,EAE/C,CAEA,iBAAiBvD,EAA0Boe,EAA4B,CACrE,KAAK,4BAA4B,MAAM,KAAK,CAAE,QAAApe,EAAS,UAAAoe,CAAU,CAAC,EAE7D,KAAK,4BAA4B,cACpC,KAAK,iCAAiC,CAE1C,CAEQ,kCAAmC,CACzC,GAAI,KAAK,4BAA4B,MAAM,OAAS,EAAG,CACrD,KAAK,4BAA4B,aAAe,GAEhD,IAAMuG,EAAwB,KAAK,4BAA4B,MAAM,MAAM,EAC3E,KAAK,sBAAsBA,EAAsB,OAAO,EACrD,MAAOphB,GAAQ,CACdlD,EAAO,UACL,KAAK,OAELA,EAAO,UACP,uEACAkD,CACF,CACF,CAAC,EACA,QAAQ,IAAM,CACb,KAAK,4BAA4B,aAAe,GAChD,KAAK,iCAAiC,CACxC,CAAC,CACL,CACF,CAEA,MAAc,sBAAsBvD,EAA0B,CAC5D,MAAM,KAAK,SAAS,SAAS,sBAAsBA,CAAO,CAC5D,CAEA,MAAM,MAAwB,CAp4DhC,IAAAX,EAq4DI,GAAI,KAAK,MAAM,QAAU,YACvB,MAAM,IAAIlB,EAAU,wCAAyC,IAAO,GAAG,EAGzE,IAAMigB,GAAY/e,EAAA,KAAK,iBAAL,KAAA,OAAAA,EAAqB,aAAA,EACvC,GAAI,CAAC+e,EACH,MAAM,KAAK,cAAc,EAG3B/d,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,eAAiB+d,CAAS,EAEtG,IAAMwG,EAAY,KAAK,IAAI,EACrBnF,EAAWte,GAAa,EAE9B,OAAakC,GACX,IAAI,QAASgI,GAAY,CACvB,IAAMwZ,EAAeC,GAAuB,CACtCA,IAAerF,IACjBrB,EAAU,IAAI,YAAayG,CAAW,EACtCxZ,EAAQ,KAAK,IAAI,EAAIuZ,CAAS,EAElC,EACAxG,EAAU,GAAG,YAAayG,CAAW,EACrCzG,EAAU,KAAKqB,CAAE,CACnB,CAAC,EACD,KAAK,QAAQ,SAAS,uBACtB,wCACF,CACF,CAEA,MAAM5P,EAAwB,CAC3B,KAAK,eAA4B,aAAa,EAAE,KAAKA,CAAK,CAC7D,CAEA,wBAAwC,CAv6D1C,IAAAxQ,EAAA4G,EAw6DI,OAAO,KAAK,qBAAwBka,GAAe,KAAKla,GAAA5G,EAAAV,EAAS,aAAT,KAAA,OAAAU,EAAqB,MAArB,KAAA,OAAA4G,EAAA,KAAA5G,EAA2BihB,EAAA,EACrF,CAEA,2BAA2BlC,EAA4B,CA36DzD,IAAA/e,EAAA4G,EA46DI,KAAK,oBAAsBmY,EAAU,UACjC+B,GAAe,KACjBla,GAAA5G,EAAAV,EAAS,aAAT,KAAA,OAAAU,EAAqB,MAArB,MAAA4G,EAAA,KAAA5G,EAA2BihB,GAAyBlC,EAAU,SAAA,EAElE,CAEA,8BAAqC,CAl7DvC,IAAA/e,EAAA4G,EAm7DI,KAAK,oBAAsB,KACvBka,GAAe,KACjBla,GAAA5G,EAAAV,EAAS,aAAT,KAAA,OAAAU,EAAqB,SAArB,MAAA4G,EAAA,KAAA5G,EAA8BihB,EAAA,EAElC,CAMA,wBAAwB/c,EAAsB,CAC5C,GAAIA,EAAI,OAAS,MAEf,KAAK,YAAY,CAAE,MAAO,SAAU,MAAOA,CAAI,CAAC,UACvCA,EAAI,OAAS,MACtB,KAAK,YAAY,CAAE,MAAO,SAAU,MAAOA,CAAI,CAAC,UACvCA,EAAI,aAAeqI,GAAgB,UAAW,CACvD,IAAM1M,EAAM,iFACZmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,8CAA+CnB,CAAG,EAClG,KAAK,YAAY,CAAE,MAAO,SAAU,MAAO,IAAIf,EAAUe,EAAK,MAAO,IAAKqE,CAAG,CAAE,CAAC,CAClF,KAAO,CACL,IAAMrE,EAAM,2DACZmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,4CAA6CnB,CAAG,EAChG,KAAK,YAAY,CAAE,MAAO,KAAK,MAAM,UAAqB,MAAO,IAAIf,EAAUe,EAAK,MAAO,IAAKqE,CAAG,CAAE,CAAC,CACxG,CACF,CAEA,0BAA0B2e,EAAwC9D,EAA4B,CAC5F,GAAI,CAAC8D,EACH,OAEF,KAAK,kBAAoBA,EACrBA,EAAkB,iBACpB,KAAK,QAAQ,eAAiBA,EAAkB,gBAElD,IAAMjT,EAAWiT,EAAkB,SACnC,GAAIjT,EAAU,CACZ,IAAM1L,EAAM,KAAK,SAAS,KAAK,sBAAsB0L,CAAQ,EAC7D,GAAI1L,EAAK,CACPlD,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,gDAAiDkD,EAAI,OAAO,EAE5G6a,EAAU,KAAK7a,CAAG,EAClB,MACF,CACF,CACA,IAAMwhB,EAAqB7C,EAAkB,mBACzC6C,IACF,KAAK,mBAAqBA,GAE5B,KAAK,gBAAkB7C,EAAkB,gBACzC,KAAK,KAAK,oBAAqBA,CAAiB,CAClD,CAEA,qBAAsB,CACpB,IAAM5X,EAAyB,KAAK,QAAQ,wBAA0BS,EAAS,uBACzEnC,EAAK,IAAIjK,EAAS,OAAO,UAAU2L,CAAsB,EAC/D,OAAO,IAAI,QAAc,CAACe,EAAS1D,IAAW,CAC5C,IAAIqd,EAAW,GACfpc,EAAG,OAAS,IAAM,CACXoc,IACHA,EAAW,GACX3Z,EAAQ,EACRzC,EAAG,MAAM,EAEb,EAEAA,EAAG,QAAUA,EAAG,QAAU,IAAM,CACzBoc,IACHA,EAAW,GACXrd,EAAO,EAEX,CACF,CAAC,CACH,CAEA,qBAAsB,CACpB,OAAO,KAAK,QAAQ,wBAA0B,0BAChD,CAEA,uBAAwB,CAlgE1B,IAAAtI,EAAA4G,EAmgEI,OAAOma,GAAmB,KAAKna,GAAA5G,EAAAV,EAAS,aAAT,KAAA,OAAAU,EAAqB,aAArB,KAAA,OAAA4G,EAAA,KAAA5G,EAAkC,KAAK,oBAAoB,CAAA,EAC5F,CACA,sBAAsB4lB,EAAY,CArgEpC,IAAA5lB,EAAA4G,EAsgEI,OAAOma,GAAmB,KAAKna,GAAA5G,EAAAV,EAAS,aAAT,KAAA,OAAAU,EAAqB,aAArB,KAAA,OAAA4G,EAAA,KAAA5G,EAAkC,KAAK,oBAAoB,EAAG4lB,CAAA,EAC/F,CACA,yBAA0B,CAxgE5B,IAAA5lB,EAAA4G,EAygEI,OAAOma,GAAmB,KAAKna,GAAA5G,EAAAV,EAAS,aAAT,KAAA,OAAAU,EAAqB,gBAArB,KAAA,OAAA4G,EAAA,KAAA5G,EAAqC,KAAK,oBAAoB,CAAA,EAC/F,CACF,EAEO6lB,GAAQjE,GCpgETkE,GAAN,cAAyB/I,EAAa,CAQpC,YAAYgJ,EAAoB1c,EAAkC,CAChE,MAAM0c,EAAK,MAAM,EAqBnB,KAAA,UAAcpD,GACL5F,GAAa,UAAU,UAAU,KAAK,KAAM4F,EAAO,KAAK,KAAK,EArBpE,KAAK,KAAOoD,EACZ,KAAK,kBAAoB,IAAIF,GAAkBE,EAAM1c,CAAO,EAC5D,KAAK,MAAQ,KAAK,kBAAkB,MAAM,MAC1C,KAAK,IAAM,OACX,KAAK,GAAK,OACV,KAAK,YAAc,KAEnB,KAAK,kBAAkB,GAAG,kBAAoBsa,GAAuC,CACnF,IAAMhB,EAAS,KAAK,MAAQgB,EAAY,QACxCrkB,EAAS,OAAO,SAAS,IAAM,CAC7B,KAAK,KAAKqjB,EAAOgB,CAAW,CAC9B,CAAC,CACH,CAAC,EACD,KAAK,kBAAkB,GAAG,SAAWA,GAAuC,CAC1ErkB,EAAS,OAAO,SAAS,IAAM,CAC7B,KAAK,KAAK,SAAUqkB,CAAW,CACjC,CAAC,CACH,CAAC,CACH,CAMA,SAAgB,CACd3iB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,uBAAwB,EAAE,EAC1E,KAAK,kBAAkB,aAAa,CAAE,MAAO,YAAa,CAAC,CAC7D,CAEA,MAAM,MAAwB,CAC5B,OAAAA,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,oBAAqB,EAAE,EAChE,KAAK,kBAAkB,KAAK,CACrC,CAEA,OAAc,CACZA,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,qBAAsB,mBAAqB,KAAK,GAAG,EACnG,KAAK,kBAAkB,aAAa,CAAE,MAAO,SAAU,CAAC,CAC1D,CAEA,IAAI,aAA6B,CAC/B,YAAK,OAAO,mBACV,iPACF,EACO,KAAK,kBAAkB,CAChC,CAEA,mBAAmC,CACjC,OAAO,KAAK,kBAAkB,kBAAkB,CAClD,CACF,EAEOglB,GAAQF,GCpETG,GAAN,KAAyB,CAOvB,YACE7G,EACAC,EACA6G,EACAC,EACA5G,EACA,CACA,KAAK,SAAWH,EAChB,KAAK,QAAUC,EACXA,IAAY,aACd,KAAK,QAAU6G,EACf,KAAK,WAAaC,GAEhB5G,IAAQ,KAAK,OAASA,EAC5B,CACF,EAEO6G,GAAQH,GCeTjF,GAAO,UAAY,CAAC,EAE1B,SAASqF,GAAuBhd,EAA8B,CAC5D,GAAIA,GAAW,WAAYA,GAAW,CAAOnG,GAASmG,EAAQ,MAAM,EAClE,OAAO,IAAIvK,EAAU,mCAAoC,IAAO,GAAG,EAErE,GAAIuK,GAAW,UAAWA,EAAS,CACjC,GAAI,CAAC,MAAM,QAAQA,EAAQ,KAAK,EAC9B,OAAO,IAAIvK,EAAU,iCAAkC,IAAO,GAAG,EAEnE,QAASgG,EAAI,EAAGA,EAAIuE,EAAQ,MAAM,OAAQvE,IAAK,CAC7C,IAAMwhB,EAAcjd,EAAQ,MAAMvE,CAAC,EACnC,GACE,CAACwhB,GACD,OAAOA,GAAgB,UACvB,CAACjJ,GAAa,SAAS,OAAO,UAAU,YAAY,KAAKiJ,CAAW,CAAC,EAErE,OAAO,IAAIxnB,EAAU,yBAA2BwnB,EAAa,IAAO,GAAG,CAE3E,CACF,CACF,CAEA,IAAMC,GAAN,MAAMC,WAAwBzJ,EAAa,CAsCzC,YAAYpQ,EAAsBhF,EAAc0B,EAA8B,CAtGhF,IAAArJ,EAAA4G,EAuGI,MAAM+F,EAAO,MAAM,EAJrB,KAAA,WAAqB,EA00BrB,KAAA,QAAU,eAERpG,EACmC,CACnCvF,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,4BAA6B,aAAe,KAAK,IAAI,EAGrG,IAAMylB,EAAY,KAAK,OAAO,KAAK,aAEnC,GAAIlgB,GAAUA,EAAO,YAAa,CAChC,GAAI,KAAK,QAAU,WACjB,MAAM,IAAIzH,EAAU,yDAA0D,IAAO,GAAG,EAE1F,GAAI,CAAC,KAAK,WAAW,aACnB,MAAM,IAAIA,EACR,qFACA,IACA,GACF,EAEF,OAAOyH,EAAO,YACdA,EAAO,YAAc,KAAK,WAAW,YACvC,CAEA,OAAOkgB,EAAU,QAAQ,KAAMlgB,CAAM,CACvC,EAEA,KAAA,UAAcoc,GACL5F,GAAa,UAAU,UAAU,KAAK,KAAM4F,EAAO,KAAK,KAAK,EAj2BpE3hB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,oBAAqB,mBAAqB2G,CAAI,EAC9F,KAAK,KAAOA,EACZ,KAAK,eAAiBuD,IAAwBlL,EAAA2M,EAAO,UAAP,KAAA3M,EAAkB,KAAM,KAAK,OAAQqJ,CAAO,EAC1F,KAAK,OAASsD,EACd,KAAK,UAAYA,EAAO,kBAAoB,IAAIA,EAAO,kBAAkB,iBAAiB,IAAI,EAAI,KAClG,KAAK,kBAAoBA,EAAO,WAAW,kBAC3C,KAAK,MAAQ,cACb,KAAK,cAAgB,IAAIoQ,GAAa,KAAK,MAAM,EACjD,KAAK,kBAAoB,OACzB,KAAK,WAAa,CAChB,aAAc,OACd,cAAe,MACjB,EACA,KAAK,WAAW1T,CAAO,EACvB,KAAK,YAAc,KACnB,KAAK,gBAAkB,KACvB,KAAK,MAAQ,KACb,KAAK,cAAgB,GACrB,KAAK,iBAAmB,CACtB,eAAgB,KAAK,eACrB,QAASsD,EAAO,QAAQ,SAAW,CAAC,EACpC,2BAA4B,MAC9B,EACA,KAAK,aAAe,CAClB,UAAW,KACX,6BAA8B,KAC9B,gCAAiC,IACnC,EAGA,KAAK,mBAAqB,IAAIoQ,GAAa,KAAK,MAAM,GAElDnW,EAAA+F,EAAO,QAAQ,UAAf,MAAA/F,EAAwB,OAC1B,KAAK,MAAQ,IAAI+F,EAAO,QAAQ,QAAQ,KAAK,YAAY,IAAI,EAEjE,CAtEA,IAAI,UAA6B,CAC/B,OAAK,KAAK,WACFhJ,GAAwB,kBAAkB,EAE3C,KAAK,SACd,CAmEA,IAAI,MAAO,CACT,OAAK,KAAK,OACFA,GAAwB,MAAM,EAE/B,KAAK,KACd,CAEA,mBAA+B,CAC7B,OAAO,IAAI7E,EACT,gDAAkD,KAAK,MACvD,MACA,IACA,KAAK,aAAe,MACtB,CACF,CAEA,OAAO,oBAAoBqB,EAAwB,CAEjD,OAAAA,EAAO,MAAM,UAAU,MAAM,KAAKA,CAAI,EAClC,OAAOA,EAAK,CAAC,GAAM,YACrBA,EAAK,QAAQ,IAAI,EAEZA,CACT,CAEA,MAAM,WAAWkJ,EAA6C,CAtKhE,IAAArJ,EAuKI,IAAM0mB,EAAyB,KAAK,eAC9BxiB,EAAMmiB,GAAuBhd,CAAO,EAC1C,GAAInF,EACF,MAAMA,EAIR,GAFA,KAAK,eAAiBgH,IAAwBlL,EAAA,KAAK,OAAO,UAAZ,KAAAA,EAAuB,KAAM,KAAK,OAAQqJ,CAAO,EAC3F,KAAK,mBAAkB,KAAK,iBAAiB,eAAiB,KAAK,gBACnE,KAAK,4BAA4BA,EAASqd,CAAsB,EAOlE,YAAK,WAAW,EACT,IAAI,QAAQ,CAAC1a,EAAS1D,IAAW,CAItC,KAAK,mBAAmB,KACtB,CAAC,WAAY,SAAU,WAAY,QAAQ,EAC3C,SAAmCqb,EAAoC,CACrE,OAAQ,KAAK,MAAO,CAClB,IAAK,SACL,IAAK,WACH3X,EAAQ,EACR,MACF,QACE1D,EAAOqb,EAAY,MAAM,CAC7B,CACF,CACF,CACF,CAAC,CAEL,CAEA,4BAA4Bta,EAAyCsd,EAAiC,CACpG,GAAI,EAAE,KAAK,QAAU,YAAc,KAAK,QAAU,aAChD,MAAO,GAET,GAAItd,GAAS,OAAQ,CAEnB,IAAMud,EAAkBC,GAAUxd,EAAQ,MAAM,EAC1Cyd,EAAiBD,GAAUF,EAAY,MAAM,EAMnD,GAJI,OAAO,KAAKC,CAAe,EAAE,SAAW,OAAO,KAAKE,CAAc,EAAE,QAIpE,CAAOpjB,GAAcojB,EAAgBF,CAAe,EACtD,MAAO,EAEX,CACA,MAAI,GAAAvd,GAAS,QACP,CAACsd,EAAY,OAAS,CAAOnlB,GAAU6H,EAAQ,MAAOsd,EAAY,KAAK,GAK/E,CAEA,MAAM,WAAWxmB,EAA4B,CAC3C,IAAI2X,EAAW3X,EAAK,CAAC,EACjBuc,EAAWvc,EAAK,OAEpB,GAAI,CAAC,KAAK,kBAAkB,YAAY,EACtC,MAAM,KAAK,kBAAkB,SAAS,EAExC,GAAIuc,GAAY,EACd,GAAUxZ,GAAS4U,CAAQ,EAAGA,EAAW,CAACW,GAAkBX,CAAQ,CAAC,UAC5D,MAAM,QAAQA,CAAQ,EAAGA,EAAWa,GAAwBb,CAAQ,MAE3E,OAAM,IAAIhZ,EACR,gGACA,MACA,GACF,OAEFgZ,EAAW,CAACW,GAAkB,CAAE,KAAMtY,EAAK,CAAC,EAAG,KAAMA,EAAK,CAAC,CAAE,CAAC,CAAC,EAEjE,IAAM2Z,EAAiB,KAAK,OAAO,QAAQ,eAC3C,MAAMjC,GAAoBC,EAAU,KAAK,cAA+B,EAExE,IAAMhB,EAAO8B,GAAgBd,CAAQ,EACrC,GAAIhB,EAAOgD,EACT,MAAM,IAAIhb,EACR,yEACEgY,EACA,oBACAgD,EACA,UACF,MACA,GACF,EAEF,OAAO,IAAI,QAAQ,CAAC9N,EAAS1D,IAAW,CACtC,KAAK,SAASwP,EAAW5T,GAASA,EAAMoE,EAAOpE,CAAG,EAAI8H,EAAQ,CAAE,CAClE,CAAC,CACH,CAEA,SAAS8L,EAA0BzQ,EAAuB,CACxDrG,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,4BAA6B,mBAAqB8W,EAAS,MAAM,EACjH,IAAM6K,EAAQ,KAAK,MACnB,OAAQA,EAAO,CACb,IAAK,SACL,IAAK,YACHtb,EAASvI,EAAU,WAAW,KAAK,kBAAkB,CAAC,CAAC,EACvD,MACF,QAAS,CACPkC,EAAO,UACL,KAAK,OACLA,EAAO,UACP,4BACA,qCAAuC2hB,CACzC,EACA,IAAM9iB,EAAM,IAAIye,GAChBze,EAAI,OAASkZ,EAAQ,QACrBlZ,EAAI,QAAU,KAAK,KACnBA,EAAI,SAAWiY,EACf,KAAK,YAAYjY,EAAKwH,CAAQ,EAC9B,KACF,CACF,CACF,CAEA,QAAQyQ,EAA4B,CAClC9W,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,4BAA6B,kBAAkB,EAC/F,IAAM+lB,EAAgB,KAAK,cAC3B,QAAS,EAAI,EAAG,EAAIjP,EAAS,OAAQ,IAAK,CACxC,IAAMnX,EAAUmX,EAAS,CAAC,EAC1BiP,EAAc,KAAKpmB,EAAQ,KAAMA,CAAO,CAC1C,CACF,CAEA,MAAM,QAA6C,CACjD,OAAI,KAAK,QAAU,WACV,KAGF,IAAI,QAAQ,CAACqL,EAAS1D,IAAW,CACtC,KAAK,QAAQ,GAAO,KAAM,CAACpE,EAAKC,IAAYD,EAAMoE,EAAOpE,CAAG,EAAI8H,EAAQ7H,CAAO,CAAE,CACnF,CAAC,CACH,CAEA,QACE6iB,EACAC,EACA5f,EACM,CACDA,IACHA,EAAYnD,GAA2B,CACjCA,GACFlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,4BACA,0BAA4BkD,EAAI,SAAS,CAC3C,CAEJ,GAGF,IAAM8b,EAAoB,KAAK,kBAC/B,GAAI,CAACA,EAAkB,YAAY,EAAG,CACpC3Y,EAAS2Y,EAAkB,SAAS,CAAC,EACrC,MACF,EAEI,KAAK,QAAU,aAAegH,IAChC,KAAK,aAAa,YAAaC,CAAY,EAG7C,KAAK,KAAK,SAAmCtD,EAAiC,CAC5E,OAAQ,KAAK,MAAO,CAClB,IAAK,WACHtc,IAAW,KAAMsc,CAAA,EACjB,MACF,IAAK,WACL,IAAK,YACL,IAAK,SACHtc,IACEsc,EAAY,QACV3D,EAAkB,SAAS,GAC3B,IAAIlhB,EAAU,6CAA+C,KAAK,MAAO,IAAO,GAAG,CAAA,EAEvF,MACF,IAAK,YACHuI,IAAW,IAAIvI,EAAU,2DAA4D,IAAO,GAAG,CAAA,EAC/F,KACJ,CACF,CAAC,CACH,CAEA,YAAmB,CACjBkC,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAAgC,wBAAwB,EACxG,IAAMkmB,EAAYzO,GAA0B,CAC1C,OAAQM,EAAQ,OAChB,QAAS,KAAK,KACd,OAAQ,KAAK,eAAe,OAG5B,cAAe,KAAK,WAAW,aACjC,CAAC,EACG,KAAK,gBACPmO,EAAU,mBAAmB,KAAK,eAAe,EACxC,KAAK,eAAe,OAC7BA,EAAU,mBAAyB7lB,GAAe,KAAK,eAAe,KAAK,CAAsB,EAE/F,KAAK,eACP6lB,EAAU,QAAQ,eAAe,EAE/B,KAAK,aAAa,kCACpBA,EAAU,cAAgB,KAAK,aAAa,8BAE9C,KAAK,YAAYA,EAAWlG,EAAI,CAClC,CAEA,MAAM,QAAwB,CAC5B,IAAMhB,EAAoB,KAAK,kBAC/B,GAAI,CAACA,EAAkB,YAAY,EACjC,MAAMA,EAAkB,SAAS,EAEnC,OAAQ,KAAK,MAAO,CAClB,IAAK,YACH,KAAK,YAAY,UAAU,EAC3B,OACF,IAAK,WACH,OACF,IAAK,SACH,MAAM,IAAIlhB,EAAU,2CAA4C,MAAO,GAAG,EAC5E,QACE,KAAK,aAAa,WAAW,EAE/B,IAAK,YACH,OAAO,IAAI,QAAQ,CAACkN,EAAS1D,IAAW,CACtC,KAAK,KAAK,SAAmCqb,EAAiC,CAC5E,OAAQ,KAAK,MAAO,CAClB,IAAK,WACH3X,EAAQ,EACR,MACF,IAAK,WACL,IAAK,YACL,IAAK,SACH1D,EACEqb,EAAY,QACV3D,EAAkB,SAAS,GAC3B,IAAIlhB,EAAU,6CAA+C,KAAK,MAAO,IAAO,GAAG,CACvF,EACA,MACF,IAAK,YACHwJ,EAAO,IAAIxJ,EAAU,2DAA4D,IAAO,GAAG,CAAC,EAC5F,KACJ,CACF,CAAC,CACH,CAAC,CACL,CACF,CAEA,WAAWuI,EAA8B,CACvCrG,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,wBAAwB,EACpG,IAAMnB,EAAM4Y,GAA0B,CAAE,OAAQM,EAAQ,OAAQ,QAAS,KAAK,IAAK,CAAC,EACpF,KAAK,YAAYlZ,EAAKwH,GAAY2Z,EAAI,CACxC,CAEA,MAAM,aAAa7gB,EAA6E,CAC9F,GAAM,CAACkc,EAAOR,CAAQ,EAAI2K,GAAgB,oBAAoBrmB,CAAI,EAElE,GAAI,KAAK,QAAU,SACjB,MAAMrB,EAAU,WAAW,KAAK,kBAAkB,CAAC,EAIrD,OAAIud,GAAS,OAAOA,GAAU,UAAY,CAAC,MAAM,QAAQA,CAAK,EAC5D,KAAK,OAAO,uBAAuB,gBAAgB,KAAMA,EAAOR,CAAQ,EAExE,KAAK,cAAc,GAAGQ,EAAOR,CAAQ,EAGhC,KAAK,OAAO,CACrB,CAEA,eAAe1b,EAA+C,CAhchE,IAAAH,EAicI,GAAM,CAACqc,EAAOR,CAAQ,EAAI2K,GAAgB,oBAAoBrmB,CAAI,EAGlE,GAAK,OAAOkc,GAAU,UAAY,CAACR,IAAa7b,EAAA,KAAK,wBAAL,MAAAA,EAA4B,IAAI6b,CAAA,EAAW,CACzF,KAAK,OAAO,uBACT,kCAAkC,KAAMQ,EAAOR,CAAQ,EACvD,QAASsL,GAAM,KAAK,cAAc,IAAIA,CAAC,CAAC,EAC3C,MACF,CAEA,KAAK,cAAc,IAAI9K,EAAOR,CAAQ,CACxC,CAEA,MAAa,CAEX,OAAQ,KAAK,MAAO,CAClB,IAAK,cACL,IAAK,YACL,IAAK,WACH,MAAM,IAAIpX,GAAiB,0CAA2C,GAAK,EAC7E,QACF,CACA,IAAMub,EAAoB,KAAK,kBAC/B,GAAI,CAACA,EAAkB,YAAY,EACjC,MAAMA,EAAkB,SAAS,EAInC,IAAMoH,EAAc3O,GAA0B,CAAE,OAAQM,EAAQ,KAAM,QAAS,KAAK,IAAK,CAAC,EACtF,KAAK,oBACPqO,EAAY,cAAgB,KAAK,mBAEnCpH,EAAkB,KAAKoH,CAAW,CACpC,CAEA,YAAYvnB,EAAsBwH,EAA8B,CAC9D,KAAK,kBAAkB,KAAKxH,EAAK,KAAK,OAAO,QAAQ,cAAewH,CAAQ,CAC9E,CAEA,aAAagT,EAA+ChT,EAA8B,CACxF,IAAMxH,EAAM4Y,GAA0B,CACpC,OAAQM,EAAQ,SAChB,QAAS,KAAK,KACd,SAAU,MAAM,QAAQsB,CAAQ,EAC5B,KAAK,OAAO,kBAAmB,gCAAgCA,CAAQ,EACvE,CAAC,KAAK,OAAO,kBAAmB,0BAA0BA,CAAQ,CAAC,CACzE,CAAC,EACD,KAAK,YAAYxa,EAAKwH,CAAQ,CAChC,CAGA,MAAM,eAAe1G,EAAyC,EAE1DA,EAAQ,SAAWoY,EAAQ,UAC3BpY,EAAQ,SAAWoY,EAAQ,SAC3BpY,EAAQ,SAAWoY,EAAQ,WAG3B,KAAK,iBAAiBpY,EAAQ,aAAa,EAG7C,IAAI0mB,EACFC,EAAS,GACX,OAAQ3mB,EAAQ,OAAQ,CACtB,KAAKoY,EAAQ,SAAU,CACrB,KAAK,WAAW,aAAepY,EAAQ,cACvC,KAAK,MAAQA,EAAQ,QAAQ,EAC7B,KAAK,OAAUA,EAAgB,QAAU,CAAC,EAC1C,IAAM4mB,EAAiB5mB,EAAQ,qBAAqB,EACpD,KAAK,MAAS4mB,GAAwBnmB,GAAemmB,CAAc,GAAM,OACzE,IAAMrB,EAAUvlB,EAAQ,QAAQ,SAAS,EACnC6mB,EAAc7mB,EAAQ,QAAQ,cAAc,EAC5CwlB,EAAaxlB,EAAQ,QAAQ,aAAa,EAChD,GAAI,KAAK,QAAU,WAAY,CACxBulB,GAEC,KAAK,WACP,KAAK,UAAU,WAAWsB,CAAW,EAGzC,IAAMrD,EAAS,IAAIiC,GAAmB,KAAK,MAAO,KAAK,MAAOF,EAASC,EAAYxlB,EAAQ,KAAK,EAChG,KAAK,mBAAmB,KAAK,SAAUwjB,CAAM,GACzC,CAAC+B,GAAW,KAAK,eAAe,mBAClC,KAAK,KAAK,SAAU/B,CAAM,CAE9B,MAAW,KAAK,QAAU,YAExB,KAAK,kBAAkB,EAEvB,KAAK,YAAY,WAAYxjB,EAAQ,MAAOulB,EAASsB,EAAarB,CAAU,EAE9E,KACF,CAEA,KAAKpN,EAAQ,SAAU,CACrB,IAAM0O,EAAY9mB,EAAQ,MACtB7B,EAAU,WAAW6B,EAAQ,KAAK,EAClC,IAAI7B,EAAU,mBAAoB,MAAO,GAAG,EAC5C,KAAK,QAAU,YACjB,KAAK,YAAY,WAAY2oB,CAAS,EAC7B,KAAK,QAAU,YAIxB,KAAK,YAAY,YAAaA,CAAS,GAC9B,KAAK,QAAU,YAAc,KAAK,QAAU,cAErD,KAAK,aAAa,YAAaA,CAAS,EAG1C,KACF,CAEA,KAAK1O,EAAQ,KAMX,GAJAuO,EAAS,GACTD,EAAoB,KAAK,kBAAoB1mB,EAAQ,cAGjD,CAACA,EAAQ,SAAU,MAEzB,KAAKoY,EAAQ,SAAU,CACrB,IAAM2O,EAAmB/mB,EAAQ,SAEjC,GAAI,CAAC+mB,EACH,MAGF,IAAMre,EAAU,KAAK,eACrB,MAAM,KAAK,0BAA0B1I,EAAS+mB,EAAmB7nB,GAAQsX,GAAsBtX,EAAKwJ,CAAO,CAAC,EAExG,KAAK,WACP,KAAK,UAAU,YAAYqe,EAAkBJ,EAAQD,CAAwB,EAE/E,KACF,CACA,KAAKtO,EAAQ,QAAS,CAEpB,GAAI,KAAK,QAAU,WAAY,CAC7B/X,EAAO,UACL,KAAK,OACLA,EAAO,UACP,mCACA,YACEL,EAAQ,GACR,8BACA,KAAK,KACL,wCACA,KAAK,MACL,KACJ,EACA,MACF,CAEA,IAAMmX,EAAWnX,EAAQ,SACvBgnB,EAAe7P,EAAS,CAAC,EACzB8P,EAAc9P,EAASA,EAAS,OAAS,CAAC,EAC1C+P,EAAgBlnB,EAAQ,cAE1B,GACEgnB,EAAa,QACbA,EAAa,OAAO,OACpBA,EAAa,OAAO,MAAM,OAAS,KAAK,aAAa,UACrD,CACA,IAAM9nB,EACJ,8EACAc,EAAQ,GACR,sBACA,KAAK,KACL,KACFK,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,mCAAoCnB,CAAG,EACvF,KAAK,4BAA4B,IAAIf,EAAUe,EAAK,MAAO,GAAG,CAAC,EAC/D,KACF,CAEA,GAAM,CAAE,mBAAAioB,CAAmB,EAAI,MAAM,KAAK,0BACxCnnB,EACAmX,EACCjY,GAAQsX,GAActX,EAAK,KAAK,gBAAgB,EAChDuI,GAAM,CAEL,IAAM2f,EAAY3f,EAElB,OAAQ2f,EAAU,KAAM,CACtB,IAAK,OAEH,YAAK,4BAA4BA,CAAS,EACnC,CAAE,mBAAoB,EAAK,EAEpC,IAAK,OAGL,IAAK,OAEH,YAAK,YAAY,SAAUA,CAAS,EAC7B,CAAE,mBAAoB,EAAK,EAEpC,QACE,MAAO,CAAE,mBAAoB,EAAM,CACvC,CACF,CACF,EACA,GAAID,EACF,OAGF,QAAShjB,EAAI,EAAGA,EAAIgT,EAAS,OAAQhT,IAAK,CACxC,IAAMjF,EAAMiY,EAAShT,CAAC,EAClB+iB,GAAiB,CAAChoB,EAAI,UACxBA,EAAI,QAAUgoB,EAAgB,IAAM/iB,EAAE,SAAS,EAAE,SAAS,EAAG,GAAG,EAGhEjF,EAAI,aAAa,EAErB,CAEA,KAAK,aAAa,UAAY+nB,EAAY,GAC1C,KAAK,aAAa,6BAA+BjnB,EAAQ,cACzD,KAAK,QAAQmX,CAAQ,EACrB,KACF,CAEA,KAAKiB,EAAQ,MAAO,CAElB,IAAM7U,EAAMvD,EAAQ,MAChBuD,GAAOA,EAAI,MAAQ,MAErB,KAAK,kBAAkB,EAEvB,KAAK,YAAY,SAAUpF,EAAU,WAAWoF,CAAG,CAAC,EAEtD,KACF,CAEA,QACElD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,mCACA,8CAAgDL,EAAQ,OAAS,GACnE,EACA,KAAK,kBAAkB,MAAMif,GAAiB,kBAAkB,CAAC,CACrE,CACF,CAQA,MAAc,0BACZoI,EACAlQ,EACAmQ,EACAC,EAC0C,CAC1C,GAAM,CAAE,GAAA9H,EAAI,aAAAwC,EAAc,UAAA7S,CAAU,EAAIiY,EAExC,QAASljB,EAAI,EAAGA,EAAIgT,EAAS,OAAQhT,IAAK,CACxC,IAAMjF,EAAMiY,EAAShT,CAAC,EAEtB,GAAI,CAEF,MAAMmjB,EAASpoB,CAAG,CACpB,OAASuI,EAAG,CAQV,GAPApH,EAAO,UACL,KAAK,OACLA,EAAO,UACP,6CACCoH,EAAY,SAAS,CACxB,EAEI8f,EAA4B,CAC9B,GAAM,CAAE,mBAAAJ,CAAmB,EAAII,EAA2B9f,CAAU,EACpE,GAAI0f,EAEF,MAAO,CAAE,mBAAoB,EAAK,CAEtC,CACF,CAEKjoB,EAAI,eAAcA,EAAI,aAAe+iB,GACrC/iB,EAAI,YAAWA,EAAI,UAAYkQ,GAChCqQ,GAAM,CAACvgB,EAAI,KAAIA,EAAI,GAAKugB,EAAK,IAAMtb,EACzC,CAEA,MAAO,CAAE,mBAAoB,EAAM,CACrC,CAEA,4BAA4Bya,EAAyB,CAC9C,KAAK,aAAa,kCACrBve,EAAO,UACL,KAAK,OACLA,EAAO,UACP,mCACA,2CACF,EACA,KAAK,aAAa,gCAAkC,GACpD,KAAK,QAAQ,GAAMue,EAAQ,IAAM,CAC/B,KAAK,aAAa,gCAAkC,EACtD,CAAC,EAEL,CAEA,YAAmB,CACjBve,EAAO,UACL,KAAK,OACLA,EAAO,UACP,6BACA,8BAAgC,KAAK,IACvC,CACF,CAEA,YACE2hB,EACApD,EACA2G,EACAsB,EACArB,EACM,CAcN,GAbAnlB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,8BACA,UAAY,KAAK,KAAO,qBAAuB,KAAK,MAAQ,qBAAuB2hB,CACrF,EACA,KAAK,gBAAgB,EAGjB,CAAC,WAAY,YAAa,QAAQ,EAAE,SAASA,CAAK,IACpD,KAAK,WAAW,cAAgB,MAG9BA,IAAU,KAAK,MACjB,OAEE,KAAK,WACP,KAAK,UAAU,kBAAkBA,EAAO6E,EAAajI,CAAM,EAEzDoD,IAAU,aAAe,KAAK,kBAAkB,MAAM,WACxD,KAAK,gBAAgB,EAErB,KAAK,iBAAiB,EAEpBpD,IACF,KAAK,YAAcA,GAErB,IAAM4E,EAAS,IAAIiC,GAAmB,KAAK,MAAOzD,EAAOuD,EAASC,EAAY5G,CAAM,EAC9E7e,EAAS,8BAAgC,KAAK,KAAO,IACrDC,EAAUgiB,GAASpD,EAAS,aAAeA,EAAS,IACtDoD,IAAU,SACZ3hB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAWN,EAAQC,CAAO,EAE/DK,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAWN,EAAQC,CAAO,EAG7DgiB,IAAU,aAAeA,IAAU,cACrC,KAAK,WAAa,GAIhBA,IAAU,YACZ,KAAK,WAAW,EAGdA,IAAU,WACZ,KAAK,cAAgB,IACZA,IAAU,aAAeA,IAAU,YAC5C,KAAK,cAAgB,IAGvB,KAAK,MAAQA,EACb,KAAK,mBAAmB,KAAKA,EAAOwB,CAAM,EAC1C,KAAK,KAAKxB,EAAOwB,CAAM,CACzB,CAEA,aAAaxB,EAAyBpD,EAAiC,CACrEve,EAAO,UACL,KAAK,OACLA,EAAO,UACP,+BACA,UAAY,KAAK,KAAO,aAAe2hB,CACzC,EACA,KAAK,YAAYA,EAAOpD,CAAM,EAE9B,KAAK,kBAAkB,CACzB,CAEA,mBAA0B,CAGxB,GAAI,CADY,KAAK,kBAAkB,MAC1B,WAAY,CACvBve,EAAO,UACL,KAAK,OACLA,EAAO,UACP,oCACA,iCAAmC,KAAK,kBAAkB,MAAM,KAClE,EACA,MACF,CASA,OAPAA,EAAO,UACL,KAAK,OACLA,EAAO,UACP,oCACA,UAAY,KAAK,KAAO,aAAe,KAAK,KAC9C,EAEQ,KAAK,MAAO,CAClB,IAAK,YACH,KAAK,4BAA4B,EACjC,KAAK,WAAW,EAChB,MACF,IAAK,YACH,KAAK,4BAA4B,EACjC,KAAK,WAAW,EAChB,MACF,IAAK,WAEH,KAAK,KAAK,EACV,MACF,QACE,KACJ,CACF,CAEA,qBAA4B,CAC1B,OAAQ,KAAK,MAAO,CAClB,IAAK,YAAa,CAChB,IAAMkD,EAAM,IAAIpF,EAAU,2BAA4B,MAAO,GAAG,EAChE,KAAK,YAAY,YAAaoF,CAAG,EACjC,KACF,CACA,IAAK,YAAa,CAChB,IAAMA,EAAM,IAAIpF,EAAU,2BAA4B,MAAO,GAAG,EAChE,KAAK,YAAY,WAAYoF,CAAG,EAChC,KACF,CACA,QACE,KAAK,kBAAkB,EACvB,KACJ,CACF,CAEA,6BAAoC,CAC7B,KAAK,aACR,KAAK,WAAa,WAAW,IAAM,CACjClD,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,8CAA+C,eAAe,EAC9G,KAAK,WAAa,KAClB,KAAK,oBAAoB,CAC3B,EAAG,KAAK,OAAO,QAAQ,SAAS,sBAAsB,EAE1D,CAEA,iBAAwB,CACtB,IAAMmnB,EAAa,KAAK,WACpBA,IACF,aAAaA,CAAU,EACvB,KAAK,WAAa,KAEtB,CAEA,iBAAwB,CACtB,GAAI,KAAK,WAAY,OAErB,KAAK,aACL,IAAMjE,EAAmBxhB,GAAa,KAAK,OAAO,QAAQ,SAAS,oBAAqB,KAAK,UAAU,EAEvG,KAAK,WAAa,WAAW,IAAM,CAG7B,KAAK,QAAU,aAAe,KAAK,kBAAkB,MAAM,aAC7D,KAAK,WAAa,KAClB1B,EAAO,UACL,KAAK,OACLA,EAAO,UACP,sCACA,yBACF,EACA,KAAK,aAAa,WAAW,EAEjC,EAAGkjB,CAAU,CACf,CAEA,kBAAyB,CACnB,KAAK,aACP,aAAa,KAAK,UAA4B,EAC9C,KAAK,WAAa,KAEtB,CAkCA,eAAkC,CAChC,IAAMkE,EAAI,KAAK,MACf,OAAIA,IAAM,eAAiBA,IAAM,YAAcA,IAAM,SAC5C,KAEF,IAAItpB,EACT,iKACEspB,EACF,MACA,GACF,CACF,CAEA,iBAAiBP,EAAqC,CACpD7mB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,qCACA,qCAAuC6mB,EAAgB,gBAAkB,KAAK,WAAW,aAC3F,EAIIA,IACF,KAAK,WAAW,cAAgBA,EAEpC,CAEA,MAAM,QAAsC,CAC1C,OAAO,KAAK,OAAO,KAAK,aAAa,OAAO,IAAI,CAClD,CACF,EAEA,SAAShB,GAAUwB,EAAmC,CACpD,IAA4CroB,EAAAqoB,GAAiB,CAAC,EAAtD,CAAA,MAAOC,CA/+BjB,EA++B8CtoB,EAC5C,OADqBuoB,EAAuBvoB,EAAvB,CAAb,OAAA,CAAA,CAEV,CAEA,IAAOwoB,GAAQjC,GCh+BTkC,GAAN,MAAMA,WAAqBjW,EAAW,CAkBpC,YAAYnJ,EAAkC,CArChD,IAAArJ,EAAA4G,EA6CI,GAPA,MAAM8E,EAAS,iBAAiBrC,EAAS,GAAO,eAAgBrI,EAAO,aAAa,CAAC,EACrFA,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,aAAc,EAAE,EAM5D,OAAO,aAAgB,SACzB,MAAM,IAAIlC,EACR,8bAMA,IACA,GACF,EAGF,KAAK,oCAAsC2pB,GAAa,oCAAoC,KAAK,QAAQ,OAAO,EAChH,KAAK,mBAAoB7hB,GAAA5G,EAAA,KAAK,QAAQ,UAAb,KAAA,OAAAA,EAAsB,mBAAtB,KAAA4G,EAA0C,KACnE,KAAK,WAAa,IAAIof,GAAW,KAAM,KAAK,OAAO,EACnD,KAAK,UAAY,IAAIzL,GAAS,IAAI,EAC9B,KAAK,QAAQ,cAAgB,IAAO,KAAK,QAAQ,CACvD,CAEA,OAAe,oCAAoCmO,EAA0B,CAC3E,IAAMC,EAAuC,CAAC,EAE9C,OAAID,GAAS,qBACXC,EAAW9H,GAAe,SAAS,EAAI6H,EAAQ,oBAE7CA,GAAS,aACXC,EAAW9H,GAAe,UAAU,EAAI6H,EAAQ,YAG3CC,CACT,CAEA,IAAI,UAAW,CACb,OAAO,KAAK,SACd,CAEA,SAAgB,CACd3nB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,qBAAsB,EAAE,EACxE,KAAK,WAAW,QAAQ,CAC1B,CAEA,OAAc,CACZA,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,mBAAoB,EAAE,EACtE,KAAK,WAAW,MAAM,CACxB,CACF,EAxEMynB,GAQY,aAAe1L,GARjC,IAAM6L,GAANH,GA0EMlO,GAAN,cAAuBwC,EAAa,CAIlC,YAAY+E,EAAwB,CAClC,MAAMA,EAAS,MAAM,EACrB,KAAK,SAAWA,EAChB,KAAK,IAAM,OAAO,OAAO,IAAI,EAC7BA,EAAS,WAAW,kBAAkB,GAAG,mBAAoB,IAAM,CACjE,KAAK,kBAAkB,CACzB,CAAC,CACH,CAEA,gBAA6C,CAC3C,IAAI+G,EAAsC,CAAC,EAC3C,QAAWlhB,KAAcxE,EAAU,KAAK,IAAK,EAAI,EAAG,CAClD,IAAMoU,EAAU,KAAK,IAAI5P,CAAI,EACzB4P,EAAQ,WAAW,gBACrBsR,EAAQlhB,CAAI,EAAI4P,EAAQ,WAAW,cAEvC,CACA,OAAOsR,CACT,CAGA,gBAAgBC,EAA4C,CAC1D,QAAWnhB,KAAcxE,EAAU2lB,EAAgB,EAAI,EAAG,CACxD,IAAMvR,EAAU,KAAK,IAAI5P,CAAI,EAC7B4P,EAAQ,WAAW,cAAgBuR,EAAenhB,CAAI,CACxD,CACF,CAGA,MAAM,sBAAsB9H,EAAsB,CAChD,IAAMkpB,EAAclpB,EAAI,QACxB,GAAIkpB,IAAgB,OAAW,CAC7B/nB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,mCACA,gDAAkDnB,EAAI,MACxD,EACA,MACF,CACA,IAAM0X,EAAU,KAAK,IAAIwR,CAAW,EACpC,GAAI,CAACxR,EAAS,CACZvW,EAAO,UACL,KAAK,OACLA,EAAO,UACP,mCACA,4CAA8C+nB,CAChD,EACA,MACF,CACA,MAAMxR,EAAQ,eAAe1X,CAAG,CAClC,CAIA,mBAAoB,CAClB,QAAWkpB,KAAe,KAAK,IAAK,CAClC,IAAMxR,EAAU,KAAK,IAAIwR,CAAW,EAChCxR,EAAQ,QAAU,aAAeA,EAAQ,QAAU,YACrDA,EAAQ,kBAAkB,EACjBA,EAAQ,QAAU,YAC3BA,EAAQ,QAAQ,GAAO,IAAI,EAClBA,EAAQ,QAAU,YAG3BA,EAAQ,aAAa,WAAW,CAEpC,CACF,CAKA,gCAAgCyR,EAAyBzJ,EAAmB,CAC1E,IAAM0J,EAAkE,CACtE,QAAS,WACT,OAAQ,WACR,OAAQ,SACR,UAAW,WACb,EACMC,EAAoB,CAAC,YAAa,WAAY,YAAa,WAAW,EACtEC,EAAiBF,EAA8BD,CAAe,EAEpE,QAAWI,KAAa,KAAK,IAAK,CAChC,IAAM7R,EAAU,KAAK,IAAI6R,CAAS,EAC9BF,EAAkB,SAAS3R,EAAQ,KAAK,GAC1CA,EAAQ,YAAY4R,EAAgB5J,CAAM,CAE9C,CACF,CAEA,IAAI5X,EAAcyD,EAAiC,CACjDzD,EAAO,OAAOA,CAAI,EAClB,IAAI4P,EAAU,KAAK,IAAI5P,CAAI,EAC3B,GAAI,CAAC4P,EACHA,EAAU,KAAK,IAAI5P,CAAI,EAAI,IAAI6gB,GAAgB,KAAK,SAAU7gB,EAAMyD,CAAc,UACzEA,EAAgB,CACzB,GAAImM,EAAQ,4BAA4BnM,EAAgBmM,EAAQ,cAAc,EAC5E,MAAM,IAAIzY,EACR,mJACA,IACA,GACF,EAEFyY,EAAQ,WAAWnM,CAAc,CACnC,CACA,OAAOmM,CACT,CAEA,WAAW5P,EAAc0hB,EAAkCje,EAAiC,CAC1F,GAAIie,EAAc,OAAQ,CACxB,IAAMC,EAAe1lB,GAASylB,EAAc,MAAM,EAC5C3iB,EAActD,GAAoBuE,CAAI,EAC5CA,EAAO,WAAW2hB,CAAM,GAAG5iB,EAAM,cAAc,IAAIA,EAAM,WAAW,EACtE,CACA,OAAO,KAAK,IAAIiB,EAAMyD,CAAc,CACtC,CAIA,QAAQzD,EAAc,CACpBA,EAAO,OAAOA,CAAI,EAClB,IAAM4P,EAAU,KAAK,IAAI5P,CAAI,EAC7B,GAAI,CAAC4P,EACH,OAEF,IAAMgS,EAAahS,EAAQ,cAAc,EACzC,GAAIgS,EACF,MAAMA,EAER,OAAO,KAAK,IAAI5hB,CAAI,CACtB,CACF,EAEO6hB,GAAQZ,GCxNf,SAASa,GAAUnjB,EAAuBojB,EAAoC,CAE5E,GAAIpjB,EAAK,cAAc,GAAKojB,EAAS,cAAc,EAEjD,OAAQpjB,EAAK,WAAyBojB,EAAS,UAIjD,IAAMC,EAAgBrjB,EAAK,QAAQ,EACjCsjB,EAAoBF,EAAS,QAAQ,EACvC,OAAIC,EAAc,YAAcC,EAAkB,UACzCD,EAAc,MAAQC,EAAkB,MAExCD,EAAc,UAAYC,EAAkB,SAEvD,CAEO,IAAMC,GAAN,cAA0B9M,EAAa,CAQ5C,YAAY1C,EAA4ByP,EAA8CC,EAAgBN,GAAW,CAC/G,MAAMpP,EAAS,MAAM,EACrB,KAAK,SAAWA,EAChB,KAAK,IAAM,OAAO,OAAO,IAAI,EAC7B,KAAK,eAAiB,GACtB,KAAK,gBAAkB,KACvB,KAAK,UAAYyP,EACjB,KAAK,UAAYC,CACnB,CAEA,IAAI/kB,EAAa,CACf,OAAO,KAAK,IAAIA,CAAG,CACrB,CAEA,UAAU4K,EAAkB,CAC1B,IAAMoa,EAAM,KAAK,IACf7lB,EAAS,CAAC,EACZ,QAAWa,KAAOglB,EAAK,CACrB,IAAM1jB,EAAO0jB,EAAIhlB,CAAG,EAChBsB,EAAK,UAAYsJ,GAAYtJ,EAAK,QAAU,UAAUnC,EAAO,KAAKmC,CAAI,CAC5E,CACA,OAAOnC,CACT,CAEA,KAAKoC,EAAgC,CACnC,IAAMyjB,EAAM,KAAK,IACfpa,EAAWrJ,GAAUA,EAAO,SAC5Bqc,EAAerc,GAAUA,EAAO,aAChCpC,EAAS,CAAC,EAEZ,QAAWa,KAAOglB,EAAK,CACrB,IAAM1jB,EAAO0jB,EAAIhlB,CAAG,EAChBsB,EAAK,SAAW,WAChBsJ,GAAYA,GAAYtJ,EAAK,UAC7Bsc,GAAgBA,GAAgBtc,EAAK,cACzCnC,EAAO,KAAKmC,CAAI,EAClB,CACA,OAAOnC,CACT,CAEA,IAAImC,EAAuB,EACrBA,EAAK,SAAW,SAAWA,EAAK,SAAW,YAC7CA,EAAOmS,GAA0BnS,CAAI,EACrCA,EAAK,OAAS,WAEhB,IAAM0jB,EAAM,KAAK,IACfhlB,EAAM,KAAK,UAAUsB,CAAI,EAEvB,KAAK,iBAAiB,OAAO,KAAK,gBAAgBtB,CAAG,EAGzD,IAAMilB,EAAeD,EAAIhlB,CAAG,EAC5B,OAAIilB,GAAgB,CAAC,KAAK,UAAU3jB,EAAM2jB,CAAY,EAC7C,IAETD,EAAIhlB,CAAG,EAAIsB,EACJ,GACT,CAEA,QAAS,CACP,IAAM0jB,EAAM,KAAK,IACf7lB,EAAS,CAAC,EACZ,QAAWa,KAAOglB,EAAK,CACrB,IAAM1jB,EAAO0jB,EAAIhlB,CAAG,EAChBsB,EAAK,QAAU,UAAUnC,EAAO,KAAKmC,CAAI,CAC/C,CACA,OAAOnC,CACT,CAEA,OAAOmC,EAAuB,CAC5B,IAAM0jB,EAAM,KAAK,IACfhlB,EAAM,KAAK,UAAUsB,CAAI,EACrB2jB,EAAeD,EAAIhlB,CAAG,EAE5B,OAAIilB,GAAgB,CAAC,KAAK,UAAU3jB,EAAM2jB,CAAY,EAC7C,IAIL,KAAK,gBACP3jB,EAAOmS,GAA0BnS,CAAI,EACrCA,EAAK,OAAS,SACd0jB,EAAIhlB,CAAG,EAAIsB,GAEX,OAAO0jB,EAAIhlB,CAAG,EAGT,CAAC,CAACilB,EACX,CAEA,WAAY,CACV,IAAMD,EAAM,KAAK,IACfE,EAAiB,KAAK,eACxBlpB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,0BACA,aAAe,KAAK,SAAS,QAAQ,KAAO,sBAAwBkpB,CACtE,EAEK,KAAK,iBACR,KAAK,gBAAwBloB,GAAKgoB,CAAG,EACrC,KAAK,cAAc,EAAI,EAE3B,CAEA,SAAU,CACR,IAAMA,EAAM,KAAK,IACfE,EAAiB,KAAK,eAOxB,GANAlpB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,wBACA,aAAe,KAAK,SAAS,QAAQ,KAAO,sBAAwBkpB,CACtE,EACIA,EAAgB,CAGlB,QAAWJ,KAAaE,EACRA,EAAIF,CAAS,EACjB,SAAW,UACnB,OAAOE,EAAIF,CAAS,EAKxB,KAAK,SAAS,kBAAwBhmB,EAAY,KAAK,eAAkD,CAAC,EAC1G,QAAWgmB,KAAa,KAAK,gBAC3B,OAAOE,EAAIF,CAAS,EAEtB,KAAK,gBAAkB,KAGvB,KAAK,cAAc,EAAK,CAC1B,CACA,KAAK,KAAK,MAAM,CAClB,CAEA,SAASziB,EAAsB,CAC7B,IAAM6iB,EAAiB,KAAK,eAO5B,GANAlpB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,yBACA,aAAe,KAAK,SAAS,QAAQ,KAAO,sBAAwBkpB,CACtE,EACI,CAACA,EAAgB,CACnB7iB,EAAS,EACT,MACF,CACA,KAAK,KAAK,OAAQA,CAAQ,CAC5B,CAEA,OAAQ,CACN,KAAK,IAAM,CAAC,EACZ,KAAK,cAAc,EAAK,EACxB,KAAK,gBAAkB,IACzB,CAEA,cAAc8iB,EAAqB,CACjCnpB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,8BAA+B,gBAAkBmpB,CAAU,EAC3G,KAAK,eAAiBA,EACtB,KAAK,SAAS,aAAe,CAACA,CAChC,CACF,EClLA,SAASC,GAAYC,EAAoC,CACvD,OAAOA,EAAiB,QAAQ,OAAO,KAAK,QAC9C,CAEA,SAASC,GAAsBD,EAAoC,CACjE,IAAMvI,EAAWuI,EAAiB,QAAQ,OAKpCza,EAAWkS,EAAS,KAAK,SAC/B,OAAQ,CAAClS,GAAYA,IAAa,MAAQkS,EAAS,WAAW,QAAU,WAC1E,CAGA,SAASyI,GAAahT,EAA0BlQ,EAAuB3G,EAAoB,CACzF,OAAQ6W,EAAQ,MAAO,CACrB,IAAK,WACL,IAAK,YACH7W,EAAO,EACP,MACF,IAAK,cACL,IAAK,WACL,IAAK,YACL,IAAK,YACGqD,GAAmBwT,EAAQ,OAAO,EAAG,SAAUrT,EAAmB,CAClEA,EAAKmD,EAASnD,CAAG,EAChBxD,EAAO,CACd,CAAC,EACD,MACF,QACE2G,EAASvI,EAAU,WAAWyY,EAAQ,kBAAkB,CAAC,CAAC,CAC9D,CACF,CAEA,IAAMiT,GAAN,cAA+BzN,EAAa,CAS1C,YAAYxF,EAA0B,CACpC,MAAMA,EAAQ,MAAM,EACpB,KAAK,QAAUA,EACf,KAAK,aAAe,GACpB,KAAK,QAAU,IAAIsS,GAAY,KAAOvjB,GAASA,EAAK,SAAW,IAAMA,EAAK,YAAY,EAEtF,KAAK,WAAa,IAAIujB,GAAY,KAAOvjB,GAASA,EAAK,QAAS,EAChE,KAAK,cAAgB,IAAIyW,GAAa,KAAK,MAAM,EACjD,KAAK,gBAAkB,CAAC,CAC1B,CAEA,MAAM,MAAMjW,EAA8B,CACxC,GAAIwjB,GAAsB,IAAI,EAC5B,MAAM,IAAIxrB,EAAU,yDAA0D,MAAO,GAAG,EAE1F,OAAO,KAAK,qBAAqB,OAAW,OAAWgI,EAAM,OAAO,CACtE,CAEA,MAAM,OAAOA,EAA8B,CACzC,GAAIwjB,GAAsB,IAAI,EAC5B,MAAM,IAAIxrB,EAAU,qDAAsD,MAAO,GAAG,EAEtF,OAAO,KAAK,qBAAqB,OAAW,OAAWgI,EAAM,QAAQ,CACvE,CAEA,MAAM,YAAY8I,EAAkB9I,EAA8B,CAChE,OAAO,KAAK,qBAAqB,OAAW8I,EAAU9I,EAAM,OAAO,CACrE,CAEA,MAAM,aAAa8I,EAAkB9I,EAA8B,CACjE,OAAO,KAAK,qBAAqB,OAAW8I,EAAU9I,EAAM,QAAQ,CACtE,CAEA,MAAM,qBACJsZ,EACAxQ,EACA9I,EACApG,EACe,CACf,IAAM6W,EAAU,KAAK,QACrB,GAAI,CAACA,EAAQ,kBAAkB,YAAY,EACzC,MAAMA,EAAQ,kBAAkB,SAAS,EAG3CvW,EAAO,UACL,KAAK,OACLA,EAAO,UACP,oBAAsBN,EAAS,WAC/B,aAAe6W,EAAQ,KAAO,UAAY6I,EAAK,eAAiBxQ,GAAY,cAAgBwa,GAAY,IAAI,EAC9G,EAEA,IAAM/P,EAAWlB,GAAwBrS,CAAI,EAU7C,OATAuT,EAAS,OAAS3Z,EACd0f,IACF/F,EAAS,GAAK+F,GAEZxQ,IACFyK,EAAS,SAAWzK,GAGtB,MAAMgI,GAAsByC,EAAU9C,EAAQ,cAA+B,EACrEA,EAAQ,MAAO,CACrB,IAAK,WACH,OAAO,IAAI,QAAQ,CAACvL,EAAS1D,IAAW,CACtCiP,EAAQ,aAAa8C,EAAWnW,GAASA,EAAMoE,EAAOpE,CAAG,EAAI8H,EAAQ,CAAE,CACzE,CAAC,EACH,IAAK,cACL,IAAK,WACHuL,EAAQ,OAAO,EAEjB,IAAK,YACH,OAAO,IAAI,QAAQ,CAACvL,EAAS1D,IAAW,CACtC,KAAK,gBAAgB,KAAK,CACxB,SAAA+R,EACA,SAAWnW,GAASA,EAAMoE,EAAOpE,CAAG,EAAI8H,EAAQ,CAClD,CAAC,CACH,CAAC,EACH,QAAS,CACP,IAAM9H,EAAM,IAAIO,GACd,aAAe/D,EAAS,8BAAgC6W,EAAQ,MAAQ,SACxE,KACF,EACA,MAAArT,EAAI,KAAO,MACLA,CACR,CACF,CACF,CAEA,MAAM,MAAM4C,EAA8B,CACxC,GAAIwjB,GAAsB,IAAI,EAC5B,MAAM,IAAIxrB,EAAU,yEAA0E,MAAO,GAAG,EAE1G,OAAO,KAAK,YAAY,OAAWgI,CAAI,CACzC,CAEA,MAAM,YAAY8I,EAAmB9I,EAA+B,CAClE,IAAMyQ,EAAU,KAAK,QACrB,GAAI,CAACA,EAAQ,kBAAkB,YAAY,EACzC,MAAMA,EAAQ,kBAAkB,SAAS,EAG3CvW,EAAO,UACL,KAAK,OACLA,EAAO,UACP,iCACA,sBAAwB,KAAK,QAAQ,KAAO,cAAgB4O,CAC9D,EACA,IAAMyK,EAAWlB,GAAwBrS,CAAI,EAC7C,OAAAuT,EAAS,OAAS,QACdzK,IACFyK,EAAS,SAAWzK,GAGf,IAAI,QAAQ,CAAC5D,EAAS1D,IAAW,CACtC,OAAQiP,EAAQ,MAAO,CACrB,IAAK,WACHA,EAAQ,aAAa8C,EAAWnW,GAASA,EAAMoE,EAAOpE,CAAG,EAAI8H,EAAQ,CAAE,EACvE,MACF,IAAK,YACH,KAAK,gBAAgB,KAAK,CACxB,SAAAqO,EACA,SAAWnW,GAASA,EAAMoE,EAAOpE,CAAG,EAAI8H,EAAQ,CAClD,CAAC,EACD,MACF,IAAK,cACL,IAAK,SAAU,CAGb,IAAM9H,EAAM,IAAIO,GAAiB,wDAAyD,KAAK,EAC/F6D,EAAOpE,CAAG,EACV,KACF,CACA,QACEoE,EAAOiP,EAAQ,kBAAkB,CAAC,CACtC,CACF,CAAC,CACH,CAEA,MAAM,IAAIhR,EAA6D,CACrE,IAAMkkB,EAAc,CAAClkB,IAAW,gBAAiBA,EAASA,EAAO,YAAc,IAE/E,OAAO,IAAI,QAAQ,CAACyF,EAAS1D,IAAW,CACtC,SAASoiB,EAAc3e,EAAsB,CAC3CC,EAAQzF,EAASwF,EAAQ,KAAKxF,CAAM,EAAIwF,EAAQ,OAAO,CAAC,CAC1D,CAGA,GAAI,KAAK,QAAQ,QAAU,YAAa,CAClC0e,EACFniB,EACExJ,EAAU,WAAW,CACnB,WAAY,IACZ,KAAM,MACN,QAAS,2EACX,CAAC,CACH,EAEA4rB,EAAc,KAAK,OAAO,EAE5B,MACF,CAEAH,GACE,KAAK,QACJrmB,GAAQoE,EAAOpE,CAAG,EACnB,IAAM,CACJ,IAAM6H,EAAU,KAAK,QACjB0e,EACF1e,EAAQ,SAAS,UAAY,CAC3B2e,EAAc3e,CAAO,CACvB,CAAC,EAED2e,EAAc3e,CAAO,CAEzB,CACF,CACF,CAAC,CACH,CAEA,MAAM,QAAQxF,EAAiF,CAC7FvF,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,6BAA8B,aAAe,KAAK,IAAI,EAEtG,IAAMylB,EAAY,KAAK,QAAQ,OAAO,KAAK,cAE3C,GAAIlgB,GAAUA,EAAO,YACnB,GAAI,KAAK,QAAQ,QAAU,WACzB,OAAOA,EAAO,YACdA,EAAO,YAAc,KAAK,QAAQ,WAAW,iBAE7C,OAAM,IAAIzH,EACR,gEAAkE,KAAK,QAAQ,MAC/E,IACA,GACF,EAIJ,OAAO2nB,EAAU,QAAQ,KAAMlgB,CAAM,CACvC,CAEA,YAAYokB,EAAgCrD,EAAiBD,EAAkC,CAC7FrmB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,iCACA,yBAA2B2pB,EAAY,OAAS,sCAAwCtD,CAC1F,EACA,IAAIuD,EAAYlkB,EACVqF,EAAU,KAAK,QACnB8e,EAAY,KAAK,WACjBC,EAAoB,CAAC,EACrBC,EAAS,KAAK,QAAQ,kBAAkB,aAEtCzD,IACF,KAAK,QAAQ,UAAU,EACnBD,IAAsB3gB,EAAQ2gB,EAAkB,MAAM,eAAe,KACvEuD,EAAalkB,EAAM,CAAC,IAIxB,QAAS5B,EAAI,EAAGA,EAAI6lB,EAAY,OAAQ7lB,IAAK,CAC3C,IAAMuV,EAAW5B,GAA0BkS,EAAY7lB,CAAC,CAAC,EACzD,OAAQuV,EAAS,OAAQ,CACvB,IAAK,QACCtO,EAAQ,OAAOsO,CAAQ,GACzByQ,EAAkB,KAAKzQ,CAAQ,EAE7BA,EAAS,eAAiB0Q,GAAU,CAAC1Q,EAAS,cAAc,GAC9DwQ,EAAU,OAAOxQ,CAAQ,EAE3B,MACF,IAAK,QACL,IAAK,UACL,IAAK,SACCtO,EAAQ,IAAIsO,CAAQ,GACtByQ,EAAkB,KAAKzQ,CAAQ,EAE7BA,EAAS,eAAiB0Q,GAC5BF,EAAU,IAAIxQ,CAAQ,EAExB,KACJ,CACF,CAEIiN,GAAU,CAACsD,IACb7e,EAAQ,QAAQ,EAChB,KAAK,QAAQ,kBAAoB,MAInC,QAASjH,EAAI,EAAGA,EAAIgmB,EAAkB,OAAQhmB,IAAK,CACjD,IAAMuV,EAAWyQ,EAAkBhmB,CAAC,EACpC,KAAK,cAAc,KAAKuV,EAAS,OAAkBA,CAAQ,CAC7D,CACF,CAEA,WAAWmN,EAA6B,CACtCxmB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,gCACA,aAAe,KAAK,QAAQ,KAAO,mBAAqBwmB,CAC1D,EAEIA,EACF,KAAK,QAAQ,UAAU,GAEvB,KAAK,kBAAkB,KAAK,QAAQ,OAAO,CAAC,EAC5C,KAAK,QAAQ,MAAM,GAIrB,KAAK,wBAAwB,EAG7B,IAAMwD,EAAkB,KAAK,gBAC3BC,EAAmBD,EAAgB,OAErC,GAAIC,EAAkB,CACpB,KAAK,gBAAkB,CAAC,EACxB,IAAMC,EAAgB,CAAC,EACjB5a,EAAcpE,GAAY,OAAO,KAAK,MAAM,EAClDlL,EAAO,UACL,KAAK,OACLA,EAAO,UACP,8BACA,WAAaiqB,EAAmB,2BAClC,EACA,QAASnmB,EAAI,EAAGA,EAAImmB,EAAkBnmB,IAAK,CACzC,IAAMuX,EAAQ2O,EAAgBlmB,CAAC,EAC/BomB,EAAc,KAAK7O,EAAM,QAAQ,EACjC/L,EAAY,KAAK+L,EAAM,QAAQ,CACjC,CACA,KAAK,QAAQ,aAAa6O,EAAe5a,CAAW,CACtD,CACF,CAEA,kBAAkBqS,EAAe6E,EAAuBtjB,EAA8B,CACpF,OAAQye,EAAO,CACb,IAAK,WACH,KAAK,WAAW6E,CAAW,EAC3B,MACF,IAAK,WACL,IAAK,SACH,KAAK,gBAAgB,EACrB,KAAK,QAAQ,MAAM,EAErB,IAAK,YACH,KAAK,oBAAoBtjB,CAAG,EAC5B,KACJ,CACF,CAEA,oBAAoBA,EAA8B,CAChD,GAAI,KAAK,gBAAgB,OAAQ,CAC/BlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,sCACA,mBAAqB,KAAK,QAAQ,KAAO,WAAmB6B,EAAaqB,CAAG,CAC9E,EACA,QAASY,EAAI,EAAGA,EAAI,KAAK,gBAAgB,OAAQA,IAC/C,GAAI,CACF,KAAK,gBAAgBA,CAAC,EAAE,SAASZ,CAAG,CAEtC,MAAY,CAAC,CACf,KAAK,gBAAkB,CAAC,CAC1B,CACF,CAEA,iBAAwB,CACtB,KAAK,WAAW,MAAM,CACxB,CAEA,yBAAgC,CAC9B,IAAM2mB,EAAY,KAAK,WACjBE,EAAS,KAAK,QAAQ,kBAAkB,aAE9C,QAAWjB,KAAae,EAAU,IAAK,CACrC,IAAMM,EAAQN,EAAU,IAAIf,CAAS,EACrC9oB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,6CACA,6BAA+BmqB,EAAM,SAAW,yBAClD,EAIA,IAAM/K,EAAK+K,EAAM,eAAiBJ,EAASI,EAAM,GAAK,OACtD,KAAK,qBAAqB/K,EAAI+K,EAAM,SAAUA,EAAM,KAAM,OAAO,EAAE,MAAOjnB,GAAQ,CAChF,IAAMiP,EAAa,IAAIrU,EAAU,gCAAiC,MAAO,IAAKoF,CAAG,EACjFlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,6CACA,2CAAmD6B,EAAaqB,CAAG,CACrE,EACA,IAAMigB,EAAS,IAAIiC,GAAmB,KAAK,QAAQ,MAAO,KAAK,QAAQ,MAAO,GAAM,GAAOjT,CAAU,EACrG,KAAK,QAAQ,KAAK,SAAUgR,CAAM,CACpC,CAAC,CACH,CACF,CAEA,kBAAkB1P,EAAgC,CAChD,IAAMsS,EAAgB,KAAK,cAC3BtS,EAAM,QAAQ,SAAUnO,EAAM,CAC5B,IAAM+T,EAAW5B,GAA0B,CACzC,OAAQ,QACR,aAAcnS,EAAK,aACnB,SAAUA,EAAK,SACf,KAAMA,EAAK,KACX,SAAUA,EAAK,SACf,UAAW,KAAK,IAAI,CACtB,CAAC,EACDygB,EAAc,KAAK,QAAS1M,CAAQ,CACtC,CAAC,CACH,CAEA,MAAM,aAAa+Q,EAAyD,CAC1E,IAAMjrB,EAAOqoB,GAAgB,oBAAoB4C,CAAK,EAChD/O,EAAQlc,EAAK,CAAC,EACd0b,EAAW1b,EAAK,CAAC,EACjBoX,EAAU,KAAK,QAErB,GAAIA,EAAQ,QAAU,SACpB,MAAMzY,EAAU,WAAWyY,EAAQ,kBAAkB,CAAC,EAGxD,KAAK,cAAc,GAAG8E,EAAOR,CAAQ,EACrC,MAAMtE,EAAQ,OAAO,CACvB,CAEA,eAAe6T,EAAgD,CAC7D,IAAMjrB,EAAOqoB,GAAgB,oBAAoB4C,CAAK,EAChD/O,EAAQlc,EAAK,CAAC,EACd0b,EAAW1b,EAAK,CAAC,EACvB,KAAK,cAAc,IAAIkc,EAAOR,CAAQ,CACxC,CACF,EAEOwP,GAAQb,GCxcTc,GAAYzK,GAAe,UAEjC,SAAS0K,GAAgBhiB,EAAoD,CAC3E,MAAO,CAAC,CAAEA,EAAqB,EACjC,CAEA,IAAMiiB,GAAN,cAAiC5K,EAAU,CAMzC,YAAYZ,EAAsCC,EAAY1Z,EAAyB,CACrF,MAAMyZ,EAAmBC,EAAM1Z,CAAM,EANvC,KAAA,UAAY+kB,GAQV/kB,EAAO,WAAajH,EAAS,OAAO,sBACpC,KAAK,OAASiH,EAAO,IACvB,CAEA,OAAO,aAAc,CACnB,MAAO,CAAC,CAACjH,EAAS,OAAO,SAC3B,CAEA,gBAAgByL,EAAa0gB,EAAuC,CAClE,YAAK,IAAM1gB,EAAYlH,GAAc4nB,CAAa,EAC3C,IAAInsB,EAAS,OAAO,UAAU,KAAK,GAAG,CAC/C,CAEA,UAAW,CACT,MAAO,2BAA6B,KAAK,GAC3C,CAEA,SAAU,CACR0B,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAAgC,UAAU,EAC1F4f,GAAU,UAAU,QAAQ,KAAK,IAAI,EACrC,IAAM/L,EAAO,KACXtO,EAAS,KAAK,OACd8C,EAAU9C,EAAO,QAEbmlB,GADWriB,EAAQ,IAAM,SAAW,SACjB,KAAK,OAAS,IAAMqC,EAAS,QAAQrC,CAAO,EAAI,IACzErI,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAAgC,QAAU0qB,CAAK,EACzF3nB,GACJ,KAAK,KAAK,cAAc,EACxB,SAAUG,EAAuBqK,EAAqC,CACpE,GAAIsG,EAAK,WACP,OAEF,IAAI8W,EAAW,GACf,QAAWC,KAASrd,EAAYod,GAAY,IAAMC,EAAQ,KAAOrd,EAAWqd,CAAK,EAAI,IAOrF,GANA5qB,EAAO,UACL6T,EAAK,OACL7T,EAAO,UACP,+BACA,cAAgB2qB,EAAW,SAAWznB,CACxC,EACIA,EAAK,CACP2Q,EAAK,WAAW3Q,CAAG,EACnB,MACF,CACA,IAAMunB,EAAgBllB,EAAO,iBAAiBgI,CAAW,EACzD,GAAI,CACF,IAAMsd,EAAgBhX,EAAK,aAAeA,EAAK,gBAAgB6W,EAAOD,CAAa,EACnFI,EAAa,WAAavsB,EAAS,OAAO,WAC1CusB,EAAa,OAAS,UAAY,CAChChX,EAAK,SAAS,CAChB,EACAgX,EAAa,QAAU,SAAUC,EAAgB,CAC/CjX,EAAK,UAAUiX,CAAE,CACnB,EACAD,EAAa,UAAY,SAAUC,EAAkB,CACnDjX,EAAK,SAASiX,EAAG,IAAI,CACvB,EACAD,EAAa,QAAU,SAAUC,EAAW,CAC1CjX,EAAK,UAAUiX,CAAgB,CACjC,EACIP,GAAgBM,CAAY,GAG9BA,EAAa,GAAG,OAAQ,UAAY,CAClChX,EAAK,WAAW,CAClB,CAAC,CAEL,OAASzM,EAAG,CACVpH,EAAO,UACL6T,EAAK,OACL7T,EAAO,UACP,+BACA,mDAAsDoH,EAAY,OAAUA,EAAY,QAC1F,EACAyM,EAAK,WAAWzM,CAAU,CAC5B,CACF,CACF,CACF,CAEA,KAAKzH,EAA0B,CAC7B,IAAMkrB,EAAe,KAAK,aAC1B,GAAI,CAACA,EAAc,CACjB7qB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,4BAA6B,sBAAsB,EACnG,MACF,CACA,GAAI,CACD6qB,EAA+B,KAC9B9T,GAAyBpX,EAAS,KAAK,kBAAkB,SAAS,SAAU,KAAK,OAAO,MAAM,CAChG,CACF,OAASyH,EAAG,CACV,IAAMvI,EAAM,qDAA6DgD,EAAauF,CAAC,EACvFpH,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,4BAA6BnB,CAAG,EAGhF,KAAK,OAAO,eAAgB,IAAIf,EAAUe,EAAK,IAAO,GAAG,CAAC,CAC5D,CACF,CAEA,SAASiH,EAAc,CACrB9F,EAAO,UACL,KAAK,OACLA,EAAO,UACP,gCACA,2BAA6B8F,EAAK,OAAS,YAAc,OAAOA,CAClE,EACA,GAAI,CACF,KAAK,kBACHwW,GACExW,EACA,KAAK,kBAAkB,SAAS,SAChC,KAAK,kBAAkB,SAAS,kBAChC,KAAK,MACP,CACF,CACF,OAASsB,EAAG,CACVpH,EAAO,UACL,KAAK,OACLA,EAAO,UACP,gCACA,iDAAoDoH,EAAY,KAClE,CACF,CACF,CAEA,UAAW,CACTpH,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,gCAAiC,kBAAkB,EACnG,KAAK,KAAK,YAAY,CACxB,CAEA,UAAU8qB,EAAyB,CACjC,IAAIC,EAAU1nB,EAYd,GAXI,OAAOynB,GAAM,UAEfznB,EAAOynB,EAAG,KAEVC,EAAWD,EAAG,UAAYznB,IAAS,MAGnCA,EAAOynB,EACPC,EAAW1nB,GAAQ,KAErB,OAAO,KAAK,aACR0nB,EAAU,CACZ/qB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,iCAAkC,0BAA0B,EAC5G,IAAMkD,EAAM,IAAIpF,EAAU,mBAAoB,MAAO,GAAG,EACxD,KAAK,OAAO,eAAgBoF,CAAG,CACjC,KAAO,CACL,IAAMrE,EAAM,+CAAiDwE,EAC3DH,EAAM,IAAIpF,EAAUe,EAAK,MAAO,GAAG,EACrCmB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,iCAAkCnB,CAAG,EACrF,KAAK,OAAO,eAAgBqE,CAAG,CACjC,CACA,KAAK,KAAK,UAAU,CACtB,CAEA,UAAUA,EAAiB,CACzBlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,+BACA,yBAA2BkD,EAAI,OACjC,EAIA5E,EAAS,OAAO,SAAS,IAAM,CAC7B,KAAK,WAAW,MAAM4E,EAAI,OAAO,CAAC,CACpC,CAAC,CACH,CAEA,SAAU,CACRlD,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAAgC,EAAE,EAClF,KAAK,WAAa,GAClB,IAAM6qB,EAAe,KAAK,aACtBA,IAIFA,EAAa,UAAY,UAAY,CAAC,EACtC,OAAO,KAAK,aAGZvsB,EAAS,OAAO,SAAS,IAAM,CAE7B,GADA0B,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAAgC,mBAAmB,EAC/F,CAAC6qB,EACH,MAAM,IAAI,MAAM,2DAA2D,EAE7EA,EAAa,MAAM,CACrB,CAAC,EAEL,CACF,EAEOG,GAAQR,GC5NFS,GAAN,KAA4B,CACjC,OAAO,gBAAgB1U,EAA0B+R,EAA2BzN,EAAwC,CAClH,IAAMqQ,EAAoBvO,GAAe,CAN7C,IAAA3d,EAAA4G,EAAAgL,EAAAC,EAAAC,EAAAC,EAOM,IAAMoa,EAAqD,CACzD,KAAMxO,EAAE,KACR,eAAe/W,GAAA5G,EAAA2d,EAAE,SAAF,KAAA,OAAA3d,EAAU,MAAV,KAAA,OAAA4G,EAAe,WAC9B,SAASiL,GAAAD,EAAA+L,EAAE,SAAF,KAAA,OAAA/L,EAAU,MAAV,KAAA,OAAAC,EAAe,KACxB,MAAO,CAAC,GAACE,GAAAD,EAAA6L,EAAE,SAAF,KAAA,OAAA7L,EAAU,MAAV,MAAAC,EAAe,YACxB,SAAU4L,EAAE,QACd,EAGE,OAAO,QAAQ2L,CAAM,EAAE,KAAK,CAAC,CAACtkB,EAAK4gB,CAAK,IACtCA,IAAU,OAAYuG,EAAQnnB,CAA8B,IAAM4gB,EAAQ,EAC5E,GAIF/J,EAAS8B,CAAC,CACZ,EACA,KAAK,wBAAwBpG,EAAS+R,EAAQzN,EAAUqQ,CAAgB,EACxE3U,EAAQ,cAAc,GAAG2U,CAAgB,CAC3C,CAGA,OAAO,wBACL3U,EACA+R,EACA8C,EACAF,EACA,CAlCJ,IAAAlsB,EAyCI,GANKuX,EAAQ,wBACXA,EAAQ,sBAAwB,IAAI,KAKlCA,EAAQ,sBAAsB,IAAI6U,CAAY,EAAG,CACnD,IAAMC,EAAkB9U,EAAQ,sBAAsB,IAAI6U,CAAY,EAKtEC,EAAgB,IAAI/C,IAAQtpB,EAAAqsB,GAAiB,IAAI/C,CAAA,IAArB,KAAA,OAAAtpB,EAA8B,OAAOksB,CAAA,IAAqB,CAACA,CAAgB,CAAC,CAC1G,MACE3U,EAAQ,sBAAsB,IAC5B6U,EACA,IAAI,IAAuD,CAAC,CAAC9C,EAAQ,CAAC4C,CAAgB,CAAC,CAAC,CAAC,CAC3F,CAEJ,CAEA,OAAO,kCACL3U,EACA+R,EACA8C,EACgC,CAEhC,GAAI,CAAC7U,EAAQ,sBACX,MAAO,CAAC,EAGV,GAAI,CAAC6U,GAAgB9C,EAEnB,OAAO,MAAM,KAAK/R,EAAQ,sBAAsB,QAAQ,CAAC,EACtD,IAAI,CAAC,CAACvS,EAAKsnB,CAAU,IAAM,CArEpC,IAAAtsB,EAuEU,IAAIusB,EAAeD,EAAW,IAAIhD,CAAM,EACxC,OAAAgD,EAAW,OAAOhD,CAAM,EAEpBgD,EAAW,OAAS,KACtBtsB,EAAAuX,EAAQ,wBAAR,MAAAvX,EAA+B,OAAOgF,CAAA,GAEjCunB,CACT,CAAC,EACA,OACC,CAACC,EAAMC,IAASA,EAAOD,EAAwC,OAAO,GAAGC,CAAG,EAAID,EAChF,CAAC,CACH,EAIJ,GAAI,CAACJ,GAAgB,CAAC7U,EAAQ,sBAAsB,IAAI6U,CAAY,EAClE,MAAO,CAAC,EAEV,IAAMC,EAAkB9U,EAAQ,sBAAsB,IAAI6U,CAAY,EAKtE,GAAI,CAAC9C,EAAQ,CAEX,IAAMrN,EAAY,MAAM,KAAKoQ,EAAgB,OAAO,CAAC,EAAE,OAAO,CAACG,EAAMC,IAAQD,EAAK,OAAO,GAAGC,CAAG,EAAG,CAAC,CAAC,EAEpG,OAAAlV,EAAQ,sBAAsB,OAAO6U,CAAY,EAC1CnQ,CACT,CAEA,IAAIA,EAAYoQ,EAAgB,IAAI/C,CAAM,EAC1C,OAAA+C,EAAgB,OAAO/C,CAAM,EAEtBrN,GAAa,CAAC,CACvB,CACF,ECjFayQ,GAAN,MAAMA,WAAwBlD,EAAa,CAEhD,YAAYngB,EAAkC,CA5BhD,IAAArJ,EA6BI,IAAMsH,EAAUolB,GAAgB,SAChC,GAAI,CAACplB,EACH,MAAM,IAAI,MAAM,oDAAoD,EAGtE,MACEoE,EAAS,iBAAiBrC,EAAS,GAAM,WAAYrI,EAAO,cAAeuJ,EAAAC,EAAA,CAAA,EACtE8Q,EAAA,EADsE,CAEzE,QAAQtb,EAAA0sB,GAAgB,SAAhB,KAAA1sB,EAA0B,OAClC,QAAAsH,EACA,iBAAkB,CAChB,iBAAA+jB,GACA,0BAAA5S,GACA,gCAAAE,GACA,gCAAAzB,EACF,EACA,mBAAA8U,GACA,oBAAqBC,EACvB,CAAA,CAAC,CACH,CACF,CAOA,WAAW,QAAS,CAClB,GAAI,KAAK,UAAY,KACnB,MAAM,IAAI,MAAM,wDAAwD,EAG1E,OAAO,KAAK,OACd,CACA,WAAW,OAAOvQ,EAAkC,CAClD,KAAK,QAAUA,CACjB,CAUF,EAjDagR,GAyBJ,MAAQzrB,GAzBJyrB,GA0BJ,kBAAoB7G,GA1BhB6G,GA2BJ,gBAAkBpO,GA3BdoO,GA6BI,QAAkC,KA7BtCA,GAyCJ,QAAUnR,GAzCNmR,GA0CJ,gBAAkBlR,GA1CdkR,GA4CJ,SAA2B,KA5CvBA,GA+CJ,MAAQxb,GA/CJwb,GAgDJ,aAAe7C,GAhDjB,IAAM9qB,GAAN2tB,GCJHC,GAAa,WACbC,GAAc,YACdC,GAAM,KAAK,IAMXC,GAAgB,IAAIF,GAAY,CAAC,EACjCG,GAA4B,CAAC,EAK7BC,GAAI,IAAIJ,GAAY,EAAE,EAM1B,SAASK,GAAkBhmB,EAAW,CACpC,OAASA,GAAKA,EAAI,IAAM4lB,GAAI,EAAG,EAAE,EAAK,CACxC,CAIA,QAFI5lB,GAAI,EACNimB,GAAS,EACJA,GAAS,IAAI,CAYlB,IATIC,GAAU,GASLC,GAAS,EAAGA,IAAUnmB,GAAI,EAAGmmB,KAChCnmB,GAAImmB,KAAW,IACjBD,GAAU,IAGVA,KACED,GAAS,IACXJ,GAAcI,EAAM,EAAID,GAAkBJ,GAAI5lB,GAAG,EAAI,CAAC,CAAC,GAEzD8lB,GAAgBG,EAAM,EAAID,GAAkBJ,GAAI5lB,GAAG,EAAI,CAAC,CAAC,EAEzDimB,MAGFjmB,IACF,CAxBM,IAAAkmB,GASKC,GAqBPC,GAAe,CAAC,CAAC,IAAIV,GAAW,IAAIC,GAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAElE,SAASU,GAAcC,EAAc,CACnC,OAAIF,GAGCE,IAAS,IAEPA,IAAS,GAAM,MAAS,GAEzBA,EAAO,QAAW,EAEnBA,GAAQ,GAGJA,CAEX,CAEA,SAASC,GAAYD,EAAcE,EAAc,CAC/C,OAAQF,IAASE,EAASF,GAAS,GAAKE,CAC1C,CAEA,SAASC,GAAO5mB,EAAkB,CAEhC,IAAI6mB,EAAQb,GAAc,MAAM,EAI5Bc,EAAQ9mB,EAAK,OAGb+mB,EAAYD,EAAQ,EACpBE,EAAe,KAAQD,EAAY,IAAM,IAAO,EAAIA,EAAY,GAGhEE,EAAQ,IAAIpB,GAAWmB,EAAe,CAAC,EACvCE,EAAQ,IAAIpB,GAAYmB,EAAM,MAAM,EAExCA,EAAM,IAAIjnB,EAAM,CAAC,EAEjBinB,EAAMH,CAAK,EAAI,IAEfI,EAAMA,EAAM,OAAS,CAAC,EAAIV,GAAcO,CAAS,EAMjD,QAHII,EAGKC,EAAQ,EAAGA,EAAQJ,EAAe,GAAII,GAAS,GAAI,CAC1D,IAAIC,EAAeR,EAAM,MAAM,EAG/B,IAAKM,EAAQ,EAAGA,EAAQ,GAAIA,IAAS,CACnC,IAAIG,EAEJ,GAAIH,EAAQ,GAEVG,EAASd,GAAcU,EAAME,EAAQD,CAAK,CAAC,MACtC,CACL,IAAII,EAAUrB,GAAEiB,EAAQ,EAAE,EACtBK,EAAUtB,GAAEiB,EAAQ,CAAC,EACzBG,EACEpB,GAAEiB,EAAQ,CAAC,EACXjB,GAAEiB,EAAQ,EAAE,GACXT,GAAYa,EAAS,CAAC,EAAIb,GAAYa,EAAS,EAAE,EAAKA,IAAY,IAClEb,GAAYc,EAAS,EAAE,EAAId,GAAYc,EAAS,EAAE,EAAKA,IAAY,GACxE,CAGAtB,GAAEiB,CAAK,EAAIG,GAAU,EAYrB,QATIG,GACDf,GAAYW,EAAa,CAAC,EAAG,CAAC,EAAIX,GAAYW,EAAa,CAAC,EAAG,EAAE,EAAIX,GAAYW,EAAa,CAAC,EAAG,EAAE,IACnGA,EAAa,CAAC,EAAIA,EAAa,CAAC,EAAM,CAACA,EAAa,CAAC,EAAIA,EAAa,CAAC,GACzEA,EAAa,CAAC,EACdC,EACArB,GAAgBkB,CAAK,EACnBO,GACDhB,GAAYW,EAAa,CAAC,EAAG,CAAC,EAAIX,GAAYW,EAAa,CAAC,EAAG,EAAE,EAAIX,GAAYW,EAAa,CAAC,EAAG,EAAE,IACnGA,EAAa,CAAC,EAAIA,EAAa,CAAC,EAAMA,EAAa,CAAC,GAAKA,EAAa,CAAC,EAAIA,EAAa,CAAC,IACpFrpB,EAAI,EAAGA,EAAI,EAAGA,IACrBqpB,EAAarpB,CAAC,EAAIqpB,EAAarpB,EAAI,CAAC,EAEtCqpB,EAAa,CAAC,EAAKI,EAAKC,EAAM,EAC9BL,EAAa,CAAC,EAAKA,EAAa,CAAC,EAAII,EAAM,CAC7C,CAGA,IAAKN,EAAQ,EAAGA,EAAQ,EAAGA,IACzBN,EAAMM,CAAK,EAAKN,EAAMM,CAAK,EAAIE,EAAaF,CAAK,EAAK,CAE1D,CAIA,OAAO,IAAItB,GACT,IAAIC,GACFe,EAAM,IAAI,SAAUjoB,EAAK,CACvB,OAAO4nB,GAAc5nB,CAAG,CAC1B,CAAC,CACH,EAAE,MACJ,CACF,CAEO,SAASmH,GAAK7H,EAAiB8B,EAAkB,CAGtD,GAFI9B,EAAI,OAAS,KAAIA,EAAM0oB,GAAO1oB,CAAG,GAEjCA,EAAI,OAAS,GAAI,CACnB,IAAMypB,EAAM,IAAI,WAAW,EAAE,EAC7BA,EAAI,IAAIzpB,EAAK,CAAC,EACdA,EAAMypB,CACR,CAKA,QAFIC,EAAW,IAAI,WAAW,EAAE,EAC5BC,EAAW,IAAI,WAAW,EAAE,EACvB7pB,EAAI,EAAGA,EAAI,GAAIA,IACtB4pB,EAAS5pB,CAAC,EAAI,GAAOE,EAAIF,CAAC,EAC1B6pB,EAAS7pB,CAAC,EAAI,GAAOE,EAAIF,CAAC,EAI5B,IAAIjF,EAAM,IAAI,WAAWiH,EAAK,OAAS,EAAE,EACzCjH,EAAI,IAAI6uB,EAAU,CAAC,EACnB7uB,EAAI,IAAIiH,EAAM,EAAE,EAGhB,IAAI3C,EAAS,IAAI,WAAW,EAAO,EACnC,OAAAA,EAAO,IAAIwqB,EAAU,CAAC,EACtBxqB,EAAO,IAAIupB,GAAO7tB,CAAG,EAAG,EAAE,EAGnB6tB,GAAOvpB,CAAM,CACtB,CC7MA,IAAMyqB,GAAN,KAA8E,CAA9E,aAAA,CACE,KAAA,cAAgB,mEAChB,KAAA,WAAa,kBAAA,CAGL,kBAAkBb,EAA2B,CACnD,IAAIc,EAAS,GACPC,EAAY,KAAK,cAEjBC,EAAahB,EAAM,WACnBiB,EAAgBD,EAAa,EAC7BE,EAAaF,EAAaC,EAE5BhnB,EAAGC,EAAGinB,EAAGC,EACTC,EAGJ,QAAStqB,EAAI,EAAGA,EAAImqB,EAAYnqB,EAAIA,EAAI,EAEtCsqB,EAASrB,EAAMjpB,CAAC,GAAK,GAAOipB,EAAMjpB,EAAI,CAAC,GAAK,EAAKipB,EAAMjpB,EAAI,CAAC,EAG5DkD,GAAKonB,EAAQ,WAAa,GAC1BnnB,GAAKmnB,EAAQ,SAAW,GACxBF,GAAKE,EAAQ,OAAS,EACtBD,EAAIC,EAAQ,GAGZP,GAAUC,EAAU9mB,CAAC,EAAI8mB,EAAU7mB,CAAC,EAAI6mB,EAAUI,CAAC,EAAIJ,EAAUK,CAAC,EAIpE,OAAIH,GAAiB,GACnBI,EAAQrB,EAAMkB,CAAU,EAExBjnB,GAAKonB,EAAQ,MAAQ,EAGrBnnB,GAAKmnB,EAAQ,IAAM,EAEnBP,GAAUC,EAAU9mB,CAAC,EAAI8mB,EAAU7mB,CAAC,EAAI,MAC/B+mB,GAAiB,IAC1BI,EAASrB,EAAMkB,CAAU,GAAK,EAAKlB,EAAMkB,EAAa,CAAC,EAEvDjnB,GAAKonB,EAAQ,QAAU,GACvBnnB,GAAKmnB,EAAQ,OAAS,EAGtBF,GAAKE,EAAQ,KAAO,EAEpBP,GAAUC,EAAU9mB,CAAC,EAAI8mB,EAAU7mB,CAAC,EAAI6mB,EAAUI,CAAC,EAAI,KAGlDL,CACT,CAEQ,oBAAoBA,EAAwB,CAClD,IAAMQ,EAAgB,OAAOR,CAAA,EACvBS,EAAMD,EAAc,OACpBtB,EAAQ,IAAI,WAAWuB,CAAG,EAChC,QAASxqB,EAAI,EAAGA,EAAIwqB,EAAKxqB,IAAK,CAC5B,IAAMyqB,EAAQF,EAAc,WAAWvqB,CAAC,EACxCipB,EAAMjpB,CAAC,EAAIyqB,CACb,CACA,OAAO,KAAK,cAAcxB,CAAK,CACjC,CAEA,SAAS/mB,EAAuC,CAC9C,OAAOA,aAAkB,aAAe,YAAY,OAAOA,CAAM,CACnE,CAEA,SAASA,EAAoC,CAC3C,GAAI,CAAC,YACH,MAAM,IAAI,MAAM,uEAAuE,EAGzF,GAAIA,aAAkB,YACpB,OAAO,IAAI,WAAWA,CAAM,EAG9B,GAAI,YAAY,OAAOA,CAAM,EAC3B,OAAO,IAAI,WAAW,KAAK,cAAcA,CAAM,CAAC,EAGlD,MAAM,IAAI,MAAM,iEAAiE,CACnF,CAEA,cAAcA,EAAiC,CAC7C,GAAI,CAAC,YACH,MAAM,IAAI,MAAM,4EAA4E,EAG9F,GAAIA,aAAkB,YACpB,OAAOA,EAGT,GAAI,YAAY,OAAOA,CAAM,EAC3B,OAAOA,EAAO,OAAO,MAAMA,EAAO,WAAYA,EAAO,WAAaA,EAAO,UAAU,EAGrF,MAAM,IAAI,MAAM,sEAAsE,CACxF,CAEA,aAAaA,EAA4B,CACvC,OAAO,KAAK,kBAAkB,KAAK,SAASA,CAAM,CAAC,CACrD,CAEA,aAAaa,EAAqB,CAChC,GAAI,aAAevI,EAAS,OAAO,KACjC,OAAO,KAAK,oBAAoBuI,CAAG,EAEnC,MAAM,IAAI,MAAM,yEAAyE,CAE7F,CAEA,UAAUb,EAA4B,CAEpC,OADmB,KAAK,SAASA,CAAM,EACrB,OAAO,CAACwoB,EAAOC,IAASD,EAAQC,EAAK,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,EAAG,EAAE,CAC1F,CAEA,UAAUC,EAAiC,CACzC,GAAIA,EAAgB,OAAS,IAAM,EACjC,MAAM,IAAI,MAAM,2DAA2D,EAG7E,IAAM/C,EAAa,IAAI,WAAW+C,EAAgB,OAAS,CAAC,EAE5D,QAAS5qB,EAAI,EAAGA,EAAI6nB,EAAW,OAAQ7nB,IACrC6nB,EAAW7nB,CAAC,EAAI,SAAS4qB,EAAgB,MAAM,EAAI5qB,EAAG,GAAKA,EAAI,EAAE,EAAG,EAAE,EAGxE,OAAO,KAAK,cAAc6nB,CAAU,CACtC,CAEA,WAAWgD,EAAwB,CACjC,GAAIrwB,EAAS,OAAO,YAAa,CAC/B,IAAMswB,EAAmB,IAAItwB,EAAS,OAAO,YAAY,EAAE,OAAOqwB,CAAM,EACxE,OAAO,KAAK,cAAcC,CAAgB,CAC5C,KACE,OAAM,IAAI,MAAM,uCAAuC,CAE3D,CAOA,WAAW5oB,EAA4B,CACrC,GAAI,CAAC,KAAK,SAASA,CAAM,EACvB,MAAM,IAAI,MAAM,kEAAkE,EAEpF,GAAI,YACF,OAAO,IAAI,YAAY,EAAE,OAAOA,CAAM,EAEtC,MAAM,IAAI,MAAM,uCAAuC,CAE3D,CAEA,gBAAgB6oB,EAAqBC,EAA8B,CACjE,GAAI,CAACD,GAAW,CAACC,EAAS,MAAO,GACjC,IAAMC,EAAe,KAAK,cAAcF,CAAO,EACzCG,EAAe,KAAK,cAAcF,CAAO,EAE/C,GAAIC,EAAa,YAAcC,EAAa,WAAY,MAAO,GAE/D,IAAMC,EAAS,IAAI,WAAWF,CAAY,EACpCG,EAAS,IAAI,WAAWF,CAAY,EAE1C,QAASlrB,EAAI,EAAGA,EAAImrB,EAAO,OAAQnrB,IACjC,GAAImrB,EAAOnrB,CAAC,GAAKorB,EAAOprB,CAAC,EAAG,MAAO,GAErC,MAAO,EACT,CAEA,WAAWkC,EAA4B,CACrC,OAAIA,aAAkB,aAAe,YAAY,OAAOA,CAAM,EACrDA,EAAO,WAET,EACT,CAEA,wBAAwBmpB,EAA+C,CACrE,OAAO,KAAK,cAAcA,CAAe,CAC3C,CAEA,WAAWxvB,EAAqBqE,EAAyB,CACvD,IAAMorB,EAAOvjB,GAAW,KAAK,SAAS7H,CAAG,EAAG,KAAK,SAASrE,CAAO,CAAC,EAClE,OAAO,KAAK,cAAcyvB,CAAI,CAChC,CACF,EAEOC,GAAQ,IAAIzB,GCzLf0B,GAAoB,SAAUC,EAAyBzoB,EAAiC,CAC1F,IAAI0oB,EAAoB,MACpBC,EAAoB,IACpBC,EAAe,MACfC,EAAsB,GAM1B,SAASC,EAAqBrqB,EAA0B,CACtD,GAAIA,EAAO,YAAc,OAASA,EAAO,OAAS,MAAO,CACvD,GAAIA,EAAO,YAAc,KAAOA,EAAO,YAAc,IACnD,OAEF,MAAM,IAAI,MACR,0BACEA,EAAO,UACP,6FACJ,CACF,CACF,CAEA,SAASsqB,EAAgBlB,EAAgB,CAEvC,OAAOA,EAAO,QAAQ,IAAK,GAAG,EAAE,QAAQ,IAAK,GAAG,CAClD,CAEA,SAASmB,EAAevqB,EAA+E,CAErG,OAAOA,aAAkBwqB,CAC3B,CAaA,MAAMA,CAAyC,CAM7C,YAAYC,EAAmBC,EAAmB5S,EAAcrZ,EAAkB,CAChF,KAAK,UAAYgsB,EACjB,KAAK,UAAYC,EACjB,KAAK,KAAO5S,EACZ,KAAK,IAAMrZ,CACb,CACF,CAiBA,MAAMmG,CAAO,CAYX,OAAO,iBAAiB5E,EAAgC,CACtD,IAAIvB,EAEJ,GAAI,CAACuB,EAAO,IACV,MAAM,IAAI,MAAM,4CAA4C,EAG1D,OAAOA,EAAO,KAAQ,SACxBvB,EAAM8C,EAAY,cAAcA,EAAY,aAAa+oB,EAAgBtqB,EAAO,GAAG,CAAC,CAAC,EAC5EA,EAAO,eAAe,YAC/BvB,EAAMuB,EAAO,IAEbvB,EAAM8C,EAAY,cAAcvB,EAAO,GAAG,EAG5C,IAAIyqB,EAAYzqB,EAAO,WAAaiqB,EAChCS,EAAYjsB,EAAI,WAAa,EAC7BqZ,EAAO9X,EAAO,MAAQmqB,EACtBQ,EAAe,IAAIH,EAAaC,EAAWC,EAAW5S,EAAMrZ,CAAG,EAEnE,GAAIuB,EAAO,WAAaA,EAAO,YAAc2qB,EAAa,UACxD,MAAM,IAAI,MACR,2CACE3qB,EAAO,UACP,mDACA2qB,EAAa,SACjB,EAGF,OAAAN,EAAqBM,CAAY,EAC1BA,CACT,CAOA,aAAa,kBAAkBD,EAA4C,CACzE,GAAI,CACF,OAAOV,EAAO,sBAAsBU,GAAaR,GAAqB,CAAC,CACzE,OAASvsB,EAAK,CACZ,MAAM,IAAIpF,EAAU,kCAAqCoF,EAAc,QAAS,IAAK,IAAOA,CAAY,CAC1G,CACF,CAOA,OAAO,UAAUqC,EAA8B3G,EAAgB,CA1JnE,IAAAI,EA2JUkxB,EAAeJ,EAAevqB,CAAM,EAAKA,EAA0B,KAAK,iBAAiBA,CAAM,EAEnG,MAAO,CACL,aAAA2qB,EACA,OAAQ,IAAIC,EAAUD,GAAclxB,EAAAuG,EAAO,KAAP,KAAAvG,EAAa,KAAMJ,CAAM,CAC/D,CACF,CACF,CAvEMuL,EACG,aAAe4lB,EA0ExB,MAAMI,CAAiG,CAMrG,YACE5qB,EACA6qB,EACiBxxB,EACjB,CACA,GAFiB,KAAA,OAAAA,EAEb,CAAC,OAAO,OACV,MAAI,gBACI,IAAI,MACR,iHACF,EAEM,IAAI,MACR,+JACF,EAIJ,KAAK,UAAY2G,EAAO,UAAY,IAAM,OAAOA,EAAO,SAAS,EAAI,IAAMA,EAAO,KAClF,KAAK,mBAAqBA,EAAO,UAAY,IAAMA,EAAO,KAC1D,KAAK,IAAMuB,EAAY,cAAcvB,EAAO,GAAG,EAC/C,KAAK,GAAK6qB,EAAKtpB,EAAY,cAAcspB,CAAE,EAAI,IACjD,CAEQ,OAAOvB,EAAqBC,EAAqB,CACvD,IAAMuB,EAAS,IAAI,YAAYxB,EAAQ,WAAaC,EAAQ,UAAU,EAChEwB,EAAa,IAAI,SAASD,CAAM,EAEhCE,EAAc,IAAI,SAASzpB,EAAY,cAAc+nB,CAAO,CAAC,EACnE,QAAS/qB,EAAI,EAAGA,EAAIysB,EAAY,WAAYzsB,IAC1CwsB,EAAW,QAAQxsB,EAAGysB,EAAY,QAAQzsB,CAAC,CAAC,EAG9C,IAAM0sB,EAAc,IAAI,SAAS1pB,EAAY,cAAcgoB,CAAO,CAAC,EACnE,QAAShrB,EAAI,EAAGA,EAAI0sB,EAAY,WAAY1sB,IAC1CwsB,EAAW,QAAQC,EAAY,WAAazsB,EAAG0sB,EAAY,QAAQ1sB,CAAC,CAAC,EAGvE,OAAOusB,CACT,CAEA,MAAM,QAAQI,EAAsD,CAClEzwB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,sBAAuB,EAAE,EAEzE,IAAMowB,EAAK,MAAM,KAAK,MAAM,EACtBM,EAAY,MAAM,OAAO,OAAO,UAAU,MAAO,KAAK,IAAK,KAAK,mBAAoB,GAAO,CAAC,SAAS,CAAC,EACtG/Z,EAAa,MAAM,OAAO,OAAO,QAAQ,CAAE,KAAM,KAAK,mBAAoB,GAAAyZ,CAAG,EAAGM,EAAWD,CAAS,EAE1G,OAAO,KAAK,OAAOL,EAAIzZ,CAAU,CACnC,CAEA,MAAM,QAAQA,EAAuD,CACnE3W,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,sBAAuB,EAAE,EAEzE,IAAM2wB,EAAwB7pB,EAAY,cAAc6P,CAAU,EAC5DyZ,EAAKO,EAAsB,MAAM,EAAGhB,CAAmB,EACvDiB,EAAiBD,EAAsB,MAAMhB,CAAmB,EAEhEe,EAAY,MAAM,OAAO,OAAO,UAAU,MAAO,KAAK,IAAK,KAAK,mBAAoB,GAAO,CAAC,SAAS,CAAC,EAC5G,OAAO,OAAO,OAAO,QAAQ,CAAE,KAAM,KAAK,mBAAoB,GAAAN,CAAG,EAAGM,EAAWE,CAAc,CAC/F,CAEA,MAAM,OAA8B,CAClC,GAAI,KAAK,GAAI,CACX,IAAIR,EAAK,KAAK,GACd,YAAK,GAAK,KACHA,CACT,CAEA,IAAMS,EAAc,MAAMtB,EAAO,qBAAqBI,CAAmB,EACzE,OAAO7oB,EAAY,cAAc+pB,CAAW,CAC9C,CACF,CAEA,OAAO1mB,CACT,ECtPK2mB,IAAAA,IACHA,EAAAA,EAAA,SAAW,CAAA,EAAX,WACAA,EAAAA,EAAA,SAAW,CAAA,EAAX,WACAA,EAAAA,EAAA,cAAgB,CAAA,EAAhB,gBACAA,EAAAA,EAAA,gBAAkB,CAAA,EAAlB,kBAJGA,IAAAA,IAAA,CAAA,CAAA,EAOEC,GAAQD,GCOf,SAASE,IAAmC,CAC1C,OAAO,IAAIlzB,EACT,mGACA,IACA,GACF,CACF,CApBA,IAAAkB,GAsBMkR,IAAOlR,GAAA,KAAM,CASjB,YAAY2M,EAAqB,CAHjC,KAAA,iBAA4D,KA0I5D,KAAA,kBAA6C,OAE7C,KAAA,oBAAsB,GACtB,KAAA,oBAAsB,GAzKxB,IAAA3M,EAgCI,KAAK,OAAS2M,GAAU,KACxB,IAAM7B,EAAuB6B,GAAQ,QAAQ,sBAAwBjB,EAAS,qBACxEb,GAA0B7K,EAAA2M,GAAQ,QAAQ,0BAAhB,KAAA3M,EAA2C,KACrEiyB,EAA2B,CAACtlB,GAAQ,QAAQ,qBAE5CulB,EAAyB1nB,EAAAA,EAAA,CAAA,EAC1B0G,GAAK,6BAAA,EACLvE,GAAQ,qCAAA,EAEPwlB,EAA2BD,EAAuB,WAClDE,EAA6BF,EAAuB,aACpDG,EAAoB,CAAC,EAAEF,GAA4BC,GAEzD,GAAI,CAACC,EACH,MAAML,GAAiC,EAGrC1yB,EAAS,OAAO,cAAgB6yB,GAClC,KAAK,oBAAsB,GAC3B,KAAK,QAAU,eACbnhB,EACAjG,EACAH,EACArE,EACAM,EACA,CACA,OAAO,IAAI,QAASmF,GAAY,CA1DxC,IAAAhM,EA2DU,IAAMsyB,EAAMH,EAAyB,cACnCpnB,EACAH,EACArE,EACAM,EACAkrB,GAAU,UACT/xB,EAAA2M,GAAUA,EAAO,QAAQ,WAAzB,KAAA3M,EAAsC,KACvC,KAAK,OACLgR,CACF,EACAshB,EAAI,KACF,WACA,CACE9hB,EACA3J,EACA+D,EACA4E,EACAlL,KACG0H,EAAQ,CAAE,MAAAwE,EAAO,KAAA3J,EAAM,QAAA+D,EAAS,SAAA4E,EAAU,WAAAlL,EAAW,CAAC,CAC7D,EACAguB,EAAI,KAAK,CACX,CAAC,CACH,EACI3lB,GAAQ,QAAQ,yBAClB,KAAK,kBAAoB,gBAAkB,CACzC,MAAO,EACT,EAEA,KAAK,kBAAoB,gBAAkB,CAvFnD,IAAA3M,EAwFUgB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,uCACA,YAAc8J,CAChB,EAEA,IAAMynB,EAAgB,MAAM,KAAK,MAC/BnmB,EAAY,IACZtB,EACA,KACA,KACAD,CACF,EAEI1G,EAAS,GACb,OAAK8tB,EAGH9tB,EAAS,CAACouB,EAAc,SAAUvyB,EAAAuyB,EAAc,OAAd,KAAA,OAAAvyB,EAA+B,QAAQ,KAAM,EAAA,IAAO,MAFtFmE,EAAS,CAACouB,EAAc,OAASjmB,GAAcimB,EAAc,UAAoB,EAKnFvxB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,uCAAwC,WAAamD,CAAM,EACpGA,CACT,GAEO7E,EAAS,OAAO,gBAAkB8yB,GAC3C,KAAK,oBAAsB,GAC3B,KAAK,QAAU,MAAOphB,EAAQjG,EAAKH,EAASrE,EAAQM,IAC3CurB,EAA2BphB,EAAQrE,GAAU,KAAM5B,EAAKH,EAASrE,EAAQM,CAAI,EAEtF,KAAK,kBAAoB,gBAAkB,CAvHjD,IAAA7G,EAwHQgB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,kCACA,YAAc8J,CAChB,EACA,IAAMynB,EAAgB,MAAM,KAAK,MAAMnmB,EAAY,IAAKtB,EAAsB,KAAM,KAAM,IAAI,EACxF3G,EAAS,CAACouB,EAAc,SAAUvyB,EAAAuyB,EAAc,OAAd,KAAA,OAAAvyB,EAA+B,QAAQ,KAAM,EAAA,IAAO,MAC5F,OAAAgB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,kCAAmC,WAAamD,CAAM,EAC/FA,CACT,GAEA,KAAK,QAAU,UAIN,CAAE,MAHKkuB,EACV,IAAI5tB,GAAiB,yCAA0C,KAAM,GAAG,EACxEutB,GAAiC,CACtB,EAGrB,CAEA,IAAI,QAAiB,CA7IvB,IAAAhyB,EAAA4G,EA8II,OAAOA,GAAA5G,EAAA,KAAK,SAAL,KAAA,OAAAA,EAAa,SAAb,KAAA4G,EAAuB5F,EAAO,aACvC,CAEA,MAAM,MACJgQ,EACAjG,EACAH,EACA/D,EACAN,EACwB,CACxB,OAAK,KAAK,QAGH,KAAK,QAAQyK,EAAQjG,EAAKH,EAASrE,EAAQM,CAAI,EAF7C,CAAE,MAAO,IAAIpC,GAAiB,qCAAsC,KAAM,GAAG,CAAE,CAG1F,CAeA,eAAesjB,EAA+B,CAC5C,IAAMzjB,EAAayjB,EAAU,WAI7B,OACGzjB,IAAe,KAAO,CAACyjB,EAAU,MACjCzjB,IAAe,KAAO,CAACyjB,EAAU,MACjCzjB,GAAc,KAAOA,GAAc,GAExC,CACF,EAhKatE,GACJ,QAAU,CAACoM,EAAY,IAAKA,EAAY,OAAQA,EAAY,KAAMA,EAAY,IAAKA,EAAY,KAAK,EADhGpM,GAEJ,mBAAqB,CAACoM,EAAY,IAAKA,EAAY,MAAM,EAFrDpM,GAGJ,gBAAkB,CAACoM,EAAY,KAAMA,EAAY,IAAKA,EAAY,KAAK,EAHnEpM,IAkKNwyB,GAAQthB,GCtLTuhB,GAAO,sBAETlzB,GAAe,OAAO,OAAW,IAAc,OAAS,OAAO,OAAW,IAAc,OAAS,KAE/FmzB,GAAN,KAAwC,CAItC,aAAc,CAMZ,GAAI,CACFnzB,GAAa,eAAe,QAAQkzB,GAAMA,EAAI,EAC9ClzB,GAAa,eAAe,WAAWkzB,EAAI,EAC3C,KAAK,iBAAmB,EAC1B,MAAY,CACV,KAAK,iBAAmB,EAC1B,CAEA,GAAI,CACFlzB,GAAa,aAAa,QAAQkzB,GAAMA,EAAI,EAC5ClzB,GAAa,aAAa,WAAWkzB,EAAI,EACzC,KAAK,eAAiB,EACxB,MAAY,CACV,KAAK,eAAiB,EACxB,CACF,CAEA,IAAI9qB,EAAmB,CACrB,OAAO,KAAK,KAAKA,EAAM,EAAK,CAC9B,CAEA,WAAWA,EAAmB,CAC5B,OAAO,KAAK,KAAKA,EAAM,EAAI,CAC7B,CAEA,OAAOA,EAAoB,CACzB,OAAO,KAAK,QAAQA,EAAM,EAAK,CACjC,CAEA,cAAcA,EAAoB,CAChC,OAAO,KAAK,QAAQA,EAAM,EAAI,CAChC,CAEA,IAAIA,EAAcie,EAAe/V,EAAoB,CACnD,OAAO,KAAK,KAAKlI,EAAMie,EAAO/V,EAAK,EAAK,CAC1C,CAEA,WAAWlI,EAAcie,EAAe/V,EAAoB,CAC1D,OAAO,KAAK,KAAKlI,EAAMie,EAAO/V,EAAK,EAAI,CACzC,CAEQ,KAAKlI,EAAcie,EAAe/V,EAAyB8iB,EAAc,CAC/E,IAAMC,EAAoC,CAAE,MAAAhN,CAAa,EACzD,OAAI/V,IACF+iB,EAAa,QAAU,KAAK,IAAI,EAAI/iB,GAE/B,KAAK,iBAAiB8iB,CAAO,EAAE,QAAQhrB,EAAM,KAAK,UAAUirB,CAAY,CAAC,CAClF,CAEQ,KAAKjrB,EAAcgrB,EAAmB,CAC5C,GAAIA,GAAW,CAAC,KAAK,iBAAkB,MAAM,IAAI,MAAM,+BAA+B,EACtF,GAAI,CAACA,GAAW,CAAC,KAAK,eAAgB,MAAM,IAAI,MAAM,6BAA6B,EACnF,IAAME,EAAU,KAAK,iBAAiBF,CAAO,EAAE,QAAQhrB,CAAI,EAC3D,GAAI,CAACkrB,EAAS,OAAO,KACrB,IAAMD,EAAe,KAAK,MAAMC,CAAO,EACvC,OAAID,EAAa,SAAWA,EAAa,QAAU,KAAK,IAAI,GAC1D,KAAK,iBAAiBD,CAAO,EAAE,WAAWhrB,CAAI,EACvC,MAEFirB,EAAa,KACtB,CAEQ,QAAQjrB,EAAcgrB,EAAmB,CAC/C,OAAO,KAAK,iBAAiBA,CAAO,EAAE,WAAWhrB,CAAI,CACvD,CAEQ,iBAAiBgrB,EAAmB,CAC1C,OAAOA,EAAUpzB,GAAa,eAAiBA,GAAa,YAC9D,CACF,EAEOuzB,GAAQ,IAAIJ,GCjFbnzB,EAAqBiD,GAAgB,EAGrCuwB,GAAsB,OAAO,aAAgB,SAK/C,OAAO,OAAW,KAAe,OAAO,kBAAsB,KAAe,CAACA,IAChF,QAAQ,IACN,8GACF,EAGF,SAASC,IAAa,CAIpB,IAAMC,EAAM1zB,EAAa,SACzB,MAAO,CAACA,EAAa,WAAa,CAAC0zB,GAAO,CAACA,EAAI,QAAUA,EAAI,OAAO,QAAQ,MAAM,EAAI,EACxF,CAGO,SAASC,IAA8B,CAE5C,OAAI,OAAO,kBAAsB,KAAe,gBAAgB,iBAKlE,CAEA,IAAMC,GAAY5zB,EAAa,WAAaA,EAAa,UAAU,UAAU,SAAS,EAChF6zB,GAAa7zB,EAAa,UAAYA,EAAa,SAAS,KAE5D8zB,GAA0B,CAC9B,MAAO,UACP,cAAe,GACf,UAAAF,GACA,WAAAC,GACA,WAAY,cACZ,UAAW7zB,EAAa,UACxB,eAAgB,CAAC,CAACA,EAAa,MAC/B,aAAcA,EAAa,gBAAkB,oBAAqB,IAAI,eACtE,WAAYyzB,GAAW,EACvB,sBAAuB,GACvB,eAAgB,CAAC,CAACzzB,EAAa,YAK/B,aAAc,GACd,YAAaA,EAAa,YAC1B,KAAMA,EAAa,KACnB,SACE,OAAOA,EAAa,aAAiB,IACjCA,EAAa,aAAa,KAAKA,CAAY,EAC3C,SAAU+zB,EAAe,CACvB,WAAWA,EAAG,CAAC,CACjB,EACN,iBAAkB/zB,EAAa,iBAC/B,QAAS,KAAK,UACd,eAAgB,SAAUsI,EAAa,CAKrC,OAAQtI,EAAa,aAAe,IAAIA,EAAa,YAAY,EAAE,OAAOsI,CAAG,EAAE,QAAWA,EAAI,MAChG,EACA,YAAatI,EAAa,YAC1B,YAAaA,EAAa,YAC1B,qBAAsB,eAAgBwvB,EAA0C,CAC9E,IAAMwE,EAAY,IAAI,WAAWxE,CAAU,EAC3CxvB,OAAAA,EAAa,OAAO,gBAAgBg0B,CAAS,EACtCA,EAAU,MACnB,EACA,YAAaL,GAAmB,EAChC,KAAM,CACJ,SAAA,UACA,WAAA,UACA,QAASJ,EACX,CACF,EAEOU,GAAQH,GCvEf,SAASI,GAAoBvvB,EAAgB,CAC3C,IAAMwvB,EAA2B,CAAC,MAAO,MAAO,KAAK,EACrD,OAAIxvB,EAAI,KACFwM,GAAK,WAAWxM,CAAG,EAAU,GAC7BwvB,EAAyB,SAASxvB,EAAI,IAAI,EAAU,GACjDA,EAAI,MAAQ,KAASA,EAAI,KAAO,IAGhC,EAEX,CAEA,SAASyvB,GAA4BzvB,EAAgB,CAGnD,OAAIuvB,GAAoBvvB,CAAG,EAClB,CAACuU,GAA0B,CAAE,OAAQM,EAAQ,MAAO,MAAO7U,CAAI,CAAC,CAAC,EAEjE,CAACuU,GAA0B,CAAE,OAAQM,EAAQ,aAAc,MAAO7U,CAAI,CAAC,CAAC,CAEnF,CAKA,IAAe0vB,GAAf,cAAsChT,EAAU,CAa9C,YAAYZ,EAAsCC,EAAY1Z,EAAyB,CACrF,MAAMyZ,EAAmBC,EAAM1Z,EAAoE,EAAI,EA0UzG,KAAA,cAAiBuH,GAAyC,CACxD,KAAK,WAAa,CAAE,aAAcA,EAAa,KAAM,CACvD,EA3UE,KAAK,OAAS,WAAYvH,EAASA,EAAO,OAAS,GACnD,KAAK,YAAc,KACnB,KAAK,YAAc,KACnB,KAAK,gBAAkB,KACvB,KAAK,aAAe,IACtB,CAUA,SAAgB,CACdvF,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,UAAU,EACtF4f,GAAU,UAAU,QAAQ,KAAK,IAAI,EACrC,IAAMra,EAAS,KAAK,OACd8C,EAAU9C,EAAO,QACjB+C,EAAOoC,EAAS,QAAQrC,EAAS9C,EAAO,IAAI,EAC5CstB,EAAOnoB,EAAS,QAAQrC,CAAO,EAC/ByqB,EAAczqB,EAAQ,IAAM,WAAa,UAE/C,KAAK,QAAUyqB,EAAcxqB,EAAO,IAAMuqB,EAAO,UACjD,IAAME,EAAa,KAAK,QAAU,UAClC/yB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,QAAU+yB,CAAU,EAC1FhwB,GAAmB,KAAK,KAAK,cAAc,EAAG,CAACG,EAAmBqK,IAAqC,CAC3G,GAAIrK,EAAK,CACP,KAAK,WAAWA,CAAG,EACnB,MACF,CACA,GAAI,KAAK,WACP,OAEF,KAAK,WAAaqK,EAClB,IAAMkd,EAAgB,KAAK,OAAO,iBAAiBld,CAAW,EAC1D,WAAYkd,IAAe,KAAK,OAASA,EAAc,QAC3DzqB,EAAO,UACL,KAAK,OACLA,EAAO,UACP,2BACA,iBAAyB6C,GAAc4nB,CAAa,CACtD,EAGA,IAAIuI,EAAe,GACbC,EAAkB,KAAK,YAAc,KAAK,cAC9CF,EACA,KACAtI,EACA,KACA,KAAK,OAASsG,GAAU,gBAAkBA,GAAU,QACtD,EAEAkC,EAAe,GAAG,OAASntB,GAAc,CAClC,KAAK,cAILktB,IACHA,EAAe,GACf,KAAK,KAAK,YAAY,GAExB,KAAK,OAAOltB,CAAI,EAClB,CAAC,EACDmtB,EAAe,GAAG,WAAa/vB,GAAmB,CAahD,GAZK,KAAK,cAERA,EAAMA,GAAO,IAAIpF,EAAU,oBAAqB,MAAO,GAAG,GAE5D,KAAK,YAAc,KAGf,CAACk1B,GAAgB,CAAC9vB,IACpB8vB,EAAe,GACf,KAAK,KAAK,YAAY,GAExB,KAAK,WAAW,EACZ9vB,EAAK,CACHA,EAAI,KAIN,KAAK,OAAOyvB,GAA4BzvB,CAAG,CAAC,EAI5C,KAAK,WAAWA,CAAG,EAErB,MACF,CACA5E,EAAS,OAAO,SAAS,IAAM,CAC7B,KAAK,KAAK,CACZ,CAAC,CACH,CAAC,EACD20B,EAAe,KAAK,CACtB,CAAC,CACH,CAEA,cAAqB,CACnBjzB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,+BAA+B,EAC/E,KAAK,0BAA0B,EAAI,CACrC,CAEA,mBAA0B,CACxBA,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,oCAAoC,EACpF,KAAK,0BAA0B,EAAK,CACtC,CAEA,0BAA0BkzB,EAAwB,CAChD,IAAMC,EAAuBD,EAAU,KAAK,SAAW,KAAK,cAC5D,GAAIC,EAAsB,CACxB,IAAMxkB,EAAU,KAAK,cAAcwkB,EAAsB,KAAM,KAAK,WAAY,KAAMpC,GAAU,QAAQ,EAExGpiB,EAAQ,GAAG,WAAazL,GAAmB,CACrCA,IACFlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,0BAA4BkzB,EAAU,UAAY,gBAClD,0BAAkCrxB,EAAaqB,CAAG,CACpD,EACA,KAAK,OAAO,eAAgBA,CAAG,EAEnC,CAAC,EACDyL,EAAQ,KAAK,CACf,CACF,CAEA,SAAgB,CACd3O,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,EAAE,EACzE,KAAK,aACR,KAAK,WAAa,GACd,KAAK,cACPA,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,2BAA4B,uBAAuB,EACnG,KAAK,YAAY,MAAM,EACvB,KAAK,YAAc,MAIrB,KAAK,OAAO,eAAgB4e,GAAiB,aAAa,CAAC,EAC3DtgB,EAAS,OAAO,SAAS,IAAM,CAC7B,KAAK,KAAK,UAAU,CACtB,CAAC,EAEL,CAEA,UAAUqB,EAAgC,CA/M5C,IAAAX,EAiNI,GAAI,KAAK,WACP,OAKF,IAAMo0B,GAAgBp0B,EAAAW,EAAQ,oBAAR,KAAA,OAAAX,EAA2B,cACjD4gB,GAAU,UAAU,UAAU,KAAK,KAAMjgB,CAAO,EAEhD,IAAM0zB,EAAqB,KAAK,QAAqBD,EACrDpzB,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,6BAA8B,aAAeqzB,CAAiB,EAC9G,KAAK,QAAUA,EAAoB,QACnC,KAAK,QAAUA,EAAoB,QACnC,KAAK,SAAWA,EAAoB,SACpC,KAAK,cAAgBA,EAAoB,aAC3C,CAEA,KAAK1zB,EAAgC,CACnC,GAAI,KAAK,YAAa,CAEpB,KAAK,aAAe,KAAK,cAAgB,CAAC,EAC1C,KAAK,aAAa,KAAKA,CAAO,EAC9B,MACF,CAEA,IAAM2zB,EAAe,KAAK,cAAgB,CAAC,EAC3CA,EAAa,KAAK3zB,CAAO,EACzB,KAAK,aAAe,KAEpB,KAAK,UAAU2zB,CAAY,CAC7B,CAEA,gBAAuB,CACrB,IAAMA,EAAe,KAAK,aAErBA,IAIL,KAAK,aAAe,KACpB,KAAK,UAAUA,CAAY,EAC7B,CAEA,UAAU7f,EAAqC,CAC7C,IAAM8f,EAAe,KAAK,YAAc,KAAK,cAC3C,KAAK,QACL,KACA,KAAK,WACL,KAAK,cAAc9f,CAAK,EACxBsd,GAAU,QACZ,EAEAwC,EAAY,GAAG,WAAY,CAACrwB,EAAgB4C,IAAiB,CAa3D,GAZI5C,GACFlD,EAAO,UACL,KAAK,OACLA,EAAO,UACP,6BACA,sBAA8B6B,EAAaqB,CAAG,CAChD,EACF,KAAK,YAAc,KAKfA,EAAK,CACHA,EAAI,KAIN,KAAK,OAAOyvB,GAA4BzvB,CAAG,CAAC,EAI5C,KAAK,WAAWA,CAAG,EAErB,MACF,CAEI4C,GACF,KAAK,OAAOA,CAAI,EAGd,KAAK,cACPxH,EAAS,OAAO,SAAS,IAAM,CAIxB,KAAK,aACR,KAAK,eAAe,CAExB,CAAC,CAEL,CAAC,EACDi1B,EAAY,KAAK,CACnB,CAEA,MAAa,CAKX,GAHI,KAAK,aAGL,CAAC,KAAK,YAAa,OAEvB,IAAMC,EAAe,KAAK,YAAc,KAAK,cAC3C,KAAK,QACL,KACA,KAAK,WACL,KACA,KAAK,OAASzC,GAAU,gBAAkBA,GAAU,aACtD,EAEAyC,EAAY,GAAG,OAAS1tB,GAAiB,CACvC,KAAK,OAAOA,CAAI,CAClB,CAAC,EACD0tB,EAAY,GAAG,WAAatwB,GAAmB,CAK7C,GAJA,KAAK,YAAc,KAGnB,KAAK,WAAW,EACZA,EAAK,CACHA,EAAI,KAIN,KAAK,OAAOyvB,GAA4BzvB,CAAG,CAAC,EAI5C,KAAK,WAAWA,CAAG,EAErB,MACF,CACA5E,EAAS,OAAO,SAAS,IAAM,CAC7B,KAAK,KAAK,CACZ,CAAC,CACH,CAAC,EACDk1B,EAAY,KAAK,CACnB,CAEA,OAAOC,EAAkD,CACvD,GAAI,CACF,IAAMhgB,EAAQ,KAAK,eAAeggB,CAAY,EAC9C,GAAIhgB,GAASA,EAAM,OACjB,QAAS3P,EAAI,EAAGA,EAAI2P,EAAM,OAAQ3P,IAChC,KAAK,kBACH4Y,GAAgCjJ,EAAM3P,CAAC,EAAG,KAAK,kBAAkB,SAAS,iBAAiB,CAC7F,CACN,OAASsD,EAAG,CACVpH,EAAO,UACL,KAAK,OACLA,EAAO,UACP,0BACA,+CAAkDoH,EAAY,KAChE,CACF,CACF,CAEA,cAAcssB,EAA8C,CAC1D,OAAO,KAAK,UAAUA,CAAY,CACpC,CAEA,eAAeD,EAAiE,CAC9E,OAAI,OAAOA,GAAgB,SAAiB,KAAK,MAAMA,CAAY,EAC5DA,CACT,CAiBF,EAEOE,GAAQf,GC9Xf,SAASgB,GAAYC,EAAuBjqB,EAAwE,CAClH,OAAaxJ,GAAqB+B,EAAUyH,CAAO,CAAC,EAAE,SAAS,kBAAkB,CACnF,CAEA,SAASkqB,GAAaD,EAAuBjqB,EAAiC,CAC5E,GAAIgqB,GAAYC,EAAcjqB,CAAO,EACnC,OAAOiqB,EAAa,OAAS/1B,EAAU,WAAW+1B,EAAa,KAAK,CAExE,CAEA,IAAM7T,GAAO,UAAY,CAAC,EACtB+T,GAAY,EACVC,GAA8C,CAAC,EAErD,SAASC,GAAUC,EAAqBC,EAAgB,CACtD,OAAOD,EAAI,mBAAqBA,EAAI,kBAAkBC,CAAM,CAC9D,CAOA,SAASC,GAAkBF,EAAqB,CAC9C,OACEA,EAAI,oBAAsBA,EAAI,kBAAkB,mBAAmB,GAAK,CAACA,EAAI,kBAAkB,gBAAgB,EAEnH,CAEA,SAASG,GAAmBH,EAAqB,CAC/C,IAAMI,EAAcJ,EAAI,sBAAsB,EAAE,KAAK,EAAE,MAAM;CAAM,EAC7DtqB,EAAkC,CAAC,EACzC,QAAS,EAAI,EAAG,EAAI0qB,EAAY,OAAQ,IAAK,CAC3C,IAAM9uB,EAAQ8uB,EAAY,CAAC,EAAE,MAAM,GAAG,EAAE,IAAKC,GAAMA,EAAE,KAAK,CAAC,EAC3D3qB,EAAQpE,EAAM,CAAC,EAAE,YAAY,CAAC,EAAIA,EAAM,CAAC,CAC3C,CACA,OAAOoE,CACT,CAEA,IAAM4qB,GAAN,MAAMC,WAAmB1Y,EAAoC,CAc3D,YACEhS,EACAH,EACArE,EACAM,EACA6uB,EACA1rB,EACApK,EACAoR,EACA,CACA,MAAMpR,CAAM,EACZ2G,EAASA,GAAU,CAAC,EACpBA,EAAO,IAAYzE,GAAa,EAChC,KAAK,IAAMiJ,EAAYlH,GAAc0C,CAAM,EAC3C,KAAK,QAAUqE,GAAW,CAAC,EAC3B,KAAK,KAAO/D,EACZ,KAAK,OAASmK,EAASA,EAAO,YAAY,EAAU/N,GAAM4D,CAAI,EAAI,MAAQ,OAC1E,KAAK,YAAc6uB,EACnB,KAAK,SAAW1rB,EAChB,KAAK,SAAW,GAChB,KAAK,gBAAkB,GACvB,KAAK,GAAK,OAAO,EAAE+qB,EAAS,EAC5BC,GAAgB,KAAK,EAAE,EAAI,IAC7B,CAEA,OAAO,cACLjqB,EACAH,EACArE,EACAM,EACA6uB,EACA1rB,EACApK,EACAoR,EACY,CAIZ,IAAM2kB,EAAY3rB,GAAY0B,EAAS,SACvC,OAAO,IAAI+pB,GACT1qB,EACAH,EACM5I,GAAKuE,CAAM,EACjBM,EACA6uB,EACAC,EACA/1B,EACAoR,CACF,CACF,CAEA,SACE9M,EACA2C,EACA+D,EACA4E,EACAlL,EACM,CACD,KAAK,kBACR,KAAK,gBAAkB,GACnB,CAACJ,GAAO2C,GACV,KAAK,KAAK,OAAQA,CAAI,EAExB,KAAK,KAAK,WAAY3C,EAAK2C,EAAM+D,EAAS4E,EAAUlL,CAAU,EAC9D,KAAK,QAAQ,EAEjB,CAEA,OAAc,CACZ,KAAK,QAAQ,CACf,CAEA,MAAa,CACX,IAAIsG,EAAU,KAAK,QACbzC,EACF,KAAK,aAAe4pB,GAAU,SAAW,KAAK,SAAS,mBAAqB,KAAK,SAAS,YAC5F6D,EAAS,KAAK,MAAQ,WAAW,IAAM,CACrC,KAAK,SAAW,GAChBV,EAAI,MAAM,CACZ,EAAG/sB,CAAO,EACV6I,EAAS,KAAK,OACdkkB,EAAO,KAAK,IAAM,IAAI,eACtBW,EAASjrB,EAAQ,OACf/D,EAAO,KAAK,KACZivB,EAA2C,OAE1CD,EAGMA,EAAO,QAAQ,uBAAuB,IAAM,IAErDC,EAAe,eAHflrB,EAAQ,OAAY,mBAMlB/D,IACkB+D,EAAQ,cAAc,IAAMA,EAAQ,cAAc,EAAI,qBAC1D,QAAQ,kBAAkB,EAAI,IAAM,OAAO/D,GAAQ,WAAUA,EAAO,KAAK,UAAUA,CAAI,GAKzGquB,EAAI,KAAKlkB,EAAQ,KAAK,IAAK,EAAI,EAC/BkkB,EAAI,aAAeY,EAEf,kBAAmBlrB,IACrBsqB,EAAI,gBAAkB,IAGxB,QAAWa,KAAKnrB,EAASsqB,EAAI,iBAAiBa,EAAGnrB,EAAQmrB,CAAC,CAAC,EAE3D,IAAMC,EAAe,CACnBC,EACAt1B,GACA0D,GACAC,KACG,CAnLT,IAAAtE,GAoLM,IAAIk2B,GAAev1B,GAAU,iBAAmBs1B,EAAW,KAAO,KAC9Dj2B,GAAA,MAAA,KAAA,OAAA,KAAM,MAAN,MAAAA,GAAW,aAAYk2B,IAAgB,2BAA6B,KAAK,IAAI,YACjFl1B,EAAO,UAAU,KAAK,OAAQA,EAAO,UAAW,aAAei1B,EAAW,KAAO,KAAMC,EAAY,EACnG,KAAK,SAAS,IAAIzxB,GAAiByxB,GAAc7xB,GAAMC,EAAU,CAAC,CACpE,EACA4wB,EAAI,QAAU,SAAUe,EAAY,CAClCD,EAAaC,EAAY,qBAAsB,KAAM,GAAG,CAC1D,EACAf,EAAI,QAAWe,GAAe,CACxB,KAAK,SACPD,EAAaC,EAAY,kDAAmD,KAAM,GAAG,EAErFD,EAAaC,EAAY,oBAAqB,KAAM,GAAG,CAE3D,EACAf,EAAI,UAAY,SAAUe,EAAY,CACpCD,EAAaC,EAAY,oBAAqB,KAAM,GAAG,CACzD,EAEA,IAAIE,EACA7xB,EACA8xB,EACAC,EAAY,EACZ7mB,EAAW,GAET8mB,EAAa,IAAM,CAGvB,GAFA,aAAaV,CAAK,EAClBQ,EAAkB9xB,EAAa,IAC3BA,GAAc,IAAK,CACrB,KAAK,SAAS,KAAM,KAAM,KAAM,KAAMA,CAAU,EAChD,MACF,CACA6xB,EAAY,KAAK,aAAepE,GAAU,iBAAmBqE,GAAmBhB,GAAkBF,CAAG,CACvG,EAEMqB,EAAQ,IAAM,CAClB,IAAIC,EACJ,GAAI,CACF,IAAM/qB,GAAcwpB,GAAUC,EAAK,cAAc,EAMjD,GAFazpB,GAAcA,GAAY,QAAQ,kBAAkB,GAAK,EAAIypB,EAAI,cAAgB,OAEpF,CAIR,IAAMuB,GACJvB,EAAI,eAAiB,cACjB51B,EAAS,YAAY,WAAW41B,EAAI,QAAQ,EAC5C,OAAOA,EAAI,YAAY,EACzBuB,GAAiB,OACnBD,EAAiB,KAAK,MAAMC,EAAgB,EAE5CD,EAAiBC,GAEnBjnB,EAAW,EACb,MACEgnB,EAAiBtB,EAAI,SAGnBsB,EAAe,WAAa,QAE9BlyB,EAAakyB,EAAe,WAC5BJ,EAAkB9xB,EAAa,IAC/BsG,EAAU4rB,EAAe,QACzBA,EAAiBA,EAAe,UAEhC5rB,EAAUyqB,GAAmBH,CAAG,CAEpC,OAAS9sB,GAAG,CACV,KAAK,SAAS,IAAI3D,GAAiB,wCAA2C2D,GAAY,QAAS,KAAM,GAAG,CAAC,EAC7G,MACF,CAMA,GAAIguB,GAAmB,MAAM,QAAQI,CAAc,EAAG,CACpD,KAAK,SAAS,KAAMA,EAAgB5rB,EAAS4E,EAAUlL,CAAU,EACjE,MACF,CAEA,IAAIJ,GAAqC4wB,GAAa0B,EAAgB5rB,CAAO,EACxE1G,KACHA,GAAM,IAAIO,GACR,wCACEH,EACA,cACAhF,EAAS,OAAO,QAAQk3B,CAAc,EACxC,KACAlyB,CACF,GAEF,KAAK,SAASJ,GAAKsyB,EAAgB5rB,EAAS4E,EAAUlL,CAAU,CAClE,EAEA,SAASoyB,GAAa,CACpB,IAAMC,EAAezB,EAAI,aACnB0B,GAAUD,EAAa,OAAS,EAClC3wB,GAAKopB,GACT,KAAOiH,EAAYO,KAAY5wB,GAAM2wB,EAAa,QAAQ;EAAMN,CAAS,GAAK,IAC5EjH,GAAQuH,EAAa,MAAMN,EAAWrwB,EAAG,EACzCqwB,EAAYrwB,GAAM,EAClB6wB,EAAQzH,EAAK,CAEjB,CAEA,IAAMyH,EAAWzH,GAAkB,CACjC,GAAI,CACFA,EAAQ,KAAK,MAAMA,CAAK,CAC1B,OAAShnB,GAAG,CACV,KAAK,SAAS,IAAI3D,GAAiB,wCAA2C2D,GAAY,QAAS,KAAM,GAAG,CAAC,EAC7G,MACF,CACA,KAAK,KAAK,OAAQgnB,CAAK,CACzB,EAEM0H,EAAc,IAAM,CACxBJ,EAAW,EACX,KAAK,eAAiB,GACtBp3B,EAAS,OAAO,SAAS,IAAM,CAC7B,KAAK,SAAS,CAChB,CAAC,CACH,EAEA41B,EAAI,mBAAqB,UAAY,CACnC,IAAM6B,EAAa7B,EAAI,WACnB6B,EAAa,GACb7B,EAAI,SAAW,IACb5wB,IAAe,SACjBA,EAAa4wB,EAAI,OACjBoB,EAAW,GAETS,GAAc,GAAKZ,EACrBO,EAAW,EACFK,GAAc,IACnBZ,EAAWW,EAAY,EACtBP,EAAM,GAGjB,EACArB,EAAI,KAAKruB,CAAW,CACtB,CAEA,SAAgB,CACd,IAAMquB,EAAM,KAAK,IACjB,GAAIA,EAAK,CACPA,EAAI,mBAAqBA,EAAI,QAAUA,EAAI,QAAUA,EAAI,UAAYlU,GACrE,KAAK,IAAM,KACX,IAAM4U,EAAQ,KAAK,MACfA,IACF,aAAaA,CAAuB,EACpC,KAAK,MAAQ,MAEV,KAAK,iBAAiBV,EAAI,MAAM,CACvC,CACA,OAAOF,GAAgB,KAAK,EAAE,CAChC,CACF,EAEOgC,GAAQxB,GC/UXlK,GAAYzK,GAAe,WACzBoW,GAAN,cAAkCtC,EAAe,CAE/C,YAAY3U,EAAsCC,EAAY1Z,EAAyB,CACrF,MAAMyZ,EAAmBC,EAAM1Z,CAAM,EAFvC,KAAA,UAAY+kB,GAGV/kB,EAAO,OAAS,GAChB,KAAK,UAAY+kB,EACnB,CAEA,OAAO,aAAc,CACnB,MAAO,CAAC,EAAEhsB,EAAS,OAAO,cAAgBA,EAAS,OAAO,WAC5D,CAEA,UAAW,CACT,MAAO,4BAA8B,KAAK,QAAU,iBAAmB,KAAK,WAC9E,CAEA,cACEyL,EACAH,EACArE,EACAM,EACA6uB,EACA,CACA,OAAOsB,GAAW,cAAcjsB,EAAKH,EAASrE,EAAQM,EAAM6uB,EAAa,KAAK,SAAU,KAAK,MAAM,CACrG,CACF,EAEOwB,GAAQD,GC7BTE,GAAyB,CAAC,aAAa,EAEvCC,GAAqD,CACzD,MAAAD,GACA,uBAAwB,CACtB,WAAYnL,GACZ,YAAakL,EACf,CACF,EAEOtW,GAAQwW,GCdT3uB,GAAsB,CAC1B,qBAAsB,+DACtB,uBAAwB,gCAIxB,kBAAmB,CAACoY,GAAe,WAAYA,GAAe,SAAS,CACzE,EAEOnV,GAAQjD,GCZf,SAAS4uB,GAAQrwB,EAA4C,CAC3D,GAAIA,IAAW,OAAW,MAAO,YACjC,IAAIswB,EACAC,EAQJ,GAPIvwB,aAAkB,aACpBuwB,EAAO,cACPD,EAAO,IAAI,SAAStwB,CAAM,GACjBA,aAAkB,WAC3BuwB,EAAO,WACPD,EAAOtwB,GAEL,CAACswB,EAAM,OAAO,KAAK,UAAUtwB,CAAM,EACvC,IAAM+mB,EAAQ,CAAC,EACf,QAASjpB,EAAI,EAAGA,EAAIkC,EAAO,WAAYlC,IAAK,CAC1C,GAAIA,EAAI,GAAI,CACVipB,EAAM,KAAK,KAAK,EAChB,KACF,CACA,IAAIyJ,EAAQF,EAAK,SAASxyB,CAAC,EAAE,SAAS,EAAE,EACpC0yB,EAAM,SAAW,IAAGA,EAAQ,IAAMA,GACtCzJ,EAAM,KAAKyJ,CAAK,CAClB,CACA,MAAO,IAAMD,EAAO,IAAMxJ,EAAM,KAAK,GAAG,EAAI,GAC9C,CAGA,SAAS0J,GAAUH,EAAgBI,EAAgB/H,EAAgB,CACjE,QAAS,EAAI,EAAGxI,EAAIwI,EAAO,OAAQ,EAAIxI,EAAG,IAAK,CAC7C,IAAMwQ,EAAYhI,EAAO,WAAW,CAAC,EAGrC,GAAIgI,EAAY,IAAM,CACpBL,EAAK,SAASI,IAAYC,IAAc,EAAK,IAAQ,CAAI,EACzD,QACF,CAGA,GAAIA,EAAY,KAAO,CACrBL,EAAK,SAASI,IAAYC,IAAc,EAAK,GAAQ,GAAI,EACzDL,EAAK,SAASI,IAAYC,IAAc,EAAK,GAAQ,GAAI,EACzD,QACF,CAGA,GAAIA,EAAY,MAAS,CACvBL,EAAK,SAASI,IAAYC,IAAc,GAAM,GAAQ,GAAI,EAC1DL,EAAK,SAASI,IAAYC,IAAc,EAAK,GAAQ,GAAI,EACzDL,EAAK,SAASI,IAAYC,IAAc,EAAK,GAAQ,GAAI,EACzD,QACF,CAGA,GAAIA,EAAY,QAAU,CACxBL,EAAK,SAASI,IAAYC,IAAc,GAAM,EAAQ,GAAI,EAC1DL,EAAK,SAASI,IAAYC,IAAc,GAAM,GAAQ,GAAI,EAC1DL,EAAK,SAASI,IAAYC,IAAc,EAAK,GAAQ,GAAI,EACzDL,EAAK,SAASI,IAAYC,IAAc,EAAK,GAAQ,GAAI,EACzD,QACF,CACA,MAAM,IAAI,MAAM,iBAAmBA,CAAS,CAC9C,CACF,CAEA,SAASC,GAASN,EAAgBI,EAAgBG,EAAgB,CAChE,IAAIlI,EAAS,GACb,QAAS7qB,EAAI4yB,EAAQI,EAAMJ,EAASG,EAAQ/yB,EAAIgzB,EAAKhzB,IAAK,CACxD,IAAM0yB,EAAQF,EAAK,SAASxyB,CAAC,EAE7B,GAAK,EAAA0yB,EAAQ,KAAgB,CAC3B7H,GAAU,OAAO,aAAa6H,CAAK,EACnC,QACF,CAEA,IAAKA,EAAQ,OAAU,IAAM,CAC3B7H,GAAU,OAAO,cAAe6H,EAAQ,KAAS,EAAMF,EAAK,SAAS,EAAExyB,CAAC,EAAI,EAAK,EACjF,QACF,CAEA,IAAK0yB,EAAQ,OAAU,IAAM,CAC3B7H,GAAU,OAAO,cACb6H,EAAQ,KAAS,IAAQF,EAAK,SAAS,EAAExyB,CAAC,EAAI,KAAS,GAAOwyB,EAAK,SAAS,EAAExyB,CAAC,EAAI,KAAS,CAChG,EACA,QACF,CAEA,IAAK0yB,EAAQ,OAAU,IAAM,CAC3B7H,GAAU,OAAO,cACb6H,EAAQ,IAAS,IACfF,EAAK,SAAS,EAAExyB,CAAC,EAAI,KAAS,IAC9BwyB,EAAK,SAAS,EAAExyB,CAAC,EAAI,KAAS,GAC9BwyB,EAAK,SAAS,EAAExyB,CAAC,EAAI,KAAS,CACpC,EACA,QACF,CACA,MAAM,IAAI,MAAM,gBAAkB0yB,EAAM,SAAS,EAAE,CAAC,CACtD,CACA,OAAO7H,CACT,CAEA,SAASoI,GAAcpI,EAAgB,CACrC,IAAInoB,EAAQ,EACZ,QAAS1C,EAAI,EAAGqiB,EAAIwI,EAAO,OAAQ7qB,EAAIqiB,EAAGriB,IAAK,CAC7C,IAAM6yB,EAAYhI,EAAO,WAAW7qB,CAAC,EACrC,GAAI6yB,EAAY,IAAM,CACpBnwB,GAAS,EACT,QACF,CACA,GAAImwB,EAAY,KAAO,CACrBnwB,GAAS,EACT,QACF,CACA,GAAImwB,EAAY,MAAS,CACvBnwB,GAAS,EACT,QACF,CACA,GAAImwB,EAAY,QAAU,CACxBnwB,GAAS,EACT,QACF,CACA,MAAM,IAAI,MAAM,iBAAmBmwB,CAAS,CAC9C,CACA,OAAOnwB,CACT,CAEA,SAASoQ,GAAOgO,EAAgBoS,EAAkB,CAChD,IAAMlhB,EAAOmhB,GAAOrS,EAAOoS,CAAM,EACjC,GAAIlhB,IAAS,EAAG,OAChB,IAAM9P,EAAS,IAAI,YAAY8P,CAAI,EAC7BwgB,EAAO,IAAI,SAAStwB,CAAM,EAChC,OAAAkxB,GAAQtS,EAAO0R,EAAM,EAAGU,CAAM,EACvBhxB,CACT,CAEA,IAAMmxB,GAAW,MAAY,MAC3BC,GAAU,EAAID,GAChB,SAASE,GAASf,EAAgBI,EAAgB,CAChD,OAAAA,EAASA,GAAU,EACZJ,EAAK,SAASI,CAAM,EAAIS,GAAUb,EAAK,UAAUI,EAAS,CAAC,CACpE,CAEA,SAASY,GAAUhB,EAAgBI,EAAgB,CACjD,OAAAA,EAASA,GAAU,EACZJ,EAAK,UAAUI,CAAM,EAAIS,GAAUb,EAAK,UAAUI,EAAS,CAAC,CACrE,CAEA,SAASa,GAASjB,EAAgBI,EAAgBhyB,EAAa,CACzDA,EAAM,oBACR4xB,EAAK,SAASI,EAAQ,KAAK,MAAMhyB,EAAM0yB,EAAO,CAAC,EAC/Cd,EAAK,SAASI,EAAS,EAAGhyB,EAAM,EAAE,IAElC4xB,EAAK,UAAUI,EAAQ,UAAU,EACjCJ,EAAK,UAAUI,EAAS,EAAG,UAAU,EAEzC,CAEA,SAASc,GAAUlB,EAAgBI,EAAgBhyB,EAAa,CAC1DA,EAAM,qBACR4xB,EAAK,UAAUI,EAAQ,KAAK,MAAMhyB,EAAM0yB,EAAO,CAAC,EAChDd,EAAK,SAASI,EAAS,EAAGhyB,EAAM,EAAE,IAElC4xB,EAAK,UAAUI,EAAQ,UAAU,EACjCJ,EAAK,UAAUI,EAAS,EAAG,UAAU,EAEzC,CAcA,IAAMe,GAAN,KAAc,CAIZ,YAAYnB,EAAgBI,EAAiB,CAK7C,KAAA,IAAOG,GAAmB,CACxB,IAAMjS,EAAwC,CAAC,EAC/C,QAAS9gB,EAAI,EAAGA,EAAI+yB,EAAQ/yB,IAAK,CAC/B,IAAME,EAAM,KAAK,MAAM,EACvB4gB,EAAM5gB,CAAa,EAAI,KAAK,MAAM,CACpC,CACA,OAAO4gB,CACT,EAEA,KAAA,IAAOiS,GAAmB,CACxB,IAAMjS,EAAQ,IAAI,YAAYiS,CAAM,EACpC,WAAI,WAAWjS,CAAK,EAAE,IAAI,IAAI,WAAW,KAAK,KAAK,OAAQ,KAAK,OAAQiS,CAAM,EAAG,CAAC,EAClF,KAAK,QAAUA,EACRjS,CACT,EAEA,KAAA,IAAM,KAAK,IAEX,KAAA,IAAOiS,GAAmB,CACxB,IAAMjS,EAAQgS,GAAS,KAAK,KAAM,KAAK,OAAQC,CAAM,EACrD,YAAK,QAAUA,EACRjS,CACT,EAEA,KAAA,MAASiS,GAAmB,CAC1B,IAAMjS,EAAQ,IAAI,MAAMiS,CAAM,EAC9B,QAAS/yB,EAAI,EAAGA,EAAI+yB,EAAQ/yB,IAC1B8gB,EAAM9gB,CAAC,EAAI,KAAK,MAAM,EAExB,OAAO8gB,CACT,EAEA,KAAA,IAAOiS,IACL,KAAK,QAAUA,EACR,CACL,KAAM,KAAK,KAAK,QAAQ,KAAK,MAAM,EACnC,KAAM,KAAK,IAAIA,CAAM,CACvB,GAGF,KAAA,MAAQ,IAAe,CACrB,IAAMN,EAAO,KAAK,KAAK,SAAS,KAAK,MAAM,EACvC3R,EAAOiS,EAGX,GAAK,EAAAN,EAAO,KACV,YAAK,SACEA,EAIT,IAAKA,EAAO,OAAU,IACpB,OAAAM,EAASN,EAAO,GAChB,KAAK,SACE,KAAK,IAAIM,CAAM,EAIxB,IAAKN,EAAO,OAAU,IACpB,OAAAM,EAASN,EAAO,GAChB,KAAK,SACE,KAAK,MAAMM,CAAM,EAI1B,IAAKN,EAAO,OAAU,IACpB,OAAAM,EAASN,EAAO,GAChB,KAAK,SACE,KAAK,IAAIM,CAAM,EAIxB,IAAKN,EAAO,OAAU,IACpB,OAAA3R,EAAQ,KAAK,KAAK,QAAQ,KAAK,MAAM,EACrC,KAAK,SACEA,EAGT,OAAQ2R,EAAM,CAEZ,IAAK,KACH,YAAK,SACE,KAGT,IAAK,KACH,KAAK,SACL,OAGF,IAAK,KACH,YAAK,SACE,GAGT,IAAK,KACH,YAAK,SACE,GAGT,IAAK,KACH,OAAAM,EAAS,KAAK,KAAK,SAAS,KAAK,OAAS,CAAC,EAC3C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,SAAS,KAAK,OAAS,CAAC,EAC3C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAjS,EAAQ,KAAK,KAAK,WAAW,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACRA,EAGT,IAAK,KACH,OAAAA,EAAQ,KAAK,KAAK,WAAW,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACRA,EAGT,IAAK,KACH,OAAAA,EAAQ,KAAK,KAAK,SAAS,KAAK,OAAS,CAAC,EAC1C,KAAK,QAAU,EACRA,EAGT,IAAK,KACH,OAAAA,EAAQ,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC3C,KAAK,QAAU,EACRA,EAGT,IAAK,KACH,OAAAA,EAAQ,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC3C,KAAK,QAAU,EACRA,EAGT,IAAK,KACH,OAAAA,EAAQ0S,GAAU,KAAK,KAAM,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR1S,EAGT,IAAK,KACH,OAAAA,EAAQ,KAAK,KAAK,QAAQ,KAAK,OAAS,CAAC,EACzC,KAAK,QAAU,EACRA,EAGT,IAAK,KACH,OAAAA,EAAQ,KAAK,KAAK,SAAS,KAAK,OAAS,CAAC,EAC1C,KAAK,QAAU,EACRA,EAGT,IAAK,KACH,OAAAA,EAAQ,KAAK,KAAK,SAAS,KAAK,OAAS,CAAC,EAC1C,KAAK,QAAU,EACRA,EAGT,IAAK,KACH,OAAAA,EAAQyS,GAAS,KAAK,KAAM,KAAK,OAAS,CAAC,EAC3C,KAAK,QAAU,EACRzS,EAGT,IAAK,KACH,OAAAiS,EAAS,EACT,KAAK,SACE,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,EACT,KAAK,SACE,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,EACT,KAAK,SACE,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,EACT,KAAK,SACE,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,GACT,KAAK,SACE,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,SAAS,KAAK,OAAS,CAAC,EAC3C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,MAAMA,CAAM,EAG1B,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,MAAMA,CAAM,EAG1B,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,EAGxB,IAAK,KACH,OAAAA,EAAS,KAAK,KAAK,UAAU,KAAK,OAAS,CAAC,EAC5C,KAAK,QAAU,EACR,KAAK,IAAIA,CAAM,CAC1B,CACA,MAAM,IAAI,MAAM,kBAAoBN,EAAK,SAAS,EAAE,CAAC,CACvD,EAhRE,KAAK,OAASG,GAAU,EACxB,KAAK,KAAOJ,CACd,CA+QF,EAEA,SAASngB,GAAOnQ,EAAqB,CACnC,IAAMswB,EAAO,IAAI,SAAStwB,CAAM,EAC1B2T,EAAU,IAAI8d,GAAQnB,CAAI,EAC1B1R,EAAQjL,EAAQ,MAAM,EAC5B,GAAIA,EAAQ,SAAW3T,EAAO,WAAY,MAAM,IAAI,MAAMA,EAAO,WAAa2T,EAAQ,OAAS,iBAAiB,EAChH,OAAOiL,CACT,CAEA,SAAS8S,GAAe9S,EAAmCoS,EAAkB,CAC3E,OAAO,OAAO,KAAKpS,CAAK,EAAE,OAAO,SAAUxd,EAAG,CAC5C,IAAM1C,EAAMkgB,EAAMxd,CAAC,EACjBmvB,EAAO,OAAO7xB,EAChB,OAAQ,CAACsyB,GAAgCtyB,GAAQ,QAA0B6xB,IAAf,YAAuB,CAAC,CAAE7xB,EAAa,OACrG,CAAC,CACH,CAEA,SAASwyB,GAAQtS,EAAgB0R,EAAgBI,EAAgBM,EAA0B,CACzF,IAAMT,EAAO,OAAO3R,EAIpB,GAAI,OAAOA,GAAU,SAAU,CAC7B,IAAMiS,EAASE,GAAcnS,CAAK,EAGlC,GAAIiS,EAAS,GACX,OAAAP,EAAK,SAASI,EAAQG,EAAS,GAAI,EACnCJ,GAAUH,EAAMI,EAAS,EAAG9R,CAAK,EAC1B,EAAIiS,EAIb,GAAIA,EAAS,IACX,OAAAP,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,SAASI,EAAS,EAAGG,CAAM,EAChCJ,GAAUH,EAAMI,EAAS,EAAG9R,CAAK,EAC1B,EAAIiS,EAIb,GAAIA,EAAS,MACX,OAAAP,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,UAAUI,EAAS,EAAGG,CAAM,EACjCJ,GAAUH,EAAMI,EAAS,EAAG9R,CAAK,EAC1B,EAAIiS,EAGb,GAAIA,EAAS,WACX,OAAAP,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,UAAUI,EAAS,EAAGG,CAAM,EACjCJ,GAAUH,EAAMI,EAAS,EAAG9R,CAAK,EAC1B,EAAIiS,CAEf,CAQA,GANI,YAAY,QAAU,YAAY,OAAOjS,CAAK,IAEhDA,EAAQA,EAAM,QAIZA,aAAiB,YAAa,CAChC,IAAMiS,EAASjS,EAAM,WAGrB,GAAIiS,EAAS,IACX,OAAAP,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,SAASI,EAAS,EAAGG,CAAM,EAChC,IAAI,WAAWP,EAAK,MAAM,EAAE,IAAI,IAAI,WAAW1R,CAAK,EAAG8R,EAAS,CAAC,EAC1D,EAAIG,EAIb,GAAIA,EAAS,MACX,OAAAP,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,UAAUI,EAAS,EAAGG,CAAM,EACjC,IAAI,WAAWP,EAAK,MAAM,EAAE,IAAI,IAAI,WAAW1R,CAAK,EAAG8R,EAAS,CAAC,EAC1D,EAAIG,EAIb,GAAIA,EAAS,WACX,OAAAP,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,UAAUI,EAAS,EAAGG,CAAM,EACjC,IAAI,WAAWP,EAAK,MAAM,EAAE,IAAI,IAAI,WAAW1R,CAAK,EAAG8R,EAAS,CAAC,EAC1D,EAAIG,CAEf,CAEA,GAAI,OAAOjS,GAAU,SAAU,CAG7B,GAAI,KAAK,MAAMA,CAAK,IAAMA,EACxB,OAAA0R,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,WAAWI,EAAS,EAAG9R,CAAK,EAC1B,EAIT,GAAIA,GAAS,EAAG,CAEd,GAAIA,EAAQ,IACV,OAAA0R,EAAK,SAASI,EAAQ9R,CAAK,EACpB,EAGT,GAAIA,EAAQ,IACV,OAAA0R,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,SAASI,EAAS,EAAG9R,CAAK,EACxB,EAGT,GAAIA,EAAQ,MACV,OAAA0R,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,UAAUI,EAAS,EAAG9R,CAAK,EACzB,EAGT,GAAIA,EAAQ,WACV,OAAA0R,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,UAAUI,EAAS,EAAG9R,CAAK,EACzB,EAGT,GAAIA,EAAQ,oBACV,OAAA0R,EAAK,SAASI,EAAQ,GAAI,EAC1Bc,GAAUlB,EAAMI,EAAS,EAAG9R,CAAK,EAC1B,EAET,MAAM,IAAI,MAAM,oBAAsBA,EAAM,SAAS,EAAE,CAAC,CAC1D,CAGA,GAAIA,GAAS,IACX,OAAA0R,EAAK,QAAQI,EAAQ9R,CAAK,EACnB,EAGT,GAAIA,GAAS,KACX,OAAA0R,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,QAAQI,EAAS,EAAG9R,CAAK,EACvB,EAGT,GAAIA,GAAS,OACX,OAAA0R,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,SAASI,EAAS,EAAG9R,CAAK,EACxB,EAGT,GAAIA,GAAS,YACX,OAAA0R,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,SAASI,EAAS,EAAG9R,CAAK,EACxB,EAGT,GAAIA,GAAS,oBACX,OAAA0R,EAAK,SAASI,EAAQ,GAAI,EAC1Ba,GAASjB,EAAMI,EAAS,EAAG9R,CAAK,EACzB,EAET,MAAM,IAAI,MAAM,wBAA0B,CAACA,GAAO,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC,CAC1E,CAGA,GAAI2R,IAAS,YACX,OAAIS,EAAe,GACnBV,EAAK,SAASI,EAAQ,GAAI,EAC1BJ,EAAK,SAASI,EAAS,EAAG,CAAI,EAC9BJ,EAAK,SAASI,EAAS,EAAG,CAAI,EACvB,GAIT,GAAI9R,IAAU,KACZ,OAAIoS,EAAe,GACnBV,EAAK,SAASI,EAAQ,GAAI,EACnB,GAIT,GAAIH,IAAS,UACX,OAAAD,EAAK,SAASI,EAAQ9R,EAAQ,IAAO,GAAI,EAClC,EAGT,GAAmB,OAAQA,EAAe,QAAtC,WAA8C,OAAOsS,GAAStS,EAAe,OAAO,EAAG0R,EAAMI,EAAQM,CAAM,EAG/G,GAAIT,IAAS,SAAU,CACrB,IAAIM,EACF/gB,EAAO,EACL1J,EACEurB,EAAU,MAAM,QAAQ/S,CAAK,EAsBnC,GApBI+S,EACFd,EAAUjS,EAAoB,QAE9BxY,EAAOsrB,GAAe9S,EAAqCoS,CAAM,EACjEH,EAASzqB,EAAK,QAGZyqB,EAAS,IACXP,EAAK,SAASI,EAAQG,GAAUc,EAAU,IAAO,IAAK,EACtD7hB,EAAO,GACE+gB,EAAS,OAClBP,EAAK,SAASI,EAAQiB,EAAU,IAAO,GAAI,EAC3CrB,EAAK,UAAUI,EAAS,EAAGG,CAAM,EACjC/gB,EAAO,GACE+gB,EAAS,aAClBP,EAAK,SAASI,EAAQiB,EAAU,IAAO,GAAI,EAC3CrB,EAAK,UAAUI,EAAS,EAAGG,CAAM,EACjC/gB,EAAO,GAGL6hB,EACF,QAAS7zB,EAAI,EAAGA,EAAI+yB,EAAQ/yB,IAC1BgS,GAAQohB,GAAStS,EAAoB9gB,CAAC,EAAGwyB,EAAMI,EAAS5gB,EAAMkhB,CAAM,UAE7D5qB,EACT,QAAStI,EAAI,EAAGA,EAAI+yB,EAAQ/yB,IAAK,CAC/B,IAAME,EAAMoI,EAAKtI,CAAC,EAClBgS,GAAQohB,GAAQlzB,EAAKsyB,EAAMI,EAAS5gB,CAAI,EACxCA,GAAQohB,GAAStS,EAAqC5gB,CAAG,EAAGsyB,EAAMI,EAAS5gB,EAAMkhB,CAAM,CACzF,CAGF,OAAOlhB,CACT,CACA,GAAIygB,IAAS,WAAY,MAAO,GAEhC,MAAM,IAAI,MAAM,gBAAkBA,CAAI,CACxC,CAEA,SAASU,GAAOrS,EAAgBoS,EAA0B,CACxD,IAAMT,EAAO,OAAO3R,EAGpB,GAAI2R,IAAS,SAAU,CACrB,IAAMM,EAASE,GAAcnS,CAAe,EAC5C,GAAIiS,EAAS,GACX,MAAO,GAAIA,EAEb,GAAIA,EAAS,IACX,MAAO,GAAIA,EAEb,GAAIA,EAAS,MACX,MAAO,GAAIA,EAEb,GAAIA,EAAS,WACX,MAAO,GAAIA,CAEf,CAQA,GANI,YAAY,QAAU,YAAY,OAAOjS,CAAK,IAEhDA,EAAQA,EAAM,QAIZA,aAAiB,YAAa,CAChC,IAAMiS,EAASjS,EAAM,WACrB,GAAIiS,EAAS,IACX,MAAO,GAAIA,EAEb,GAAIA,EAAS,MACX,MAAO,GAAIA,EAEb,GAAIA,EAAS,WACX,MAAO,GAAIA,CAEf,CAEA,GAAI,OAAOjS,GAAU,SAAU,CAG7B,GAAI,KAAK,MAAMA,CAAK,IAAMA,EAAO,MAAO,GAGxC,GAAIA,GAAS,EAAG,CAEd,GAAIA,EAAQ,IAAM,MAAO,GAEzB,GAAIA,EAAQ,IAAO,MAAO,GAE1B,GAAIA,EAAQ,MAAS,MAAO,GAE5B,GAAIA,EAAQ,WAAa,MAAO,GAEhC,GAAIA,EAAQ,oBAAqB,MAAO,GAExC,MAAM,IAAI,MAAM,oBAAsBA,EAAM,SAAS,EAAE,CAAC,CAC1D,CAEA,GAAIA,GAAS,IAAO,MAAO,GAE3B,GAAIA,GAAS,KAAO,MAAO,GAE3B,GAAIA,GAAS,OAAS,MAAO,GAE7B,GAAIA,GAAS,YAAa,MAAO,GAEjC,GAAIA,GAAS,oBAAqB,MAAO,GAEzC,MAAM,IAAI,MAAM,uBAAyBA,EAAM,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC,CACvE,CAGA,GAAI2R,IAAS,UAAW,MAAO,GAG/B,GAAI3R,IAAU,KAAM,OAAOoS,EAAS,EAAI,EACxC,GAAIpS,IAAU,OAAW,OAAOoS,EAAS,EAAI,EAE7C,GAAmB,OAAQpS,EAAe,QAAtC,WAA8C,OAAOqS,GAAQrS,EAAe,OAAO,EAAGoS,CAAM,EAGhG,GAAIT,IAAS,SAAU,CACrB,IAAIM,EACF/gB,EAAO,EACT,GAAI,MAAM,QAAQ8O,CAAK,EAAG,CACxBiS,EAASjS,EAAM,OACf,QAAS9gB,EAAI,EAAGA,EAAI+yB,EAAQ/yB,IAC1BgS,GAAQmhB,GAAOrS,EAAM9gB,CAAC,EAAGkzB,CAAM,CAEnC,KAAO,CACL,IAAM5qB,EAAOsrB,GAAe9S,EAAqCoS,CAAM,EACvEH,EAASzqB,EAAK,OACd,QAAStI,EAAI,EAAGA,EAAI+yB,EAAQ/yB,IAAK,CAC/B,IAAME,EAAMoI,EAAKtI,CAAC,EAClBgS,GAAQmhB,GAAOjzB,CAAG,EAAIizB,GAAQrS,EAAqC5gB,CAAG,EAAGgzB,CAAM,CACjF,CACF,CACA,GAAIH,EAAS,GACX,MAAO,GAAI/gB,EAEb,GAAI+gB,EAAS,MACX,MAAO,GAAI/gB,EAEb,GAAI+gB,EAAS,WACX,MAAO,GAAI/gB,EAEb,MAAM,IAAI,MAAM,8BAAgC+gB,EAAO,SAAS,EAAE,CAAC,CACrE,CACA,GAAIN,IAAS,WAAY,MAAO,GAEhC,MAAM,IAAI,MAAM,gBAAkBA,CAAI,CACxC,CAEA,IAAOr4B,GAAQ,CACb,OAAA0Y,GACA,OAAAT,GACA,QAAAkgB,GACA,UAAAI,GACA,SAAAG,GACA,cAAAG,EACF,ECryBA,SAASnD,GAAYC,EAAuBjqB,EAAyD,CACnG,MAAO,CAAC,CAACA,EAAQ,IAAI,kBAAkB,CACzC,CAEA,SAASkqB,GAAaD,EAAuBjqB,EAAkB,CAC7D,GAAIgqB,GAAYC,EAAcjqB,CAAO,EACnC,OAAOiqB,EAAa,OAAS/1B,EAAU,WAAW+1B,EAAa,KAAK,CAExE,CAEA,SAAS+D,GAAehuB,EAAkB,CACxC,IAAMzG,EAA0B,CAAC,EAEjC,OAAAyG,EAAQ,QAAQ,CAACgb,EAAO5gB,IAAQ,CAC9Bb,EAAOa,CAAG,EAAI4gB,CAChB,CAAC,EAEMzhB,CACT,CAEA,eAAO00B,GACL7nB,EACArE,EACA5B,EACAH,EACArE,EACAM,EACwB,CACxB,IAAMiyB,EAAe,IAAI,QAAQluB,GAAW,CAAC,CAAC,EACxCgQ,EAAU5J,EAASA,EAAO,YAAY,EAAU/N,GAAM4D,CAAI,EAAI,MAAQ,OAEtEkyB,EAAa,IAAI,gBAEnB5wB,EACE6wB,EAAyC,IAAI,QAAShtB,GAAY,CACtE7D,EAAU,WACR,IAAM,CACJ4wB,EAAW,MAAM,EAGjB/sB,EAAQ,CAAE,MAAO,IAAIvH,GAAiB,oBAAqB,KAAM,GAAG,CAAE,CAAC,CACzE,EACAkI,EAASA,EAAO,QAAQ,SAAS,mBAAqBjB,EAAS,SAAS,kBAC1E,CACF,CAAC,EAEKutB,EAA2B,CAC/B,OAAQre,EACR,QAASke,EACT,KAAAjyB,EACA,OAAQkyB,EAAW,MACrB,EAEKz5B,EAAS,OAAO,cACnB25B,EAAY,YAAcH,EAAa,IAAI,eAAe,EAAI,UAAY,eAG5E,IAAMI,GAAiB,SAAoC,CACzD,GAAI,CACF,IAAMC,EAAY,IAAI,gBAAgB5yB,GAAU,CAAC,CAAC,EAClD4yB,EAAU,IAAI,MAAar3B,GAAa,CAAC,EACzC,IAAMs3B,EAAcruB,EAAM,IAAMouB,EAC1BlzB,EAAM,MAAYzD,GAAgB,EAAE,MAAM42B,EAAaH,CAAW,EAIxE,GAFA,aAAa9wB,CAAQ,EAEjBlC,EAAI,QAAU,IAChB,MAAO,CAAE,MAAO,KAAM,WAAYA,EAAI,MAAO,EAG/C,IAAMwF,EAAcxF,EAAI,QAAQ,IAAI,cAAc,EAC9CY,EACA4E,GAAeA,EAAY,QAAQ,uBAAuB,EAAI,GAChE5E,EAAO,MAAMZ,EAAI,YAAY,EACpBwF,GAAeA,EAAY,QAAQ,kBAAkB,EAAI,GAClE5E,EAAO,MAAMZ,EAAI,KAAK,EAEtBY,EAAO,MAAMZ,EAAI,KAAK,EAGxB,IAAMuJ,EAAW,CAAC,CAAC/D,GAAeA,EAAY,QAAQ,uBAAuB,IAAM,GAC7Eb,EAAUguB,GAAe3yB,EAAI,OAAO,EAE1C,OAAKA,EAAI,GAWA,CAAE,MAAO,KAAM,KAAAY,EAAM,QAAA+D,EAAS,SAAA4E,EAAU,WAAYvJ,EAAI,MAAO,EAF/D,CAAE,MAPP6uB,GAAajuB,EAAMZ,EAAI,OAAO,GAC9B,IAAIxB,GACF,wCAA0CwB,EAAI,OAAS,cAAgB3G,EAAS,OAAO,QAAQuH,CAAI,EACnG,KACAZ,EAAI,MACN,EAEc,KAAAY,EAAM,QAAA+D,EAAS,SAAA4E,EAAU,WAAYvJ,EAAI,MAAO,CAIpE,OAASuK,EAAO,CACd,oBAAarI,CAAQ,EACd,CAAE,MAAAqI,CAAmC,CAC9C,CACF,GAAG,EAEH,OAAO,QAAQ,KAAK,CAACwoB,EAAgBE,CAAa,CAAC,CACrD,CC3GO,IAAMG,GAAmE,CAC9E,WAAYrC,GACZ,aAAc6B,EAChB,E/DeM1tB,GAASmlB,GAAkBkD,GAAQnD,EAAW,EAEpD/wB,EAAS,OAAS6L,GAClB7L,EAAS,YAAc+wB,GACvB/wB,EAAS,KAAOkzB,GAChBlzB,EAAS,OAASk0B,GAClBl0B,EAAS,WAAashB,GACtBthB,EAAS,WAAawzB,GAEtB,QAAWwG,IAAe,CAACt6B,GAAaD,EAAe,EACrDu6B,EAAY,OAASnuB,GACrBmuB,EAAY,SAAWp6B,GAGzBszB,GAAK,8BAAgC6G,GAErCr4B,EAAO,gBAAgB,EAEvB1B,EAAS,SAAWqM,GAAYD,EAAgB,EAE5CpM,EAAS,OAAO,QAElBA,EAAS,SAAS,OAAS,IAAMA,EAAS,OAAO,OAKnD,IAAOL,GAAQ,CACb,UAAAH,EACA,KAAME,GACN,SAAUD,GACV,QAAAG,EACF,2XgEtDA,IAAAq6B,GAAA,GAAAC,GAAAD,GAAA,oBAAAE,GAAA,YAAAC,KCEO,IAAMC,GAAN,KAAgB,CAMrB,YAAYC,EAAsBC,EAAgB,CAChD,KAAK,aAAeD,EACpB,KAAK,QAAU,GAAGC,CAAM,cAC1B,CAEA,mBAAmBC,EAAeC,EAAqB,CACrD,KAAK,aAAeD,EACpB,KAAK,YAAcC,CACrB,CAEA,sBAA6B,CAC3B,KAAK,aAAe,OACpB,KAAK,YAAc,MACrB,CAEQ,SAAkC,CACxC,IAAMC,EAA4B,CAChC,eAAgB,mBAChB,kBAAmB,KAAK,YAC1B,EACA,OAAI,KAAK,eAAcA,EAAE,iBAAiB,EAAI,KAAK,cAC/C,KAAK,cAAaA,EAAE,gBAAgB,EAAI,KAAK,aAC1CA,CACT,CAEA,MAAc,QACZC,EACAC,EACAC,EACY,CACZ,IAAMC,EAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAGF,CAAI,GAAI,CAChD,OAAAD,EACA,QAAS,KAAK,QAAQ,EACtB,KAAME,EAAO,KAAK,UAAUA,CAAI,EAAI,MACtC,CAAC,EAED,GAAI,CAACC,EAAI,GAAI,CACX,IAAMC,EAAO,MAAMD,EAAI,KAAK,EAAE,MAAM,IAAM,EAAE,EAC5C,MAAM,IAAI,MAAM,8BAA8BA,EAAI,MAAM,KAAKC,CAAI,EAAE,CACrE,CAEA,OAAOD,EAAI,KAAK,CAClB,CAEA,MAAM,gBAAuC,CAC3C,OAAO,KAAK,QAAQ,MAAO,eAAe,CAC5C,CAEA,MAAM,iBAAiBE,EAG8B,CACnD,OAAO,KAAK,QAAQ,OAAQ,iBAAkB,CAC5C,GAAGA,EACH,aAAc,KAAK,YACrB,CAAC,CACH,CAEA,MAAM,YACJC,EACAC,EACoB,CACpB,IAAMC,EAAK,IAAI,gBACXD,GAAQ,OAAOC,EAAG,IAAI,QAAS,OAAOD,EAAO,KAAK,CAAC,EACnDA,GAAQ,MAAMC,EAAG,IAAI,OAAQ,OAAOD,EAAO,IAAI,CAAC,EACpD,IAAME,EAAQD,EAAG,SAAS,EAAI,IAAIA,EAAG,SAAS,CAAC,GAAK,GACpD,OAAO,KAAK,QAAQ,MAAO,kBAAkBF,CAAc,YAAYG,CAAK,EAAE,CAChF,CAEA,MAAM,WAAWH,EAAwBI,EAAkF,CACzH,IAAMC,EAAW,IAAI,SACrBA,EAAS,OAAO,OAAQD,CAAI,EAE5B,IAAME,EAAkC,CACtC,kBAAmB,KAAK,YAC1B,EACI,KAAK,eAAcA,EAAQ,iBAAiB,EAAI,KAAK,cACrD,KAAK,cAAaA,EAAQ,gBAAgB,EAAI,KAAK,aAEvD,IAAMT,EAAM,MAAM,MAAM,GAAG,KAAK,OAAO,kBAAkBG,CAAc,UAAW,CAChF,OAAQ,OACR,QAAAM,EACA,KAAMD,CACR,CAAC,EAED,GAAI,CAACR,EAAI,GAAI,CACX,IAAMC,EAAO,MAAMD,EAAI,KAAK,EAAE,MAAM,IAAM,EAAE,EAC5C,MAAM,IAAI,MAAM,iCAAiCA,EAAI,MAAM,KAAKC,CAAI,EAAE,CACxE,CAEA,OAAOD,EAAI,KAAK,CAClB,CAEA,MAAM,YACJG,EACAD,EACkB,CAClB,OAAO,KAAK,QACV,OACA,kBAAkBC,CAAc,YAChCD,CACF,CACF,CAEA,MAAM,yBAAmD,CACvD,OAAO,KAAK,QAAQ,MAAO,gBAAgB,CAC7C,CAEA,MAAM,mBAAmBC,EAA+C,CACtE,OAAO,KAAK,QAAQ,OAAQ,kBAAkBA,CAAc,SAAS,CACvE,CAEA,MAAM,aAAaA,EAA0C,CAC3D,OAAO,KAAK,QAAQ,OAAQ,cAAe,CAAE,eAAAA,CAAe,CAAC,CAC/D,CACF,EC3HA,IAAAO,GAAsB,SAUTC,GAAN,KAAqB,CAO1B,YAAYC,EAAsB,CANlC,KAAQ,OAA+B,KACvC,KAAQ,QAAuC,KAC/C,KAAQ,eAAgC,KAExC,KAAQ,SAAoC,KAG1C,KAAK,UAAYA,CACnB,CAEA,MAAM,UACJC,EACAC,EACe,CAEf,KAAK,YAAY,EAEjB,KAAK,eAAiBD,EACtB,KAAK,SAAWC,EAEhB,GAAI,CACF,IAAMC,EAAe,MAAM,KAAK,UAAU,aAAaF,CAAc,EAErE,KAAK,OAAS,IAAS,YAAS,CAC9B,aAAc,CAACG,EAAOC,IAAa,CACjCA,EAAS,KAAMF,CAAiC,CAClD,EACA,SAAU,WAAWF,CAAc,EACrC,CAAC,EAED,IAAMK,EAAc,gBAAgBL,CAAc,GAClD,KAAK,QAAU,KAAK,OAAO,SAAS,IAAIK,CAAW,EAEnD,KAAK,QAAQ,UAAWC,GAAQ,CAC9B,GAAKA,EAAI,KAET,GAAI,CACF,IAAMC,EACJ,OAAOD,EAAI,MAAS,SAAW,KAAK,MAAMA,EAAI,IAAI,EAAIA,EAAI,KAExDC,EAAK,OAAS,+BAAiCA,EAAK,SACtDN,EAAS,2BAA2BM,EAAK,QAAwB,EAEjEA,EAAK,OAAS,8BACdA,EAAK,UAELN,EAAS,UAAUM,EAAK,QAAmB,CAE/C,OAASC,EAAG,CACV,QAAQ,MAAM,mDAAoDA,CAAC,CACrE,CACF,CAAC,CACH,OAASA,EAAG,CACV,QAAQ,MAAM,iDAAkDA,CAAC,CACnE,CACF,CAEA,aAAoB,CACd,KAAK,UACP,KAAK,QAAQ,YAAY,EACzB,KAAK,QAAU,MAEb,KAAK,SACP,KAAK,OAAO,MAAM,EAClB,KAAK,OAAS,MAEhB,KAAK,eAAiB,KACtB,KAAK,SAAW,IAClB,CAEA,aAAuB,CACrB,OAAO,KAAK,QAAQ,WAAW,QAAU,WAC3C,CACF,ECpDA,IAAMC,GAAmB,CACvB,QAAS,CACP,MAAO,mBACP,YAAa,uDACb,KAAM,OACN,gBAAiB,WACjB,MAAO,SACP,iBAAkB,gBAClB,MAAO,mBACP,QAAS,eACT,cAAe,wCACf,YAAa,4BACf,EACA,KAAM,CACJ,YAAa,yBACb,OAAQ,+BACR,OAAQ,mBACR,WAAY,iBACZ,UAAW,cACX,aAAc,sCACd,SAAU,QACZ,EACA,cAAe,CACb,MAAO,cACP,gBAAiB,gBACjB,MAAO,+BACP,KAAM,SACN,OAAQ,UACR,WAAY,wBACd,CACF,EAEMC,GAAmB,CACvB,QAAS,CACP,MAAO,uBACP,YAAa,+CACb,KAAM,OACN,gBAAiB,YACjB,MAAO,QACP,iBAAkB,gBAClB,MAAO,qBACP,QAAS,cACT,cAAe,+BACf,YAAa,gBACf,EACA,KAAM,CACJ,YAAa,oBACb,OAAQ,qCACR,OAAQ,sBACR,WAAY,cACZ,UAAW,eACX,aAAc,4BACd,SAAU,UACZ,EACA,cAAe,CACb,MAAO,UACP,gBAAiB,mBACjB,MAAO,0BACP,KAAM,OACN,OAAQ,SACR,WAAY,iBACd,CACF,EAEMC,GAAmB,CACvB,QAAS,CACP,MAAO,0BACP,YAAa,oEACb,KAAM,SACN,gBAAiB,YACjB,MAAO,wBACP,iBAAkB,eAClB,MAAO,0BACP,QAAS,eACT,cAAe,6BACf,YAAa,2BACf,EACA,KAAM,CACJ,YAAa,wBACb,OAAQ,wCACR,OAAQ,0BACR,WAAY,mBACZ,UAAW,cACX,aAAc,0CACd,SAAU,WACZ,EACA,cAAe,CACb,MAAO,cACP,gBAAiB,wBACjB,MAAO,oCACP,KAAM,UACN,OAAQ,UACR,WAAY,qBACd,CACF,EAEMC,GAAwC,CAAE,GAAAH,GAAI,GAAAC,GAAI,GAAAC,EAAG,EAEpD,SAASE,GAAgBC,EAA8B,CAC5D,OAAOF,GAAQE,CAAM,GAAKF,GAAQ,EACpC,CCnIa,IC0BAG,GChBPC,ECPFC,GAgGSC,GC8ETC,GAWAC,GAEEC,GA0BAC,GC/LFC,GAoJEC,GACAC,GC7KKC,GNWEC,GAAgC,CAAG,EACnCC,GAAY,CAAA,EACZC,GACZ,oECdYC,GAAUC,MAAMD,QAStB,SAASE,GAAOC,EAAKC,EAAAA,CAE3B,QAASR,KAAKQ,EAAOD,EAAIP,CAAAA,EAAKQ,EAAMR,CAAAA,EACpC,OAA6BO,CAC9B,CAQgB,SAAAE,GAAWC,EAAAA,CACtBA,GAAQA,EAAKC,YAAYD,EAAKC,WAAWC,YAAYF,CAAAA,CAC1D,CEVgB,SAAAG,GAAcC,EAAMN,EAAOO,EAAAA,CAC1C,IACCC,EACAC,EACAjB,EAHGkB,EAAkB,CAAA,EAItB,IAAKlB,KAAKQ,EACLR,GAAK,MAAOgB,EAAMR,EAAMR,CAAAA,EACnBA,GAAK,MAAOiB,EAAMT,EAAMR,CAAAA,EAC5BkB,EAAgBlB,CAAAA,EAAKQ,EAAMR,CAAAA,EAUjC,GAPImB,UAAUC,OAAS,IACtBF,EAAgBH,SACfI,UAAUC,OAAS,EAAI/B,GAAMgC,KAAKF,UAAW,CAAA,EAAKJ,GAKjC,OAARD,GAAQ,YAAcA,EAAKQ,cAAgB,KACrD,IAAKtB,KAAKc,EAAKQ,aACVJ,EAAgBlB,CAAAA,IADNsB,SAEbJ,EAAgBlB,CAAAA,EAAKc,EAAKQ,aAAatB,CAAAA,GAK1C,OAAOuB,GAAYT,EAAMI,EAAiBF,EAAKC,EAAK,IAAA,CACrD,CAcgB,SAAAM,GAAYT,EAAMN,EAAOQ,EAAKC,EAAKO,EAAAA,CAIlD,IAAMC,EAAQ,CACbX,KAAAA,EACAN,MAAAA,EACAQ,IAAAA,EACAC,IAAAA,EACAS,IAAW,KACXC,GAAS,KACTC,IAAQ,EACRC,IAAM,KAKNC,IAAAA,OACAC,IAAY,KACZC,YAAAA,OACAC,IAAWT,GAAAA,EAAqBjC,GAChC2C,IAAAA,GACAC,IAAQ,CAAA,EAMT,OAFIX,GAAY,MAAQlC,EAAQmC,OAAS,MAAMnC,EAAQmC,MAAMA,CAAAA,EAEtDA,CACR,CAMgB,SAAAW,GAASC,EAAAA,CACxB,OAAOA,EAAMC,QACd,CAAA,SChFgBC,GAAcF,EAAOG,EAAAA,CACpCC,KAAKJ,MAAQA,EACbI,KAAKD,QAAUA,CAChB,CA0EgB,SAAAE,GAAcC,EAAOC,EAAAA,CACpC,GAAIA,GAAc,KAEjB,OAAOD,EAAKE,GACTH,GAAcC,EAAKE,GAAUF,EAAKG,IAAU,CAAA,EAC5C,KAIJ,QADIC,EACGH,EAAaD,EAAKK,IAAWC,OAAQL,IAG3C,IAFAG,EAAUJ,EAAKK,IAAWJ,CAAAA,IAEX,MAAQG,EAAOG,KAAS,KAItC,OAAOH,EAAOG,IAShB,OAA4B,OAAdP,EAAMQ,MAAQ,WAAaT,GAAcC,CAAAA,EAAS,IACjE,CA2CA,SAASS,GAAwBT,EAAAA,CAAjC,IAGWU,EACJC,EAHN,IAAKX,EAAQA,EAAKE,KAAa,MAAQF,EAAKY,KAAe,KAAM,CAEhE,IADAZ,EAAKO,IAAQP,EAAKY,IAAYC,KAAO,KAC5BH,EAAI,EAAGA,EAAIV,EAAKK,IAAWC,OAAQI,IAE3C,IADIC,EAAQX,EAAKK,IAAWK,CAAAA,IACf,MAAQC,EAAKJ,KAAS,KAAM,CACxCP,EAAKO,IAAQP,EAAKY,IAAYC,KAAOF,EAAKJ,IAC1C,KACD,CAGD,OAAOE,GAAwBT,CAAAA,CAChC,CACD,CA4BgB,SAAAc,GAAcC,EAAAA,EAAAA,CAE1BA,EAACC,MACDD,EAACC,IAAAA,KACFC,GAAcC,KAAKH,CAAAA,GAAAA,CAClBI,GAAOC,OACTC,KAAiBC,EAAQC,sBAEzBF,GAAeC,EAAQC,oBACNC,IAAOL,EAAAA,CAE1B,CASA,SAASA,IAAAA,CAAT,IACKJ,EAMEU,EAzGkBC,EAOjBC,EANHC,EACHC,EACAC,EACAC,EAmGD,IAHAd,GAAce,KAAKC,EAAAA,EAGXlB,EAAIE,GAAciB,MAAAA,GACrBnB,EAACC,MACAS,EAAoBR,GAAcX,OAlGjCqB,EAAAA,OALNE,GADGD,GADoBF,EA0GNX,GAzGMoB,KACN5B,IACjBuB,EAAc,CAAA,EACdC,EAAW,CAAA,EAERL,EAASU,OACNT,EAAWU,GAAO,CAAA,EAAIT,CAAAA,GACpBO,IAAaP,EAAQO,IAAa,EACtCb,EAAQtB,OAAOsB,EAAQtB,MAAM2B,CAAAA,EAEjCW,GACCZ,EAASU,IACTT,EACAC,EACAF,EAASa,IACTb,EAASU,IAAYI,aJzII,GI0IzBZ,EAAQa,IAAyB,CAACZ,CAAAA,EAAU,KAC5CC,EACAD,GAAiB9B,GAAc6B,CAAAA,EAAYC,CAAAA,EJ5IlB,GI6ItBD,EAAQa,KACXV,CAAAA,EAGDJ,EAAQQ,IAAaP,EAAQO,IAC7BR,EAAQzB,GAAAG,IAAmBsB,EAAQxB,GAAAA,EAAWwB,EAC9Ce,GAAWZ,EAAaH,EAAUI,CAAAA,EAE9BJ,EAAQpB,KAASsB,GACpBpB,GAAwBkB,CAAAA,GA8EpBV,GAAcX,OAASmB,GAI1BR,GAAce,KAAKC,EAAAA,GAItBd,GAAOC,IAAkB,CAC1B,CG5MgB,SAAAuB,GACfC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACApB,EACAD,EACAsB,EACApB,EAAAA,CAXe,IAaXrB,EAEHkB,EAEAwB,EAEAC,EAEAC,GAKGC,EAAeR,GAAkBA,EAAc1C,KAAemD,GAE9DC,EAAoBZ,EAAavC,OAMrC,IAJAwC,EAAc9B,IAAYa,EAC1B6B,GAA0BZ,EAAgBD,EAAcU,CAAAA,EACxD1B,EAASiB,EAAc9B,IAElBN,EAAI,EAAGA,EAAI+C,EAAmB/C,KAClC0C,EAAaN,EAAczC,IAAWK,CAAAA,IACpB,OAKjBkB,EADGwB,EAAUjD,MACbyB,GAAW+B,GAEAJ,EAAYH,EAAUjD,GAAAA,GAAYwD,GAI9CP,EAAUjD,IAAUO,EAGpB4B,GACCM,EACAQ,EACAxB,EACAoB,EACAC,EACAC,EACApB,EACAD,EACAsB,EACApB,CAAAA,EAIDsB,EAASD,EAAU7C,IACf6C,EAAWQ,KAAOhC,EAASgC,KAAOR,EAAWQ,MAC5ChC,EAASgC,KACZC,GAASjC,EAASgC,IAAK,KAAMR,CAAAA,EAE9BrB,EAASb,KACRkC,EAAWQ,IACXR,EAAUxC,KAAeyC,EACzBD,CAAAA,GAIEE,IAAiB,MAAQD,GAAU,OACtCC,GAAgBD,GP1GS,MO8GzBD,EAAUX,KACVb,EAAQvB,MAAe+C,EAAU/C,IAEjCwB,EAASiC,GAAOV,EAAYvB,EAAQe,CAAAA,EAEV,OAAnBQ,EAAW5C,MAAQ,YAC1B4C,EAAUpC,MADQR,OAMlBqB,EAASuB,EAAUpC,IACTqC,IACVxB,EAASwB,EAAOU,aAQjBX,EAAUpC,IAAAA,OAGVoC,EAAUX,KAAAA,SAaXK,EAAc9B,IAAYa,EAC1BiB,EAAcvC,IAAQ+C,EACvB,CAOA,SAASI,GAA0BZ,EAAgBD,EAAcU,EAAAA,CAAjE,IAEK7C,EAEA0C,EAEAxB,EA+DGoC,EAOAC,EApEDR,EAAoBZ,EAAavC,OACnC4D,EAAoBX,EAAYjD,OACnC6D,EAAuBD,EAEpBE,EAAO,EAGX,IADAtB,EAAczC,IAAa,CAAA,EACtBK,EAAI,EAAGA,EAAI+C,EAAmB/C,KAGlC0C,EAAaP,EAAanC,CAAAA,IAGX,MACO,OAAd0C,GAAc,WACA,OAAdA,GAAc,YA8ChBY,EAActD,EAAI0D,GA/BvBhB,EAAaN,EAAczC,IAAWK,CAAAA,EANjB,OAAd0C,GAAc,UACA,OAAdA,GAAc,UAEA,OAAdA,GAAc,UACrBA,EAAWiB,aAAeC,OAEiBC,GAC1C,KACAnB,EACA,KACA,KACA,IAAA,EAESoB,GAAQpB,CAAAA,EACyBmB,GAC1C9E,GACA,CAAEE,SAAUyD,CAAAA,EACZ,KACA,KACA,IAAA,EAESA,EAAWiB,cAFpB,QAEiDjB,EAAUqB,IAAU,EAK3BF,GAC1CnB,EAAW5C,KACX4C,EAAW1D,MACX0D,EAAWsB,IACXtB,EAAWQ,IAAMR,EAAWQ,IAAM,KAClCR,EAAUjB,GAAAA,EAGgCiB,GAIlClD,GAAW4C,EACrBM,EAAUqB,IAAU3B,EAAc2B,IAAU,EAY5C7C,EAAW,MAPLqC,EAAiBb,EAAUjD,IAAUwE,GAC1CvB,EACAG,EACAS,EACAG,CAAAA,KAGU,KAGVA,KADAvC,EAAW2B,EAAYU,CAAAA,KAGtBrC,EAAQa,KPlPW,SOyPFb,GAAY,MAAQA,EAAQO,MAAe,MAGzD8B,GAH0C9B,IAI7CiC,IAI6B,OAAnBhB,EAAW5C,MAAQ,aAC7B4C,EAAUX,KPpQc,QOsQfwB,IAAkBD,IAiBxBC,GAAiBD,EAAc,EAClCI,IACUH,GAAiBD,EAAc,EACzCI,KAEIH,EAAgBD,EACnBI,IAEAA,IAMDhB,EAAUX,KPrSc,SOqLzBW,EAAaN,EAAczC,IAAWK,CAAAA,EAAK,KAyH7C,GAAIyD,EACH,IAAKzD,EAAI,EAAGA,EAAIwD,EAAmBxD,KAClCkB,EAAW2B,EAAY7C,CAAAA,IACP,MP/SI,SO+SKkB,EAAQa,OAC5Bb,EAAQrB,KAASuC,EAAc9B,MAClC8B,EAAc9B,IAAYjB,GAAc6B,CAAAA,GAGzCgD,GAAQhD,EAAUA,CAAAA,EAItB,CAQA,SAASkC,GAAOe,EAAahD,EAAQe,EAAAA,CAArC,IAIMjD,EACKe,EAFV,GAA+B,OAApBmE,EAAYrE,MAAQ,WAAY,CAE1C,IADIb,EAAWkF,EAAWxE,IACjBK,EAAI,EAAGf,GAAYe,EAAIf,EAASW,OAAQI,IAC5Cf,EAASe,CAAAA,IAKZf,EAASe,CAAAA,EAAER,GAAW2E,EACtBhD,EAASiC,GAAOnE,EAASe,CAAAA,EAAImB,EAAQe,CAAAA,GAIvC,OAAOf,CACR,CAAWgD,EAAWtE,KAASsB,IAC1BA,GAAUgD,EAAYrE,MAAAA,CAASoC,EAAUkC,SAASjD,CAAAA,IACrDA,EAAS9B,GAAc8E,CAAAA,GAExBjC,EAAUmC,aAAaF,EAAWtE,IAAOsB,GAAU,IAAA,EACnDA,EAASgD,EAAWtE,KAGrB,GACCsB,EAASA,GAAUA,EAAOkC,kBAClBlC,GAAU,MAAQA,EAAOmD,WAAa,GAE/C,OAAOnD,CACR,CA4BA,SAASoD,GACRC,EACAC,EACAC,EACAC,EAAAA,CAJD,IAMOC,EAAMJ,EAAWI,IACjBC,EAAOL,EAAWK,KACpBC,EAAIJ,EAAc,EAClBK,EAAIL,EAAc,EAClBM,EAAWP,EAAYC,CAAAA,EAkB3B,GACCM,IAAa,MACZA,GACAJ,GAAOI,EAASJ,KAChBC,IAASG,EAASH,MP1ZE,SO2ZnBG,EAAQC,KAEV,OAAOP,EACD,IAZW,OAATG,GAAS,YAAcA,IAASK,IAAYN,IACpDD,GACEK,GAAY,MPpZO,SOoZEA,EAAQC,KAA2B,EAAI,GAW9D,KAAOH,GAAK,GAAKC,EAAIN,EAAYU,QAAQ,CACxC,GAAIL,GAAK,EAAG,CAEX,IADAE,EAAWP,EAAYK,CAAAA,IPjaJ,SOoajBE,EAAQC,MACTL,GAAOI,EAASJ,KAChBC,IAASG,EAASH,KAElB,OAAOC,EAERA,GACD,CAEA,GAAIC,EAAIN,EAAYU,OAAQ,CAE3B,IADAH,EAAWP,EAAYM,CAAAA,IP9aJ,SOibjBC,EAAQC,MACTL,GAAOI,EAASJ,KAChBC,IAASG,EAASH,KAElB,OAAOE,EAERA,GACD,CACD,CAGD,MAAA,EACD,CFjcA,SAASK,GAASC,EAAOT,EAAKU,EAAAA,CACzBV,EAAI,CAAA,IAAO,IACdS,EAAME,YAAYX,EAAKU,GAAgB,EAAKA,EAE5CD,EAAMT,CAAAA,EADIU,GAAS,KACN,GACa,OAATA,GAAS,UAAYE,GAAmBC,KAAKb,CAAAA,EACjDU,EAEAA,EAAQ,IAEvB,CAuBgB,SAAAC,GAAYG,EAAKC,EAAML,EAAOM,EAAUC,EAAAA,CACvD,IAAIC,EAEJC,EAAG,GAAIJ,IAAS,QACf,GAAoB,OAATL,GAAS,SACnBI,EAAIL,MAAMW,QAAUV,MACd,CAKN,GAJuB,OAAZM,GAAY,WACtBF,EAAIL,MAAMW,QAAUJ,EAAW,IAG5BA,EACH,IAAKD,KAAQC,EACNN,GAASK,KAAQL,GACtBF,GAASM,EAAIL,MAAOM,EAAM,EAAA,EAK7B,GAAIL,EACH,IAAKK,KAAQL,EACPM,GAAYN,EAAMK,CAAAA,IAAUC,EAASD,CAAAA,GACzCP,GAASM,EAAIL,MAAOM,EAAML,EAAMK,CAAAA,CAAAA,CAIpC,SAGQA,EAAK,CAAA,IAAO,KAAOA,EAAK,CAAA,IAAO,IACvCG,EACCH,KAAUA,EAAOA,EAAKM,QAAQ,8BAA+B,IAAA,GAQ7DN,EAJAA,EAAKO,YAAAA,IAAiBR,GACtBC,IAAS,cACTA,IAAS,YAEFA,EAAKO,YAAAA,EAAcC,MAAM,CAAA,EACrBR,EAAKQ,MAAM,CAAA,EAElBT,EAAGU,IAAaV,EAAGU,EAAc,CAAA,GACtCV,EAAGU,EAAYT,EAAOG,CAAAA,EAAcR,EAEhCA,EACEM,EAQJN,EAAMe,EAAYT,EAASS,GAP3Bf,EAAMe,EAAYC,GAClBZ,EAAIa,iBACHZ,EACAG,EAAaU,GAAoBC,GACjCX,CAAAA,GAMFJ,EAAIgB,oBACHf,EACAG,EAAaU,GAAoBC,GACjCX,CAAAA,MAGI,CACN,GAAID,GAAa,6BAIhBF,EAAOA,EAAKM,QAAQ,cAAe,GAAA,EAAKA,QAAQ,SAAU,GAAA,UAE1DN,GAAQ,SACRA,GAAQ,UACRA,GAAQ,QACRA,GAAQ,QACRA,GAAQ,QAGRA,GAAQ,YACRA,GAAQ,YACRA,GAAQ,WACRA,GAAQ,WACRA,GAAQ,QACRA,GAAQ,WACRA,KAAQD,EAER,GAAA,CACCA,EAAIC,CAAAA,EAAQL,GAAgB,GAE5B,MAAMS,CACK,MAAHY,CAAG,CAUO,OAATrB,GAAS,aAETA,GAAS,MAASA,IAAlBA,IAAqCK,EAAK,CAAA,IAAO,IAG3DD,EAAIkB,gBAAgBjB,CAAAA,EAFpBD,EAAImB,aAAalB,EAAMA,GAAQ,WAAaL,GAAS,EAAO,GAAKA,CAAAA,EAInE,CACD,CAOA,SAASwB,GAAiBhB,EAAAA,CAMzB,OAAA,SAAiBa,EAAAA,CAChB,GAAII,KAAIX,EAAa,CACpB,IAAMY,EAAeD,KAAIX,EAAYO,EAAE9B,KAAOiB,CAAAA,EAC9C,GAAIa,EAAEM,GAAe,KACpBN,EAAEM,EAAcX,aAKNK,EAAEM,EAAcD,EAAaX,EACvC,OAGD,OADIa,EAAQC,QAAOR,EAAIO,EAAQC,MAAMR,CAAAA,GAC9B,gBAAiBK,EAAeA,EAAaI,YAAYT,CAAAA,EAAKK,EAAaL,CAAAA,CACnF,CACD,CACD,CAAA,SG5IgBU,GACfC,EACAC,EACAvC,EACAwC,EACA3B,EACA4B,EACAC,EACAC,EACAC,EACAC,EAAAA,CAAAA,IAGIC,EAkBEC,EAAGC,EAAOC,EAAUC,EAAUC,GAAUC,EACxCC,EACEC,EAMFC,EACAC,EAyGOC,GA4BPC,GACHC,GASSF,GA6BNG,EAtMLC,GAAUtB,EAAS1C,KAIpB,GAAI0C,EAASuB,cAAb,OAAwC,OAAW,KR/CtB,IQkDzB9D,EAAQC,MACX2C,EAAAA,CAAAA,ERrD0B,GQqDT5C,EAAQC,KAEzBwC,EAAoB,CADpBE,EAASJ,EAAQwB,IAAQ/D,EAAQ+D,GAAAA,IAI7BjB,EAAMZ,EAAO8B,MAASlB,EAAIP,CAAAA,EAE/B0B,EAAO,GAAsB,OAAXJ,IAAW,WAC5B,GAAA,CAkEC,GAhEIR,EAAWd,EAAS2B,MAClBZ,EACL,cAAeO,IAAWA,GAAQM,UAAUC,OAKzCb,GADJT,EAAMe,GAAQQ,cACQ7B,EAAcM,EAAGwB,GAAAA,EACnCd,EAAmBV,EACpBS,EACCA,EAASW,MAAM5D,MACfwC,EAAGyB,GACJ/B,EAGCxC,EAAQsE,IAEXlB,GADAL,EAAIR,EAAQ+B,IAActE,EAAQsE,KACNC,GAAwBxB,EAACyB,KAGjDlB,EAEHf,EAAQ+B,IAAcvB,EAAI,IAAIc,GAAQR,EAAUG,CAAAA,GAGhDjB,EAAQ+B,IAAcvB,EAAI,IAAI0B,GAC7BpB,EACAG,CAAAA,EAEDT,EAAEe,YAAcD,GAChBd,EAAEqB,OAASM,IAERnB,GAAUA,EAASoB,IAAI5B,CAAAA,EAE3BA,EAAEmB,MAAQb,EACLN,EAAE6B,QAAO7B,EAAE6B,MAAQ,CAAE,GAC1B7B,EAAE8B,QAAUrB,EACZT,EAAC+B,IAAkBtC,EACnBQ,EAAQD,EAACgC,IAAAA,GACThC,EAACiC,IAAoB,CAAA,EACrBjC,EAACkC,IAAmB,CAAA,GAIjB3B,GAAoBP,EAACmC,KAAe,OACvCnC,EAACmC,IAAcnC,EAAE6B,OAGdtB,GAAoBO,GAAQsB,0BAA4B,OACvDpC,EAACmC,KAAenC,EAAE6B,QACrB7B,EAACmC,IAAcE,GAAO,CAAA,EAAIrC,EAACmC,GAAAA,GAG5BE,GACCrC,EAACmC,IACDrB,GAAQsB,yBAAyB9B,EAAUN,EAACmC,GAAAA,CAAAA,GAI9CjC,EAAWF,EAAEmB,MACbhB,EAAWH,EAAE6B,MACb7B,EAACsC,IAAU9C,EAGPS,EAEFM,GACAO,GAAQsB,0BAA4B,MACpCpC,EAAEuC,oBAAsB,MAExBvC,EAAEuC,mBAAAA,EAGChC,GAAoBP,EAAEwC,mBAAqB,MAC9CxC,EAACiC,IAAkBQ,KAAKzC,EAAEwC,iBAAAA,MAErB,CAUN,GARCjC,GACAO,GAAQsB,0BAA4B,MACpC9B,IAAaJ,GACbF,EAAE0C,2BAA6B,MAE/B1C,EAAE0C,0BAA0BpC,EAAUG,CAAAA,EAAAA,CAIrCT,EAACgB,MACAhB,EAAE2C,uBAAyB,MAC5B3C,EAAE2C,sBACDrC,EACAN,EAACmC,IACD1B,CAAAA,IAJEkC,IAMHnD,EAAQ8C,MAAerF,EAAQqF,KAC/B,CAkBD,IAhBI9C,EAAQ8C,MAAerF,EAAQqF,MAKlCtC,EAAEmB,MAAQb,EACVN,EAAE6B,MAAQ7B,EAACmC,IACXnC,EAACgC,IAAAA,IAGFxC,EAAQwB,IAAQ/D,EAAQ+D,IACxBxB,EAAQoD,IAAa3F,EAAQ2F,IAC7BpD,EAAQoD,IAAWC,KAAK,SAAAC,GAAAA,CACnBA,KAAOA,GAAKtB,GAAWhC,EAC5B,CAAA,EAESkB,GAAI,EAAGA,GAAIV,EAACkC,IAAiB9E,OAAQsD,KAC7CV,EAACiC,IAAkBQ,KAAKzC,EAACkC,IAAiBxB,EAAAA,CAAAA,EAE3CV,EAACkC,IAAmB,CAAA,EAEhBlC,EAACiC,IAAkB7E,QACtBuC,EAAY8C,KAAKzC,CAAAA,EAGlB,MAAMkB,CACP,CAEIlB,EAAE+C,qBAAuB,MAC5B/C,EAAE+C,oBAAoBzC,EAAUN,EAACmC,IAAa1B,CAAAA,EAG3CF,GAAoBP,EAAEgD,oBAAsB,MAC/ChD,EAACiC,IAAkBQ,KAAK,UAAA,CACvBzC,EAAEgD,mBAAmB9C,EAAUC,EAAUC,EAAAA,CAC1C,CAAA,CAEF,CASA,GAPAJ,EAAE8B,QAAUrB,EACZT,EAAEmB,MAAQb,EACVN,EAACiD,IAAc1D,EACfS,EAACgB,IAAAA,GAEGL,GAAaxB,EAAO+D,IACvBtC,GAAQ,EACLL,EAAkB,CAQrB,IAPAP,EAAE6B,MAAQ7B,EAACmC,IACXnC,EAACgC,IAAAA,GAEGrB,IAAYA,GAAWnB,CAAAA,EAE3BO,EAAMC,EAAEqB,OAAOrB,EAAEmB,MAAOnB,EAAE6B,MAAO7B,EAAE8B,OAAAA,EAE1BpB,GAAI,EAAGA,GAAIV,EAACkC,IAAiB9E,OAAQsD,KAC7CV,EAACiC,IAAkBQ,KAAKzC,EAACkC,IAAiBxB,EAAAA,CAAAA,EAE3CV,EAACkC,IAAmB,CAAA,CACrB,KACC,IACClC,EAACgC,IAAAA,GACGrB,IAAYA,GAAWnB,CAAAA,EAE3BO,EAAMC,EAAEqB,OAAOrB,EAAEmB,MAAOnB,EAAE6B,MAAO7B,EAAE8B,OAAAA,EAGnC9B,EAAE6B,MAAQ7B,EAACmC,UACHnC,EAACgC,KAAAA,EAAapB,GAAQ,IAIhCZ,EAAE6B,MAAQ7B,EAACmC,IAEPnC,EAAEmD,iBAAmB,OACxB1D,EAAgB4C,GAAOA,GAAO,CAAA,EAAI5C,CAAAA,EAAgBO,EAAEmD,gBAAAA,CAAAA,GAGjD5C,GAAAA,CAAqBN,GAASD,EAAEoD,yBAA2B,OAC9DhD,GAAWJ,EAAEoD,wBAAwBlD,EAAUC,CAAAA,GAOhDkD,GACC9D,EACA+D,GAJGzC,EADHd,GAAO,MAAQA,EAAIjD,OAASK,IAAY4C,EAAIlD,KAAO,KACZkD,EAAIoB,MAAMoC,SAAWxD,CAAAA,EAIpCc,EAAe,CAACA,CAAAA,EACxCrB,EACAvC,EACAwC,EACA3B,EACA4B,EACAC,EACAC,EACAC,EACAC,CAAAA,EAGDE,EAAEwD,KAAOhE,EAAQwB,IAGjBxB,EAAQtC,KAAAA,KAEJ8C,EAACiC,IAAkB7E,QACtBuC,EAAY8C,KAAKzC,CAAAA,EAGdK,IACHL,EAACyB,IAAiBzB,EAACwB,GAAwB,KAoB7C,OAlBS5C,GAAAA,CAGR,GAFAY,EAAQ8C,IAAa,KAEjBzC,GAAeH,GAAqB,KAAM,CAK7C,IAJAF,EAAQtC,KAAW2C,EAChB4D,IRlRuB,IQqRnB7D,GAAUA,EAAO8D,WAAa,GAAK9D,EAAO+D,aAChD/D,EAASA,EAAO+D,YAEjBjE,EAAkBA,EAAkBkE,QAAQhE,CAAAA,CAAAA,EAAW,KACvDJ,EAAQwB,IAAQpB,CACjB,MACCJ,EAAQwB,IAAQ/D,EAAQ+D,IACxBxB,EAAQoD,IAAa3F,EAAQ2F,IAE9BzD,EAAO6B,IAAapC,GAAGY,EAAUvC,CAAAA,CAClC,MAEAyC,GAAqB,MACrBF,EAAQ8C,MAAerF,EAAQqF,KAE/B9C,EAAQoD,IAAa3F,EAAQ2F,IAC7BpD,EAAQwB,IAAQ/D,EAAQ+D,KAExBxB,EAAQwB,IAAQ6C,GACf5G,EAAQ+D,IACRxB,EACAvC,EACAwC,EACA3B,EACA4B,EACAC,EACAE,EACAC,CAAAA,GAIGC,EAAMZ,EAAQ2E,SAAS/D,EAAIP,CAAAA,CACjC,CAOO,SAASuE,GAAWpE,EAAaqE,EAAMlE,EAAAA,CAC7CkE,EAAIhC,IAAAA,OAEJ,QAAStB,EAAI,EAAGA,EAAIZ,EAAS1C,OAAQsD,IACpCuD,GAASnE,EAASY,CAAAA,EAAIZ,EAAAA,EAAWY,CAAAA,EAAIZ,EAAAA,EAAWY,CAAAA,CAAAA,EAG7CvB,EAAOoC,KAAUpC,EAAOoC,IAASyC,EAAMrE,CAAAA,EAE3CA,EAAYkD,KAAK,SAAA7C,EAAAA,CAChB,GAAA,CAECL,EAAcK,EAACiC,IACfjC,EAACiC,IAAoB,CAAA,EACrBtC,EAAYkD,KAAK,SAAAqB,EAAAA,CAEhBA,EAAGC,KAAKnE,CAAAA,CACT,CAAA,CAGD,OAFSpB,EAAAA,CACRO,EAAO6B,IAAapC,EAAGoB,EAACsC,GAAAA,CACzB,CACD,CAAA,CACD,CAiBA,SAASuB,GACRlG,EACA6B,EACAvC,EACAwC,EACA3B,EACA4B,EACAC,EACAE,EACAC,EAAAA,CATD,IAeKY,EAEA0D,EAEAC,EAEAC,EACA/G,EACAgH,EACAC,GAbAtE,EAAWjD,EAASkE,MACpBb,EAAWd,EAAS2B,MACpBuC,EAAkClE,EAAS1C,KAmB/C,GALI4G,IAAa,MAAO5F,EAAY,6BAC3B4F,IAAa,OACrB5F,EAAY,qCACHA,IAAWA,EAAY,gCAE7B4B,GAAqB,MACxB,IAAKgB,EAAI,EAAGA,EAAIhB,EAAkBtC,OAAQsD,IAMzC,IALAnD,EAAQmC,EAAkBgB,CAAAA,IAOzB,iBAAkBnD,GAAAA,CAAAA,CAAYmG,IAC7BA,EAAWnG,EAAMkH,YAAcf,EAAWnG,EAAMmG,WAAa,GAC7D,CACD/F,EAAMJ,EACNmC,EAAkBgB,CAAAA,EAAK,KACvB,KACD,EAIF,GAAI/C,GAAO,KAAM,CAChB,GAAI+F,IAAa,KAChB,OAAOgB,SAASC,eAAerE,CAAAA,EAGhC3C,EAAM+G,SAASE,gBACd9G,EACA4F,EACApD,EAASuE,IAAMvE,CAAAA,EAKZT,IACCV,EAAO2F,KACV3F,EAAO2F,IAAoBtF,EAAUE,CAAAA,EACtCG,EAAAA,IAGDH,EAAoB,IACrB,CAEA,GAAIgE,IAAa,KAEZxD,IAAaI,GAAcT,GAAelC,EAAIoH,OAASzE,IAC1D3C,EAAIoH,KAAOzE,OAEN,CASN,GAPAZ,EAAoBA,GAAqBtB,GAAM+F,KAAKxG,EAAIqH,UAAAA,EAExD9E,EAAWjD,EAASkE,OAAS8D,GAAAA,CAKxBpF,GAAeH,GAAqB,KAExC,IADAQ,EAAW,CAAE,EACRQ,EAAI,EAAGA,EAAI/C,EAAIuH,WAAW9H,OAAQsD,IAEtCR,GADA3C,EAAQI,EAAIuH,WAAWxE,CAAAA,GACR9C,IAAAA,EAAQL,EAAMA,MAI/B,IAAKmD,KAAKR,EAET,GADA3C,EAAQ2C,EAASQ,CAAAA,EACbA,GAAK,YAALA,GACOA,GAAK,0BACf2D,EAAU9G,UACJ,EAAMmD,KAAKJ,GAAW,CAC5B,GACEI,GAAK,SAAW,iBAAkBJ,GAClCI,GAAK,WAAa,mBAAoBJ,EAEvC,SAED9C,GAAYG,EAAK+C,EAAG,KAAMnD,EAAOO,CAAAA,CAClC,EAKD,IAAK4C,KAAKJ,EACT/C,EAAQ+C,EAASI,CAAAA,EACbA,GAAK,WACR4D,EAAc/G,EACJmD,GAAK,0BACf0D,EAAU7G,EACAmD,GAAK,QACf6D,EAAahH,EACHmD,GAAK,UACf8D,GAAUjH,EAERsC,GAA+B,OAATtC,GAAS,YACjC2C,EAASQ,CAAAA,IAAOnD,GAEhBC,GAAYG,EAAK+C,EAAGnD,EAAO2C,EAASQ,CAAAA,EAAI5C,CAAAA,EAK1C,GAAIsG,EAGDvE,GACCwE,IACAD,EAAOe,SAAYd,EAAOc,QAC1Bf,EAAOe,SAAYxH,EAAIyH,aAEzBzH,EAAIyH,UAAYhB,EAAOe,QAGxB3F,EAAQoD,IAAa,CAAA,UAEjByB,IAAS1G,EAAIyH,UAAY,IAE7B/B,GACC1F,EACA2F,GAAQgB,CAAAA,EAAeA,EAAc,CAACA,CAAAA,EACtC9E,EACAvC,EACAwC,EACAiE,IAAa,gBACV,+BACA5F,EACH4B,EACAC,EACAD,EACGA,EAAkB,CAAA,EAClBzC,EAAQ2F,KAAcyC,GAAcpI,EAAU,CAAA,EACjD4C,EACAC,CAAAA,EAIGJ,GAAqB,KACxB,IAAKgB,EAAIhB,EAAkBtC,OAAQsD,KAClC4E,GAAW5F,EAAkBgB,CAAAA,CAAAA,EAM3Bb,IACJa,EAAI,QACAgD,IAAa,YAAca,GAAc,KAC5C5G,EAAIkB,gBAAgB,OAAA,EAEpB0F,IAFoB,SAOnBA,IAAe5G,EAAI+C,CAAAA,GAClBgD,IAAa,YAAbA,CAA4Ba,GAI5Bb,IAAa,UAAYa,IAAerE,EAASQ,CAAAA,IAEnDlD,GAAYG,EAAK+C,EAAG6D,EAAYrE,EAASQ,CAAAA,EAAI5C,CAAAA,EAG9C4C,EAAI,UACA8D,KADA,QACyBA,KAAY7G,EAAI+C,CAAAA,GAC5ClD,GAAYG,EAAK+C,EAAG8D,GAAStE,EAASQ,CAAAA,EAAI5C,CAAAA,EAG7C,CAEA,OAAOH,CACR,CAQgB,SAAAsG,GAASsB,EAAKhI,EAAOuF,EAAAA,CACpC,GAAA,CACC,GAAkB,OAAPyC,GAAO,WAAY,CAC7B,IAAIC,EAAuC,OAAhBD,EAAGrI,KAAa,WACvCsI,GAEHD,EAAGrI,IAAAA,EAGCsI,GAAiBjI,GAAS,OAI9BgI,EAAGrI,IAAYqI,EAAIhI,CAAAA,EAErB,MAAOgI,EAAIE,QAAUlI,CAGtB,OAFSqB,EAAAA,CACRO,EAAO6B,IAAapC,EAAGkE,CAAAA,CACxB,CACD,CASgB,SAAA4C,GAAQ5C,EAAO6C,EAAaC,EAAAA,CAA5B,IACXC,EAsBMnF,EAbV,GARIvB,EAAQuG,SAASvG,EAAQuG,QAAQ5C,CAAAA,GAEhC+C,EAAI/C,EAAMyC,OACTM,EAAEJ,SAAWI,EAAEJ,UAAY3C,EAAK9B,KACpCiD,GAAS4B,EAAG,KAAMF,CAAAA,IAIfE,EAAI/C,EAAKvB,MAAgB,KAAM,CACnC,GAAIsE,EAAEC,qBACL,GAAA,CACCD,EAAEC,qBAAAA,CAGH,OAFSlH,EAAAA,CACRO,EAAO6B,IAAapC,EAAG+G,CAAAA,CACxB,CAGDE,EAAErC,KAAOqC,EAAC5C,IAAc,IACzB,CAEA,GAAK4C,EAAI/C,EAAKF,IACb,IAASlC,EAAI,EAAGA,EAAImF,EAAEzI,OAAQsD,IACzBmF,EAAEnF,CAAAA,GACLgF,GACCG,EAAEnF,CAAAA,EACFiF,EACAC,GAAmC,OAAd9C,EAAMhG,MAAQ,UAARA,EAM1B8I,GACJN,GAAWxC,EAAK9B,GAAAA,EAKjB8B,EAAKvB,IAAcuB,EAAKtB,GAAWsB,EAAK9B,IAAQ8B,EAAKd,IAAAA,MACtD,CAGA,SAASL,GAASR,EAAOU,EAAOC,EAAAA,CAC/B,OAAO9C,KAAK+B,YAAYI,EAAOW,CAAAA,CAChC,CAAA,SCrnBgBT,GAAOyB,EAAOvD,EAAWwG,EAAAA,CAAAA,IAMpClG,EAOA5C,EAQA0C,EACHG,EArBGX,EAAOqC,IAAQrC,EAAOqC,GAAOsB,EAAOvD,CAAAA,EAYpCtC,GAPA4C,EAAoC,OAAfkG,GAAe,YAQrC,KACCA,GAAeA,EAAWnD,KAAerD,EAASqD,IAMlDjD,EAAc,CAAA,EACjBG,EAAW,CAAA,EACZR,GACCC,EAPDuD,GAAAA,CAAWjD,GAAekG,GAAgBxG,GAASqD,IAClDoD,GAAc7I,GAAU,KAAM,CAAC2F,CAAAA,CAAAA,EAU/B7F,GAAYgI,GACZA,GACA1F,EAAU0G,aAAAA,CACTpG,GAAekG,EACb,CAACA,CAAAA,EACD9I,EACC,KACAsC,EAAU2G,WACT9H,GAAM+F,KAAK5E,EAAUyF,UAAAA,EACrB,KACLrF,EAAAA,CACCE,GAAekG,EACbA,EACA9I,EACCA,EAAQ+D,IACRzB,EAAU2G,WACdrG,EACAC,CAAAA,EAIDiE,GAAWpE,EAAamD,EAAOhD,CAAAA,CAChC,CRpCaqG,GAAQC,GAAUD,MChBzBE,EAAU,CACfC,ISHe,SAAYC,EAAOC,EAAOC,EAAUC,EAAAA,CAQnD,QANIC,EAEHC,EAEAC,EAEOL,EAAQA,EAAKM,IACpB,IAAKH,EAAYH,EAAKO,MAAAA,CAAiBJ,EAASG,GAC/C,GAAA,CAcC,IAbAF,EAAOD,EAAUK,cAELJ,EAAKK,0BAA4B,OAC5CN,EAAUO,SAASN,EAAKK,yBAAyBV,CAAAA,CAAAA,EACjDM,EAAUF,EAASQ,KAGhBR,EAAUS,mBAAqB,OAClCT,EAAUS,kBAAkBb,EAAOG,GAAa,CAAE,CAAA,EAClDG,EAAUF,EAASQ,KAIhBN,EACH,OAAQF,EAASU,IAAiBV,CAIpC,OAFSW,EAAAA,CACRf,EAAQe,CACT,CAIF,MAAMf,CACP,CAAA,ERvCIgB,GAAU,EAgGDC,GAAiB,SAAAhB,EAAAA,CAAK,OAClCA,GAAS,MAAQA,EAAMQ,aHzFCS,IGyFuB,EC1EhDC,GAAcC,UAAUT,SAAW,SAAUU,EAAQC,EAAAA,CAEpD,IAAIC,EAEHA,EADGC,KAAIC,KAAe,MAAQD,KAAIC,MAAgBD,KAAKE,MACnDF,KAAIC,IAEJD,KAAIC,IAAcE,GAAO,CAAE,EAAEH,KAAKE,KAAAA,EAGlB,OAAVL,GAAU,aAGpBA,EAASA,EAAOM,GAAO,CAAA,EAAIJ,CAAAA,EAAIC,KAAKI,KAAAA,GAGjCP,GACHM,GAAOJ,EAAGF,CAAAA,EAIPA,GAAU,MAEVG,KAAIK,MACHP,GACHE,KAAIM,IAAiBC,KAAKT,CAAAA,EAE3BU,GAAcR,IAAAA,EAEhB,EAQAL,GAAcC,UAAUa,YAAc,SAAUX,EAAAA,CAC3CE,KAAIK,MAIPL,KAAIzB,IAAAA,GACAuB,GAAUE,KAAIU,IAAkBH,KAAKT,CAAAA,EACzCU,GAAcR,IAAAA,EAEhB,EAYAL,GAAcC,UAAUe,OAASC,GA8F7BC,GAAgB,CAAA,EAadC,GACa,OAAXC,SAAW,WACfA,QAAQnB,UAAUoB,KAAKC,KAAKF,QAAQG,QAAAA,CAAAA,EACpCC,WAuBEC,GAAY,SAACC,EAAGC,EAAAA,CAAM,OAAAD,EAAChB,IAAAkB,IAAiBD,EAACjB,IAAAkB,GAAc,EAuB7DC,GAAOC,IAAkB,ECtNrBC,GAAa,EAoJXC,GAAaC,GAAAA,EAAiB,EAC9BC,GAAoBD,GAAAA,EAAiB,EC7KhCE,GAAI,EMCf,IAAIC,GAGAC,GAGAC,GAmBAC,GAhBAC,GAAc,EAGdC,GAAoB,CAAA,EAGlBC,GAAuDC,EAEzDC,GAAgBF,GAAOG,IACvBC,GAAkBJ,GAAOK,IACzBC,GAAeN,GAAQO,OACvBC,GAAYR,GAAOS,IACnBC,GAAmBV,GAAQW,QAC3BC,GAAUZ,GAAOa,GA8GrB,SAASC,GAAaC,EAAOC,EAAAA,CACxBhB,GAAOiB,KACVjB,GAAOiB,IAAOtB,GAAkBoB,EAAOjB,IAAekB,CAAAA,EAEvDlB,GAAc,EAOd,IAAMoB,EACLvB,GAAgBwB,MACfxB,GAAgBwB,IAAW,CAC3BN,GAAO,CAAA,EACPI,IAAiB,CAAA,CAAA,GAOnB,OAJIF,GAASG,EAAKL,GAAOO,QACxBF,EAAKL,GAAOQ,KAAK,CAAA,CAAA,EAGXH,EAAKL,GAAOE,CAAAA,CACpB,CAOgB,SAAAO,GAASC,EAAAA,CAExB,OADAzB,GAAc,EACP0B,GAAWC,GAAgBF,CAAAA,CACnC,CAUO,SAASC,GAAWE,EAASH,EAAcI,EAAAA,CAEjD,IAAMC,EAAYd,GAAapB,KAAgB,CAAA,EAE/C,GADAkC,EAAUC,EAAWH,EAAAA,CAChBE,EAASnB,MACbmB,EAASf,GAAU,CACjBc,EAAiDA,EAAKJ,CAAAA,EAA/CE,GAAAA,OAA0BF,CAAAA,EAElC,SAAAO,EAAAA,CACC,IAAMC,EAAeH,EAASI,IAC3BJ,EAASI,IAAY,CAAA,EACrBJ,EAASf,GAAQ,CAAA,EACdoB,EAAYL,EAAUC,EAASE,EAAcD,CAAAA,EAE/CC,IAAiBE,IACpBL,EAASI,IAAc,CAACC,EAAWL,EAASf,GAAQ,CAAA,CAAA,EACpDe,EAASnB,IAAYyB,SAAS,CAAA,CAAA,EAEhC,CAAA,EAGDN,EAASnB,IAAcd,GAAAA,CAElBA,GAAiBwC,GAAkB,CAAA,IAgC9BC,EAAT,SAAyBC,EAAGC,EAAGC,EAAAA,CAC9B,GAAA,CAAKX,EAASnB,IAAAU,IAAqB,MAAA,GAGnC,IACMqB,EACLZ,EAASnB,IAAAU,IAAAN,GAA0B4B,OAFhB,SAAAC,EAAAA,CAAK,MAAA,CAAA,CAAEA,EAACjC,GAAW,CAAA,EAOvC,GAHsB+B,EAAWG,MAAM,SAAAD,EAAAA,CAAK,MAAA,CAACA,EAACV,GAAW,CAAA,EAIxD,MAAA,CAAOY,GAAUA,EAAQC,KAAKC,KAAMT,EAAGC,EAAGC,CAAAA,EAM3C,IAAIQ,EAAenB,EAASnB,IAAYuC,QAAUX,EAUlD,OATAG,EAAWS,QAAQ,SAAAC,EAAAA,CAClB,GAAIA,EAAQlB,IAAa,CACxB,IAAMD,EAAemB,EAAQrC,GAAQ,CAAA,EACrCqC,EAAQrC,GAAUqC,EAAQlB,IAC1BkB,EAAQlB,IAAAA,OACJD,IAAiBmB,EAAQrC,GAAQ,CAAA,IAAIkC,EAAAA,GAC1C,CACD,CAAA,EAEOH,GACJA,EAAQC,KAAKC,KAAMT,EAAGC,EAAGC,CAAAA,GACzBQ,CACJ,EA9DApD,GAAiBwC,EAAAA,GACjB,IAAIS,EAAUjD,GAAiBwD,sBACzBC,EAAUzD,GAAiB0D,oBAKjC1D,GAAiB0D,oBAAsB,SAAUhB,EAAGC,EAAGC,EAAAA,CACtD,GAAIO,KAAIQ,IAAS,CAChB,IAAIC,EAAMX,EAEVA,EAAAA,OACAR,EAAgBC,EAAGC,EAAGC,CAAAA,EACtBK,EAAUW,CACX,CAEIH,GAASA,EAAQP,KAAKC,KAAMT,EAAGC,EAAGC,CAAAA,CACvC,EA+CA5C,GAAiBwD,sBAAwBf,CAC1C,CAGD,OAAOR,EAASI,KAAeJ,EAASf,EACzC,CAOgB,SAAA2C,GAAUC,EAAUC,EAAAA,CAEnC,IAAMC,EAAQ7C,GAAapB,KAAgB,CAAA,EAAA,CACtCM,GAAO4D,KAAiBC,GAAYF,EAAKxC,IAAQuC,CAAAA,IACrDC,EAAK9C,GAAU4C,EACfE,EAAMG,EAAeJ,EAErB/D,GAAgBwB,IAAAF,IAAyBI,KAAKsC,CAAAA,EAEhD,CAmBgB,SAAAI,GAAOC,EAAAA,CAEtB,OADAC,GAAc,EACPC,GAAQ,UAAA,CAAA,MAAO,CAAEC,QAASH,CAAAA,CAAc,EAAG,CAAA,CAAA,CACnD,CA8BO,SAASI,GAAQC,EAASC,EAAAA,CAEhC,IAAMC,EAAQC,GAAaC,KAAgB,CAAA,EAO3C,OANIC,GAAYH,EAAKI,IAAQL,CAAAA,IAC5BC,EAAKK,GAAUP,EAAAA,EACfE,EAAKI,IAASL,EACdC,EAAKM,IAAYR,GAGXE,EAAKK,EACb,CAOgB,SAAAE,GAAYC,EAAUT,EAAAA,CAErC,OADAU,GAAc,EACPZ,GAAQ,UAAA,CAAM,OAAAW,CAAQ,EAAET,CAAAA,CAChC,CAkFA,SAASW,IAAAA,CAER,QADIC,EACIA,EAAYC,GAAkBC,MAAAA,GACrC,GAAKF,EAASG,KAAgBH,EAASI,IACvC,GAAA,CACCJ,EAASI,IAAAC,IAAyBC,QAAQC,EAAAA,EAC1CP,EAASI,IAAAC,IAAyBC,QAAQE,EAAAA,EAC1CR,EAASI,IAAAC,IAA2B,CAAA,CAIrC,OAHSI,EAAAA,CACRT,EAASI,IAAAC,IAA2B,CAAA,EACpCK,GAAOC,IAAaF,EAAGT,EAASY,GAAAA,CACjC,CAEF,CAvaAF,GAAOG,IAAS,SAAAC,EAAAA,CACfC,GAAmB,KACfC,IAAeA,GAAcF,CAAAA,CAClC,EAEAJ,GAAOO,GAAS,SAACH,EAAOI,EAAAA,CACnBJ,GAASI,EAASC,KAAcD,EAASC,IAAAC,MAC5CN,EAAKM,IAASF,EAASC,IAAAC,KAGpBC,IAASA,GAAQP,EAAOI,CAAAA,CAC7B,EAGAR,GAAOY,IAAW,SAAAR,EAAAA,CACbS,IAAiBA,GAAgBT,CAAAA,EAGrCU,GAAe,EAEf,IAAMC,GAHNV,GAAmBD,EAAKY,KAGMtB,IAC1BqB,IACCE,KAAsBZ,IACzBU,EAAKpB,IAAmB,CAAA,EACxBU,GAAgBV,IAAoB,CAAA,EACpCoB,EAAKR,GAAOX,QAAQ,SAAAsB,EAAAA,CACfA,EAAQC,MACXD,EAAQX,GAAUW,EAAQC,KAE3BD,EAASE,EAAeF,EAAQC,IAAAA,MACjC,CAAA,IAEAJ,EAAKpB,IAAiBC,QAAQC,EAAAA,EAC9BkB,EAAKpB,IAAiBC,QAAQE,EAAAA,EAC9BiB,EAAKpB,IAAmB,CAAA,EACxBmB,GAAe,IAGjBG,GAAoBZ,EACrB,EAGAL,GAAQqB,OAAS,SAAAjB,EAAAA,CACZkB,IAAcA,GAAalB,CAAAA,EAE/B,IAAMmB,EAAInB,EAAKY,IACXO,GAAKA,EAAC7B,MACL6B,EAAC7B,IAAAC,IAAyB6B,SAAmBjC,GAAkBkC,KAAKF,CAAAA,IA6ZlD,GAAKG,KAAY1B,GAAQ2B,yBAC/CD,GAAU1B,GAAQ2B,wBACNC,IAAgBvC,EAAAA,GA9Z5BkC,EAAC7B,IAAAa,GAAeX,QAAQ,SAAAsB,EAAAA,CACnBA,EAASE,IACZF,EAAQxB,IAASwB,EAASE,GAE3BF,EAASE,EAAAA,MACV,CAAA,GAEDH,GAAoBZ,GAAmB,IACxC,EAIAL,GAAOgB,IAAW,SAACZ,EAAOyB,EAAAA,CACzBA,EAAYC,KAAK,SAAAxC,EAAAA,CAChB,GAAA,CACCA,EAASK,IAAkBC,QAAQC,EAAAA,EACnCP,EAASK,IAAoBL,EAASK,IAAkBoC,OAAO,SAAAC,EAAAA,CAC9D,MAAA,CAAAA,EAAEzB,IAAUT,GAAakC,CAAAA,CAAU,CAAA,CAQrC,OANSjC,EAAAA,CACR8B,EAAYC,KAAK,SAAAP,EAAAA,CACZA,EAAC5B,MAAmB4B,EAAC5B,IAAoB,CAAA,EAC9C,CAAA,EACAkC,EAAc,CAAA,EACd7B,GAAOC,IAAaF,EAAGT,EAASY,GAAAA,CACjC,CACD,CAAA,EAEI+B,IAAWA,GAAU7B,EAAOyB,CAAAA,CACjC,EAGA7B,GAAQkC,QAAU,SAAA9B,EAAAA,CACb+B,IAAkBA,GAAiB/B,CAAAA,EAEvC,IAEKgC,EAFCb,EAAInB,EAAKY,IACXO,GAAKA,EAAC7B,MAET6B,EAAC7B,IAAAa,GAAeX,QAAQ,SAAAyC,EAAAA,CACvB,GAAA,CACCxC,GAAcwC,CAAAA,CAGf,OAFStC,EAAAA,CACRqC,EAAarC,CACd,CACD,CAAA,EACAwB,EAAC7B,IAAAA,OACG0C,GAAYpC,GAAOC,IAAamC,EAAYb,EAACrB,GAAAA,EAEnD,EAyUA,IAAIoC,GAA0C,OAAzBX,uBAAyB,WAY9C,SAASC,GAAeW,EAAAA,CACvB,IAOIC,EAPEC,EAAO,UAAA,CACZC,aAAaC,CAAAA,EACTL,IAASM,qBAAqBJ,CAAAA,EAClCK,WAAWN,CAAAA,CACZ,EACMI,EAAUE,WAAWJ,EA/bR,GAAA,EAkcfH,KACHE,EAAMb,sBAAsBc,CAAAA,EAE9B,CAqBA,SAAS5C,GAAciD,EAAAA,CAGtB,IAAMC,EAAO1C,GACT2C,EAAUF,EAAI9B,IACI,OAAXgC,GAAW,aACrBF,EAAI9B,IAAAA,OACJgC,EAAAA,GAGD3C,GAAmB0C,CACpB,CAOA,SAASjD,GAAagD,EAAAA,CAGrB,IAAMC,EAAO1C,GACbyC,EAAI9B,IAAY8B,EAAIvC,GAAAA,EACpBF,GAAmB0C,CACpB,CAOA,SAASE,GAAYC,EAASC,EAAAA,CAC7B,MAAA,CACED,GACDA,EAAQ1B,SAAW2B,EAAQ3B,QAC3B2B,EAAQrB,KAAK,SAACsB,EAAKC,EAAAA,CAAU,OAAAD,IAAQF,EAAQG,CAAAA,CAAM,CAAA,CAErD,CAQA,SAASC,GAAeF,EAAKG,EAAAA,CAC5B,OAAmB,OAALA,GAAK,WAAaA,EAAEH,CAAAA,EAAOG,CAC1C,CErhBO,ICXHC,GAAU,EAERC,GAAUC,MAAMD,QAsBtB,SAASE,EAAYC,EAAMC,EAAOC,EAAKC,EAAkBC,EAAUC,EAAAA,CAC7DJ,IAAOA,EAAQ,CAAA,GAIpB,IACCK,EACAC,EAFGC,EAAkBP,EAIlB,QAASA,IACZK,EAAML,EAAMK,IAAAA,OACLL,EAAMK,KAId,IAAMG,EAAQ,CACbT,KAAAA,EACAC,MAAOO,EACPN,IAAAA,EACAI,IAAAA,EACAI,IAAW,KACXC,GAAS,KACTC,IAAQ,EACRC,IAAM,KACNC,IAAAA,OACAC,IAAY,KACZC,YAAAA,OACAC,IAAAA,EAAarB,GACbsB,IAAAA,GACAC,IAAQ,EACRf,SAAAA,EACAC,OAAAA,CAAAA,EAKD,GAAoB,OAATL,GAAS,aAAeM,EAAMN,EAAKoB,cAC7C,IAAKb,KAAKD,EACEE,EAAgBD,CAAAA,IADlBD,SAERE,EAAgBD,CAAAA,EAAKD,EAAIC,CAAAA,GAK5B,OADIc,EAAQZ,OAAOY,EAAQZ,MAAMA,CAAAA,EAC1BA,CACR,CCvEO,IAAMa,GAAW,IACtBC,EAAC,OAAI,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,eAAa,IAAI,iBAAe,QAAQ,kBAAgB,QACjH,SAAAA,EAAC,QAAK,EAAE,gEAAgE,EAC1E,EAGWC,GAAQ,IACnBD,EAAC,OAAI,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,eAAa,IAAI,iBAAe,QAAQ,kBAAgB,QACjH,UAAAA,EAAC,QAAK,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EACpCA,EAAC,QAAK,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GACtC,EAGWE,GAAgB,IAC3BF,EAAC,OAAI,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,eAAa,IAAI,iBAAe,QAAQ,kBAAgB,QACjH,UAAAA,EAAC,QAAK,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,EACrCA,EAAC,YAAS,OAAO,kBAAkB,GACrC,EAGWG,GAAW,IACtBH,EAAC,OAAI,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,eAAa,IAAI,iBAAe,QAAQ,kBAAgB,QACjH,UAAAA,EAAC,QAAK,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,EACrCA,EAAC,WAAQ,OAAO,4BAA4B,GAC9C,EAGWI,GAAW,IACtBJ,EAAC,OAAI,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,eAAa,IAAI,iBAAe,QAAQ,kBAAgB,QACjH,UAAAA,EAAC,QAAK,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,EACrCA,EAAC,QAAK,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GACvC,EAGWK,GAAgB,IAC3BL,EAAC,OAAI,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,eAAa,IAAI,iBAAe,QAAQ,kBAAgB,QACjH,SAAAA,EAAC,QAAK,EAAE,oHAAoH,EAC9H,EAGWM,GAAe,IAC1BN,EAAC,OAAI,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,eAAa,IAAI,iBAAe,QAAQ,kBAAgB,QACjH,UAAAA,EAAC,QAAK,EAAE,4CAA4C,EACpDA,EAAC,YAAS,OAAO,mBAAmB,EACpCA,EAAC,QAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GACvC,EAGWO,GAAW,IACtBP,EAAC,OAAI,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,eAAa,IAAI,iBAAe,QAAQ,kBAAgB,QACjH,UAAAA,EAAC,QAAK,EAAE,6DAA6D,EACrEA,EAAC,YAAS,OAAO,iBAAiB,GACpC,EC3CK,SAASQ,GAAW,CACzB,OAAAC,EACA,SAAAC,EACA,YAAAC,EACA,QAAAC,CACF,EAAoB,CAIlB,OACEC,EAAC,UACC,MAAO,aAJTH,IAAa,cAAgB,kBAAoB,kBAInB,GAC5B,QAASE,EACT,aAAYH,EAAS,aAAe,YAEnC,UAAAA,EAASI,EAACC,GAAA,EAAM,EAAKD,EAACE,GAAA,EAAS,EAC/B,CAACN,GAAUE,EAAc,GACxBE,EAAC,QAAK,MAAM,mBACT,SAAAF,EAAc,GAAK,MAAQA,EAC9B,GAEJ,CAEJ,CCnBO,SAASK,GAAiB,CAC/B,cAAAC,EACA,YAAAC,EACA,QAAAC,EACA,SAAAC,EACA,MAAAC,EACA,EAAAC,CACF,EAA0B,CACxB,IAAMC,EAAUN,EAAc,KAAMO,GAAMA,EAAE,IAAI,EAC1CC,EAAYP,EAAY,OAAO,wBAErC,OAAIC,EAEAO,EAAC,OAAI,MAAM,aACT,SAAAA,EAAC,OAAI,MAAM,aAAa,EAC1B,EAKFA,EAAC,OAAI,MAAM,cACR,WAACH,GACAG,EAAC,OAAI,MAAM,mBACT,SAAAA,EAAC,UAAO,MAAM,uBAAuB,QAASL,EAC5C,UAAAK,EAACC,GAAA,EAAS,EACTL,EAAE,cAAc,iBACnB,EACF,EAGFI,EAAC,OAAI,MAAM,qBACR,SAAAT,EAAc,SAAW,EACxBS,EAAC,OAAI,MAAM,qBAAsB,SAAAJ,EAAE,cAAc,MAAM,EAEvDL,EAAc,IAAKW,GAAS,CAC1B,IAAMC,EAAcD,EAAK,MAAQH,EAEjC,OACEC,EAAC,UAEC,MAAM,oBACN,QAAS,IAAMG,GAAeT,EAASQ,CAAI,EAC3C,SAAU,CAACC,EAEX,UAAAH,EAAC,OAAI,MAAM,wBACT,UAAAA,EAAC,QAAK,MAAM,0BACT,SAAAR,EAAY,KACf,EACAQ,EAAC,QACC,MAAO,4BAA4BE,EAAK,KAAO,iCAAmC,kCAAkC,GAEnH,SAAAA,EAAK,KAAON,EAAE,cAAc,KAAOA,EAAE,cAAc,OACtD,GACF,EACAI,EAAC,QAAK,MAAM,4BACT,SAAAE,EAAK,aAAa,SAAWN,EAAE,cAAc,WAChD,IAjBKM,EAAK,EAkBZ,CAEJ,CAAC,EAEL,GACF,CAEJ,CCtDO,SAASE,GAAa,CAC3B,MAAAC,EACA,SAAAC,EACA,OAAAC,EACA,aAAAC,EACA,aAAAC,EACA,aAAAC,EACA,UAAAC,EACA,SAAAC,EACA,YAAAC,EACA,EAAAC,CACF,EAAsB,CACpB,IAAMC,EAAcC,GAA4B,IAAI,EAC9CC,EAAeD,GAAyB,IAAI,EAE5CE,EAAgBC,GACnBC,GAAqB,CAChBA,EAAE,MAAQ,SAAW,CAACA,EAAE,WAC1BA,EAAE,eAAe,EACjBb,EAAO,EAEX,EACA,CAACA,CAAM,CACT,EAEMc,EAAcF,GACjBC,GAAa,CACZ,IAAME,EAASF,EAAE,OACjBd,EAASgB,EAAO,KAAK,EACrBA,EAAO,MAAM,OAAS,OACtBA,EAAO,MAAM,OAAS,GAAG,KAAK,IAAIA,EAAO,aAAc,GAAG,CAAC,IAC7D,EACA,CAAChB,CAAQ,CACX,EAEMiB,EAAoBJ,GAAY,IAAM,CAC1CF,EAAa,SAAS,MAAM,CAC9B,EAAG,CAAC,CAAC,EAECO,GAAmBL,GACtBC,GAAa,CACZ,IAAMK,EAAQL,EAAE,OACVM,EAAOD,EAAM,QAAQ,CAAC,EACxBC,GACFlB,EAAakB,CAAI,EAEnBD,EAAM,MAAQ,EAChB,EACA,CAACjB,CAAY,CACf,EAEMmB,EAAUjB,GAAc,KAAK,KAAK,WAAW,QAAQ,EACrDkB,GAAWvB,EAAM,KAAK,GAAKK,IAAiB,CAACE,GAAY,CAACD,EAEhE,OACEkB,EAAC,OAAI,MAAM,cACR,UAAAnB,GACCmB,EAAC,OAAI,MAAM,uBACR,UAAAF,GAAWjB,EAAa,QACvBmB,EAAC,OACC,IAAKnB,EAAa,QAClB,IAAKA,EAAa,KAAK,KACvB,MAAM,6BACR,EAEAmB,EAAC,OAAI,MAAM,4BACT,SAAAA,EAACC,GAAA,EAAS,EACZ,EAEFD,EAAC,OAAI,MAAM,4BACT,UAAAA,EAAC,OAAI,MAAM,4BACR,SAAAnB,EAAa,KAAK,KACrB,EACAmB,EAAC,OAAI,MAAM,8BACR,SAAAlB,EAAYG,EAAE,KAAK,UAAYiB,GAAWrB,EAAa,KAAK,IAAI,EACnE,GACF,EACC,CAACC,GACAkB,EAAC,UACC,MAAM,8BACN,QAASpB,EACT,aAAW,cAEX,SAAAoB,EAACG,GAAA,EAAM,EACT,GAEJ,EAGFH,EAAC,OAAI,MAAM,mBACT,UAAAA,EAAC,UACC,MAAM,sBACN,QAASN,EACT,SAAUX,GAAYD,GAAa,CAAC,CAACD,EACrC,aAAYI,EAAE,KAAK,WAEnB,SAAAe,EAACI,GAAA,EAAc,EACjB,EAEAJ,EAAC,YACC,IAAKd,EACL,MAAM,qBACN,MAAOV,EACP,QAASgB,EACT,UAAWH,EACX,YAAaL,GAAeC,EAAE,KAAK,YACnC,SAAUF,EACV,KAAM,EACR,EAEAiB,EAAC,UACC,MAAM,oBACN,QAAStB,EACT,SAAU,CAACqB,EACX,aAAW,eAEX,SAAAC,EAACK,GAAA,EAAS,EACZ,GACF,EAEAL,EAAC,SACC,KAAK,OACL,IAAKZ,EACL,SAAUO,GACV,MAAO,CAAE,QAAS,MAAO,EACzB,OAAO,4DACT,GACF,CAEJ,CAEA,SAASO,GAAWI,EAAuB,CACzC,OAAIA,EAAQ,KAAa,GAAGA,CAAK,KAC7BA,EAAQ,KAAO,KAAa,IAAIA,EAAQ,MAAM,QAAQ,CAAC,CAAC,MACrD,IAAIA,GAAS,KAAO,OAAO,QAAQ,CAAC,CAAC,KAC9C,CCpJO,SAASC,GAAc,CAAE,IAAAC,EAAK,IAAAC,EAAK,QAAAC,CAAQ,EAAuB,CACvE,IAAMC,EAAgBC,GACnBC,GAAqB,CAChBA,EAAE,MAAQ,UAAUH,EAAQ,CAClC,EACA,CAACA,CAAO,CACV,EAEA,OAAAI,GAAU,KACR,SAAS,iBAAiB,UAAWH,CAAa,EAC3C,IAAM,SAAS,oBAAoB,UAAWA,CAAa,GACjE,CAACA,CAAa,CAAC,EAGhBI,EAAC,OAAI,MAAM,cAAc,QAASL,EAChC,UAAAK,EAAC,UAAO,MAAM,qBAAqB,QAASL,EAC1C,SAAAK,EAACC,GAAA,EAAM,EACT,EACAD,EAAC,OACC,IAAKP,EACL,IAAKC,GAAO,GACZ,MAAM,mBACN,QAAUI,GAAMA,EAAE,gBAAgB,EACpC,GACF,CAEJ,CC1BO,SAASI,GAAa,CAAE,MAAAC,EAAO,aAAAC,EAAc,EAAAC,CAAE,EAAsB,CAC1E,IAAMC,GAAYH,EAAM,UAAY,IAAI,YAAY,EAEpD,GAAIG,EAAS,WAAW,QAAQ,GAAKH,EAAM,OAAS,QAAS,CAC3D,IAAMI,EAAWJ,EAAM,eAAe,OAASA,EAAM,IAC/CK,EAAUL,EAAM,eAAe,OAASA,EAAM,IACpD,OACEM,EAAC,OACC,IAAKF,EACL,IAAKJ,EAAM,KACX,MAAM,eACN,QAAS,IAAMC,EAAaI,CAAO,EACrC,CAEJ,CAEA,OAAIF,EAAS,WAAW,QAAQ,EAE5BG,EAAC,SAAM,SAAQ,GAAC,MAAM,iBAAiB,QAAQ,WAC7C,SAAAA,EAAC,UAAO,IAAKN,EAAM,IAAK,KAAMG,EAAU,EAC1C,EAKFG,EAAC,KACC,KAAMN,EAAM,IACZ,OAAO,SACP,IAAI,sBACJ,MAAM,gBACN,SAAUA,EAAM,KAEhB,UAAAM,EAAC,OAAI,MAAM,sBACT,SAAAA,EAACC,GAAA,EAAS,EACZ,EACAD,EAAC,QAAK,MAAM,sBAAuB,SAAAN,EAAM,KAAK,EAC9CM,EAAC,QAAK,MAAM,0BACV,SAAAA,EAACE,GAAA,EAAa,EAChB,GACF,CAEJ,CCtCO,SAASC,GAAY,CAAE,SAAAC,EAAU,QAAAC,EAAS,EAAAC,CAAE,EAAqB,CACtE,IAAMC,EAASC,GAAuB,IAAI,EACpC,CAACC,EAAaC,CAAc,EAAIC,GAAwB,IAAI,EAMlE,OAJAC,GAAU,IAAM,CACdL,EAAO,SAAS,eAAe,CAAE,SAAU,QAAS,CAAC,CACvD,EAAG,CAACH,CAAQ,CAAC,EAETC,EAEAQ,EAAC,OAAI,MAAM,aACT,SAAAA,EAAC,OAAI,MAAM,aAAa,EAC1B,EAKFA,EAAC,OAAI,MAAM,cACR,UAAAT,EAAS,IAAKU,GACbD,EAACE,GAAA,CAEC,QAASD,EACT,aAAcJ,EACd,EAAGJ,GAHEQ,EAAI,EAIX,CACD,EACDD,EAAC,OAAI,IAAKN,EAAQ,EACjBE,GACCI,EAACG,GAAA,CACC,IAAKP,EACL,QAAS,IAAMC,EAAe,IAAI,EACpC,GAEJ,CAEJ,CAEA,SAASK,GAAc,CACrB,QAAAE,EACA,aAAAC,EACA,EAAAZ,CACF,EAIG,CACD,IAAMa,EAAWF,EAAQ,OAAS,SAC5BG,EAAMD,EAAW,wBAA0B,uBAE3CE,EAAO,IAAI,KAAKJ,EAAQ,SAAS,EAAE,mBAAmB,CAAC,EAAG,CAC9D,KAAM,UACN,OAAQ,SACV,CAAC,EAED,OACEJ,EAAC,OAAI,MAAOO,EACT,WAACD,GACAN,EAAC,OAAI,MAAM,iBACR,SAAAI,EAAQ,MAAM,QAAQ,IACrBJ,EAAC,OACC,IAAKI,EAAQ,KAAK,OAAO,IACzB,IAAKA,EAAQ,KAAK,WAAa,QACjC,GAECA,EAAQ,MAAM,YAAY,CAAC,GAAK,KAAK,YAAY,EAEtD,EAEFJ,EAAC,OAAI,MAAM,eACR,UAAAI,EAAQ,OACPJ,EAACS,GAAA,CACC,MAAOL,EAAQ,MACf,aAAcC,EACd,EAAGZ,EACL,EAEDW,EAAQ,SACPJ,EAAC,OAAI,MAAM,kBAAmB,SAAAI,EAAQ,QAAQ,EAEhDJ,EAAC,OAAI,MAAM,eAAgB,SAAAQ,EAAK,GAClC,GACF,CAEJ,CCpFO,SAASE,GAAY,CAC1B,YAAAC,EACA,SAAAC,EACA,QAAAC,EACA,EAAAC,CACF,EAAqB,CACnB,GAAM,CAACC,EAAMC,CAAO,EAAIC,GAAS,EAAE,EAC7B,CAACC,EAAOC,CAAQ,EAAIF,GAAS,EAAE,EAE/B,CAAE,YAAAG,EAAa,aAAAC,EAAc,iBAAAC,CAAiB,EAAIX,EAAY,OAE9DY,EAAgBC,GAAa,CACjCA,EAAE,eAAe,EACjBZ,EAAS,CACP,KAAMG,EAAK,KAAK,GAAK,OACrB,MAAOG,EAAM,KAAK,GAAK,MACzB,CAAC,CACH,EAEMO,GACH,CAACL,GAAeL,EAAK,KAAK,KAAO,CAACM,GAAgBH,EAAM,KAAK,GAEhE,OACEQ,EAAC,QAAK,MAAM,aAAa,SAAUH,EACjC,UAAAG,EAAC,OAAI,MAAM,oBAAqB,SAAAZ,EAAE,QAAQ,MAAM,EAChDY,EAAC,OAAI,MAAM,mBAAoB,SAAAZ,EAAE,QAAQ,YAAY,EAEpDM,GACCM,EAAC,OAAI,MAAM,oBACT,UAAAA,EAAC,SAAM,MAAM,oBAAqB,SAAAZ,EAAE,QAAQ,KAAK,EACjDY,EAAC,SACC,MAAM,oBACN,KAAK,OACL,MAAOX,EACP,QAAUS,GAAMR,EAASQ,EAAE,OAA4B,KAAK,EAC5D,YAAaV,EAAE,QAAQ,gBACvB,SAAQ,GACV,GACF,EAGDO,GACCK,EAAC,OAAI,MAAM,oBACT,UAAAA,EAAC,SAAM,MAAM,oBAAqB,SAAAZ,EAAE,QAAQ,MAAM,EAClDY,EAAC,SACC,MAAM,oBACN,KAAK,QACL,MAAOR,EACP,QAAUM,GAAML,EAAUK,EAAE,OAA4B,KAAK,EAC7D,YAAaV,EAAE,QAAQ,iBACvB,SAAQ,GACV,GACF,EAGFY,EAAC,UACC,MAAM,qBACN,KAAK,SACL,SAAU,CAACD,GAAWZ,EAErB,SAAAA,EAAUC,EAAE,QAAQ,QAAUA,EAAE,QAAQ,MAC3C,EAECQ,GACCI,EAAC,OAAI,MAAM,sBACR,UAAAZ,EAAE,QAAQ,cAAe,IAC1BY,EAAC,KAAE,KAAMJ,EAAkB,OAAO,SAAS,IAAI,sBAC5C,SAAAR,EAAE,QAAQ,YACb,GACF,GAEJ,CAEJ,CClDO,SAASa,GAAW,CACzB,YAAAC,EACA,UAAAC,EACA,eAAAC,EACA,QAAAC,EACA,OAAAC,EACA,QAAAC,EACA,gBAAAC,EACA,SAAAC,EACA,QAAAC,EACA,EAAAC,EACA,sBAAAC,CACF,EAAoB,CAClB,GAAM,CAACC,EAAMC,CAAO,EAAIC,GAAe,MAAM,EACvC,CAACC,EAAcC,CAAe,EAAIF,GAA8B,IAAI,EACpE,CAACG,GAAeC,CAAgB,EAAIJ,GAAyB,CAAC,CAAC,EAC/D,CAACK,EAAUC,CAAW,EAAIN,GAAoB,CAAC,CAAC,EAChD,CAACO,EAAYC,CAAa,EAAIR,GAAS,EAAE,EACzC,CAACS,GAASC,EAAU,EAAIV,GAAS,EAAI,EACrC,CAACW,GAASC,EAAU,EAAIZ,GAAS,EAAK,EACtC,CAACa,EAAcC,EAAe,EAAId,GAA8B,IAAI,EACpE,CAACe,GAAgBC,CAAiB,EAAIhB,GAAwB,IAAI,EAClE,CAACiB,GAAWC,EAAY,EAAIlB,GAAS,EAAK,EAE1CmB,EAASlB,GAAc,OAAS,GAEhCmB,GAAmBjC,EAAY,OAAO,kBAAoBM,EAGhE4B,GAAU,MACK,SAAY,CACvBX,GAAW,EAAI,EACf,GAAI,CACF,GAAIU,GAAkB,CAEpB,IAAME,EAAQ,MAAMlC,EAAU,wBAAwB,EAGtD,GAFAgB,EAAiBkB,CAAK,EAElBzB,EAAuB,CACzB,IAAM0B,EAAOD,EAAM,KAAME,IAAMA,GAAE,KAAO3B,CAAqB,EAC7D,GAAI0B,EAAM,CACR,MAAME,GAAiBF,CAAI,EAC3B,MACF,CACF,CAEID,EAAM,OAAS,EACjBvB,EAAQ,eAAe,EAEnB2B,GAAa,EACf3B,EAAQ,SAAS,EAEjB,MAAM4B,GAAqB,CAGjC,KAAO,CAEL,IAAMC,EACJ/B,GAAyBP,EAAQ,kBAAkB,EAErD,GAAIsC,EACF,GAAI,CACF,IAAMC,EAAO,MAAMzC,EAAU,YAAYwC,EAAU,CAAE,MAAO,EAAG,CAAC,EAChEtB,EAAY,MAAM,QAAQuB,CAAI,EAAIA,EAAK,QAAQ,EAAI,CAAC,CAAC,EACrD3B,EAAgB,CAAE,GAAI0B,EAAU,KAAM,EAAK,CAAiB,EAC5D7B,EAAQ,MAAM,EACd+B,GAAgBF,CAAQ,CAC1B,MAAQ,CACNtC,EAAQ,MAAM,EACVoC,GAAa,EACf3B,EAAQ,SAAS,EAEjB,MAAM4B,GAAqB,CAE/B,MAEID,GAAa,EACf3B,EAAQ,SAAS,EAEjB,MAAM4B,GAAqB,CAGjC,CACF,OAASI,EAAG,CACV,QAAQ,MAAM,uCAAwCA,CAAC,CACzD,QAAE,CACArB,GAAW,EAAK,CAClB,CACF,GAEK,EAEE,IAAM,CACXrB,EAAe,YAAY,CAC7B,GACC,CAAC,CAAC,EAEL,IAAMqC,GAAeM,GAAY,IAC3BxC,GAAS,MAAQA,GAAS,MAAc,GAE1CL,EAAY,OAAO,aAAeA,EAAY,OAAO,aAEtD,CAACA,EAAaK,CAAO,CAAC,EAEnBsC,GAAkBE,GACrBC,GAAmB,CAClB5C,EAAe,UAAU4C,EAAQ,CAC/B,UAAYC,GAAQ,CAClB5B,EAAa6B,GACPA,EAAK,KAAMC,IAAMA,GAAE,KAAOF,EAAI,EAAE,EAC3BC,EAAK,IAAKC,IACfA,GAAE,KAAOF,EAAI,GAAK,CAAE,GAAGE,GAAG,GAAGF,CAAI,EAAIE,EACvC,EAOK,CAAC,GALYD,EAAK,OACtBC,IACC,CAAC,OAAOA,GAAE,EAAE,EAAE,WAAW,OAAO,GAChCA,GAAE,UAAYF,EAAI,OACtB,EACwBA,CAAG,CAC5B,EACD3C,EAAO,KAAK,mBAAoB2C,CAAG,CACrC,EACA,2BAA6BX,GAAS,CACpCrB,EAAiBiC,GACfA,GAAO,CAAE,GAAGA,EAAM,KAAMZ,EAAK,IAAK,CACpC,EACKA,EAAK,MACRhC,EAAO,KAAK,sBAAuBgC,CAAI,CAE3C,CACF,CAAC,CACH,EACA,CAAClC,EAAgBE,CAAM,CACzB,EAEMkC,GAAmBO,GACvB,MAAOT,GAAuB,CAC5Bb,GAAW,EAAI,EACf,GAAI,CACF,IAAMmB,EAAO,MAAMzC,EAAU,YAAYmC,EAAK,GAAI,CAAE,MAAO,EAAG,CAAC,EAC/DjB,EAAY,MAAM,QAAQuB,CAAI,EAAIA,EAAK,QAAQ,EAAI,CAAC,CAAC,EACrD3B,EAAgBqB,CAAI,EACpBxB,EAAQ,MAAM,EACdT,EAAQ,kBAAkBiC,EAAK,EAAE,EACjCO,GAAgBP,EAAK,EAAE,CACzB,OAASQ,EAAG,CACV,QAAQ,MAAM,+CAAgDA,CAAC,CACjE,QAAE,CACArB,GAAW,EAAK,CAClB,CACF,EACA,CAACtB,EAAWE,EAASwC,EAAe,CACtC,EAEMH,GAAuBK,GAAY,SAAY,CACnDtB,GAAW,EAAI,EACf,GAAI,CACF,IAAM2B,EAAS,MAAMjD,EAAU,iBAAiB,CAC9C,KAAMI,GAAS,KACf,MAAOA,GAAS,KAClB,CAAC,EACDU,EAAgBmC,CAAM,EACtB/B,EAAY+B,EAAO,UAAY,CAAC,CAAC,EACjCtC,EAAQ,MAAM,EACdT,EAAQ,kBAAkB+C,EAAO,EAAE,EACnCP,GAAgBO,EAAO,EAAE,EACzB9C,EAAO,KAAK,uBAAwB8C,CAAM,CAC5C,OAASN,EAAG,CACV,QAAQ,MAAM,gDAAiDA,CAAC,CAClE,QAAE,CACArB,GAAW,EAAK,CAClB,CACF,EAAG,CAACtB,EAAWI,EAASF,EAASwC,GAAiBvC,CAAM,CAAC,EAEnD+C,GAAsBN,GAC1B,MAAOO,GAA4C,CACjDjD,EAAQ,WAAW,CAAE,GAAGE,EAAS,GAAG+C,CAAK,CAAC,EAC1C,IAAMF,EAAS,MAAMjD,EAAU,iBAAiBmD,CAAI,EACpDrC,EAAgBmC,CAAM,EACtB/B,EAAY+B,EAAO,UAAY,CAAC,CAAC,EACjCtC,EAAQ,MAAM,EACdT,EAAQ,kBAAkB+C,EAAO,EAAE,EACnCP,GAAgBO,EAAO,EAAE,EACzB9C,EAAO,KAAK,uBAAwB8C,CAAM,CAC5C,EACA,CAACjD,EAAWI,EAASF,EAASwC,GAAiBvC,CAAM,CACvD,EAEMiD,GAAmBR,GACvB,MAAOS,GAAe,CACpB,GAAI,CAACxC,EAAc,OAEnB,IAAMyC,EAAW,GAAK,KAAO,KAC7B,GAAID,EAAK,KAAOC,EAAU,CACxB,QAAQ,KAAK,iCAAiC,EAC9C,MACF,CAEA,IAAMC,EAAUF,EAAK,KAAK,WAAW,QAAQ,EACzC,IAAI,gBAAgBA,CAAI,EACxB,OAEJ3B,GAAgB,CAAE,KAAA2B,EAAM,QAAAE,CAAQ,CAAC,EACjCzB,GAAa,EAAI,EAEjB,GAAI,CACF,IAAM0B,GAAW,MAAMxD,EAAU,WAAWa,EAAa,GAAIwC,CAAI,EACjEzB,EAAkB4B,GAAS,EAAE,CAC/B,OAASb,GAAG,CACV,QAAQ,MAAM,yCAA0CA,EAAC,EACzDjB,GAAgB,IAAI,EAChB6B,GAAS,IAAI,gBAAgBA,CAAO,CAC1C,QAAE,CACAzB,GAAa,EAAK,CACpB,CACF,EACA,CAAC9B,EAAWa,CAAY,CAC1B,EAEM4C,GAAmBb,GAAY,IAAM,CACrCnB,GAAc,SAAS,IAAI,gBAAgBA,EAAa,OAAO,EACnEC,GAAgB,IAAI,EACpBE,EAAkB,IAAI,CACxB,EAAG,CAACH,CAAY,CAAC,EAEXiC,GAAad,GAAY,SAAY,CACzC,IAAMe,EAAUxC,EAAW,KAAK,EAChC,GAAK,CAACwC,GAAW,CAAChC,IAAmB,CAACd,GAAgBU,GAAS,OAE/D,IAAMqC,EAAS,QAAQ,KAAK,IAAI,CAAC,GAC3BC,EAAsB,CAC1B,GAAID,EACJ,QAAAD,EACA,KAAM,SACN,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,UAAW,IAAI,KAAK,EAAE,YAAY,CACpC,EAEMG,GAAUnC,IAAkB,OAElCP,EAAc,EAAE,EAChBM,GAAgB,IAAI,EACpBE,EAAkB,IAAI,EACtBJ,GAAW,EAAI,EACfN,EAAa6B,IAAS,CAAC,GAAGA,GAAMc,CAAU,CAAC,EAE3C,GAAI,CACF,IAAMf,GAAM,MAAM9C,EAAU,YAAYa,EAAa,GAAI,CACvD,QAAS8C,GAAW,OACpB,QAAAG,EACF,CAAC,EACD5C,EAAa6B,IAASA,GAAK,IAAKC,IAAOA,GAAE,KAAOY,EAASd,GAAME,EAAE,CAAC,EAClE7C,EAAO,KAAK,eAAgB2C,EAAG,CACjC,OAASH,GAAG,CACV,QAAQ,MAAM,0CAA2CA,EAAC,EAC1DzB,EAAa6B,IAASA,GAAK,OAAQC,IAAMA,GAAE,KAAOY,CAAM,CAAC,EACzDxC,EAAcuC,CAAO,CACvB,QAAE,CACAnC,GAAW,EAAK,CAClB,CACF,EAAG,CAACL,EAAYQ,GAAgBd,EAAcU,GAASvB,EAAWG,CAAM,CAAC,EAEnE4D,GAAenB,GAAY,SAAY,CAC3C,GAAK/B,EACL,GAAI,CACF,IAAMmD,EAAU,MAAMhE,EAAU,mBAAmBa,EAAa,EAAE,EAClEC,EAAiBiC,GAASA,GAAO,CAAE,GAAGA,EAAM,KAAMiB,EAAQ,MAAQ,EAAK,CAAQ,CACjF,OAASrB,EAAG,CACV,QAAQ,MAAM,iDAAkDA,CAAC,CACnE,CACF,EAAG,CAAC9B,EAAcb,CAAS,CAAC,EAEtBiE,GAAarB,GAAY,IAAM,CAC/BZ,IAAoBtB,IAAS,QAC/BT,EAAe,YAAY,EAC3BU,EAAQ,eAAe,EACvBG,EAAgB,IAAI,EACpBI,EAAY,CAAC,CAAC,EACdlB,EAAU,wBAAwB,EAAE,KAAKgB,CAAgB,EAAE,MAAM,IAAM,CAAC,CAAC,GAEzET,EAAQ,CAEZ,EAAG,CAACyB,GAAkBtB,EAAMT,EAAgBD,EAAWO,CAAO,CAAC,EAEzD2D,GACJ5D,IAAa,cAAgB,kBAAoB,mBAE7C6D,GACJzD,IAAS,gBACLF,EAAE,cAAc,MAChBT,EAAY,KAEZqE,GACHpC,IAAoBtB,IAAS,QAAWA,IAAS,UAEpD,OACE2D,EAAC,OAAI,MAAO,aAAaH,EAAQ,GAE/B,UAAAG,EAAC,OAAI,MAAM,YACT,UAAAA,EAAC,OAAI,MAAM,mBACR,UAAAD,IACCC,EAAC,UAAO,MAAM,kBAAkB,QAASJ,GACvC,SAAAI,EAACC,GAAA,EAAc,EACjB,EAEDH,IACH,EACAE,EAAC,UAAO,MAAM,mBAAmB,QAAS9D,EACxC,SAAA8D,EAACE,GAAA,EAAM,EACT,GACF,EAGClD,IAAWX,IAAS,OACnB2D,EAAC,OAAI,MAAM,aACT,SAAAA,EAAC,OAAI,MAAM,aAAa,EAC1B,EAEAA,EAAAG,GAAA,CACG,UAAA9D,IAAS,WACR2D,EAACI,GAAA,CACC,YAAa1E,EACb,SAAUmD,GACV,QAAS7B,GACT,EAAGb,EACL,EAGDE,IAAS,iBACR2D,EAACK,GAAA,CACC,cAAe3D,GACf,YAAahB,EACb,QAASsB,GACT,SAAUgB,GACV,MACEC,GAAa,EACT,IAAM3B,EAAQ,SAAS,EACvB4B,GAEN,EAAG/B,EACL,EAGDE,IAAS,QACR2D,EAAAG,GAAA,CACE,UAAAH,EAACM,GAAA,CAAY,SAAU1D,EAAU,QAASI,GAAS,EAAGb,EAAG,EACxDuB,EACCsC,EAACO,GAAA,CACC,MAAOzD,EACP,SAAUC,EACV,OAAQsC,GACR,aAAcN,GACd,aAAcK,GACd,aAAchC,EACd,UAAWI,GACX,SAAUN,IAAWF,GACrB,YAAab,EAAE,KAAK,YACpB,EAAGA,EACL,EAEA6D,EAAC,OAAI,MAAM,mBACT,UAAAA,EAAC,QAAK,MAAM,yBAA0B,SAAA7D,EAAE,KAAK,OAAO,EACnDT,EAAY,OAAO,yBAClBsE,EAAC,UAAO,MAAM,2BAA2B,QAASN,GAC/C,SAAAvD,EAAE,KAAK,OACV,GAEJ,EAEDT,EAAY,OAAO,kBAClBsE,EAAC,OAAI,MAAM,oBACT,SAAAA,EAAC,KACC,KAAMtE,EAAY,OAAO,iBACzB,OAAO,SACP,IAAI,sBAEH,SAAAS,EAAE,QAAQ,YACb,EACF,GAEJ,GAEJ,GAEJ,CAEJ,CC3YO,SAASqE,GAAI,CAClB,YAAAC,EACA,UAAAC,EACA,eAAAC,EACA,QAAAC,EACA,OAAAC,EACA,QAAAC,EACA,gBAAAC,EACA,SAAAC,EACA,OAAAC,EACA,EAAAC,EACA,UAAAC,EACA,UAAAC,CACF,EAAa,CACX,GAAM,CAACC,EAAQC,CAAc,EAAIC,GAASJ,EAAU,OAAO,EACrD,CAACK,EAAUC,EAAW,EAAIF,GAASN,CAAM,EACzC,CAACS,CAAW,EAAIH,GAAS,CAAC,EAGhC,OAAAI,GAAU,IAAM,CACd,IAAMC,EAAS,IAAM,CACnBN,EAAe,EAAI,EACnBH,EAAU,QAAU,GACpBC,EAAU,EAAI,CAChB,EACMS,EAAU,IAAM,CACpBP,EAAe,EAAK,EACpBH,EAAU,QAAU,GACpBC,EAAU,EAAK,CACjB,EACMU,GAAS,IAAML,GAAY,EAAK,EAChCM,GAAS,IAAM,CACnBN,GAAY,EAAI,EAChBH,EAAe,EAAK,EACpBH,EAAU,QAAU,GACpBC,EAAU,EAAK,CACjB,EAEA,OAAAP,EAAO,GAAG,QAASe,CAAM,EACzBf,EAAO,GAAG,SAAUgB,CAAO,EAC3BhB,EAAO,GAAG,OAAQiB,EAAM,EACxBjB,EAAO,GAAG,OAAQkB,EAAM,EAEjB,IAAM,CACXlB,EAAO,IAAI,QAASe,CAAM,EAC1Bf,EAAO,IAAI,SAAUgB,CAAO,EAC5BhB,EAAO,IAAI,OAAQiB,EAAM,EACzBjB,EAAO,IAAI,OAAQkB,EAAM,CAC3B,CACF,EAAG,CAAClB,EAAQM,EAAWC,CAAS,CAAC,EAkB/BY,EAAAC,GAAA,CACG,WAACT,GACAQ,EAACE,GAAA,CACC,OAAQb,EACR,SAAUL,EACV,YAAaU,EACb,QAtBa,IAAM,CACzB,IAAMS,EAAO,CAACd,EACdC,EAAea,CAAI,EACnBhB,EAAU,QAAUgB,EACpBf,EAAUe,CAAI,EACdtB,EAAO,KAAKsB,EAAO,OAAS,OAAO,CACrC,EAiBM,EAEDd,GACCW,EAACI,GAAA,CACC,YAAa3B,EACb,UAAWC,EACX,eAAgBC,EAChB,QAASC,EACT,OAAQC,EACR,QAASC,EACT,gBAAiBC,EACjB,SAAUC,EACV,QA3BY,IAAM,CACxBM,EAAe,EAAK,EACpBH,EAAU,QAAU,GACpBC,EAAU,EAAK,EACfP,EAAO,KAAK,OAAO,CACrB,EAuBQ,EAAGK,EACL,GAEJ,CAEJ,CCvHA,IAAOmB,GAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":["web_exports","__export","ErrorInfo","DefaultRealtime","DefaultRest","web_default","msgpack_default","fromDeserializedIncludingDependencies","module","__toCommonJS","Platform","globalObject","pad","timeSegment","three","getHandler","logger","msg","time","getDefaultLoggers","_a","consoleLogger","errorLogger","args","_Logger","description","level","handler","logHandler","logErrorHandler","action","message","oldName","newName","className","Logger","logger_default","utils_exports","Format","allSame","allToLowerCase","allToUpperCase","arrChooseN","arrDeleteValue","arrEquals","arrIntersect","arrIntersectOb","arrPopRandomElement","arrSubtract","arrWithoutValue","cheapRandStr","containsValue","copy","createMissingPluginError","dataSizeBytes","decodeBody","encodeBody","ensureArray","forInOwnNonNullProperties","getBackoffCoefficient","getGlobalObject","getJitterCoefficient","getRetryTime","inherits","inspectBody","inspectError","intersect","isEmpty","isErrorInfoOrPartialErrorInfo","isNil","isObject","keysArray","matchDerivedChannel","mixin","parseQueryString","prototypicalClone","randomString","shallowClone","shallowEquals","throwMissingPluginError","toBase64","toQueryString","valuesArray","whenPromiseSettles","withTimeoutAsync","toString","err","result","_ErrorInfo","code","statusCode","cause","values","PartialErrorInfo","_PartialErrorInfo","randomPosn","arrOrStr","target","i","source","key","src","obj","ob","prop","arg","ownProperties","F","ctor","superCtor","val","arr","arr1","arr2","member","element","idx","res","newArr","ownOnly","fn","first","item","params","parts","query","match","search","_b","body","data","numBytes","buffer","n","numItems","mutableArr","promise","callback","MsgPack","format","count","initialTimeout","retryAttempt","name","regex","str","bufferUtils","textBuffer","a","b","pluginName","timeout","e","_resolve","reject","version","agent","Defaults","getHost","getPort","getHttpScheme","environmentFallbackHosts","getFallbackHosts","getHosts","checkHost","objectifyOptions","normaliseOptions","defaultGetHeaders","defaultPostHeaders","options","host","ws","tls","environment","fallbackHosts","httpMaxRetryCount","hosts","getRealtimeHost","production","getTimeouts","timeouts","getAgentString","agentStr","allowKeyOrToken","sourceForErrorMessage","modularPluginsToInclude","optionsObj","__spreadProps","__spreadValues","loggerToUse","restHost","realtimeHost","headers","connectivityCheckParams","connectivityCheckUrl","uri","qs","wsConnectivityCheckUrl","normaliseChannelOptions","Crypto","channelOptions","cipher","contentTypes","defaultHeadersOptions","protocolVersion","contentType","defaults_default","getDefaults","platformDefaults","Multicaster","_Multicaster","members","resolve","instance","multicaster_default","HttpMethods","HttpMethods_default","HttpStatusCodes","isSuccessCode","HttpStatusCodes_default","MAX_TOKEN_LENGTH","random","isRealtime","client","normaliseAuthcallbackError","hmac","text","keyBuffer","digest","c14n","capability","c14nCapability","keys","logAndValidateTokenAuthMethod","authOptions","basicAuthForced","useTokenAuth","noWayToRenew","trId","getTokenRequestId","Auth","tokenParams","tokenDetails","resolvedAuthOptions","resolvedTokenParams","tokenRequestCallback","cb","authHeaders","usePost","providedQsParams","queryIdx","authParams","authUrlRequestCallback","contentTypeHeaderOrHeaders","json","tokenRequest","signedTokenParams","tokenCb","keyName","path","tokenUri","requestHeaders","tokenRequestCallbackTimeoutExpired","timeoutLength","tokenRequestCallbackTimeout","tokenRequestOrDetails","objectSize","tokenResponse","unpacked","keyParts","keySecret","request","clientId","ttl","nonce","timestamp","signText","queryTime","forceSupersede","token","tokenRequestId","caughtError","multicaster","tokenClientId","error","specifiers","auth_default","paramString","paramPairs","needle","appendingParams","logResult","method","logRequest","Http","connection","connectionHost","uriFromHost","currentFallback","tryAHostStartedAt","tryAHost","candidateHosts","persistOnSuccess","BaseClient","_c","_d","_e","_f","_g","_h","normalOptions","keyMatch","customHeaders","specOrSpecs","channels","logOptions","baseclient_default","DeviceDetails","_DeviceDetails","device","devicedetails_default","withAuthDetails","opCallback","unenvelope","wrappedStatusCode","response","wrappedHeaders","wrappedErr","Resource","_Resource","envelope","throwError","doRequest","decodedBody","decodeErr","httpResult","resource_default","getRelParams","linkUrl","urlMatch","parseRelLinks","linkHeader","relParams","linkMatch","returnErrOnly","useHPR","PaginatedResource","bodyHandler","useHttpPaginatedResponse","items","HttpPaginatedResponse","PaginatedResult","resource","self","paginatedresource_default","_PushChannelSubscription","PushChannelSubscription","pushchannelsubscription_default","Push","Admin","registerCallback","updateFailedCallback","deregisterCallback","DeviceRegistrations","ChannelSubscriptions","recipient","payload","requestBody","deviceIdOrDetails","deviceId","_ChannelSubscriptions","subscription","parsedBody","push_default","MessageActionArray","MessageActionMap","index","ReverseMessageActionMap","toMessageActionString","actionNumber","toMessageActionNumber","messageAction","normaliseContext","context","normalizeCipherOptions","getMessageSize","size","fromEncoded","encoded","inputOptions","fromWireProtocol","decode","fromEncodedArray","encodedArray","_fromEncoded","channel","_fromEncodedArray","encrypt","encoding","ciphertext","encode","encodeArray","messages","serialize","inputContext","lastPayload","xforms","lastProcessedEncodingIndex","encodingsToProcess","xform","xformAlgorithm","deltaBase","deltaBaseBuffer","fromValues","Message","fromValuesArray","getMessagesSize","total","message_default","actions","toActionValue","actionString","PresenceMessage","fromData","presencemessage_default","RestPresence","decoded","restpresence_default","MSG_ID_ENTROPY_BYTES","allEmptyIds","RestChannel","second","idempotentRestPublishing","msgIdBase","maxMessageSize","restchannel_default","Stats","_Stats","stats_default","RestChannelMixin","RestPresenceMixin","presence","Rest","Channels","statsValues","timeUri","encoder","decoder","_method","paginatedResource","resbody","requestBodyDTO","singleSpecMode","batchResults","channelsParam","resolvedOptions","specifier","BaseRest","allCommonModularPlugins","DefaultMessage","DefaultPresenceMessage","_DefaultRest","newValue","callListener","eventThis","listener","removeListener","targetListeners","eventFilter","listeners","eventName","targetListenersIndex","EventEmitter","event","firstArg","secondArg","eventsOnceListeners","eventsListeners","argCount","listenerWrapper","innerArgs","targetState","currentState","eventemitter_default","ActionName","flags","flagNames","toStringArray","array","channelModes","deserialize","serialized","presenceMessagePlugin","deserialized","fromDeserialized","m","pm","ProtocolMessage","stringify","simpleAttributes","attribute","attribIndex","stringifiedParams","flag","modes","mode","protocolmessage_default","MessageQueue","serial","startSerial","endSerial","completeMessages","messagequeue_default","PendingMessage","Protocol","transport","messageQueue","pendingMessage","protocol_default","ConnectionStateChange","previous","current","retryIn","reason","connectionstatechange_default","ConnectionErrorCodes","ConnectionErrors","isRetriable","connectionerrors_default","closeMessage","disconnectMessage","Transport","connectionManager","auth","forceJsonProtocol","maxPromisedIdle","id","sinceLast","timeRemaining","transportCtor","transportParams","transportAttemptTimer","errorCb","realtimeRequestTimeout","transport_default","TransportNames","haveWebStorage","haveSessionStorage","noop","transportPreferenceName","bundleWith","dest","maxSize","kind","proposed","decodeRecoveryKey","recoveryKey","TransportParams","connectionKey","recoveryContext","ConnectionManager","_ConnectionManager","realtime","connectingTimeout","addEventListener","additionalImplementations","storage","implementations","transportName","modeCb","recoverFn","lastSessionData","sessionRecoveryName","shouldRecover","candidate","state","connectionId","connectionDetails","existingState","connectedState","existingActiveProtocol","connectedErr","_connectionId","currentProtocol","wasActive","wasPending","noTransportsScheduledForActivation","newConnectionState","hasConnectionError","prevConnId","newError","stateChange","newState","transitionState","interval","connectivity","indicated","retryImmediately","retryDelay","change","autoReconnect","connectCount","connect","authCb","transportPreference","shouldContinue","giveUp","hostAttemptCb","fatal","tryFallbackHosts","activeTransport","authMsg","successListener","failureListener","queueEvent","lastQueued","pendingMessages","numQueued","pendingChannelMessage","pingStart","onHeartbeat","responseId","connectionStateTtl","finished","value","connectionmanager_default","Connection","ably","connection_default","ChannelStateChange","resumed","hasBacklog","channelstatechange_default","validateChannelOptions","currentMode","RealtimeChannel","_RealtimeChannel","restMixin","previousChannelOptions","prevOptions","requestedParams","omitAgent","existingParams","subscriptions","forceReattach","attachReason","attachMsg","l","syncMessage","syncChannelSerial","isSync","modesFromFlags","hasPresence","detachErr","presenceMessages","firstMessage","lastMessage","channelSerial","unrecoverableError","errorInfo","protocolMessage","decodeFn","decodeErrorRecoveryHandler","stateTimer","s","channelParams","_","__objRest","realtimechannel_default","_BaseRealtime","plugins","transports","BaseRealtime","serials","channelSerials","channelName","connectionState","connectionStateToChannelState","fromChannelStates","toChannelState","channelId","deriveOptions","filter","releaseErr","baserealtime_default","newerThan","existing","itemOrderings","existingOrderings","PresenceMap","memberKey","newer","map","existingItem","syncInProgress","inProgress","getClientId","realtimePresence","isAnonymousOrWildcard","waitAttached","RealtimePresence","waitForSync","returnMembers","presenceSet","syncCursor","myMembers","broadcastMessages","connId","pendingPresence","pendingPresCount","presenceArray","entry","_args","realtimepresence_default","shortName","isNodeWebSocket","WebSocketTransport","connectParams","wsUri","paramStr","param","wsConnection","ev","wasClean","websockettransport_default","FilteredSubscriptions","filteredListener","mapping","realListener","realListenerMap","filterMaps","listenerMaps","prev","cur","_DefaultRealtime","uint8Array","uint32Array","pow","DEFAULT_STATE","ROUND_CONSTANTS","M","getFractionalBits","nPrime","isPrime","factor","LittleEndian","convertEndian","word","rightRotate","bits","sha256","STATE","legth","bitLength","newBitLength","bytes","words","round","block","workingState","MRound","gamma0x","gamma1x","t1","t2","tmp","innerKey","outerKey","BufferUtils","base64","encodings","byteLength","byteRemainder","mainLength","c","d","chunk","binary_string","len","ascii","accum","byte","hexEncodedBytes","string","encodedByteArray","buffer1","buffer2","arrayBuffer1","arrayBuffer2","bytes1","bytes2","arrayBufferView","hash","bufferutils_default","createCryptoClass","config","DEFAULT_ALGORITHM","DEFAULT_KEYLENGTH","DEFAULT_MODE","DEFAULT_BLOCKLENGTH","validateCipherParams","normaliseBase64","isCipherParams","CipherParams","algorithm","keyLength","cipherParams","CBCCipher","iv","output","outputView","buffer1View","buffer2View","plaintext","cryptoKey","ciphertextArrayBuffer","ciphertextBody","randomBlock","XHRStates","XHRStates_default","createMissingImplementationError","connectivityUrlIsDefault","requestImplementations","xhrRequestImplementation","fetchRequestImplementation","hasImplementation","req","requestResult","http_default","test","Webstorage","session","wrappedValue","rawItem","webstorage_default","isVercelEdgeRuntime","allowComet","loc","isWebWorkerContext","userAgent","currentUrl","Config","f","byteArray","config_default","shouldBeErrorAction","UNRESOLVABLE_ERROR_CODES","protocolMessageFromRawError","CometTransport","port","cometScheme","connectUri","preconnected","connectRequest","closing","closeOrDisconnectUri","connectionStr","baseConnectionUri","pendingItems","sendRequest","recvRequest","responseData","requestItems","comettransport_default","isAblyError","responseBody","getAblyError","idCounter","pendingRequests","getHeader","xhr","header","isEncodingChunked","getHeadersAsObject","headerPairs","x","XHRRequest","_XHRRequest","requestMode","_timeouts","timer","accept","responseType","h","errorHandler","errorEvent","errorMessage","streaming","successResponse","streamPos","onResponse","onEnd","parsedResponse","jsonResponseBody","onProgress","responseText","bodyEnd","onChunk","onStreamEnd","readyState","xhrrequest_default","XHRPollingTransport","xhrpollingtransport_default","order","defaultTransports","inspect","view","type","byte_","utf8Write","offset","codePoint","utf8Read","length","end","utf8ByteCount","sparse","sizeof","_encode","SH_L_32","SH_R_32","getInt64","getUint64","setInt64","setUint64","Decoder","encodeableKeys","isArray","convertHeaders","fetchRequest","fetchHeaders","controller","timeoutPromise","requestInit","resultPromise","urlParams","preparedURI","defaultBundledRequestImplementations","clientClass","src_exports","__export","BaseportalChat","src_default","ApiClient","channelToken","apiUrl","email","hash","h","method","path","body","res","text","data","conversationId","params","qs","query","file","formData","headers","Ably","RealtimeClient","apiClient","conversationId","handlers","tokenRequest","_data","callback","channelName","msg","data","e","pt","en","es","locales","getTranslations","locale","slice","options","vnodeId","isValidElement","rerenderQueue","prevDebounce","defer","depthSort","eventClock","eventProxy","eventProxyCapture","i","EMPTY_OBJ","EMPTY_ARR","IS_NON_DIMENSIONAL","isArray","Array","assign","obj","props","removeNode","node","parentNode","removeChild","createElement","type","children","key","ref","normalizedProps","arguments","length","call","defaultProps","createVNode","original","vnode","__k","__","__b","__e","__d","__c","constructor","__v","__i","__u","Fragment","props","children","BaseComponent","context","this","getDomSibling","vnode","childIndex","__","__i","sibling","__k","length","__e","type","updateParentDomPointers","i","child","__c","base","enqueueRender","c","__d","rerenderQueue","push","process","__r","prevDebounce","options","debounceRendering","defer","renderQueueLength","component","newVNode","oldVNode","oldDom","commitQueue","refQueue","sort","depthSort","shift","__v","__P","assign","diff","__n","namespaceURI","__u","commitRoot","diffChildren","parentDom","renderResult","newParentVNode","oldParentVNode","globalContext","namespace","excessDomChildren","isHydrating","childVNode","newDom","firstChildDom","oldChildren","EMPTY_ARR","newChildrenLength","constructNewChildrenArray","EMPTY_OBJ","ref","applyRef","insert","nextSibling","skewedIndex","matchingIndex","oldChildrenLength","remainingOldChildren","skew","constructor","String","createVNode","isArray","__b","key","findMatchingIndex","unmount","parentVNode","contains","insertBefore","nodeType","findMatchingIndex","childVNode","oldChildren","skewedIndex","remainingOldChildren","key","type","x","y","oldVNode","__u","Fragment","length","setStyle","style","value","setProperty","IS_NON_DIMENSIONAL","test","dom","name","oldValue","namespace","useCapture","o","cssText","replace","toLowerCase","slice","l","_attached","eventClock","addEventListener","eventProxyCapture","eventProxy","removeEventListener","e","removeAttribute","setAttribute","createEventProxy","this","eventHandler","_dispatched","options","event","handleEvent","diff","parentDom","newVNode","globalContext","excessDomChildren","commitQueue","oldDom","isHydrating","refQueue","tmp","c","isNew","oldProps","oldState","snapshot","clearProcessingException","newProps","isClassComponent","provider","componentContext","i","renderHook","count","renderResult","newType","constructor","__e","__b","outer","props","prototype","render","contextType","__c","__","__E","BaseComponent","doRender","sub","state","context","__n","__d","__h","_sb","__s","getDerivedStateFromProps","assign","__v","componentWillMount","componentDidMount","push","componentWillReceiveProps","shouldComponentUpdate","__k","some","vnode","componentWillUpdate","componentDidUpdate","__P","__r","getChildContext","getSnapshotBeforeUpdate","diffChildren","isArray","children","base","MODE_HYDRATE","nodeType","nextSibling","indexOf","diffElementNodes","diffed","commitRoot","root","applyRef","cb","call","newHtml","oldHtml","newChildren","inputValue","checked","localName","document","createTextNode","createElementNS","is","__m","data","childNodes","EMPTY_OBJ","attributes","__html","innerHTML","getDomSibling","removeNode","ref","hasRefUnmount","current","unmount","parentVNode","skipRemove","r","componentWillUnmount","replaceNode","createElement","namespaceURI","firstChild","slice","EMPTY_ARR","options","__e","error","vnode","oldVNode","errorInfo","component","ctor","handled","__","__c","constructor","getDerivedStateFromError","setState","__d","componentDidCatch","__E","e","vnodeId","isValidElement","undefined","BaseComponent","prototype","update","callback","s","this","__s","state","assign","props","__v","_sb","push","enqueueRender","forceUpdate","__h","render","Fragment","rerenderQueue","defer","Promise","then","bind","resolve","setTimeout","depthSort","a","b","__b","process","__r","eventClock","eventProxy","createEventProxy","eventProxyCapture","i","currentIndex","currentComponent","previousComponent","prevRaf","currentHook","afterPaintEffects","options","_options","oldBeforeDiff","__b","oldBeforeRender","__r","oldAfterDiff","diffed","oldCommit","__c","oldBeforeUnmount","unmount","oldRoot","__","getHookState","index","type","__h","hooks","__H","length","push","useState","initialState","useReducer","invokeOrReturn","reducer","init","hookState","_reducer","action","currentValue","__N","nextValue","setState","_hasScuFromHooks","updateHookState","p","s","c","stateHooks","filter","x","every","prevScu","call","this","shouldUpdate","props","forEach","hookItem","shouldComponentUpdate","prevCWU","componentWillUpdate","__e","tmp","useEffect","callback","args","state","__s","argsChanged","_pendingArgs","useRef","initialValue","currentHook","useMemo","current","useMemo","factory","args","state","getHookState","currentIndex","argsChanged","__H","__","__h","useCallback","callback","currentHook","flushAfterPaintEffects","component","afterPaintEffects","shift","__P","__H","__h","forEach","invokeCleanup","invokeEffect","e","options","__e","__v","__b","vnode","currentComponent","oldBeforeDiff","__","parentDom","__k","__m","oldRoot","__r","oldBeforeRender","currentIndex","hooks","__c","previousComponent","hookItem","__N","_pendingArgs","diffed","oldAfterDiff","c","length","push","prevRaf","requestAnimationFrame","afterNextFrame","commitQueue","some","filter","cb","oldCommit","unmount","oldBeforeUnmount","hasErrored","s","HAS_RAF","callback","raf","done","clearTimeout","timeout","cancelAnimationFrame","setTimeout","hook","comp","cleanup","argsChanged","oldArgs","newArgs","arg","index","invokeOrReturn","f","vnodeId","isArray","Array","createVNode","type","props","key","isStaticChildren","__source","__self","ref","i","normalizedProps","vnode","__k","__","__b","__e","__d","__c","constructor","__v","__i","__u","defaultProps","options","IconChat","u","IconX","IconArrowLeft","IconSend","IconPlus","IconPaperclip","IconDownload","IconFile","ChatBubble","isOpen","position","unreadCount","onClick","u","IconX","IconChat","ConversationList","conversations","channelInfo","loading","onSelect","onNew","t","hasOpen","c","canReopen","u","IconPlus","conv","isClickable","MessageInput","value","onChange","onSend","onFileSelect","onFileRemove","attachedFile","uploading","disabled","placeholder","t","textareaRef","A","fileInputRef","handleKeyDown","q","e","handleInput","target","handleAttachClick","handleFileChange","input","file","isImage","canSend","u","IconFile","formatSize","IconX","IconPaperclip","IconSend","bytes","ImageLightbox","src","alt","onClose","handleKeyDown","q","e","y","u","IconX","MessageMedia","media","onImageClick","t","mimeType","thumbSrc","fullSrc","u","IconFile","IconDownload","MessageList","messages","loading","t","endRef","A","lightboxSrc","setLightboxSrc","h","y","u","msg","MessageBubble","ImageLightbox","message","onImageClick","isClient","cls","time","MessageMedia","PreChatForm","channelInfo","onSubmit","loading","t","name","setName","h","email","setEmail","requireName","requireEmail","privacyPolicyUrl","handleSubmit","e","isValid","u","ChatWindow","channelInfo","apiClient","realtimeClient","storage","events","visitor","isAuthenticated","position","onClose","t","initialConversationId","view","setView","h","conversation","setConversation","conversations","setConversations","messages","setMessages","inputValue","setInputValue","loading","setLoading","sending","setSending","attachedFile","setAttachedFile","uploadedFileId","setUploadedFileId","uploading","setUploading","isOpen","allowViewHistory","y","convs","conv","c","openConversation","needsPreChat","startNewConversation","storedId","msgs","connectRealtime","e","q","convId","msg","prev","m","result","handlePreChatSubmit","data","handleFileSelect","file","MAX_SIZE","preview","uploaded","handleFileRemove","handleSend","content","tempId","optimistic","mediaId","handleReopen","updated","handleBack","posClass","headerTitle","showBack","u","IconArrowLeft","IconX","b","PreChatForm","ConversationList","MessageList","MessageInput","App","channelInfo","apiClient","realtimeClient","storage","events","visitor","isAuthenticated","position","hidden","t","isOpenRef","setIsOpen","isOpen","setIsOpenState","h","isHidden","setIsHidden","unreadCount","y","onOpen","onClose","onShow","onHide","u","b","ChatBubble","next","ChatWindow","widget_css_default","styleElement","hostElement","mount","options","widget_css_default","primaryColor","contrastColor","getContrastColor","q","_","App","unmount","updateTheme","hex","r","g","b","EventEmitter","event","callback","args","cb","e","Storage","channelToken","email","raw","data","current","id","visitor","DEFAULT_API_URL","BaseportalChat","config","EventEmitter","ApiClient","Storage","RealtimeClient","primaryColor","t","getTranslations","mount","open","updateTheme","e","visitor","data","content","id","theme","position","locale","event","callback","unmount","src_default","BaseportalChat"]}