{"version":3,"file":"index.mjs","sources":["../src/constants.ts","../src/utils.ts","../src/Super.ts","../src/Joystick.ts","../src/Collection.ts","../src/index.ts","../src/Factory.ts"],"sourcesContent":["import type { EventType, InteractType } from './types';\n\n/** Defines the different positioning modes available for the joystick */\nexport const MODES = {\n    /** The joystick disappears on release. */\n    dynamic: 'dynamic',\n    /** The joystick stays in place after first touch, and disappears if the subsequent touch is too far. */\n    semi: 'semi',\n    /** The joystick stays at its initial position. */\n    static: 'static',\n} as const;\n\nconst IS_TOUCH = typeof window !== 'undefined' && 'ontouchstart' in window;\nconst IS_POINTER = typeof window !== 'undefined' && !!window.PointerEvent;\n\ntype Bindings = Record<EventType, string>;\nconst EVENTS_TO_BIND: Record<InteractType, Bindings> = {\n    touch: {\n        start: 'touchstart',\n        move: 'touchmove',\n        end: 'touchend, touchcancel',\n        pressure: 'webkitmouseforcechanged',\n    },\n    mouse: {\n        start: 'mousedown',\n        move: 'mousemove',\n        end: 'mouseup, mouseleave',\n        pressure: 'webkitmouseforcechanged',\n    },\n    pointer: {\n        start: 'pointerdown',\n        move: 'pointermove',\n        end: 'pointerup, pointercancel, pointerleave',\n        pressure: 'webkitmouseforcechanged',\n    },\n};\n\nlet primaryBind: Bindings;\nlet secondaryBind: Bindings | undefined;\n\n// Determine which interface to bind.\n// Pointer is the priority because it's the most modern and easy to use.\nif (IS_POINTER) {\n    primaryBind = EVENTS_TO_BIND.pointer;\n} else if (IS_TOUCH) {\n    // Some touch interfaces support both mouse and touch,\n    // so we need to bind both.\n    primaryBind = EVENTS_TO_BIND.touch;\n    secondaryBind = EVENTS_TO_BIND.mouse;\n} else {\n    // Default to mouse.\n    primaryBind = EVENTS_TO_BIND.mouse;\n}\n\n// What will we bind on the dom elements?\nexport const PRIMARY_BIND = primaryBind;\nexport const SECONDARY_BIND = secondaryBind;\n\n// Some static math constants.\nexport const ANGLE_45 = Math.PI / 4;\nexport const ANGLE_90 = Math.PI / 2;\n","import type {\n    AnyPosition,\n    Coordinates,\n    DomEvent,\n    Identifier,\n    ProcessedEvent,\n    SupportedElement,\n    SupportedEvent,\n    SupportedEventHandler,\n} from './types';\n\n/**\n * Calculate the distance between two points.\n * @param {Coordinates} p1 - The first point.\n * @param {Coordinates} p2 - The second point.\n * @returns {number} The distance between the two points.\n */\nexport const distance = (p1: Coordinates, p2: Coordinates): number => {\n    const dx = p2.x - p1.x;\n    const dy = p2.y - p1.y;\n\n    return Math.sqrt(dx * dx + dy * dy);\n};\n\n/**\n * Calculate the angle formed by a segment of two points, in degrees.\n * @param {Coordinates} p1 - The first point.\n * @param {Coordinates} p2 - The second point.\n * @returns {number} The angle between the two points in degrees.\n */\nexport const angle = (p1: Coordinates, p2: Coordinates): number => {\n    const dx = p2.x - p1.x;\n    const dy = p2.y - p1.y;\n\n    return degrees(Math.atan2(dy, dx));\n};\n\n/**\n * Find the coordinates of a point given a distance and angle from another point.\n * @param {Coordinates} p - The starting point.\n * @param {number} d - The distance from the starting point.\n * @param {number} a - The angle from the starting point in degrees.\n * @returns {Coordinates} The coordinates of the new point.\n */\nexport const findCoord = (p: Coordinates, d: number, a: number): Coordinates => {\n    const aInRad = radians(a);\n    return {\n        x: p.x - d * Math.cos(aInRad),\n        y: p.y - d * Math.sin(aInRad),\n    };\n};\n\n/**\n * Convert degrees to radians.\n * @param {number} a - The angle in degrees.\n * @returns {number} The angle in radians.\n */\nexport const radians = (a: number): number => {\n    return a * (Math.PI / 180);\n};\n\n/**\n * Convert radians to degrees.\n * @param {number} a - The angle in radians.\n * @returns {number} The angle in degrees.\n */\nexport const degrees = (a: number): number => {\n    return a * (180 / Math.PI);\n};\n\nconst timers = new Map<() => void, number>();\n/**\n * Throttle a function to be called at most once every 100 milliseconds.\n * @param {() => void} cb - The function to throttle.\n */\nexport const throttle = (cb: () => void): void => {\n    if (timers.has(cb)) {\n        clearTimeout(timers.get(cb));\n    }\n    timers.set(cb, setTimeout(cb, 100) as unknown as number);\n};\n\n/**\n * Bind an event listener to an element.\n * @param {SupportedElement} el - The element to bind the event listener to.\n * @param {string} arg - The event type(s) to bind the event listener to.\n * @param {SupportedEventHandler} handler - The event listener to bind.\n */\nexport const bindEvt = (\n    el: SupportedElement,\n    arg: string,\n    handler: SupportedEventHandler,\n): void => {\n    const types = arg.split(/[ ,]+/g);\n    for (let i = 0; i < types.length; i += 1) {\n        el.addEventListener(types[i], handler as EventListenerOrEventListenerObject, false);\n    }\n};\n\n/**\n * Unbind an event listener from an element.\n * @param {SupportedElement} el - The element to unbind the event listener from.\n * @param {string} arg - The event type(s) to unbind the event listener from.\n * @param {SupportedEventHandler} handler - The event listener to unbind.\n */\nexport const unbindEvt = (\n    el: SupportedElement,\n    arg: string,\n    handler: SupportedEventHandler,\n): void => {\n    const types = arg.split(/[ ,]+/g);\n    for (let i = 0; i < types.length; i += 1) {\n        el.removeEventListener(types[i], handler as EventListenerOrEventListenerObject);\n    }\n};\n\n/**\n * Extract pressure/force value from a processed event.\n * Handles Touch (force), Pointer (pressure), Safari trackpad (webkitForce),\n * and falls back to binary mouse-button detection.\n */\nexport const getPressureFromEvt = (evt: ProcessedEvent): number => {\n    // Compute the pressure data.\n    return 'force' in evt // Pressure on Touch.\n        ? evt.force\n        : 'pressure' in evt // Pressure on Pointers.\n          ? evt.pressure\n          : 'webkitForce' in evt // Pressure on trackpads, max is 3, only in Safari.\n            ? (evt.webkitForce as number) / 3\n            : 'buttons' in evt // Id of the mouse button pressed. 0 is none, 1 is left, 2 is right, ...\n              ? evt.buttons !== 0\n                  ? 1\n                  : 0\n              : 0;\n};\n\n/**\n * Normalize a single interaction event (touch, pointer, or mouse) into\n * a unified DomEvent with identifier, position, pressure, and type.\n */\nexport const processEvent = (evt: SupportedEvent, processedEvt: ProcessedEvent): DomEvent => {\n    // Compute identifier of the event.\n    // It's especially important for touches,\n    // to track the correct touch in a multitouch interaction.\n    const identifier: Identifier = (\n        'identifier' in processedEvt\n            ? processedEvt.identifier\n            : 'pointerId' in processedEvt\n              ? processedEvt.pointerId\n              : // Using 1 as identifier, because pointerId starts at 1.\n                // Using 0 would detach our pressure detection on Safari,\n                // as the webkitForce events are triggered as MouseEvent, with no identifier.\n                // So if we have a \"start\" event with a pointerId of 1, we need a \"pressure\" event\n                // with an identifier of 1 too, so we can track the correct joystick.\n                1\n    ) as Identifier;\n\n    // This is only what we need, to normalize the interaction event.\n    // Everything else is based off this data.\n    return {\n        identifier,\n        isTouch: 'touches' in evt || 'changedTouches' in evt,\n        position: {\n            x: processedEvt.pageX,\n            y: processedEvt.pageY,\n        },\n        pressure: getPressureFromEvt(processedEvt),\n        type: evt.type,\n        initial: evt,\n        raw: processedEvt,\n    };\n};\n\n/**\n * Reconciliation layer for MouseEvent, TouchEvent and PointerEvent.\n * Splits multi-touch events into individual DomEvent items and calls\n * preventDefault() on move events to suppress default browser gestures.\n *\n * We skip preventDefault() on start (pointerdown/touchstart/mousedown) events\n * because the zone element already has `touch-action: none` set, and calling\n * preventDefault() on pointerdown can interfere with multitouch on mobile.\n */\nexport const processEvents = (evt: SupportedEvent): DomEvent[] => {\n    // Only preventDefault on move events — start events rely on\n    // touch-action: none (set on the zone) to prevent default gestures,\n    // and calling preventDefault on pointerdown breaks multitouch.\n    const type = evt.type.toLowerCase();\n    if (type.includes('move')) {\n        evt.preventDefault();\n    }\n\n    // Prepare arrays of initial events.\n    const domEvents: ProcessedEvent[] = [];\n    // TouchEvent may have multitouches, split them out in an array.\n    if ('changedTouches' in evt) {\n        // evt.changedTouches doesn't really offer a nice iterable interface.\n        for (const touch of evt.changedTouches) {\n            if (touch) {\n                domEvents.push(touch);\n            }\n        }\n    } else {\n        domEvents.push(evt);\n    }\n\n    // Will return an array of events, based on touches, pointer or mouse data.\n    return domEvents.map<DomEvent>((domEvt) => {\n        return processEvent(evt, domEvt);\n    });\n};\n\n/**\n * Get the current scroll position of the window.\n * @returns {Coordinates} The current scroll position of the window.\n */\nexport const getScroll = (): Coordinates => ({\n    x: window.scrollX,\n    y: window.scrollY,\n});\n\n/**\n * Apply a position to an element.\n * @param {HTMLElement} el - The element to apply the position to.\n * @param {Coordinates} pos - The position to apply.\n */\nexport const applyPosition = (el: HTMLElement, pos: AnyPosition): void => {\n    const { left, top, right, bottom, x, y } = pos;\n    if (top || right || bottom || left) {\n        extend(el.style, { top, right, bottom, left });\n    } else if (isNumber(x) || isNumber(y)) {\n        extend(el.style, {\n            left: isNumber(x) ? `${x}px` : undefined,\n            top: isNumber(y) ? `${y}px` : undefined,\n        } as Partial<CSSStyleDeclaration>);\n    }\n};\n\n/**\n * Configure a style property object with vendor prefixes.\n * @param {string} prop - The property to configure.\n * @returns {Record<string, string>} The configured style property object.\n */\nexport const configStylePropertyObject = (\n    prop: string,\n    value: string = '',\n): Record<string, string> => ({\n    [prop]: value,\n});\n\n/**\n * Extend an object with the properties of another object.\n * @param {T} objA - The object to extend.\n * @param {Partial<T>} objB - The object to extend with.\n * @returns {T} The extended object.\n */\nexport const extend = <T extends object>(objA: T, objB: Partial<T>): T => {\n    for (const i in objB) {\n        if (Object.hasOwn(objB, i)) {\n            objA[i as keyof T] = objB[i] as T[keyof T];\n        }\n    }\n    return objA;\n};\n\n/**\n * Clamp a position within a range.\n * @param {Coordinates} pos - The position to clamp.\n * @param {Coordinates} joystickPos - The position of the joystick.\n * @param {number} size - The size of the range.\n * @returns {Coordinates} The clamped position.\n */\nexport const clamp = (pos: Coordinates, joystickPos: Coordinates, size: number): Coordinates => ({\n    //                          left-clamping          right-clamping\n    x: Math.min(Math.max(pos.x, joystickPos.x - size), joystickPos.x + size),\n    //                          top-clamping           bottom-clamping\n    y: Math.min(Math.max(pos.y, joystickPos.y - size), joystickPos.y + size),\n});\n\n/**\n * Check if a value is a number.\n * @param {unknown} value - The value to check.\n * @returns {boolean} True if the value is a number, false otherwise.\n */\nexport const isNumber = (value: unknown): value is number => {\n    return typeof value === 'number' && !isNaN(value);\n};\n","import type Collection from './Collection';\nimport type Factory from './Factory';\nimport type Joystick from './Joystick';\nimport { PRIMARY_BIND, SECONDARY_BIND } from './constants';\nimport type {\n    FactoryEventType,\n    EventType,\n    LogLevel,\n    SupportedElement,\n    InternalEventHandler,\n    JoystickEventData,\n    SupportedEvent,\n    DomEventHandler,\n    AttachEventData,\n    Uid,\n} from './types';\nimport * as u from './utils';\n\nexport type SuperEventType<T extends FactoryEventType> = `${T}${string}` | `${string}${T}`;\nexport type Name = 'super' | 'joystick' | 'collection' | 'factory';\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n    debug: 0,\n    info: 1,\n    warning: 2,\n    error: 3,\n    none: 4,\n};\n\nlet currentLogLevel: LogLevel = 'warning';\n\n/**\n * Base class providing the event system and DOM event binding used by\n * Joystick, Collection, and Factory.\n *\n * Events are strings that can be space/comma separated to listen to multiple\n * at once (e.g. `\"start end\"`). Handlers are stored in a `Set` per event type.\n */\nexport class Super {\n    uid: Uid = 0 as Uid;\n    index: number = 0;\n    name: Name = 'super';\n    private _domHandlers_: Map<DomEventHandler, (evt: SupportedEvent) => void> = new Map();\n    private _handlers_: Partial<Record<FactoryEventType, Set<InternalEventHandler<any>>>> = {};\n\n    constructor(name: Name) {\n        this.name = name;\n        this.log('construct', this.name, this.index);\n    }\n\n    mapOnEvents(arg: string, cb: (type: FactoryEventType) => void): void {\n        const types = arg.split(/[ ,]+/g) as FactoryEventType[];\n\n        for (let i = 0; i < types.length; i += 1) {\n            cb(types[i]);\n        }\n    }\n\n    // Basic event system.\n    on(arg: SuperEventType<'attached'>, cb: InternalEventHandler<AttachEventData>): void;\n    on(arg: SuperEventType<'detached'>, cb: InternalEventHandler<AttachEventData>): void;\n    on(arg: SuperEventType<'dir'>, cb: InternalEventHandler<JoystickEventData>): void;\n    on(arg: SuperEventType<'plain'>, cb: InternalEventHandler<JoystickEventData>): void;\n    on(arg: SuperEventType<'move'>, cb: InternalEventHandler<JoystickEventData>): void;\n    on(arg: SuperEventType<'added'>, cb: InternalEventHandler<Joystick>): void;\n    on(arg: SuperEventType<'removed'>, cb: InternalEventHandler<Joystick>): void;\n    on(arg: SuperEventType<'start'>, cb: InternalEventHandler<Joystick>): void;\n    on(arg: SuperEventType<'end'>, cb: InternalEventHandler<Joystick>): void;\n    on(arg: SuperEventType<'shown'>, cb: InternalEventHandler<Joystick>): void;\n    on(arg: SuperEventType<'hidden'>, cb: InternalEventHandler<Joystick>): void;\n    on(arg: SuperEventType<'rested'>, cb: InternalEventHandler<Joystick>): void;\n    on(arg: SuperEventType<'joystickCreated'>, cb: InternalEventHandler<Joystick>): void;\n    on(arg: SuperEventType<'joystickDestroyed'>, cb: InternalEventHandler<Joystick>): void;\n    on(arg: SuperEventType<'collectionCreated'>, cb: InternalEventHandler<Collection>): void;\n    on(arg: SuperEventType<'collectionDestroyed'>, cb: InternalEventHandler<Collection>): void;\n    on(arg: SuperEventType<'factoryCreated'>, cb: InternalEventHandler<Factory>): void;\n    on(arg: SuperEventType<'factoryDestroyed'>, cb: InternalEventHandler<Factory>): void;\n    on(arg: SuperEventType<'pressure'>, cb: InternalEventHandler<number>): void;\n    on<T>(arg: string, cb: InternalEventHandler<T>): void {\n        this.mapOnEvents(arg, (type) => {\n            this._handlers_[type] = this._handlers_[type] || new Set();\n            this._handlers_[type]!.add(cb);\n        });\n    }\n\n    off(arg?: SuperEventType<'attached'>, cb?: InternalEventHandler<AttachEventData>): void;\n    off(arg?: SuperEventType<'detached'>, cb?: InternalEventHandler<AttachEventData>): void;\n    off(arg?: SuperEventType<'dir'>, cb?: InternalEventHandler<JoystickEventData>): void;\n    off(arg?: SuperEventType<'plain'>, cb?: InternalEventHandler<JoystickEventData>): void;\n    off(arg?: SuperEventType<'move'>, cb?: InternalEventHandler<JoystickEventData>): void;\n    off(arg?: SuperEventType<'added'>, cb?: InternalEventHandler<Joystick>): void;\n    off(arg?: SuperEventType<'removed'>, cb?: InternalEventHandler<Joystick>): void;\n    off(arg?: SuperEventType<'start'>, cb?: InternalEventHandler<Joystick>): void;\n    off(arg?: SuperEventType<'end'>, cb?: InternalEventHandler<Joystick>): void;\n    off(arg?: SuperEventType<'shown'>, cb?: InternalEventHandler<Joystick>): void;\n    off(arg?: SuperEventType<'hidden'>, cb?: InternalEventHandler<Joystick>): void;\n    off(arg?: SuperEventType<'rested'>, cb?: InternalEventHandler<Joystick>): void;\n    off(arg?: SuperEventType<'joystickCreated'>, cb?: InternalEventHandler<Joystick>): void;\n    off(arg?: SuperEventType<'joystickDestroyed'>, cb?: InternalEventHandler<Joystick>): void;\n    off(arg?: SuperEventType<'collectionCreated'>, cb?: InternalEventHandler<Collection>): void;\n    off(arg?: SuperEventType<'collectionDestroyed'>, cb?: InternalEventHandler<Collection>): void;\n    off(arg?: SuperEventType<'factoryCreated'>, cb?: InternalEventHandler<Factory>): void;\n    off(arg?: SuperEventType<'factoryDestroyed'>, cb?: InternalEventHandler<Factory>): void;\n    off(arg?: SuperEventType<'pressure'>, cb?: InternalEventHandler<number>): void;\n    off<T>(arg?: string, cb?: InternalEventHandler<T>): void {\n        if (arg === undefined) {\n            // If no arguments provided, clear all handlers.\n            this._handlers_ = {};\n        } else {\n            this.mapOnEvents(arg, (type) => {\n                if (cb === undefined) {\n                    // If no callback provided, clear all handlers for the type.\n                    this._handlers_[type] = new Set();\n                } else if (this._handlers_[type]) {\n                    // If the callback is found, remove it.\n                    this._handlers_[type]!.delete(cb);\n                }\n            });\n        }\n    }\n\n    trigger(arg: SuperEventType<'attached'>, data: AttachEventData): void;\n    trigger(arg: SuperEventType<'detached'>, data: AttachEventData): void;\n    trigger(arg: SuperEventType<'dir'>, data: JoystickEventData): void;\n    trigger(arg: SuperEventType<'plain'>, data: JoystickEventData): void;\n    trigger(arg: SuperEventType<'move'>, data: JoystickEventData): void;\n    trigger(arg: SuperEventType<'added'>, data: Joystick): void;\n    trigger(arg: SuperEventType<'removed'>, data: Joystick): void;\n    trigger(arg: SuperEventType<'start'>, data: Joystick): void;\n    trigger(arg: SuperEventType<'end'>, data: Joystick): void;\n    trigger(arg: SuperEventType<'shown'>, data: Joystick): void;\n    trigger(arg: SuperEventType<'hidden'>, data: Joystick): void;\n    trigger(arg: SuperEventType<'rested'>, data: Joystick): void;\n    trigger(arg: SuperEventType<'joystickCreated'>, data: Joystick): void;\n    trigger(arg: SuperEventType<'joystickDestroyed'>, data: Joystick): void;\n    trigger(arg: SuperEventType<'collectionCreated'>, data: Collection): void;\n    trigger(arg: SuperEventType<'collectionDestroyed'>, data: Collection): void;\n    trigger(arg: SuperEventType<'factoryCreated'>, data: Factory): void;\n    trigger(arg: SuperEventType<'factoryDestroyed'>, data: Factory): void;\n    trigger(arg: SuperEventType<'pressure'>, data: number): void;\n    trigger<T>(arg: string, data: T): void {\n        this.mapOnEvents(arg, (type) => {\n            this.log(`- \"${type}\" [trigger]`);\n            const handlers = this._handlers_[type];\n            if (handlers && handlers.size) {\n                // Snapshot to avoid issues if a handler modifies the Set\n                const snapshot = [...handlers];\n                for (const handler of snapshot) {\n                    handler.call(this, {\n                        type,\n                        target: this,\n                        data,\n                    });\n                }\n            }\n        });\n    }\n\n    // Bind DOM events.\n    bindEvt(el: SupportedElement, type: EventType, handler: DomEventHandler) {\n        const cb = (evt: SupportedEvent) => {\n            for (const domEvt of u.processEvents(evt)) {\n                this.log(`- \"${type}\" [dom:trigger:${domEvt.identifier}]`);\n                handler.call(this, domEvt);\n            }\n        };\n\n        // Save the handler so we can unbind later.\n        this._domHandlers_.set(handler, cb);\n\n        u.bindEvt(el, PRIMARY_BIND[type], cb);\n\n        if (SECONDARY_BIND?.[type]) {\n            // Support multiple interfaces type when necessary.\n            u.bindEvt(el, SECONDARY_BIND[type], cb);\n        }\n    }\n\n    // Unbind DOM events.\n    unbindEvt(el: SupportedElement, type: EventType, handler: DomEventHandler) {\n        const cb = this._domHandlers_.get(handler);\n\n        if (!cb) {\n            this.error(`Internal handler not found for event ${type}.`, handler);\n            return;\n        }\n\n        u.unbindEvt(el, PRIMARY_BIND[type], cb);\n\n        if (SECONDARY_BIND?.[type]) {\n            // Support multiple interfaces type when necessary.\n            u.unbindEvt(el, SECONDARY_BIND[type], cb);\n        }\n\n        this._domHandlers_.delete(handler);\n    }\n\n    logPrefix() {\n        const prefixes: Record<Name, string> = {\n            super: '',\n            joystick: '  ',\n            collection: '    ',\n            factory: '      ',\n        };\n\n        return prefixes[this.name];\n    }\n\n    logSuffix() {\n        return `[${this.name}|${this.uid}]`;\n    }\n\n    static get logLevel(): LogLevel {\n        return currentLogLevel;\n    }\n\n    static set logLevel(level: LogLevel) {\n        currentLogLevel = level;\n    }\n\n    log(...args: any[]) {\n        if (LOG_LEVELS[currentLogLevel] <= LOG_LEVELS.debug) {\n            console.log(this.logPrefix(), ...args, this.logSuffix());\n        }\n    }\n\n    info(...args: any[]) {\n        if (LOG_LEVELS[currentLogLevel] <= LOG_LEVELS.info) {\n            console.info(this.logPrefix(), ...args, this.logSuffix());\n        }\n    }\n\n    warn(...args: any[]) {\n        if (LOG_LEVELS[currentLogLevel] <= LOG_LEVELS.warning) {\n            console.warn(this.logPrefix(), ...args, this.logSuffix());\n        }\n    }\n\n    error(...args: any[]) {\n        if (LOG_LEVELS[currentLogLevel] <= LOG_LEVELS.error) {\n            console.error(this.logPrefix(), ...args, this.logSuffix());\n        }\n    }\n}\n\nexport default Super;\n","import type Collection from './Collection';\nimport Super from './Super';\nimport { ANGLE_45, ANGLE_90, MODES } from './constants';\nimport type {\n    Coordinates,\n    Direction,\n    Identifier,\n    JoystickEventData,\n    JoystickOptions,\n    ProcessedEvent,\n    Uid,\n} from './types';\nimport * as u from './utils';\n\n/**\n * A single virtual joystick element.\n *\n * Manages its own DOM (outer circle + inner thumb), position tracking,\n * direction computation, and fade-in/fade-out lifecycle. Created and\n * owned by a Collection.\n */\nexport class Joystick extends Super {\n    static index: number = 0;\n    private _identifier?: Identifier;\n    private _pressure?: number;\n    uid: Uid;\n    position: Coordinates;\n    frontPosition: Coordinates;\n    collection: Collection;\n    ui: {\n        el: HTMLElement;\n        back: HTMLElement;\n        front: HTMLElement;\n    };\n    pressureInterval?: number;\n    removeTimeout?: number;\n    showTimeout?: number;\n    activeTimeout?: number;\n    restTimeout?: number;\n    direction: Direction = {};\n    options: Required<JoystickOptions>;\n    defaults: Required<Omit<JoystickOptions, 'identifier' | 'position' | 'frontPosition'>> = {\n        size: 100,\n        threshold: 0.1,\n        color: 'white',\n        fadeTime: 250,\n        dataOnly: false,\n        restJoystick: true,\n        restOpacity: 0.5,\n        mode: 'dynamic',\n        zone: document.body,\n        lockX: false,\n        lockY: false,\n        shape: 'circle',\n    };\n\n    constructor(collection: Collection, options: JoystickOptions) {\n        super('joystick');\n\n        this.position = options.position;\n        this.frontPosition = options.frontPosition;\n        this.collection = collection;\n        this.options = { ...this.defaults, ...options };\n\n        // Overwrites\n        if (this.options.mode === 'dynamic') {\n            // For dynamic Joystick, they will fade completely out.\n            this.options.restOpacity = 0;\n        }\n\n        this.uid = Joystick.index++ as Uid;\n\n        this.ui = {\n            el: document.createElement('div'),\n            back: document.createElement('div'),\n            front: document.createElement('div'),\n        };\n    }\n\n    init() {\n        if (!this.options.dataOnly) {\n            this.buildEl();\n        }\n        this.trigger('added', this);\n        this.trigger('joystickCreated', this);\n    }\n\n    get identifier(): Identifier | undefined {\n        return this._identifier;\n    }\n\n    set identifier(identifier: Identifier | undefined) {\n        if (!u.isNumber(identifier)) {\n            this.trigger(`detached`, {\n                collection: this.collection,\n                joystick: this,\n                identifier: this._identifier!,\n            });\n            this._identifier = undefined;\n        } else {\n            this._identifier = identifier;\n            this.trigger(`attached`, {\n                collection: this.collection,\n                joystick: this,\n                identifier,\n            });\n        }\n    }\n\n    private resolveColors(): { front: string; back: string } {\n        const color = this.options.color;\n        if (typeof color === 'object' && color !== null) {\n            return color;\n        }\n        return { front: color as string, back: color as string };\n    }\n\n    private buildEl() {\n        // Build the dom element.\n        this.ui.el.className = `joystick collection_${this.collection.uid}`;\n        this.ui.back.className = 'back';\n        this.ui.front.className = 'front';\n\n        this.ui.el.setAttribute('id', `joystick_${this.collection.uid}_${this.uid}`);\n\n        this.ui.el.appendChild(this.ui.back);\n        this.ui.el.appendChild(this.ui.front);\n\n        // Apply CSS to the dom elements.\n        const animTime = `${this.options.fadeTime}ms`;\n        const borderStyle = u.configStylePropertyObject('borderRadius', '50%');\n        const transitStyle = u.configStylePropertyObject('transition', `opacity ${animTime}`);\n        const colors = this.resolveColors();\n\n        u.extend(this.ui.el.style, {\n            position: 'absolute',\n            opacity: this.options.restOpacity.toString(),\n            display: 'block',\n            zIndex: '999',\n            ...transitStyle,\n        });\n\n        u.extend(this.ui.back.style, {\n            position: 'absolute',\n            display: 'block',\n            width: `${this.options.size}px`,\n            height: `${this.options.size}px`,\n            left: '0',\n            marginLeft: `${-this.options.size / 2}px`,\n            marginTop: `${-this.options.size / 2}px`,\n            background: colors.back,\n            ...(this.options.shape === 'circle' ? borderStyle : {}),\n        });\n\n        u.extend(this.ui.front.style, {\n            width: `${this.options.size / 2}px`,\n            height: `${this.options.size / 2}px`,\n            position: 'absolute',\n            display: 'block',\n            left: '0',\n            marginLeft: `${-this.options.size / 4}px`,\n            marginTop: `${-this.options.size / 4}px`,\n            background: colors.front,\n            opacity: '.5',\n            transform: 'translate(0px, 0px)',\n            ...borderStyle,\n        });\n    }\n\n    get pressure(): number {\n        return this._pressure ?? 0;\n    }\n\n    set pressure(pressure: number) {\n        if (pressure !== this._pressure) {\n            this._pressure = pressure;\n            this.trigger('pressure', pressure);\n        }\n    }\n\n    startPressureInterval(evt: ProcessedEvent): void {\n        if (this.pressureInterval) {\n            return;\n        }\n\n        this.pressureInterval = window.setInterval(() => {\n            this.pressure = u.getPressureFromEvt(evt);\n        }, 100);\n    }\n\n    stopPressureInterval(): void {\n        clearInterval(this.pressureInterval);\n        this.pressureInterval = undefined;\n    }\n\n    // Inject the Joystick instance into DOM.\n    addToDom(): void {\n        // We're not adding it if we're dataOnly or already in dom.\n        if (this.options.dataOnly || document.body.contains(this.ui.el)) {\n            return;\n        }\n        this.options.zone.appendChild(this.ui.el);\n    }\n\n    // Remove the Joystick instance from DOM.\n    removeFromDom(): void {\n        if (this.options.dataOnly || !document.body.contains(this.ui.el)) {\n            return;\n        }\n        this.options.zone.removeChild(this.ui.el);\n    }\n\n    private clearTimeouts(): void {\n        clearTimeout(this.removeTimeout);\n        clearTimeout(this.showTimeout);\n        clearTimeout(this.restTimeout);\n        clearTimeout(this.activeTimeout);\n\n        this.removeTimeout = undefined;\n        this.showTimeout = undefined;\n        this.restTimeout = undefined;\n        this.activeTimeout = undefined;\n    }\n\n    // Fade in the Joystick instance.\n    start(evt: ProcessedEvent, cb?: () => void): void {\n        this.trigger('start', this);\n        // Clear the timeouts.\n        this.clearTimeouts();\n\n        if (this.options.dataOnly) {\n            if (typeof cb === 'function') {\n                cb.call(this);\n            }\n            return;\n        }\n\n        this.addToDom();\n\n        this.startPressureInterval(evt);\n\n        requestAnimationFrame(() => {\n            this.ui.el.style.opacity = '1';\n        });\n\n        this.showTimeout = window.setTimeout(() => {\n            this.showTimeout = undefined;\n            this.trigger('shown', this);\n            if (typeof cb === 'function') {\n                cb.call(this);\n            }\n        }, this.options.fadeTime);\n    }\n\n    // Fade out the Joystick instance.\n    end(cb?: () => void): void {\n        this.resetDirection();\n        this.clearTimeouts();\n        this.stopPressureInterval();\n        this.pressure = 0;\n        this.trigger('end', this);\n\n        if (this.options.dataOnly) {\n            if (typeof cb === 'function') {\n                cb.call(this);\n            }\n            return;\n        }\n\n        // Set the faded out opacity.\n        this.ui.el.style.opacity = this.options.restOpacity.toString();\n\n        // If the Joystick has to rest (go back to center),\n        // we update its position.\n        if (this.options.restJoystick) {\n            const rest = this.options.restJoystick;\n            const newPosition = {\n                x: rest === true || rest.x !== false ? 0 : this.frontPosition.x,\n                y: rest === true || rest.y !== false ? 0 : this.frontPosition.y,\n            };\n\n            this.setPosition(cb, newPosition);\n        }\n\n        // Create a timeout to trigger an event after the fadeTime.\n        // And destroy it if it's a dynamic Joystick.\n        clearTimeout(this.removeTimeout);\n        this.removeTimeout = window.setTimeout(() => {\n            this.removeTimeout = undefined;\n            // If dynamic, we'll completely hide the Joystick (display: none).\n            this.ui.el.style.display = this.options.mode === MODES.dynamic ? 'none' : 'block';\n            this.trigger('hidden', this);\n\n            // We trigger a removed event only in dynamic mode,\n            // which is the only mode where joysticks get removed.\n            if (this.options.mode === MODES.dynamic) {\n                this.trigger('removed', this);\n                this.destroy();\n            }\n\n            if (typeof cb === 'function') {\n                cb.call(this);\n            }\n        }, this.options.fadeTime);\n    }\n\n    setTransition(animated: boolean = false, cb?: () => void) {\n        if (animated) {\n            const activeTime = 100;\n            const animTime = `${activeTime}ms`;\n            const transitStyle = u.extend(\n                // Transition style.\n                u.configStylePropertyObject('transition', `transform ${animTime}`),\n                // Transform style.\n                u.configStylePropertyObject(\n                    'transform',\n                    `translate(${this.frontPosition.x}px, ${this.frontPosition.y}px)`,\n                ),\n            );\n\n            // Apply CSS.\n            u.extend(this.ui.front.style, transitStyle);\n\n            clearTimeout(this.activeTimeout);\n            this.activeTimeout = window.setTimeout(() => {\n                this.activeTimeout = undefined;\n                if (typeof cb === 'function') {\n                    cb.call(this);\n                }\n            }, activeTime);\n        } else {\n            u.extend(this.ui.front.style, u.configStylePropertyObject('transition', 'none'));\n        }\n    }\n\n    // Set the Joystick to the specified position\n    setPosition(cb: (() => void) | undefined, position: Coordinates): void {\n        this.frontPosition = {\n            x: position.x,\n            y: position.y,\n        };\n\n        this.setTransition(true);\n\n        clearTimeout(this.restTimeout);\n        this.restTimeout = window.setTimeout(() => {\n            this.restTimeout = undefined;\n            if (typeof cb === 'function') {\n                cb.call(this);\n            }\n            // Once rested, remove the transition.\n            this.setTransition(false);\n            this.trigger('rested', this);\n        }, this.options.fadeTime);\n    }\n\n    resetDirection(): void {\n        // Fully rebuild the object to let the iteration possible.\n        this.direction = {};\n    }\n\n    computeDirectionAndTriggerEvents(obj: JoystickEventData): JoystickEventData {\n        const rAngle = obj.angle.radian;\n        const direction: Direction = {};\n\n        // Angular direction\n        //     \\  UP /\n        //      \\   /\n        // LEFT       RIGHT\n        //      /   \\\n        //     /DOWN \\\n        //\n        if (rAngle > ANGLE_45 && rAngle < ANGLE_45 * 3 && !obj.lockX) {\n            direction.angle = 'up';\n        } else if (rAngle > -ANGLE_45 && rAngle <= ANGLE_45 && !obj.lockY) {\n            direction.angle = 'left';\n        } else if (rAngle > -ANGLE_45 * 3 && rAngle <= -ANGLE_45 && !obj.lockX) {\n            direction.angle = 'down';\n        } else if (!obj.lockY) {\n            direction.angle = 'right';\n        }\n\n        // Plain direction\n        //    UP                 |\n        // _______               | RIGHT\n        //                  LEFT |\n        //   DOWN                |\n        if (!obj.lockY) {\n            if (rAngle > -ANGLE_90 && rAngle < ANGLE_90) {\n                direction.x = 'left';\n            } else {\n                direction.x = 'right';\n            }\n        }\n\n        if (!obj.lockX) {\n            if (rAngle > 0) {\n                direction.y = 'up';\n            } else {\n                direction.y = 'down';\n            }\n        }\n\n        // Rotate the angle measure from 0 to 180° to have a more human reading of it.\n        obj.angle = {\n            radian: u.radians(180 - obj.angle.degree),\n            degree: 180 - obj.angle.degree,\n        };\n\n        this.triggerDirectionEvents(obj, direction);\n\n        return obj;\n    }\n\n    private triggerDirectionEvents(obj: JoystickEventData, direction: Direction): void {\n        if (obj.force > this.options.threshold) {\n            const oldDirection = {\n                x: this.direction.x,\n                y: this.direction.y,\n                angle: this.direction.angle,\n            };\n\n            this.direction = direction;\n            obj.direction = direction;\n\n            if (oldDirection.x !== direction.x) {\n                this.trigger(`plain plain:${direction.x}`, obj);\n            }\n\n            if (oldDirection.y !== direction.y) {\n                this.trigger(`plain plain:${direction.y}`, obj);\n            }\n\n            if (oldDirection.angle !== direction.angle) {\n                this.trigger(`dir dir:${direction.angle}`, obj);\n            }\n        } else {\n            this.resetDirection();\n        }\n\n        this.trigger('move', obj);\n    }\n\n    // Entirely destroy this Joystick\n    destroy(): void {\n        this.clearTimeouts();\n        this.identifier = undefined;\n        this.removeFromDom();\n        this.trigger('joystickDestroyed', this);\n        this.off();\n    }\n}\n\nexport default Joystick;\n","import type Factory from './Factory';\nimport Joystick from './Joystick';\nimport Super from './Super';\nimport { MODES } from './constants';\nimport type {\n    CollectionOptions,\n    JoystickEventData,\n    DomEvent,\n    Coordinates,\n    AnyPosition,\n    Uid,\n    Identifier,\n} from './types';\nimport * as u from './utils';\n\nexport class Collection extends Super {\n    /**\n     *  The static incremented ID of the Collections.\n     * */\n    static index: number = 0;\n    /**\n     *  The unique ID of this Collection instance.\n     * */\n    uid: Uid;\n    /**\n     *  The parent factory that created this Collection.\n     * */\n    factory: Factory;\n    /**\n     *  The options of this Collection.\n     * */\n    options: Required<CollectionOptions>;\n    /**\n     *  The list of all the Joysticks of this Collection.\n     *\n     *  Indexed by their uid.\n     * */\n    all: Map<Uid, Joystick> = new Map();\n    /**\n     *  The list of the idle Joysticks of this Collection.\n     *\n     *  Idle Joysticks are the ones that are not being moved by the user.\n     *\n     *  Indexed by their uid.\n     * */\n    idles: Set<Uid> = new Set();\n    /**\n     *  The list of the active Joysticks of this Collection.\n     *\n     *  Active Joysticks are the ones that are being moved or touched by the user.\n     *\n     *  Indexed by their event's identifier.\n     * */\n    actives: Map<Identifier, Joystick> = new Map();\n    /**\n     *  The list of the resting Joysticks of this Collection.\n     *\n     *  Resting Joysticks are the ones that are on their way out.\n     *\n     *  Keeping them here, just in case we get a new start before the end.\n     *\n     *  Indexed by their event's identifier.\n     * */\n    resting: Map<Identifier, Joystick> = new Map();\n    /**\n     *  Is the parent element of the Joysticks a flex container?\n     * */\n    parentIsFlex: boolean = false;\n    /**\n     *  The bounding box of the parent element of the Joysticks.\n     * */\n    box: DOMRect;\n    /**\n     *  ResizeObserver watching the zone element for automatic repositioning.\n     * */\n    private resizeObserver?: ResizeObserver;\n    /**\n     *  The default options of a Collection.\n     * */\n    defaults: Required<CollectionOptions> = {\n        catchDistance: 200,\n        color: 'white',\n        dataOnly: false,\n        dynamicPage: false,\n        fadeTime: 250,\n        follow: false,\n        lockX: false,\n        lockY: false,\n        maxNumberOfJoysticks: 10,\n        mode: MODES.dynamic,\n        multitouch: false,\n        position: { top: '0px', left: '0px' },\n        restJoystick: true,\n        restOpacity: 0.5,\n        shape: 'circle',\n        size: 100,\n        threshold: 0.1,\n        zone: document.body,\n    };\n\n    constructor(factory: Factory, options: CollectionOptions) {\n        super('collection');\n        this.factory = factory;\n        this.uid = Collection.index++ as Uid;\n        this.options = { ...this.defaults, ...options };\n\n        // Overwrite the multitouch option if we are in static or semi modes.\n        // As they cannot support multitouch.\n        if (this.options.mode === MODES.static || this.options.mode === MODES.semi) {\n            this.options.multitouch = false;\n        }\n\n        // Overwrite the maxNumberOfJoysticks in a non multitouch setup.\n        if (!this.options.multitouch) {\n            this.options.maxNumberOfJoysticks = 1;\n        }\n\n        // Compute the parentIsFlex value.\n        const computedStyle =\n            this.options.zone.parentElement && getComputedStyle(this.options.zone.parentElement);\n        if (computedStyle?.display === 'flex') {\n            this.parentIsFlex = true;\n        }\n\n        // Warn if the zone has no CSS positioning set.\n        const zonePosition = getComputedStyle(this.options.zone).position;\n        if (zonePosition === 'static') {\n            this.warn(\n                'The zone element has no CSS \"position\" set (it is \"static\").',\n                'Joysticks may not be positioned correctly.',\n                'Set \"position: relative\" (or absolute/fixed) on the zone element.',\n            );\n        }\n\n        // Compute the bounding box of the zone.\n        this.box = this.options.zone.getBoundingClientRect();\n\n        // Bind the start event.\n        this.bindEvt(this.options.zone, 'start', this.processOnStart);\n\n        // Disable the default actions of touches (zooming, panning, etc...)\n        // and prevent text selection while interacting with the joystick.\n        u.extend(this.options.zone.style, {\n            touchAction: 'none',\n            userSelect: 'none',\n            webkitUserSelect: 'none',\n        } as Partial<CSSStyleDeclaration>);\n\n        // Automatically reposition when the zone element resizes.\n        if (typeof ResizeObserver !== 'undefined') {\n            this.resizeObserver = new ResizeObserver(() => {\n                this.reposition();\n            });\n            this.resizeObserver.observe(this.options.zone);\n        }\n    }\n\n    init() {\n        this.trigger('collectionCreated', this);\n\n        // In static mode, we create our own static Joystick.\n        if (this.options.mode === MODES.static) {\n            const joystick = this.createJoystick(this.options.position);\n            joystick.addToDom();\n        }\n    }\n\n    getJoystickByUid(uid?: Uid): Joystick | undefined {\n        // If we have no uid, we return the first Joystick.\n        if (uid === undefined) {\n            return this.all.values().next().value;\n        }\n\n        return this.all.get(uid);\n    }\n\n    private bindJoystick(joystick: Joystick) {\n        // When a Joystick gets destroyed, we clean behind.\n        joystick.on('joystickDestroyed', () => {\n            this.deleteJoystickFromLists(joystick);\n        });\n\n        // When a Joystick gets attached, we move it from idle to active.\n        joystick.on('attached', (evt) => {\n            this.idles.delete(evt.data.joystick.uid);\n            this.actives.set(evt.data.identifier, joystick);\n        });\n\n        // When a Joystick gets detached, we move it from active to idle.\n        joystick.on('detached', (evt) => {\n            this.idles.add(evt.data.joystick.uid);\n            this.deleteIdentifierFromLists(evt.data.identifier);\n        });\n\n        // When a Joystick gets hidden, we move it from active to resting.\n        joystick.on('end', (evt) => {\n            if (u.isNumber(evt.data.identifier)) {\n                this.actives.delete(evt.data.identifier);\n                this.resting.set(evt.data.identifier, joystick);\n            }\n        });\n\n        // When a Joystick gets hidden, we move it from resting to idle.\n        joystick.on('hidden', (evt) => {\n            if (u.isNumber(evt.data.identifier)) {\n                this.resting.delete(evt.data.identifier);\n            }\n            this.idles.add(evt.data.uid);\n        });\n\n        // Other events that will get bubbled up.\n        joystick.on('pressure', (evt) => {\n            this.trigger(`pressure ${joystick.uid}:pressure`, evt.data);\n        });\n        joystick.on('attached detached', (evt) => {\n            type EvtType = `attached${string}` & `detached${string}`;\n            const type = `${evt.type} ${evt.data.joystick.uid}:${evt.type}`;\n            this.trigger(type as EvtType, evt.data);\n        });\n        joystick.on(\n            'added start shown hidden rested removed end joystickCreated joystickDestroyed',\n            (evt) => {\n                type EvtType = `added${string}` &\n                    `start${string}` &\n                    `shown${string}` &\n                    `hidden${string}` &\n                    `rested${string}` &\n                    `removed${string}` &\n                    `end${string}` &\n                    `joystickCreated${string}` &\n                    `joystickDestroyed${string}`;\n                const type = `${evt.type} ${evt.data.uid}:${evt.type}`;\n                this.trigger(type as EvtType, evt.data);\n            },\n        );\n        joystick.on('move', (evt) => {\n            this.trigger(`move ${evt.data.instance.uid}:move`, evt.data);\n        });\n        joystick.on('dir dir:up dir:right dir:down dir:left', (evt) => {\n            const type = `${evt.type} ${evt.data.instance.uid}:${evt.type}`;\n            this.trigger(type as `dir${string}`, evt.data);\n        });\n        joystick.on('plain plain:up plain:right plain:down plain:left', (evt) => {\n            const type = `${evt.type} ${evt.data.instance.uid}:${evt.type}`;\n            this.trigger(type as `plain${string}`, evt.data);\n        });\n    }\n\n    private deleteJoystickFromLists(joystick: Joystick) {\n        this.deleteUidFromLists(joystick.uid);\n        if (u.isNumber(joystick.identifier)) {\n            this.deleteIdentifierFromLists(joystick.identifier);\n        }\n    }\n\n    private deleteUidFromLists(uid: Uid) {\n        this.all.delete(uid);\n        this.idles.delete(uid);\n    }\n\n    private deleteIdentifierFromLists(identifier: Identifier) {\n        this.actives.delete(identifier);\n        this.resting.delete(identifier);\n    }\n\n    private getOrCreate(position: Coordinates): Joystick {\n        // In semi and static modes, we recycle the idle joystick.\n        if (this.options.mode === MODES.semi || this.options.mode === MODES.static) {\n            // If there is an idle joystick, we use it.\n            const idleUid: Uid | undefined = this.idles.values().next().value;\n            if (u.isNumber(idleUid)) {\n                const joystick = this.all.get(idleUid);\n                if (!joystick) {\n                    this.error(`Couldn't find the joystick ${idleUid}. Creating a new one.`);\n                    // Clean unbound uid.\n                    this.deleteUidFromLists(idleUid);\n                } else {\n                    return joystick;\n                }\n            }\n\n            // In semi mode, we may not have an idle joystick.\n            // So we create a new one.\n            if (this.options.mode === MODES.semi) {\n                return this.createJoystick(position);\n            }\n\n            // This should never be reached.\n            // Static mode should always have an idle joystick.\n            this.warn(\"Couldn't find the expected joystick. Creating a new one.\");\n        }\n\n        // Return a new joystick.\n        return this.createJoystick(position);\n    }\n\n    private createJoystick(position: AnyPosition): Joystick {\n        const scroll = this.factory.scroll;\n        // Offset converts page-absolute coordinates to zone-relative.\n        // In flex containers, absolute children are positioned relative to the\n        // flex item's content box, so we only need scroll offset.\n        const offset = {\n            x: this.parentIsFlex ? scroll.x : scroll.x + this.box.left,\n            y: this.parentIsFlex ? scroll.y : scroll.y + this.box.top,\n        };\n\n        // Two paths: numeric {x, y} from pointer events (dynamic/semi mode)\n        // or CSS strings {top, left, ...} from options (static mode).\n        let toApply: AnyPosition;\n        let newPosition: Coordinates;\n\n        if (u.isNumber(position.x) && u.isNumber(position.y)) {\n            toApply = {\n                x: position.x - offset.x,\n                y: position.y - offset.y,\n            };\n            newPosition = {\n                x: position.x,\n                y: position.y,\n            };\n        } else if (position.top || position.right || position.bottom || position.left) {\n            // Compute coordinates from given CssPosition by creating a stub element.\n            const stub = document.createElement('DIV');\n            u.extend(stub.style, {\n                visibility: 'hidden',\n                position: 'absolute',\n                top: position.top,\n                right: position.right,\n                bottom: position.bottom,\n                left: position.left,\n            });\n\n            // Add it to the dom to get its bounding box.\n            this.options.zone.appendChild(stub);\n            const stubBox = stub.getBoundingClientRect();\n            // Then remove it.\n            this.options.zone.removeChild(stub);\n\n            toApply = position;\n            // No offset needed — the stub is positioned inside the zone,\n            // so stubBox.left already accounts for the zone's position.\n            newPosition = {\n                x: stubBox.left + scroll.x,\n                y: stubBox.top + scroll.y,\n            };\n        } else {\n            this.error('Invalid or missing position.', position);\n            return undefined as unknown as Joystick;\n        }\n\n        const joystick = new Joystick(this, {\n            color: this.options.color,\n            size: this.options.size,\n            threshold: this.options.threshold,\n            fadeTime: this.options.fadeTime,\n            dataOnly: this.options.dataOnly,\n            restJoystick: this.options.restJoystick,\n            restOpacity: this.options.restOpacity,\n            mode: this.options.mode,\n            // Page-absolute position of the joystick center.\n            // Used to compute distance/angle in processOnMove and catchDistance in semi mode.\n            position: newPosition!,\n            zone: this.options.zone,\n            frontPosition: {\n                x: 0,\n                y: 0,\n            },\n            shape: this.options.shape,\n        });\n\n        if (this.all.has(joystick.uid)) {\n            this.error(`Joystick with uid ${joystick.uid} already exists.`);\n        }\n\n        if (!this.options.dataOnly) {\n            // Position the Joystick at the right place.\n            u.applyPosition(joystick.ui.el, toApply!);\n            u.applyPosition(joystick.ui.front, joystick.frontPosition);\n        }\n\n        this.all.set(joystick.uid, joystick);\n        this.idles.add(joystick.uid);\n        this.bindJoystick(joystick);\n\n        // Initialize the joystick.\n        // We do this in order to have the events triggered by the joystick during initialisation caught by the collection.\n        // Otherwise, if everything is done in the constructor, we can't listen for start/created events.\n        joystick.init();\n\n        return joystick;\n    }\n\n    processOnStart(evt: DomEvent, _depth: number = 0) {\n        // Refresh the box position.\n        this.box = this.options.zone.getBoundingClientRect();\n        // If we don't have spots available, we stop right here.\n        if (\n            // Only if the event is already active.\n            !this.actives.has(evt.identifier) &&\n            this.actives.size >= this.options.maxNumberOfJoysticks\n        ) {\n            this.warn('No more joysticks allowed.');\n            return;\n        }\n\n        // Get an existing joystick or create a new one.\n        const joystick =\n            this.actives.get(evt.identifier) ||\n            this.resting.get(evt.identifier) ||\n            this.getOrCreate(evt.position);\n\n        const process = () => {\n            // Show the joystick.\n            joystick.start(evt.raw);\n            // Attach joystick to its event.\n            joystick.identifier = evt.identifier;\n            // Trigger a first move.\n            this.processOnMove(evt, true);\n        };\n\n        // In semi mode, we need to verify what to do, do we recycle (if we're in the catch distance),\n        // or do we create a new one and delete the previous one?\n        if (this.options.mode === MODES.semi) {\n            const distance = u.distance(evt.position, joystick.position);\n            if (distance <= this.options.catchDistance) {\n                // We're in the catch distance, we keep this one.\n                process();\n            } else if (_depth < 3) {\n                // We're too far, delete it and start over.\n                joystick.destroy();\n                this.processOnStart(evt, _depth + 1);\n            } else {\n                this.error('Max semi-mode recursion depth reached.');\n            }\n        } else {\n            // In the other modes, we just process it.\n            process();\n        }\n    }\n\n    /**\n     *  Whenever a move event happens.\n     *\n     *  This is called from the Factory.\n     * */\n    processOnMove(evt: DomEvent, animated: boolean = false) {\n        const joystick = this.actives.get(evt.identifier);\n        const scroll = this.factory.scroll;\n\n        // Can happen in multitouch when more touches exist than maxNumberOfJoysticks —\n        // processOnStart rejected the touch but Factory still dispatches move events for it.\n        if (!joystick) {\n            this.error(`Found zombie joystick onMove with identifier ${evt.identifier}`);\n            this.deleteIdentifierFromLists(evt.identifier);\n            return;\n        }\n\n        // If it's not pressed, and not on its way out, just process it as an end event instead.\n        // It can happen if the joystick is in its resting animation.\n        // if (!evt.pressure && !joystick.removeTimeout) {\n        // this.error(\n        //     `Found unpressed joystick ${joystick?.uid} for identifier ${evt.identifier}`,\n        // );\n        // this.processOnEnd(evt);\n        // return;\n        // }\n\n        // If we're on a dynamic page, we need to refresh positions constantly.\n        if (this.options.dynamicPage) {\n            this.reposition();\n        }\n\n        const size = joystick.options.size / 2;\n        // Position of the touch.\n        let pos: Coordinates = {\n            x: evt.position.x,\n            y: evt.position.y,\n        };\n\n        // Freeze the direction we have locked.\n        if (this.options.lockX) {\n            pos.y = joystick.position.y;\n        }\n        if (this.options.lockY) {\n            pos.x = joystick.position.x;\n        }\n\n        let dist = u.distance(pos, joystick.position);\n        const angle = u.angle(pos, joystick.position);\n        const rAngle = u.radians(angle);\n        const force = dist / size;\n\n        // Save the raw data pre-processing/clamping.\n        const raw: { distance: number; position: Coordinates } = {\n            distance: dist,\n            position: pos,\n        };\n\n        let clamped_dist;\n        let clamped_pos;\n\n        if (joystick.options.shape === 'circle') {\n            // In the case of a circle, the distance is the radius (eg. size) of our joystick.\n            clamped_dist = Math.min(dist, size);\n            // The clamped position is the coordinates of the clamped distance, from the center at the given angle.\n            clamped_pos = u.findCoord(joystick.position, clamped_dist, angle);\n        } else {\n            // In the case of a square, we need to clamp the x and y separately.\n            clamped_pos = u.clamp(pos, joystick.position, size);\n            // The clamped distance becomes the distance between the clamped position and the center.\n            clamped_dist = u.distance(clamped_pos, joystick.position);\n        }\n\n        let baseDelta = { x: 0, y: 0 };\n\n        if (this.options.follow) {\n            // If we want the joystick's basis to follow the touch when it reaches outside its bounds.\n            if (dist > size) {\n                const delta_x = pos.x - clamped_pos.x;\n                const delta_y = pos.y - clamped_pos.y;\n                baseDelta = { x: delta_x, y: -delta_y };\n                // Move the joystick's basis to the touch's position.\n                joystick.position.x += delta_x;\n                joystick.position.y += delta_y;\n                // Apply to the CSS.\n                u.extend(joystick.ui.el.style, {\n                    top: `${joystick.position.y - (this.box.top + scroll.y)}px`,\n                    left: `${joystick.position.x - (this.box.left + scroll.x)}px`,\n                });\n\n                // Compute the new distance.\n                dist = u.distance(pos, joystick.position);\n                // No need to apply the clamped position, as we're following the touch.\n            }\n        } else {\n            // Apply the clamped measures.\n            pos = clamped_pos;\n            dist = clamped_dist;\n        }\n\n        // Move the nibble of the joystick.\n        const xPosition = pos.x - joystick.position.x;\n        const yPosition = pos.y - joystick.position.y;\n\n        joystick.frontPosition = {\n            x: xPosition,\n            y: yPosition,\n        };\n\n        // Apply the transformation to the nibble if we're not data only.\n        if (!this.options.dataOnly) {\n            if (animated) {\n                joystick.setTransition(true, () => {\n                    joystick.setTransition(false);\n                });\n            }\n            joystick.ui.front.style.transform = `translate(${xPosition}px,${yPosition}px)`;\n        }\n\n        // Prepare the event.\n        const toSend: JoystickEventData = {\n            position: pos,\n            force,\n            pressure: evt.pressure,\n            distance: dist,\n            angle: {\n                radian: rAngle,\n                degree: angle,\n            },\n            vector: {\n                x: xPosition / size,\n                y: -yPosition / size,\n            },\n            raw,\n            instance: joystick,\n            lockX: this.options.lockX,\n            lockY: this.options.lockY,\n            baseDelta,\n        };\n\n        joystick.computeDirectionAndTriggerEvents(toSend);\n    }\n\n    processOnEnd(evt: DomEvent) {\n        const joystick = this.actives.get(evt.identifier);\n\n        // This should not happen.\n        if (!joystick) {\n            this.error(`Found zombie joystick onEnd with identifier ${evt.identifier}`);\n            this.deleteIdentifierFromLists(evt.identifier);\n            return;\n        }\n\n        // We hide the joystick.\n        joystick.end();\n    }\n\n    /**\n     * Recalculate the zone bounding box and all joystick positions.\n     * Call this after the zone element has been moved, resized, or\n     * when its layout has changed (e.g. entering fullscreen).\n     * This is a lighter alternative to `dynamicPage: true` which\n     * recalculates on every move event.\n     */\n    reposition() {\n        // Refresh scroll position in case layout context changed (e.g. fullscreen)\n        this.factory.scroll = u.getScroll();\n        this.box = this.options.zone.getBoundingClientRect();\n        const scroll = this.factory.scroll;\n        this.all.forEach((joystick) => {\n            if (joystick.options.dataOnly) {\n                return;\n            }\n            const elBox = joystick.ui.el.getBoundingClientRect();\n            joystick.position = {\n                x: scroll.x + elBox.left,\n                y: scroll.y + elBox.top,\n            };\n        });\n    }\n\n    destroy() {\n        if (this.resizeObserver) {\n            this.resizeObserver.disconnect();\n            this.resizeObserver = undefined;\n        }\n        this.unbindEvt(this.options.zone, 'start', this.processOnStart);\n        // Destroy all joysticks.\n        this.all.forEach((joystick) => {\n            joystick.destroy();\n        });\n\n        // Empty the lists.\n        this.all.clear();\n        this.idles.clear();\n        this.actives.clear();\n        this.resting.clear();\n\n        // Events.\n        this.trigger('collectionDestroyed', this);\n        this.off();\n    }\n}\n\nexport default Collection;\n","import type Collection from './Collection';\nimport Factory from './Factory';\nimport Super from './Super';\nimport type { CollectionOptions, LogLevel } from './types';\n\n/**\n * Singleton Factory instance used to create joystick collections\n */\nexport const factory = new Factory();\n\n/**\n * Creates a new Collection of joysticks with the given options\n * @param options Configuration options for creating the joystick collection\n * @returns A Collection instance that manages the created joysticks\n */\nexport const create = (options: CollectionOptions): Collection => {\n    return factory.create(options);\n};\n\n/**\n * Set the log level for nipplejs.\n * - `'debug'` — all logs (verbose)\n * - `'info'` — info, warnings, and errors\n * - `'warning'` — warnings and errors (default)\n * - `'error'` — errors only\n * - `'none'` — silent\n */\nexport const setLogLevel = (level: LogLevel): void => {\n    Super.logLevel = level;\n};\n\n/**\n * Get the current log level.\n */\nexport const getLogLevel = (): LogLevel => {\n    return Super.logLevel;\n};\n\n/**\n * Default export containing the create function and factory instance\n */\nexport default {\n    create,\n    factory,\n    setLogLevel,\n    getLogLevel,\n} as const;\n","import Collection from './Collection';\nimport type Joystick from './Joystick';\nimport Super from './Super';\nimport { MODES } from './constants';\nimport type { CollectionOptions, DomEvent, Identifier, ProcessedEvent, Uid } from './types';\nimport * as u from './utils';\n\n/**\n * Singleton that manages all joystick Collections.\n *\n * Responsible for creating/destroying collections, tracking joysticks across\n * collections, and binding document-level move/end events so that interactions\n * that leave a collection's zone are still handled.\n */\nexport class Factory extends Super {\n    /** Current window scroll position, kept in sync via a scroll listener. */\n    scroll: { x: number; y: number } = u.getScroll();\n    private binded: boolean = false;\n    private joysticksByUid: Map<Uid, Joystick> = new Map();\n    private joysticksByIdentifier: Map<Identifier, Joystick> = new Map();\n    private collections: Set<Collection> = new Set();\n    private resizeHandler: (() => void) | null = null;\n    private scrollHandler: (() => void) | null = null;\n\n    constructor() {\n        super('factory');\n        this.bindResize();\n        this.bindScroll();\n        this.trigger('factoryCreated', this);\n    }\n\n    // Stable references for throttle (avoids creating new closures per event)\n    private repositionAll = () => {\n        this.collections.forEach((collection) => {\n            collection.reposition();\n        });\n    };\n    private refreshScroll = () => {\n        this.scroll = u.getScroll();\n    };\n\n    // Listen for resize, to reposition every joystick\n    private bindResize() {\n        this.resizeHandler = () => u.throttle(this.repositionAll);\n        u.bindEvt(window, 'resize', this.resizeHandler);\n    }\n\n    // Listen for scrolls, so we have a global scroll value\n    // without having to request it all the time.\n    private bindScroll() {\n        this.scrollHandler = () => u.throttle(this.refreshScroll);\n        u.bindEvt(window, 'scroll', this.scrollHandler);\n    }\n\n    // Get a joystick from its uid.\n    // Public API, not used internally.\n    getJoystickByUid(uid: Uid) {\n        return this.joysticksByUid.get(uid);\n    }\n\n    // Get a joystick from its identifier.\n    // Public API, not used internally.\n    getJoystickByIdentifier(identifier: Identifier) {\n        return this.joysticksByIdentifier.get(identifier);\n    }\n\n    // Collection Factory\n    create(options: CollectionOptions): Collection {\n        const collection = new Collection(this, options);\n        // Bind it to bubble the other events up.\n        this.bindCollection(collection);\n        this.collections.add(collection);\n\n        // Initialize the collection.\n        // We do this in order to have the events triggered by the collection during initialisation caught by the factory.\n        // Otherwise, if everything is done in the constructor, we can't listen for created events.\n        collection.init();\n\n        return collection;\n    }\n\n    private removeJoystickFromLists(joystick: Joystick) {\n        this.joysticksByUid.delete(joystick.uid);\n        if (u.isNumber(joystick.identifier)) {\n            this.joysticksByIdentifier.delete(joystick.identifier);\n        }\n    }\n\n    private bindCollection(collection: Collection) {\n        // When a collection gets destroyed, we clean behind.\n        collection.on('collectionDestroyed', (evt) => {\n            // Clean local lists.\n            this.collections.delete(evt.data);\n            evt.data.all.forEach((joystick) => {\n                this.removeJoystickFromLists(joystick);\n            });\n            this.unbindDocument();\n        });\n\n        collection.on('joystickDestroyed', (evt) => {\n            this.removeJoystickFromLists(evt.data);\n            this.unbindDocument();\n        });\n\n        collection.on('end', (evt) => {\n            if (u.isNumber(evt.data.identifier)) {\n                this.joysticksByIdentifier.delete(evt.data.identifier);\n            }\n            this.unbindDocument();\n        });\n\n        collection.on('added', (evt) => {\n            this.joysticksByUid.set(evt.data.uid, evt.data);\n            this.bindDocument();\n        });\n\n        collection.on('attached', (evt) => {\n            this.joysticksByIdentifier.set(evt.data.identifier, evt.data.joystick);\n        });\n\n        // collection.on('detached', (evt) => {\n        //     this.joysticksByIdentifier.delete(evt.data.identifier);\n        // });\n\n        // Other events that we bubble up.\n        collection.on('pressure', (evt) => {\n            this.trigger(`pressure ${evt.target.uid}:pressure`, evt.data);\n        });\n        collection.on('collectionCreated collectionDestroyed', (evt) => {\n            type EvtType = `collectionCreated${string}` & `collectionDestroyed${string}`;\n            const type = `${evt.type} ${evt.data.uid}:${evt.type}`;\n            this.trigger(type as EvtType, evt.data);\n        });\n        collection.on('attached detached', (evt) => {\n            const type = `${evt.type} ${evt.data.joystick.uid}:${evt.type}`;\n            this.trigger(type as `attached${string}` & `detached${string}`, evt.data);\n        });\n        collection.on(\n            'added start shown hidden rested removed end joystickCreated joystickDestroyed',\n            (evt) => {\n                type EvtType = `added${string}` &\n                    `start${string}` &\n                    `shown${string}` &\n                    `hidden${string}` &\n                    `rested${string}` &\n                    `removed${string}` &\n                    `end${string}` &\n                    `joystickCreated${string}` &\n                    `joystickDestroyed${string}`;\n                const type = `${evt.type} ${evt.data.uid}:${evt.type}`;\n                this.trigger(type as EvtType, evt.data);\n            },\n        );\n        collection.on('move', (evt) => {\n            this.trigger(`move ${evt.data.instance.uid}:move`, evt.data);\n        });\n        collection.on('dir dir:up dir:right dir:down dir:left', (evt) => {\n            const type = `${evt.type} ${evt.data.instance.uid}:${evt.type}`;\n            this.trigger(type as `dir${string}`, evt.data);\n        });\n        collection.on('plain plain:up plain:right plain:down plain:left', (evt) => {\n            const type = `${evt.type} ${evt.data.instance.uid}:${evt.type}`;\n            this.trigger(type as `plain${string}`, evt.data);\n        });\n    }\n\n    cleanInactiveTouches(evt: DomEvent) {\n        const toucheIdentifiers =\n            'touches' in evt.initial\n                ? Array.from(evt.initial.touches).map((t) => t.identifier)\n                : [evt.identifier];\n        this.log(\n            'Cleaning inactive',\n            toucheIdentifiers,\n            Array.from(this.joysticksByIdentifier.keys()),\n        );\n        // Make some place in the other touches that may be dormant.\n        // Search within our Factory's joysticks.\n        for (const [identifier, joystick] of this.joysticksByIdentifier) {\n            // No need to clean if the collection is static or semi.\n            if (joystick.collection.options.mode !== MODES.dynamic) {\n                continue;\n            }\n\n            // If we don't find a saved identifier in the list of touches\n            // that are currently active on the event,\n            // we trigger an end event on it.\n            if (!toucheIdentifiers.includes(identifier)) {\n                if (!joystick) {\n                    this.error(`No collection found for cleaning identifier ${identifier}`);\n                    return;\n                }\n                this.log('💣 Cleaning', identifier);\n                // Build a synthetic event reusing the current event's position\n                // but with the inactive identifier. We extract specific properties\n                // because spreading native event objects doesn't copy prototype props.\n                const raw = evt.raw;\n                joystick.collection.processOnEnd(\n                    u.processEvent(evt.initial, {\n                        identifier,\n                        pageX: raw.pageX,\n                        pageY: raw.pageY,\n                        clientX: raw.clientX,\n                        clientY: raw.clientY,\n                    } as unknown as ProcessedEvent),\n                );\n            }\n        }\n    }\n\n    bindDocument() {\n        // Bind only if not already binded\n        if (!this.binded) {\n            this.log('bind dom');\n            this.bindEvt(document, 'start', this.onstart);\n            this.bindEvt(document, 'move', this.onmove);\n            this.bindEvt(document, 'end', this.onend);\n            this.bindEvt(document, 'pressure', this.onpressure);\n            this.binded = true;\n        }\n    }\n\n    unbindDocument(force: boolean = false) {\n        // If there are no touch left unbind the document.\n        if (this.binded && (!this.joysticksByUid.size || force === true)) {\n            this.log(`${force ? 'force ' : ''}unbind dom`);\n            this.unbindEvt(document, 'start', this.onstart);\n            this.unbindEvt(document, 'move', this.onmove);\n            this.unbindEvt(document, 'end', this.onend);\n            this.unbindEvt(document, 'pressure', this.onpressure);\n            this.binded = false;\n        }\n    }\n\n    private onstart(evt: DomEvent) {\n        // Each collection handles its own start event on their respective zones.\n        // Clean the inactive touches.\n        this.cleanInactiveTouches(evt);\n    }\n\n    private onmove(evt: DomEvent) {\n        this.handleEventInCollection(evt, (coll) => {\n            coll.processOnMove(evt);\n        });\n    }\n\n    private onend(evt: DomEvent) {\n        // Clean the inactive touches.\n        this.cleanInactiveTouches(evt);\n        // Proceed with each collection.\n        this.handleEventInCollection(evt, (coll) => {\n            coll.processOnEnd(evt);\n        });\n    }\n\n    private onpressure(evt: DomEvent) {\n        evt.initial.preventDefault();\n        const joystick = this.joysticksByIdentifier.get(evt.identifier);\n        if (!joystick) {\n            this.error(`No joystick found for pressure event ${evt.identifier}`);\n            return;\n        }\n        joystick.pressure = evt.pressure;\n    }\n\n    private handleEventInCollection(evt: DomEvent, cb: (coll: Collection) => void) {\n        const joystick = this.joysticksByIdentifier.get(evt.identifier);\n\n        // If the event doesn't have any joystick, we don't call any.\n        if (!joystick) {\n            return;\n        }\n\n        cb(joystick.collection);\n    }\n\n    // Cleanly destroy the factory\n    destroy() {\n        this.unbindDocument(true);\n        this.collections.forEach((collection) => {\n            collection.destroy();\n        });\n        // Unbind window listeners.\n        if (this.resizeHandler) {\n            u.unbindEvt(window, 'resize', this.resizeHandler);\n            this.resizeHandler = null;\n        }\n        if (this.scrollHandler) {\n            u.unbindEvt(window, 'scroll', this.scrollHandler);\n            this.scrollHandler = null;\n        }\n        this.trigger('factoryDestroyed', this);\n        // Clear all the event listeners.\n        this.off();\n    }\n}\n\nexport default Factory;\n"],"names":["MODES","IS_TOUCH","window","EVENTS_TO_BIND","start","move","end","pressure","primaryBind","secondaryBind","PointerEvent","PRIMARY_BIND","SECONDARY_BIND","ANGLE_45","Math","PI","ANGLE_90","distance","p1","p2","dx","x","dy","y","sqrt","radians","a","degrees","timers","Map","throttle","cb","has","clearTimeout","get","set","setTimeout","bindEvt","el","arg","handler","types","split","i","length","addEventListener","unbindEvt","removeEventListener","getPressureFromEvt","evt","force","webkitForce","buttons","processEvent","processedEvt","identifier","pointerId","isTouch","position","pageX","pageY","type","initial","raw","getScroll","scrollX","scrollY","applyPosition","pos","left","top","right","bottom","extend","style","isNumber","configStylePropertyObject","prop","value","objA","objB","Object","hasOwn","isNaN","LOG_LEVELS","debug","info","warning","error","none","currentLogLevel","Super","constructor","name","this","uid","index","_domHandlers_","_handlers_","log","mapOnEvents","on","Set","add","off","delete","trigger","data","handlers","size","snapshot","call","target","domEvt","toLowerCase","includes","preventDefault","domEvents","touch","changedTouches","push","map","u.processEvents","u.bindEvt","u.unbindEvt","logPrefix","super","joystick","collection","factory","logSuffix","logLevel","level","args","console","warn","_Joystick","options","direction","defaults","threshold","color","fadeTime","dataOnly","restJoystick","restOpacity","mode","zone","document","body","lockX","lockY","shape","frontPosition","ui","createElement","back","front","init","buildEl","_identifier","u.isNumber","resolveColors","className","setAttribute","appendChild","animTime","borderStyle","u.configStylePropertyObject","transitStyle","colors","u.extend","opacity","toString","display","zIndex","width","height","marginLeft","marginTop","background","transform","_pressure","startPressureInterval","pressureInterval","setInterval","u.getPressureFromEvt","stopPressureInterval","clearInterval","addToDom","contains","removeFromDom","removeChild","clearTimeouts","removeTimeout","showTimeout","restTimeout","activeTimeout","requestAnimationFrame","resetDirection","rest","newPosition","setPosition","destroy","setTransition","animated","activeTime","computeDirectionAndTriggerEvents","obj","rAngle","angle","radian","u.radians","degree","triggerDirectionEvents","oldDirection","Joystick","_Collection","all","idles","actives","resting","parentIsFlex","catchDistance","dynamicPage","follow","maxNumberOfJoysticks","multitouch","computedStyle","parentElement","getComputedStyle","box","getBoundingClientRect","processOnStart","touchAction","userSelect","webkitUserSelect","ResizeObserver","resizeObserver","reposition","observe","createJoystick","getJoystickByUid","values","next","bindJoystick","deleteJoystickFromLists","deleteIdentifierFromLists","instance","deleteUidFromLists","getOrCreate","idleUid","scroll","offset","toApply","stub","visibility","stubBox","u.applyPosition","_depth","process","processOnMove","u.distance","dist","atan2","u.angle","clamped_dist","clamped_pos","min","p","d","aInRad","cos","sin","u.findCoord","joystickPos","max","u.clamp","baseDelta","delta_x","delta_y","xPosition","yPosition","toSend","vector","processOnEnd","u.getScroll","forEach","elBox","disconnect","clear","Collection","binded","joysticksByUid","joysticksByIdentifier","collections","resizeHandler","scrollHandler","repositionAll","refreshScroll","bindResize","bindScroll","u.throttle","getJoystickByIdentifier","create","bindCollection","removeJoystickFromLists","unbindDocument","bindDocument","cleanInactiveTouches","toucheIdentifiers","Array","from","touches","t","keys","u.processEvent","clientX","clientY","onstart","onmove","onend","onpressure","handleEventInCollection","coll","setLogLevel","getLogLevel"],"mappings":"AAGO,MAAMA,EAEA,UAFAA,EAIH,OAJGA,EAMD,SAGNC,EAA6B,oBAAXC,QAA0B,iBAAkBA,OAI9DC,EAOK,CACHC,MAAO,YACPC,KAAM,YACNC,IAAK,sBACLC,SAAU,2BAUlB,IAAIC,EACAC,EAzBiC,oBAAXP,UAA4BA,OAAOQ,aA8BzDF,EAdS,CACLJ,MAAO,cACPC,KAAM,cACNC,IAAK,yCACLC,SAAU,2BAWPN,GAGPO,EA9BO,CACHJ,MAAO,aACPC,KAAM,YACNC,IAAK,wBACLC,SAAU,2BA2BdE,EAAgBN,GAGhBK,EAAcL,EAIX,MAAMQ,EAAeH,EACfI,EAAiBH,EAGjBI,EAAWC,KAAKC,GAAK,EACrBC,EAAWF,KAAKC,GAAK,EC3CrBE,EAAW,CAACC,EAAiBC,KAChC,MAAAC,EAAKD,EAAGE,EAAIH,EAAGG,EACfC,EAAKH,EAAGI,EAAIL,EAAGK,EAErB,OAAOT,KAAKU,KAAKJ,EAAKA,EAAKE,EAAKA,EAAE,EAoCzBG,EAAWC,GACbA,GAAKZ,KAAKC,GAAK,KAQbY,EAAWD,GACbA,GAAK,IAAMZ,KAAKC,IAGrBa,MAAaC,IAKNC,EAAYC,IACjBH,EAAOI,IAAID,IACEE,aAAAL,EAAOM,IAAIH,IAE5BH,EAAOO,IAAIJ,EAAIK,WAAWL,EAAI,KAAyB,EAS9CM,EAAU,CACnBC,EACAC,EACAC,KAEM,MAAAC,EAAQF,EAAIG,MAAM,UACxB,IAAA,IAASC,EAAI,EAAGA,EAAIF,EAAMG,OAAQD,GAAK,EACnCL,EAAGO,iBAAiBJ,EAAME,GAAIH,GAA+C,EAAK,EAU7EM,EAAY,CACrBR,EACAC,EACAC,KAEM,MAAAC,EAAQF,EAAIG,MAAM,UACxB,IAAA,IAASC,EAAI,EAAGA,EAAIF,EAAMG,OAAQD,GAAK,EACnCL,EAAGS,oBAAoBN,EAAME,GAAIH,EAA6C,EASzEQ,EAAsBC,GAExB,UAAWA,EACZA,EAAIC,MACJ,aAAcD,EACZA,EAAI1C,SACJ,gBAAiB0C,EACdA,EAAIE,YAAyB,EAC9B,YAAaF,GACK,IAAhBA,EAAIG,QACA,EAEJ,EAOHC,EAAe,CAACJ,EAAqBK,KAmBvC,CACHC,WAfA,eAAgBD,EACVA,EAAaC,WACb,cAAeD,EACbA,EAAaE,UAAA,EAarBC,QAAS,YAAaR,GAAO,mBAAoBA,EACjDS,SAAU,CACNrC,EAAGiC,EAAaK,MAChBpC,EAAG+B,EAAaM,OAEpBrD,SAAUyC,EAAmBM,GAC7BO,KAAMZ,EAAIY,KACVC,QAASb,EACTc,IAAKT,IA8CAU,EAAY,KAAoB,CACzC3C,EAAGnB,OAAO+D,QACV1C,EAAGrB,OAAOgE,UAQDC,EAAgB,CAAC7B,EAAiB8B,KAC3C,MAAMC,KAAEA,EAAMC,IAAAA,EAAAC,MAAKA,SAAOC,EAAQnD,EAAAA,EAAAE,EAAGA,GAAM6C,EACvCE,GAAOC,GAASC,GAAUH,EAC1BI,EAAOnC,EAAGoC,MAAO,CAAEJ,MAAKC,QAAOC,SAAQH,UAChCM,EAAStD,IAAMsD,EAASpD,KAC/BkD,EAAOnC,EAAGoC,MAAO,CACbL,KAAMM,EAAStD,GAAK,GAAGA,WAAQ,EAC/BiD,IAAKK,EAASpD,GAAK,GAAGA,WAAQ,GACD,EAS5BqD,EAA4B,CACrCC,EACAC,EAAgB,MACU,CAC1BD,CAACA,GAAOC,IASCL,EAAS,CAAmBM,EAASC,KAC9C,IAAA,MAAWrC,KAAKqC,EACRC,OAAOC,OAAOF,EAAMrC,KACfoC,EAAApC,GAAgBqC,EAAKrC,IAG3B,OAAAoC,CAAA,EAsBEJ,EAAYG,GACG,iBAAVA,IAAuBK,MAAML,GCvQzCM,EAAuC,CACzCC,MAAO,EACPC,KAAM,EACNC,QAAS,EACTC,MAAO,EACPC,KAAM,GAGV,IAAIC,EAA4B,UASzB,MAAMC,EAOT,WAAAC,CAAYC,GANDC,KAAAC,IAAA,EACKD,KAAAE,MAAA,EACHF,KAAAD,KAAA,QACLC,KAAAG,kBAAyEpE,IACjFiE,KAAQI,WAAgF,CAAC,EAGrFJ,KAAKD,KAAOA,EACZC,KAAKK,IAAI,YAAaL,KAAKD,KAAMC,KAAKE,MAAK,CAG/C,WAAAI,CAAY7D,EAAaR,GACf,MAAAU,EAAQF,EAAIG,MAAM,UAExB,IAAA,IAASC,EAAI,EAAGA,EAAIF,EAAMG,OAAQD,GAAK,EAChCZ,EAAAU,EAAME,GACb,CAuBJ,EAAA0D,CAAM9D,EAAaR,GACV+D,KAAAM,YAAY7D,GAAMsB,IACdiC,KAAAI,WAAWrC,GAAQiC,KAAKI,WAAWrC,QAAayC,IACrDR,KAAKI,WAAWrC,GAAO0C,IAAIxE,EAAE,GAChC,CAsBL,GAAAyE,CAAOjE,EAAcR,QACL,IAARQ,EAEAuD,KAAKI,WAAa,CAAC,EAEdJ,KAAAM,YAAY7D,GAAMsB,SACR,IAAP9B,EAEA+D,KAAKI,WAAWrC,GAAQ,IAAIyC,IACrBR,KAAKI,WAAWrC,IAEvBiC,KAAKI,WAAWrC,GAAO4C,OAAO1E,EAAE,GAG5C,CAsBJ,OAAA2E,CAAWnE,EAAaoE,GACfb,KAAAM,YAAY7D,GAAMsB,IACdiC,KAAAK,IAAI,MAAMtC,gBACT,MAAA+C,EAAWd,KAAKI,WAAWrC,GAC7B,GAAA+C,GAAYA,EAASC,KAAM,CAErB,MAAAC,EAAW,IAAIF,GACrB,IAAA,MAAWpE,KAAWsE,EAClBtE,EAAQuE,KAAKjB,KAAM,CACfjC,OACAmD,OAAQlB,KACRa,QAER,IAEP,CAIL,OAAAtE,CAAQC,EAAsBuB,EAAiBrB,GACrC,MAAAT,EAAMkB,IACR,IAAA,MAAWgE,IDqBM,CAAChE,IAIbA,EAAIY,KAAKqD,cACbC,SAAS,SACdlE,EAAImE,iBAIR,MAAMC,EAA8B,GAEpC,GAAI,mBAAoBpE,EAET,IAAA,MAAAqE,KAASrE,EAAIsE,eAChBD,GACAD,EAAUG,KAAKF,QAIvBD,EAAUG,KAAKvE,GAIZ,OAAAoE,EAAUI,KAAeR,GACrB5D,EAAaJ,EAAKgE,IAC5B,EC/C4BS,CAAgBzE,GACjC6C,KAAKK,IAAI,MAAMtC,mBAAsBoD,EAAO1D,eACpCf,EAAAuE,KAAKjB,KAAMmB,EAAM,EAK5BnB,KAAAG,cAAc9D,IAAIK,EAAST,GAEhC4F,EAAUrF,EAAI3B,EAAakD,GAAO9B,GAE9BnB,IAAiBiD,IAEjB8D,EAAUrF,EAAI1B,EAAeiD,GAAO9B,EACxC,CAIJ,SAAAe,CAAUR,EAAsBuB,EAAiBrB,GAC7C,MAAMT,EAAK+D,KAAKG,cAAc/D,IAAIM,GAE7BT,GAKL6F,EAAYtF,EAAI3B,EAAakD,GAAO9B,GAEhCnB,IAAiBiD,IAEjB+D,EAAYtF,EAAI1B,EAAeiD,GAAO9B,GAGrC+D,KAAAG,cAAcQ,OAAOjE,IAXtBsD,KAAKN,MAAM,wCAAwC3B,KAASrB,EAW/B,CAGrC,SAAAqF,GAQW,MAPgC,CACnCC,MAAO,GACPC,SAAU,KACVC,WAAY,OACZC,QAAS,UAGGnC,KAAKD,KAAI,CAG7B,SAAAqC,GACI,MAAO,IAAIpC,KAAKD,QAAQC,KAAKC,MAAG,CAGpC,mBAAWoC,GACA,OAAAzC,CAAA,CAGX,mBAAWyC,CAASC,GACE1C,EAAA0C,CAAA,CAGtB,GAAAjC,IAAOkC,GACCjD,EAAWM,IAAoBN,EAAWC,OAClCiD,QAAAnC,IAAIL,KAAK+B,eAAgBQ,EAAMvC,KAAKoC,YAChD,CAGJ,IAAA5C,IAAQ+C,GACAjD,EAAWM,IAAoBN,EAAWE,MAClCgD,QAAAhD,KAAKQ,KAAK+B,eAAgBQ,EAAMvC,KAAKoC,YACjD,CAGJ,IAAAK,IAAQF,GACAjD,EAAWM,IAAoBN,EAAWG,SAClC+C,QAAAC,KAAKzC,KAAK+B,eAAgBQ,EAAMvC,KAAKoC,YACjD,CAGJ,KAAA1C,IAAS6C,GACDjD,EAAWM,IAAoBN,EAAWI,OAClC8C,QAAA9C,MAAMM,KAAK+B,eAAgBQ,EAAMvC,KAAKoC,YAClD,EC5ND,MAAMM,EAAN,MAAMA,UAAiB7C,EAmC1B,WAAAC,CAAYoC,EAAwBS,GAChCX,MAAM,YAlBVhC,KAAA4C,UAAuB,CAAC,EAEiE5C,KAAA6C,SAAA,CACrF9B,KAAM,IACN+B,UAAW,GACXC,MAAO,QACPC,SAAU,IACVC,UAAU,EACVC,cAAc,EACdC,YAAa,GACbC,KAAM,UACNC,KAAMC,SAASC,KACfC,OAAO,EACPC,OAAO,EACPC,MAAO,UAMP1D,KAAKpC,SAAW+E,EAAQ/E,SACxBoC,KAAK2D,cAAgBhB,EAAQgB,cAC7B3D,KAAKkC,WAAaA,EAClBlC,KAAK2C,QAAU,IAAK3C,KAAK6C,YAAaF,GAGZ,YAAtB3C,KAAK2C,QAAQS,OAEbpD,KAAK2C,QAAQQ,YAAc,GAG/BnD,KAAKC,IAAMyC,EAASxC,QAEpBF,KAAK4D,GAAK,CACNpH,GAAI8G,SAASO,cAAc,OAC3BC,KAAMR,SAASO,cAAc,OAC7BE,MAAOT,SAASO,cAAc,OAClC,CAGJ,IAAAG,GACShE,KAAK2C,QAAQM,UACdjD,KAAKiE,UAEJjE,KAAAY,QAAQ,QAASZ,MACjBA,KAAAY,QAAQ,kBAAmBZ,KAAI,CAGxC,cAAIvC,GACA,OAAOuC,KAAKkE,WAAA,CAGhB,cAAIzG,CAAWA,GACN0G,EAAW1G,IAQZuC,KAAKkE,YAAczG,EACnBuC,KAAKY,QAAQ,WAAY,CACrBsB,WAAYlC,KAAKkC,WACjBD,SAAUjC,KACVvC,iBAXJuC,KAAKY,QAAQ,WAAY,CACrBsB,WAAYlC,KAAKkC,WACjBD,SAAUjC,KACVvC,WAAYuC,KAAKkE,cAErBlE,KAAKkE,iBAAc,EAQvB,CAGI,aAAAE,GACE,MAAArB,EAAQ/C,KAAK2C,QAAQI,MAC3B,MAAqB,iBAAVA,GAAgC,OAAVA,EACtBA,EAEJ,CAAEgB,MAAOhB,EAAiBe,KAAMf,EAAgB,CAGnD,OAAAkB,GAEJjE,KAAK4D,GAAGpH,GAAG6H,UAAY,uBAAuBrE,KAAKkC,WAAWjC,MACzDD,KAAA4D,GAAGE,KAAKO,UAAY,OACpBrE,KAAA4D,GAAGG,MAAMM,UAAY,QAErBrE,KAAA4D,GAAGpH,GAAG8H,aAAa,KAAM,YAAYtE,KAAKkC,WAAWjC,OAAOD,KAAKC,OAEtED,KAAK4D,GAAGpH,GAAG+H,YAAYvE,KAAK4D,GAAGE,MAC/B9D,KAAK4D,GAAGpH,GAAG+H,YAAYvE,KAAK4D,GAAGG,OAG/B,MAAMS,EAAW,GAAGxE,KAAK2C,QAAQK,aAC3ByB,EAAcC,EAA4B,eAAgB,OAC1DC,EAAeD,EAA4B,aAAc,WAAWF,KACpEI,EAAS5E,KAAKoE,gBAEpBS,EAAS7E,KAAK4D,GAAGpH,GAAGoC,MAAO,CACvBhB,SAAU,WACVkH,QAAS9E,KAAK2C,QAAQQ,YAAY4B,WAClCC,QAAS,QACTC,OAAQ,SACLN,IAGPE,EAAS7E,KAAK4D,GAAGE,KAAKlF,MAAO,CACzBhB,SAAU,WACVoH,QAAS,QACTE,MAAO,GAAGlF,KAAK2C,QAAQ5B,SACvBoE,OAAQ,GAAGnF,KAAK2C,QAAQ5B,SACxBxC,KAAM,IACN6G,YAAgBpF,KAAK2C,QAAQ5B,KAAO,EAAxB,KACZsE,WAAerF,KAAK2C,QAAQ5B,KAAO,EAAxB,KACXuE,WAAYV,EAAOd,QACQ,WAAvB9D,KAAK2C,QAAQe,MAAqBe,EAAc,CAAA,IAGxDI,EAAS7E,KAAK4D,GAAGG,MAAMnF,MAAO,CAC1BsG,MAAUlF,KAAK2C,QAAQ5B,KAAO,EAAvB,KACPoE,OAAWnF,KAAK2C,QAAQ5B,KAAO,EAAvB,KACRnD,SAAU,WACVoH,QAAS,QACTzG,KAAM,IACN6G,YAAgBpF,KAAK2C,QAAQ5B,KAAO,EAAxB,KACZsE,WAAerF,KAAK2C,QAAQ5B,KAAO,EAAxB,KACXuE,WAAYV,EAAOb,MACnBe,QAAS,KACTS,UAAW,yBACRd,GACN,CAGL,YAAIhK,GACA,OAAOuF,KAAKwF,WAAa,CAAA,CAG7B,YAAI/K,CAASA,GACLA,IAAauF,KAAKwF,YAClBxF,KAAKwF,UAAY/K,EACZuF,KAAAY,QAAQ,WAAYnG,GAC7B,CAGJ,qBAAAgL,CAAsBtI,GACd6C,KAAK0F,mBAIJ1F,KAAA0F,iBAAmBtL,OAAOuL,aAAY,KAClC3F,KAAAvF,SAAWmL,EAAqBzI,EAAG,GACzC,KAAG,CAGV,oBAAA0I,GACIC,cAAc9F,KAAK0F,kBACnB1F,KAAK0F,sBAAmB,CAAA,CAI5B,QAAAK,GAEQ/F,KAAK2C,QAAQM,UAAYK,SAASC,KAAKyC,SAAShG,KAAK4D,GAAGpH,KAG5DwD,KAAK2C,QAAQU,KAAKkB,YAAYvE,KAAK4D,GAAGpH,GAAE,CAI5C,aAAAyJ,IACQjG,KAAK2C,QAAQM,UAAaK,SAASC,KAAKyC,SAAShG,KAAK4D,GAAGpH,KAG7DwD,KAAK2C,QAAQU,KAAK6C,YAAYlG,KAAK4D,GAAGpH,GAAE,CAGpC,aAAA2J,GACJhK,aAAa6D,KAAKoG,eAClBjK,aAAa6D,KAAKqG,aAClBlK,aAAa6D,KAAKsG,aAClBnK,aAAa6D,KAAKuG,eAElBvG,KAAKoG,mBAAgB,EACrBpG,KAAKqG,iBAAc,EACnBrG,KAAKsG,iBAAc,EACnBtG,KAAKuG,mBAAgB,CAAA,CAIzB,KAAAjM,CAAM6C,EAAqBlB,GAClB+D,KAAAY,QAAQ,QAASZ,MAEtBA,KAAKmG,gBAEDnG,KAAK2C,QAAQM,SACK,mBAAPhH,GACPA,EAAGgF,KAAKjB,OAKhBA,KAAK+F,WAEL/F,KAAKyF,sBAAsBtI,GAE3BqJ,uBAAsB,KACbxG,KAAA4D,GAAGpH,GAAGoC,MAAMkG,QAAU,GAAA,IAG1B9E,KAAAqG,YAAcjM,OAAOkC,YAAW,KACjC0D,KAAKqG,iBAAc,EACdrG,KAAAY,QAAQ,QAASZ,MACJ,mBAAP/D,GACPA,EAAGgF,KAAKjB,KAAI,GAEjBA,KAAK2C,QAAQK,UAAQ,CAI5B,GAAAxI,CAAIyB,GAOI,GANJ+D,KAAKyG,iBACLzG,KAAKmG,gBACLnG,KAAK6F,uBACL7F,KAAKvF,SAAW,EACXuF,KAAAY,QAAQ,MAAOZ,MAEhBA,KAAK2C,QAAQM,SACK,mBAAPhH,GACPA,EAAGgF,KAAKjB,UAFZ,CAYA,GAJJA,KAAK4D,GAAGpH,GAAGoC,MAAMkG,QAAU9E,KAAK2C,QAAQQ,YAAY4B,WAIhD/E,KAAK2C,QAAQO,aAAc,CACrB,MAAAwD,EAAO1G,KAAK2C,QAAQO,aACpByD,EAAc,CAChBpL,GAAY,IAATmL,IAA4B,IAAXA,EAAKnL,EAAc,EAAIyE,KAAK2D,cAAcpI,EAC9DE,GAAY,IAATiL,IAA4B,IAAXA,EAAKjL,EAAc,EAAIuE,KAAK2D,cAAclI,GAG7DuE,KAAA4G,YAAY3K,EAAI0K,EAAW,CAKpCxK,aAAa6D,KAAKoG,eACbpG,KAAAoG,cAAgBhM,OAAOkC,YAAW,KACnC0D,KAAKoG,mBAAgB,EAEhBpG,KAAA4D,GAAGpH,GAAGoC,MAAMoG,QAAUhF,KAAK2C,QAAQS,OAASlJ,EAAgB,OAAS,QACrE8F,KAAAY,QAAQ,SAAUZ,MAInBA,KAAK2C,QAAQS,OAASlJ,IACjB8F,KAAAY,QAAQ,UAAWZ,MACxBA,KAAK6G,WAGS,mBAAP5K,GACPA,EAAGgF,KAAKjB,KAAI,GAEjBA,KAAK2C,QAAQK,SArCZ,CAqCoB,CAG5B,aAAA8D,CAAcC,GAAoB,EAAO9K,GACrC,GAAI8K,EAAU,CACV,MAAMC,EAAa,IAEbrC,EAAeE,EAEjBH,EAA4B,aAAc,aAH7B,GAAGsC,SAKhBtC,EACI,YACA,aAAa1E,KAAK2D,cAAcpI,QAAQyE,KAAK2D,cAAclI,SAKnEoJ,EAAS7E,KAAK4D,GAAGG,MAAMnF,MAAO+F,GAE9BxI,aAAa6D,KAAKuG,eACbvG,KAAAuG,cAAgBnM,OAAOkC,YAAW,KACnC0D,KAAKuG,mBAAgB,EACH,mBAAPtK,GACPA,EAAGgF,KAAKjB,KAAI,GAEjBgH,EAAU,MAEXnC,EAAO7E,KAAK4D,GAAGG,MAAMnF,MAAO8F,EAA4B,aAAc,QAC5E,CAIJ,WAAAkC,CAAY3K,EAA8B2B,GACtCoC,KAAK2D,cAAgB,CACjBpI,EAAGqC,EAASrC,EACZE,EAAGmC,EAASnC,GAGhBuE,KAAK8G,eAAc,GAEnB3K,aAAa6D,KAAKsG,aACbtG,KAAAsG,YAAclM,OAAOkC,YAAW,KACjC0D,KAAKsG,iBAAc,EACD,mBAAPrK,GACPA,EAAGgF,KAAKjB,MAGZA,KAAK8G,eAAc,GACd9G,KAAAY,QAAQ,SAAUZ,KAAI,GAC5BA,KAAK2C,QAAQK,SAAQ,CAG5B,cAAAyD,GAEIzG,KAAK4C,UAAY,CAAC,CAAA,CAGtB,gCAAAqE,CAAiCC,GACvB,MAAAC,EAASD,EAAIE,MAAMC,OACnBzE,EAAuB,CAAC,EAgDvB,OAvCHuE,EAASpM,GAAYoM,EAAoB,EAAXpM,IAAiBmM,EAAI1D,MACnDZ,EAAUwE,MAAQ,KACXD,GAAUpM,GAAYoM,GAAUpM,IAAamM,EAAIzD,MACxDb,EAAUwE,MAAQ,OACXD,EAAqB,GAAXpM,GAAgBoM,IAAWpM,IAAamM,EAAI1D,MAC7DZ,EAAUwE,MAAQ,OACVF,EAAIzD,QACZb,EAAUwE,MAAQ,SAQjBF,EAAIzD,QAEDb,EAAUrH,EADV4L,GAAUjM,GAAYiM,EAASjM,EACjB,OAEA,SAIjBgM,EAAI1D,QAEDZ,EAAUnH,EADV0L,EAAS,EACK,KAEA,QAKtBD,EAAIE,MAAQ,CACRC,OAAQC,EAAU,IAAMJ,EAAIE,MAAMG,QAClCA,OAAQ,IAAML,EAAIE,MAAMG,QAGvBvH,KAAAwH,uBAAuBN,EAAKtE,GAE1BsE,CAAA,CAGH,sBAAAM,CAAuBN,EAAwBtE,GACnD,GAAIsE,EAAI9J,MAAQ4C,KAAK2C,QAAQG,UAAW,CACpC,MAAM2E,EAAe,CACjBlM,EAAGyE,KAAK4C,UAAUrH,EAClBE,EAAGuE,KAAK4C,UAAUnH,EAClB2L,MAAOpH,KAAK4C,UAAUwE,OAG1BpH,KAAK4C,UAAYA,EACjBsE,EAAItE,UAAYA,EAEZ6E,EAAalM,IAAMqH,EAAUrH,GAC7ByE,KAAKY,QAAQ,eAAegC,EAAUrH,IAAK2L,GAG3CO,EAAahM,IAAMmH,EAAUnH,GAC7BuE,KAAKY,QAAQ,eAAegC,EAAUnH,IAAKyL,GAG3CO,EAAaL,QAAUxE,EAAUwE,OACjCpH,KAAKY,QAAQ,WAAWgC,EAAUwE,QAASF,EAC/C,MAEAlH,KAAKyG,iBAGJzG,KAAAY,QAAQ,OAAQsG,EAAG,CAI5B,OAAAL,GACI7G,KAAKmG,gBACLnG,KAAKvC,gBAAa,EAClBuC,KAAKiG,gBACAjG,KAAAY,QAAQ,oBAAqBZ,MAClCA,KAAKU,KAAI,GA5aJgC,EACFxC,MAAgB,EADpB,IAAMwH,EAANhF,ECNA,MAAMiF,EAAN,MAAMA,UAAmB9H,EAqF5B,WAAAC,CAAYqC,EAAkBQ,GAC1BX,MAAM,cAhEVhC,KAAA4H,QAA8B7L,IAQ9BiE,KAAA6H,UAAsBrH,IAQtBR,KAAA8H,YAAyC/L,IAUzCiE,KAAA+H,YAAyChM,IAIjBiE,KAAAgI,cAAA,EAYgBhI,KAAA6C,SAAA,CACpCoF,cAAe,IACflF,MAAO,QACPE,UAAU,EACViF,aAAa,EACblF,SAAU,IACVmF,QAAQ,EACR3E,OAAO,EACPC,OAAO,EACP2E,qBAAsB,GACtBhF,KAAMlJ,EACNmO,YAAY,EACZzK,SAAU,CAAEY,IAAK,MAAOD,KAAM,OAC9B2E,cAAc,EACdC,YAAa,GACbO,MAAO,SACP3C,KAAM,IACN+B,UAAW,GACXO,KAAMC,SAASC,MAKfvD,KAAKmC,QAAUA,EACfnC,KAAKC,IAAM0H,EAAWzH,QACtBF,KAAK2C,QAAU,IAAK3C,KAAK6C,YAAaF,GAIlC3C,KAAK2C,QAAQS,OAASlJ,GAAgB8F,KAAK2C,QAAQS,OAASlJ,IAC5D8F,KAAK2C,QAAQ0F,YAAa,GAIzBrI,KAAK2C,QAAQ0F,aACdrI,KAAK2C,QAAQyF,qBAAuB,GAIlC,MAAAE,EACFtI,KAAK2C,QAAQU,KAAKkF,eAAiBC,iBAAiBxI,KAAK2C,QAAQU,KAAKkF,eAC3C,SAA3BD,GAAetD,UACfhF,KAAKgI,cAAe,GAKH,WADAQ,iBAAiBxI,KAAK2C,QAAQU,MAAMzF,UAEhDoC,KAAAyC,KACD,+DACA,6CACA,qEAKRzC,KAAKyI,IAAMzI,KAAK2C,QAAQU,KAAKqF,wBAG7B1I,KAAKzD,QAAQyD,KAAK2C,QAAQU,KAAM,QAASrD,KAAK2I,gBAI9C9D,EAAS7E,KAAK2C,QAAQU,KAAKzE,MAAO,CAC9BgK,YAAa,OACbC,WAAY,OACZC,iBAAkB,SAIQ,oBAAnBC,iBACF/I,KAAAgJ,eAAiB,IAAID,gBAAe,KACrC/I,KAAKiJ,YAAW,IAEpBjJ,KAAKgJ,eAAeE,QAAQlJ,KAAK2C,QAAQU,MAC7C,CAGJ,IAAAW,GAII,GAHKhE,KAAAY,QAAQ,oBAAqBZ,MAG9BA,KAAK2C,QAAQS,OAASlJ,EAAc,CACnB8F,KAAKmJ,eAAenJ,KAAK2C,QAAQ/E,UACzCmI,UAAS,CACtB,CAGJ,gBAAAqD,CAAiBnJ,GAEb,YAAY,IAARA,EACOD,KAAK4H,IAAIyB,SAASC,OAAOtK,MAG7BgB,KAAK4H,IAAIxL,IAAI6D,EAAG,CAGnB,YAAAsJ,CAAatH,GAERA,EAAA1B,GAAG,qBAAqB,KAC7BP,KAAKwJ,wBAAwBvH,EAAQ,IAIhCA,EAAA1B,GAAG,YAAapD,IACrB6C,KAAK6H,MAAMlH,OAAOxD,EAAI0D,KAAKoB,SAAShC,KACpCD,KAAK8H,QAAQzL,IAAIc,EAAI0D,KAAKpD,WAAYwE,EAAQ,IAIzCA,EAAA1B,GAAG,YAAapD,IACrB6C,KAAK6H,MAAMpH,IAAItD,EAAI0D,KAAKoB,SAAShC,KAC5BD,KAAAyJ,0BAA0BtM,EAAI0D,KAAKpD,WAAU,IAI7CwE,EAAA1B,GAAG,OAAQpD,IACZgH,EAAWhH,EAAI0D,KAAKpD,cACpBuC,KAAK8H,QAAQnH,OAAOxD,EAAI0D,KAAKpD,YAC7BuC,KAAK+H,QAAQ1L,IAAIc,EAAI0D,KAAKpD,WAAYwE,GAAQ,IAK7CA,EAAA1B,GAAG,UAAWpD,IACfgH,EAAWhH,EAAI0D,KAAKpD,aACpBuC,KAAK+H,QAAQpH,OAAOxD,EAAI0D,KAAKpD,YAEjCuC,KAAK6H,MAAMpH,IAAItD,EAAI0D,KAAKZ,IAAG,IAItBgC,EAAA1B,GAAG,YAAapD,IACrB6C,KAAKY,QAAQ,YAAYqB,EAAShC,eAAgB9C,EAAI0D,KAAI,IAErDoB,EAAA1B,GAAG,qBAAsBpD,IAExB,MAAAY,EAAO,GAAGZ,EAAIY,QAAQZ,EAAI0D,KAAKoB,SAAShC,OAAO9C,EAAIY,OACpDiC,KAAAY,QAAQ7C,EAAiBZ,EAAI0D,KAAI,IAEjCoB,EAAA1B,GACL,iFACCpD,IAUS,MAAAY,EAAO,GAAGZ,EAAIY,QAAQZ,EAAI0D,KAAKZ,OAAO9C,EAAIY,OAC3CiC,KAAAY,QAAQ7C,EAAiBZ,EAAI0D,KAAI,IAGrCoB,EAAA1B,GAAG,QAASpD,IACZ6C,KAAAY,QAAQ,QAAQzD,EAAI0D,KAAK6I,SAASzJ,WAAY9C,EAAI0D,KAAI,IAEtDoB,EAAA1B,GAAG,0CAA2CpD,IAC7C,MAAAY,EAAO,GAAGZ,EAAIY,QAAQZ,EAAI0D,KAAK6I,SAASzJ,OAAO9C,EAAIY,OACpDiC,KAAAY,QAAQ7C,EAAwBZ,EAAI0D,KAAI,IAExCoB,EAAA1B,GAAG,oDAAqDpD,IACvD,MAAAY,EAAO,GAAGZ,EAAIY,QAAQZ,EAAI0D,KAAK6I,SAASzJ,OAAO9C,EAAIY,OACpDiC,KAAAY,QAAQ7C,EAA0BZ,EAAI0D,KAAI,GAClD,CAGG,uBAAA2I,CAAwBvH,GACvBjC,KAAA2J,mBAAmB1H,EAAShC,KAC7BkE,EAAWlC,EAASxE,aACfuC,KAAAyJ,0BAA0BxH,EAASxE,WAC5C,CAGI,kBAAAkM,CAAmB1J,GAClBD,KAAA4H,IAAIjH,OAAOV,GACXD,KAAA6H,MAAMlH,OAAOV,EAAG,CAGjB,yBAAAwJ,CAA0BhM,GACzBuC,KAAA8H,QAAQnH,OAAOlD,GACfuC,KAAA+H,QAAQpH,OAAOlD,EAAU,CAG1B,WAAAmM,CAAYhM,GAEZ,GAAAoC,KAAK2C,QAAQS,OAASlJ,GAAc8F,KAAK2C,QAAQS,OAASlJ,EAAc,CAExE,MAAM2P,EAA2B7J,KAAK6H,MAAMwB,SAASC,OAAOtK,MACxD,GAAAmF,EAAW0F,GAAU,CACrB,MAAM5H,EAAWjC,KAAK4H,IAAIxL,IAAIyN,GAC9B,GAAK5H,EAKM,OAAAA,EAJFjC,KAAAN,MAAM,8BAA8BmK,0BAEzC7J,KAAK2J,mBAAmBE,EAG5B,CAKJ,GAAI7J,KAAK2C,QAAQS,OAASlJ,EACf,OAAA8F,KAAKmJ,eAAevL,GAK/BoC,KAAKyC,KAAK,2DAA0D,CAIjE,OAAAzC,KAAKmJ,eAAevL,EAAQ,CAG/B,cAAAuL,CAAevL,GACb,MAAAkM,EAAS9J,KAAKmC,QAAQ2H,OAItBC,EACC/J,KAAKgI,aAAe8B,EAAOvO,EAAIuO,EAAOvO,EAAIyE,KAAKyI,IAAIlK,KADpDwL,EAEC/J,KAAKgI,aAAe8B,EAAOrO,EAAIqO,EAAOrO,EAAIuE,KAAKyI,IAAIjK,IAKtD,IAAAwL,EACArD,EAEA,GAAAxC,EAAWvG,EAASrC,IAAM4I,EAAWvG,EAASnC,GACpCuO,EAAA,CACNzO,EAAGqC,EAASrC,EAAIwO,EAChBtO,EAAGmC,EAASnC,EAAIsO,GAENpD,EAAA,CACVpL,EAAGqC,EAASrC,EACZE,EAAGmC,EAASnC,OAEpB,MAAWmC,EAASY,KAAOZ,EAASa,OAASb,EAASc,QAAUd,EAASW,MA2B9D,YADFyB,KAAAN,MAAM,+BAAgC9B,GA1BgC,CAErE,MAAAqM,EAAO3G,SAASO,cAAc,OAClCgB,EAAOoF,EAAKrL,MAAO,CACjBsL,WAAY,SACZtM,SAAU,WACVY,IAAKZ,EAASY,IACdC,MAAOb,EAASa,MAChBC,OAAQd,EAASc,OACjBH,KAAMX,EAASW,OAIdyB,KAAA2C,QAAQU,KAAKkB,YAAY0F,GACxB,MAAAE,EAAUF,EAAKvB,wBAEhB1I,KAAA2C,QAAQU,KAAK6C,YAAY+D,GAEpBD,EAAApM,EAGI+I,EAAA,CACVpL,EAAG4O,EAAQ5L,KAAOuL,EAAOvO,EACzBE,EAAG0O,EAAQ3L,IAAMsL,EAAOrO,EAC5B,CAGO,CAGL,MAAAwG,EAAW,IAAIyF,EAAS1H,KAAM,CAChC+C,MAAO/C,KAAK2C,QAAQI,MACpBhC,KAAMf,KAAK2C,QAAQ5B,KACnB+B,UAAW9C,KAAK2C,QAAQG,UACxBE,SAAUhD,KAAK2C,QAAQK,SACvBC,SAAUjD,KAAK2C,QAAQM,SACvBC,aAAclD,KAAK2C,QAAQO,aAC3BC,YAAanD,KAAK2C,QAAQQ,YAC1BC,KAAMpD,KAAK2C,QAAQS,KAGnBxF,SAAU+I,EACVtD,KAAMrD,KAAK2C,QAAQU,KACnBM,cAAe,CACXpI,EAAG,EACHE,EAAG,GAEPiI,MAAO1D,KAAK2C,QAAQe,QAsBjB,OAnBH1D,KAAK4H,IAAI1L,IAAI+F,EAAShC,MACtBD,KAAKN,MAAM,qBAAqBuC,EAAShC,uBAGxCD,KAAK2C,QAAQM,WAEdmH,EAAgBnI,EAAS2B,GAAGpH,GAAIwN,GAChCI,EAAgBnI,EAAS2B,GAAGG,MAAO9B,EAAS0B,gBAGhD3D,KAAK4H,IAAIvL,IAAI4F,EAAShC,IAAKgC,GACtBjC,KAAA6H,MAAMpH,IAAIwB,EAAShC,KACxBD,KAAKuJ,aAAatH,GAKlBA,EAAS+B,OAEF/B,CAAA,CAGX,cAAA0G,CAAexL,EAAekN,EAAiB,GAI3C,GAFArK,KAAKyI,IAAMzI,KAAK2C,QAAQU,KAAKqF,yBAIxB1I,KAAK8H,QAAQ5L,IAAIiB,EAAIM,aACtBuC,KAAK8H,QAAQ/G,MAAQf,KAAK2C,QAAQyF,qBAGlC,YADApI,KAAKyC,KAAK,8BAKd,MAAMR,EACFjC,KAAK8H,QAAQ1L,IAAIe,EAAIM,aACrBuC,KAAK+H,QAAQ3L,IAAIe,EAAIM,aACrBuC,KAAK4J,YAAYzM,EAAIS,UAEnB0M,EAAU,KAEHrI,EAAA3H,MAAM6C,EAAIc,KAEnBgE,EAASxE,WAAaN,EAAIM,WAErBuC,KAAAuK,cAAcpN,GAAK,EAAI,EAKhC,GAAI6C,KAAK2C,QAAQS,OAASlJ,EAAY,CACjBsQ,EAAWrN,EAAIS,SAAUqE,EAASrE,WACnCoC,KAAK2C,QAAQsF,cAEjBqC,IACDD,EAAS,GAEhBpI,EAAS4E,UACJ7G,KAAA2I,eAAexL,EAAKkN,EAAS,IAElCrK,KAAKN,MAAM,yCACf,MAGQ4K,GACZ,CAQJ,aAAAC,CAAcpN,EAAe4J,GAAoB,GAC7C,MAAM9E,EAAWjC,KAAK8H,QAAQ1L,IAAIe,EAAIM,YAChCqM,EAAS9J,KAAKmC,QAAQ2H,OAI5B,IAAK7H,EAGD,OAFAjC,KAAKN,MAAM,gDAAgDvC,EAAIM,mBAC1DuC,KAAAyJ,0BAA0BtM,EAAIM,YAenCuC,KAAK2C,QAAQuF,aACblI,KAAKiJ,aAGH,MAAAlI,EAAOkB,EAASU,QAAQ5B,KAAO,EAErC,IAAIzC,EAAmB,CACnB/C,EAAG4B,EAAIS,SAASrC,EAChBE,EAAG0B,EAAIS,SAASnC,GAIhBuE,KAAK2C,QAAQa,QACTlF,EAAA7C,EAAIwG,EAASrE,SAASnC,GAE1BuE,KAAK2C,QAAQc,QACTnF,EAAA/C,EAAI0G,EAASrE,SAASrC,GAG9B,IAAIkP,EAAOD,EAAWlM,EAAK2D,EAASrE,UACpC,MAAMwJ,EH1cO,EAAChM,EAAiBC,KAC7B,MAAAC,EAAKD,EAAGE,EAAIH,EAAGG,EACfC,EAAKH,EAAGI,EAAIL,EAAGK,EAErB,OAAOI,EAAQb,KAAK0P,MAAMlP,EAAIF,GAAG,EGscfqP,CAAQrM,EAAK2D,EAASrE,UAC9BuJ,EAASG,EAAUF,GACnBhK,EAAQqN,EAAO1J,EAGf9C,EAAmD,CACrD9C,SAAUsP,EACV7M,SAAUU,GAGV,IAAAsM,EACAC,EAE2B,WAA3B5I,EAASU,QAAQe,OAEFkH,EAAA5P,KAAK8P,IAAIL,EAAM1J,GAE9B8J,EH7ca,EAACE,EAAgBC,EAAWpP,KAC3C,MAAAqP,EAAStP,EAAQC,GAChB,MAAA,CACHL,EAAGwP,EAAExP,EAAIyP,EAAIhQ,KAAKkQ,IAAID,GACtBxP,EAAGsP,EAAEtP,EAAIuP,EAAIhQ,KAAKmQ,IAAIF,GAC1B,EGwcsBG,CAAYnJ,EAASrE,SAAUgN,EAAcxD,KAG3DyD,EH7OS,EAACvM,EAAkB+M,EAA0BtK,KAA+B,CAE7FxF,EAAGP,KAAK8P,IAAI9P,KAAKsQ,IAAIhN,EAAI/C,EAAG8P,EAAY9P,EAAIwF,GAAOsK,EAAY9P,EAAIwF,GAEnEtF,EAAGT,KAAK8P,IAAI9P,KAAKsQ,IAAIhN,EAAI7C,EAAG4P,EAAY5P,EAAIsF,GAAOsK,EAAY5P,EAAIsF,KGyO7CwK,CAAQjN,EAAK2D,EAASrE,SAAUmD,GAE9C6J,EAAeJ,EAAWK,EAAa5I,EAASrE,WAGpD,IAAI4N,EAAY,CAAEjQ,EAAG,EAAGE,EAAG,GAEvB,GAAAuE,KAAK2C,QAAQwF,QAEb,GAAIsC,EAAO1J,EAAM,CACP,MAAA0K,EAAUnN,EAAI/C,EAAIsP,EAAYtP,EAC9BmQ,EAAUpN,EAAI7C,EAAIoP,EAAYpP,EACpC+P,EAAY,CAAEjQ,EAAGkQ,EAAShQ,GAAIiQ,GAE9BzJ,EAASrE,SAASrC,GAAKkQ,EACvBxJ,EAASrE,SAASnC,GAAKiQ,EAEvB7G,EAAS5C,EAAS2B,GAAGpH,GAAGoC,MAAO,CAC3BJ,IAAQyD,EAASrE,SAASnC,GAAKuE,KAAKyI,IAAIjK,IAAMsL,EAAOrO,GAAhD,KACL8C,KAAS0D,EAASrE,SAASrC,GAAKyE,KAAKyI,IAAIlK,KAAOuL,EAAOvO,GAAjD,OAIVkP,EAAOD,EAAWlM,EAAK2D,EAASrE,SAAQ,OAKtCU,EAAAuM,EACCJ,EAAAG,EAIX,MAAMe,EAAYrN,EAAI/C,EAAI0G,EAASrE,SAASrC,EACtCqQ,EAAYtN,EAAI7C,EAAIwG,EAASrE,SAASnC,EAE5CwG,EAAS0B,cAAgB,CACrBpI,EAAGoQ,EACHlQ,EAAGmQ,GAIF5L,KAAK2C,QAAQM,WACV8D,GACS9E,EAAA6E,eAAc,GAAM,KACzB7E,EAAS6E,eAAc,EAAK,IAGpC7E,EAAS2B,GAAGG,MAAMnF,MAAM2G,UAAY,aAAaoG,OAAeC,QAIpE,MAAMC,EAA4B,CAC9BjO,SAAUU,EACVlB,QACA3C,SAAU0C,EAAI1C,SACdU,SAAUsP,EACVrD,MAAO,CACHC,OAAQF,EACRI,OAAQH,GAEZ0E,OAAQ,CACJvQ,EAAGoQ,EAAY5K,EACftF,GAAImQ,EAAY7K,GAEpB9C,MACAyL,SAAUzH,EACVuB,MAAOxD,KAAK2C,QAAQa,MACpBC,MAAOzD,KAAK2C,QAAQc,MACpB+H,aAGJvJ,EAASgF,iCAAiC4E,EAAM,CAGpD,YAAAE,CAAa5O,GACT,MAAM8E,EAAWjC,KAAK8H,QAAQ1L,IAAIe,EAAIM,YAGtC,IAAKwE,EAGD,OAFAjC,KAAKN,MAAM,+CAA+CvC,EAAIM,mBACzDuC,KAAAyJ,0BAA0BtM,EAAIM,YAKvCwE,EAASzH,KAAI,CAUjB,UAAAyO,GAESjJ,KAAAmC,QAAQ2H,OAASkC,IACtBhM,KAAKyI,IAAMzI,KAAK2C,QAAQU,KAAKqF,wBACvB,MAAAoB,EAAS9J,KAAKmC,QAAQ2H,OACvB9J,KAAA4H,IAAIqE,SAAShK,IACV,GAAAA,EAASU,QAAQM,SACjB,OAEJ,MAAMiJ,EAAQjK,EAAS2B,GAAGpH,GAAGkM,wBAC7BzG,EAASrE,SAAW,CAChBrC,EAAGuO,EAAOvO,EAAI2Q,EAAM3N,KACpB9C,EAAGqO,EAAOrO,EAAIyQ,EAAM1N,IACxB,GACH,CAGL,OAAAqI,GACQ7G,KAAKgJ,iBACLhJ,KAAKgJ,eAAemD,aACpBnM,KAAKgJ,oBAAiB,GAE1BhJ,KAAKhD,UAAUgD,KAAK2C,QAAQU,KAAM,QAASrD,KAAK2I,gBAE3C3I,KAAA4H,IAAIqE,SAAShK,IACdA,EAAS4E,SAAQ,IAIrB7G,KAAK4H,IAAIwE,QACTpM,KAAK6H,MAAMuE,QACXpM,KAAK8H,QAAQsE,QACbpM,KAAK+H,QAAQqE,QAGRpM,KAAAY,QAAQ,sBAAuBZ,MACpCA,KAAKU,KAAI,GAjnBJiH,EAIFzH,MAAgB,EAJpB,IAAMmM,EAAN1E,ECPM,MAAAxF,EAAU,ICMhB,cAAsBtC,EAUzB,WAAAC,GACIkC,MAAM,WATVhC,KAAA8J,OAAmCkC,IACnChM,KAAQsM,QAAkB,EAClBtM,KAAAuM,mBAAyCxQ,IACzCiE,KAAAwM,0BAAuDzQ,IACvDiE,KAAAyM,gBAAmCjM,IAC3CR,KAAQ0M,cAAqC,KAC7C1M,KAAQ2M,cAAqC,KAU7C3M,KAAQ4M,cAAgB,KACf5M,KAAAyM,YAAYR,SAAS/J,IACtBA,EAAW+G,YAAW,GACzB,EAELjJ,KAAQ6M,cAAgB,KACf7M,KAAA8J,OAASkC,GAAY,EAZ1BhM,KAAK8M,aACL9M,KAAK+M,aACA/M,KAAAY,QAAQ,iBAAkBZ,KAAI,CAc/B,UAAA8M,GACJ9M,KAAK0M,cAAgB,IAAMM,EAAWhN,KAAK4M,eAC3C/K,EAAUzH,OAAQ,SAAU4F,KAAK0M,cAAa,CAK1C,UAAAK,GACJ/M,KAAK2M,cAAgB,IAAMK,EAAWhN,KAAK6M,eAC3ChL,EAAUzH,OAAQ,SAAU4F,KAAK2M,cAAa,CAKlD,gBAAAvD,CAAiBnJ,GACN,OAAAD,KAAKuM,eAAenQ,IAAI6D,EAAG,CAKtC,uBAAAgN,CAAwBxP,GACb,OAAAuC,KAAKwM,sBAAsBpQ,IAAIqB,EAAU,CAIpD,MAAAyP,CAAOvK,GACH,MAAMT,EAAa,IAAImK,EAAWrM,KAAM2C,GAUjC,OARP3C,KAAKmN,eAAejL,GACflC,KAAAyM,YAAYhM,IAAIyB,GAKrBA,EAAW8B,OAEJ9B,CAAA,CAGH,uBAAAkL,CAAwBnL,GACvBjC,KAAAuM,eAAe5L,OAAOsB,EAAShC,KAChCkE,EAAWlC,EAASxE,aACfuC,KAAAwM,sBAAsB7L,OAAOsB,EAASxE,WAC/C,CAGI,cAAA0P,CAAejL,GAERA,EAAA3B,GAAG,uBAAwBpD,IAE7B6C,KAAAyM,YAAY9L,OAAOxD,EAAI0D,MAC5B1D,EAAI0D,KAAK+G,IAAIqE,SAAShK,IAClBjC,KAAKoN,wBAAwBnL,EAAQ,IAEzCjC,KAAKqN,gBAAe,IAGbnL,EAAA3B,GAAG,qBAAsBpD,IAC3B6C,KAAAoN,wBAAwBjQ,EAAI0D,MACjCb,KAAKqN,gBAAe,IAGbnL,EAAA3B,GAAG,OAAQpD,IACdgH,EAAWhH,EAAI0D,KAAKpD,aACpBuC,KAAKwM,sBAAsB7L,OAAOxD,EAAI0D,KAAKpD,YAE/CuC,KAAKqN,gBAAe,IAGbnL,EAAA3B,GAAG,SAAUpD,IACpB6C,KAAKuM,eAAelQ,IAAIc,EAAI0D,KAAKZ,IAAK9C,EAAI0D,MAC1Cb,KAAKsN,cAAa,IAGXpL,EAAA3B,GAAG,YAAapD,IACvB6C,KAAKwM,sBAAsBnQ,IAAIc,EAAI0D,KAAKpD,WAAYN,EAAI0D,KAAKoB,SAAQ,IAQ9DC,EAAA3B,GAAG,YAAapD,IACvB6C,KAAKY,QAAQ,YAAYzD,EAAI+D,OAAOjB,eAAgB9C,EAAI0D,KAAI,IAErDqB,EAAA3B,GAAG,yCAA0CpD,IAE9C,MAAAY,EAAO,GAAGZ,EAAIY,QAAQZ,EAAI0D,KAAKZ,OAAO9C,EAAIY,OAC3CiC,KAAAY,QAAQ7C,EAAiBZ,EAAI0D,KAAI,IAE/BqB,EAAA3B,GAAG,qBAAsBpD,IAC1B,MAAAY,EAAO,GAAGZ,EAAIY,QAAQZ,EAAI0D,KAAKoB,SAAShC,OAAO9C,EAAIY,OACpDiC,KAAAY,QAAQ7C,EAAmDZ,EAAI0D,KAAI,IAEjEqB,EAAA3B,GACP,iFACCpD,IAUS,MAAAY,EAAO,GAAGZ,EAAIY,QAAQZ,EAAI0D,KAAKZ,OAAO9C,EAAIY,OAC3CiC,KAAAY,QAAQ7C,EAAiBZ,EAAI0D,KAAI,IAGnCqB,EAAA3B,GAAG,QAASpD,IACd6C,KAAAY,QAAQ,QAAQzD,EAAI0D,KAAK6I,SAASzJ,WAAY9C,EAAI0D,KAAI,IAEpDqB,EAAA3B,GAAG,0CAA2CpD,IAC/C,MAAAY,EAAO,GAAGZ,EAAIY,QAAQZ,EAAI0D,KAAK6I,SAASzJ,OAAO9C,EAAIY,OACpDiC,KAAAY,QAAQ7C,EAAwBZ,EAAI0D,KAAI,IAEtCqB,EAAA3B,GAAG,oDAAqDpD,IACzD,MAAAY,EAAO,GAAGZ,EAAIY,QAAQZ,EAAI0D,KAAK6I,SAASzJ,OAAO9C,EAAIY,OACpDiC,KAAAY,QAAQ7C,EAA0BZ,EAAI0D,KAAI,GAClD,CAGL,oBAAA0M,CAAqBpQ,GACjB,MAAMqQ,EACF,YAAarQ,EAAIa,QACXyP,MAAMC,KAAKvQ,EAAIa,QAAQ2P,SAAShM,KAAKiM,GAAMA,EAAEnQ,aAC7C,CAACN,EAAIM,YACVuC,KAAAK,IACD,oBACAmN,EACAC,MAAMC,KAAK1N,KAAKwM,sBAAsBqB,SAI1C,IAAA,MAAYpQ,EAAYwE,KAAajC,KAAKwM,sBAEtC,GAAIvK,EAASC,WAAWS,QAAQS,OAASlJ,IAOpCsT,EAAkBnM,SAAS5D,GAAa,CACzC,IAAKwE,EAED,YADKjC,KAAAN,MAAM,+CAA+CjC,KAGzDuC,KAAAK,IAAI,cAAe5C,GAIxB,MAAMQ,EAAMd,EAAIc,IAChBgE,EAASC,WAAW6J,aAChB+B,EAAe3Q,EAAIa,QAAS,CACxBP,aACAI,MAAOI,EAAIJ,MACXC,MAAOG,EAAIH,MACXiQ,QAAS9P,EAAI8P,QACbC,QAAS/P,EAAI+P,UAErB,CAER,CAGJ,YAAAV,GAEStN,KAAKsM,SACNtM,KAAKK,IAAI,YACTL,KAAKzD,QAAQ+G,SAAU,QAAStD,KAAKiO,SACrCjO,KAAKzD,QAAQ+G,SAAU,OAAQtD,KAAKkO,QACpClO,KAAKzD,QAAQ+G,SAAU,MAAOtD,KAAKmO,OACnCnO,KAAKzD,QAAQ+G,SAAU,WAAYtD,KAAKoO,YACxCpO,KAAKsM,QAAS,EAClB,CAGJ,cAAAe,CAAejQ,GAAiB,IAExB4C,KAAKsM,QAAYtM,KAAKuM,eAAexL,OAAkB,IAAV3D,IAC7C4C,KAAKK,KAAOjD,EAAQ,SAAW,IAAtB,cACT4C,KAAKhD,UAAUsG,SAAU,QAAStD,KAAKiO,SACvCjO,KAAKhD,UAAUsG,SAAU,OAAQtD,KAAKkO,QACtClO,KAAKhD,UAAUsG,SAAU,MAAOtD,KAAKmO,OACrCnO,KAAKhD,UAAUsG,SAAU,WAAYtD,KAAKoO,YAC1CpO,KAAKsM,QAAS,EAClB,CAGI,OAAA2B,CAAQ9Q,GAGZ6C,KAAKuN,qBAAqBpQ,EAAG,CAGzB,MAAA+Q,CAAO/Q,GACN6C,KAAAqO,wBAAwBlR,GAAMmR,IAC/BA,EAAK/D,cAAcpN,EAAG,GACzB,CAGG,KAAAgR,CAAMhR,GAEV6C,KAAKuN,qBAAqBpQ,GAErB6C,KAAAqO,wBAAwBlR,GAAMmR,IAC/BA,EAAKvC,aAAa5O,EAAG,GACxB,CAGG,UAAAiR,CAAWjR,GACfA,EAAIa,QAAQsD,iBACZ,MAAMW,EAAWjC,KAAKwM,sBAAsBpQ,IAAIe,EAAIM,YAC/CwE,EAILA,EAASxH,SAAW0C,EAAI1C,SAHpBuF,KAAKN,MAAM,wCAAwCvC,EAAIM,aAGnC,CAGpB,uBAAA4Q,CAAwBlR,EAAelB,GAC3C,MAAMgG,EAAWjC,KAAKwM,sBAAsBpQ,IAAIe,EAAIM,YAG/CwE,GAILhG,EAAGgG,EAASC,WAAU,CAI1B,OAAA2E,GACI7G,KAAKqN,gBAAe,GACfrN,KAAAyM,YAAYR,SAAS/J,IACtBA,EAAW2E,SAAQ,IAGnB7G,KAAK0M,gBACL5K,EAAY1H,OAAQ,SAAU4F,KAAK0M,eACnC1M,KAAK0M,cAAgB,MAErB1M,KAAK2M,gBACL7K,EAAY1H,OAAQ,SAAU4F,KAAK2M,eACnC3M,KAAK2M,cAAgB,MAEpB3M,KAAAY,QAAQ,mBAAoBZ,MAEjCA,KAAKU,KAAI,GDtRJwM,EAAUvK,GACZR,EAAQ+K,OAAOvK,GAWb4L,EAAejM,IACxBzC,EAAMwC,SAAWC,CAAA,EAMRkM,EAAc,IAChB3O,EAAMwC,SAMjB,IAAenC,EAAA,CACXgN,SACA/K,UACAoM,cACAC"}