{"version":3,"file":"FilterSystem.mjs","sources":["../../src/filters/FilterSystem.ts"],"sourcesContent":["import { ExtensionType } from '../extensions/Extensions';\nimport { PassthroughFilter } from '../filters/defaults/passthrough/PassthroughFilter';\nimport { Matrix } from '../maths/matrix/Matrix';\nimport { type Rectangle } from '../maths/shapes/Rectangle';\nimport { BindGroup } from '../rendering/renderers/gpu/shader/BindGroup';\nimport { Geometry } from '../rendering/renderers/shared/geometry/Geometry';\nimport { UniformGroup } from '../rendering/renderers/shared/shader/UniformGroup';\nimport { Texture } from '../rendering/renderers/shared/texture/Texture';\nimport { TexturePool } from '../rendering/renderers/shared/texture/TexturePool';\nimport { RendererType } from '../rendering/renderers/types';\nimport { Bounds } from '../scene/container/bounds/Bounds';\nimport { getGlobalRenderableBounds } from '../scene/container/bounds/getRenderableBounds';\nimport { warn } from '../utils/logging/warn';\n\nimport type { WebGLRenderer } from '../rendering/renderers/gl/WebGLRenderer';\nimport type { WebGPURenderer } from '../rendering/renderers/gpu/WebGPURenderer';\nimport type { Instruction } from '../rendering/renderers/shared/instructions/Instruction';\nimport type { Renderable } from '../rendering/renderers/shared/Renderable';\nimport type { RenderTarget } from '../rendering/renderers/shared/renderTarget/RenderTarget';\nimport type { RenderSurface } from '../rendering/renderers/shared/renderTarget/RenderTargetSystem';\nimport type { System } from '../rendering/renderers/shared/system/System';\nimport type { Container } from '../scene/container/Container';\nimport type { Sprite } from '../scene/sprite/Sprite';\nimport type { Filter } from './Filter';\nimport type { FilterEffect } from './FilterEffect';\n\nconst quadGeometry = new Geometry({\n    attributes: {\n        aPosition: {\n            buffer: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]),\n            format: 'float32x2',\n            stride: 2 * 4,\n            offset: 0,\n        },\n    },\n    indexBuffer: new Uint32Array([0, 1, 2, 0, 2, 3]),\n});\n\n/**\n * The filter pipeline is responsible for applying filters scene items!\n *\n * KNOWN BUGS:\n * 1. Global bounds calculation is incorrect if it is used when flip flopping filters. The maths can be found below\n * eg: filters [noiseFilter, blurFilter] noiseFilter will calculate the global bounds incorrectly.\n *\n * 2. RenderGroups do not work with filters. This is because the renderGroup matrix is not currently taken into account.\n *\n * Implementation notes:\n * 1. Gotcha - nesting filters that require blending will not work correctly. This creates a chicken and egg problem\n * the complexity and performance required to do this is not worth it i feel.. but lets see if others agree!\n *\n * 2. Filters are designed to be changed on the fly, this is means that changing filter information each frame will\n * not trigger an instruction rebuild. If you are constantly turning a filter on and off.. its therefore better to set\n * enabled to true or false on the filter. Or setting an empty array.\n *\n * 3. Need to look at perhaps aliasing when flip flopping filters. Really we should only need to antialias the FIRST\n * Texture we render too. The rest can be non aliased. This might help performance.\n * Currently we flip flop with an antialiased texture if antialiasing is enabled on the filter.\n * @internal\n */\nexport interface FilterInstruction extends Instruction\n{\n    renderPipeId: 'filter',\n    action: 'pushFilter' | 'popFilter',\n    container?: Container,\n    renderables?: Renderable[],\n    filterEffect: FilterEffect,\n}\n\n/**\n * Class representing the data required for applying filters.\n * This class holds various properties that are used during the filter application process.\n * @internal\n */\nclass FilterData\n{\n    /**\n     * Indicates whether the filter should be skipped.\n     * @type {boolean}\n     */\n    public skip = false;\n\n    /**\n     * The texture to which the filter is applied.\n     * @type {Texture}\n     */\n    public inputTexture: Texture = null;\n\n    /**\n     * The back texture used for blending, if required.\n     * @type {Texture | null}\n     */\n    public backTexture?: Texture = null;\n\n    /**\n     * The list of filters to be applied.\n     * @type {Filter[]}\n     */\n    public filters: Filter[] = null;\n\n    /**\n     * The bounds of the filter area.\n     * @type {Bounds}\n     */\n    public bounds = new Bounds();\n\n    /**\n     * The container to which the filter is applied.\n     * @type {Container}\n     */\n    public container: Container = null;\n\n    /**\n     * Indicates whether blending is required for the filter.\n     * @type {boolean}\n     */\n    public blendRequired: boolean = false;\n\n    /**\n     * The render surface where the output of the filter is rendered.\n     * @type {RenderSurface}\n     */\n    public outputRenderSurface: RenderSurface = null;\n\n    /**\n     * The global frame of the filter area.\n     * @type {{ x: number, y: number, width: number, height: number }}\n     */\n    public globalFrame = { x: 0, y: 0, width: 0, height: 0 };\n\n    /**\n     * Indicates whether antialiasing is enabled for the filter.\n     * @type {boolean}\n     */\n    public antialias: boolean;\n\n    /**\n     * The resolution of the filter.\n     * @type {number}\n     */\n    public resolution: number;\n\n    /** The first enabled filter index in the current filter list. */\n    public firstEnabledIndex = -1;\n\n    /** The last enabled filter index in the current filter list. */\n    public lastEnabledIndex = -1;\n}\n\n/**\n * System that manages the filter pipeline\n * @category rendering\n * @advanced\n */\nexport class FilterSystem implements System\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLSystem,\n            ExtensionType.WebGPUSystem,\n        ],\n        name: 'filter',\n    } as const;\n\n    public readonly renderer: WebGLRenderer | WebGPURenderer;\n\n    private _filterStackIndex = 0;\n    private _filterStack: FilterData[] = [];\n\n    private readonly _filterGlobalUniforms = new UniformGroup({\n        uInputSize: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uInputPixel: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uInputClamp: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uOutputFrame: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uGlobalFrame: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uOutputTexture: { value: new Float32Array(4), type: 'vec4<f32>' },\n    });\n\n    private readonly _globalFilterBindGroup: BindGroup = new BindGroup({});\n    private _activeFilterData: FilterData;\n    private _passthroughFilter: Filter;\n\n    constructor(renderer: WebGLRenderer | WebGPURenderer)\n    {\n        this.renderer = renderer;\n    }\n\n    /**\n     * The back texture of the currently active filter. Requires the filter to have `blendRequired` set to true.\n     * @readonly\n     */\n    public get activeBackTexture(): Texture | undefined\n    {\n        return this._activeFilterData?.backTexture;\n    }\n\n    /**\n     * Pushes a filter instruction onto the filter stack.\n     * @param instruction - The instruction containing the filter effect and container.\n     * @internal\n     */\n    public push(instruction: FilterInstruction)\n    {\n        const renderer = this.renderer;\n\n        const filters = instruction.filterEffect.filters;\n\n        // get a filter data from the stack. They can be reused multiple times each frame,\n        // so we don't need to worry about overwriting them in a single pass.\n        const filterData = this._pushFilterData();\n\n        filterData.skip = false;\n\n        filterData.filters = filters as Filter[];\n        filterData.container = instruction.container;\n        filterData.outputRenderSurface = renderer.renderTarget.renderSurface;\n\n        const colorTextureSource = renderer.renderTarget.renderTarget.colorTexture.source;\n\n        const rootResolution = colorTextureSource.resolution;\n        const rootAntialias = colorTextureSource.antialias;\n\n        // if there are no filters, or all of them disabled, we skip the pass\n        if (filters.every((filter) => !filter.enabled))\n        {\n            filterData.skip = true;\n\n            return;\n        }\n\n        const bounds = filterData.bounds;\n\n        this._calculateFilterArea(instruction, bounds);\n\n        this._calculateFilterBounds(filterData, renderer.renderTarget.rootViewPort, rootAntialias, rootResolution, 1);\n\n        if (filterData.skip)\n        {\n            return;\n        }\n\n        const previousFilterData = this._getPreviousFilterData();\n\n        const globalResolution = this._findFilterResolution(rootResolution);\n        let offsetX = 0;\n        let offsetY = 0;\n\n        if (previousFilterData)\n        {\n            offsetX = previousFilterData.bounds.minX;\n            offsetY = previousFilterData.bounds.minY;\n        }\n\n        this._calculateGlobalFrame(\n            filterData,\n            offsetX, offsetY,\n            globalResolution,\n            colorTextureSource.width,\n            colorTextureSource.height\n        );\n\n        // set all the filter data\n\n        this._setupFilterTextures(filterData, bounds, renderer, previousFilterData);\n    }\n\n    /**\n     * Applies filters to a texture.\n     *\n     * This method takes a texture and a list of filters, applies the filters to the texture,\n     * and returns the resulting texture.\n     * @param {object} params - The parameters for applying filters.\n     * @param {Texture} params.texture - The texture to apply filters to.\n     * @param {Filter[]} params.filters - The filters to apply.\n     * @returns {Texture} The resulting texture after all filters have been applied.\n     * @example\n     *\n     * ```ts\n     * // Create a texture and a list of filters\n     * const texture = new Texture(...);\n     * const filters = [new BlurFilter(), new ColorMatrixFilter()];\n     *\n     * // Apply the filters to the texture\n     * const resultTexture = filterSystem.applyToTexture({ texture, filters });\n     *\n     * // Use the resulting texture\n     * sprite.texture = resultTexture;\n     * ```\n     *\n     * Key Points:\n     * 1. padding is not currently supported here - so clipping may occur with filters that use padding.\n     * 2. If all filters are disabled or skipped, the original texture is returned.\n     */\n    public generateFilteredTexture({ texture, filters }: {texture: Texture, filters: Filter[]}): Texture\n    {\n        // get a filter data from the stack. They can be reused multiple times each frame,\n        // so we don't need to worry about overwriting them in a single pass.\n        const filterData = this._pushFilterData();\n\n        this._activeFilterData = filterData;\n        filterData.skip = false;\n\n        filterData.filters = filters;\n\n        const colorTextureSource = texture.source;\n\n        const rootResolution = colorTextureSource.resolution;\n        const rootAntialias = colorTextureSource.antialias;\n\n        // if there are no filters, or all of them disabled, we skip the pass\n        if (filters.every((filter) => !filter.enabled))\n        {\n            filterData.skip = true;\n\n            return texture;\n        }\n\n        const bounds = filterData.bounds;\n\n        // this path is used by the blend modes mostly!\n        // they collect all renderables and push them into a list.\n        // this list is then used to calculate the bounds of the filter area\n\n        bounds.addRect(texture.frame);\n\n        this._calculateFilterBounds(filterData, bounds.rectangle, rootAntialias, rootResolution, 0);\n\n        if (filterData.skip)\n        {\n            return texture;\n        }\n\n        const globalResolution = rootResolution;\n        const offsetX = 0;\n        const offsetY = 0;\n\n        this._calculateGlobalFrame(\n            filterData,\n            offsetX, offsetY,\n            globalResolution,\n            colorTextureSource.width,\n            colorTextureSource.height\n        );\n\n        /// /////////\n\n        // set all the filter data\n        // get a P02 texture from our pool...\n        filterData.outputRenderSurface = TexturePool.getOptimalTexture(\n            bounds.width,\n            bounds.height,\n            filterData.resolution,\n            filterData.antialias,\n        );\n\n        filterData.backTexture = Texture.EMPTY;\n\n        /// ///\n        // bind...\n        // TODO this might need looking at for padding!\n        filterData.inputTexture = texture;\n\n        /// ////////////// PART 2 POP //////////////////////\n\n        const renderer = this.renderer;\n\n        // TODO required? check with AA\n        renderer.renderTarget.finishRenderPass();\n\n        // get a BufferResource from the uniformBatch.\n        // this will batch the shader uniform data and give us a buffer resource we can\n        // set on our globalUniform Bind Group\n        this._applyFiltersToTexture(filterData, true);\n\n        const outputTexture = filterData.outputRenderSurface as Texture;\n\n        outputTexture.source.alphaMode = 'premultiplied-alpha';\n\n        return outputTexture;\n    }\n\n    /** @internal */\n    public pop()\n    {\n        const renderer = this.renderer;\n\n        const filterData = this._popFilterData();\n\n        // if we are skipping this filter then we just do nothing :D\n        if (filterData.skip)\n        {\n            return;\n        }\n\n        renderer.globalUniforms.pop();\n\n        renderer.renderTarget.finishRenderPass();\n\n        this._activeFilterData = filterData;\n\n        this._applyFiltersToTexture(filterData, false);\n\n        // if we made a background texture, lets return that also\n        if (filterData.blendRequired)\n        {\n            TexturePool.returnTexture(filterData.backTexture);\n        }\n\n        // return the texture to the pool so we can reuse the next frame\n        TexturePool.returnTexture(filterData.inputTexture);\n    }\n\n    /**\n     * Copies the last render surface to a texture.\n     * @param lastRenderSurface - The last render surface to copy from.\n     * @param bounds - The bounds of the area to copy.\n     * @param previousBounds - The previous bounds to use for offsetting the copy.\n     */\n    public getBackTexture(lastRenderSurface: RenderTarget, bounds: Bounds, previousBounds?: Bounds)\n    {\n        const backgroundResolution = lastRenderSurface.colorTexture.source._resolution;\n\n        const backTexture = TexturePool.getOptimalTexture(\n            bounds.width,\n            bounds.height,\n            backgroundResolution,\n            false,\n        );\n\n        let x = bounds.minX;\n        let y = bounds.minY;\n\n        if (previousBounds)\n        {\n            x -= previousBounds.minX;\n            y -= previousBounds.minY;\n        }\n\n        x = Math.floor(x * backgroundResolution);\n        y = Math.floor(y * backgroundResolution);\n\n        const width = Math.ceil(bounds.width * backgroundResolution);\n        const height = Math.ceil(bounds.height * backgroundResolution);\n\n        this.renderer.renderTarget.copyToTexture(\n            lastRenderSurface,\n            backTexture,\n            { x, y },\n            { width, height },\n            { x: 0, y: 0 }\n        );\n\n        return backTexture;\n    }\n\n    /**\n     * Applies a filter to a texture.\n     * @param filter - The filter to apply.\n     * @param input - The input texture.\n     * @param output - The output render surface.\n     * @param clear - Whether to clear the output surface before applying the filter.\n     */\n    public applyFilter(filter: Filter, input: Texture, output: RenderSurface, clear: boolean)\n    {\n        const renderer = this.renderer;\n\n        const filterData = this._activeFilterData;\n\n        const outputRenderSurface = filterData.outputRenderSurface;\n\n        const isFinalTarget = outputRenderSurface === output;\n\n        // Find the correct resolution by looking back through the filter stack\n        const rootResolution = renderer.renderTarget.rootRenderTarget.colorTexture.source._resolution;\n        const resolution = this._findFilterResolution(rootResolution);\n\n        // Calculate the offset for both outputFrame and globalFrame\n        let offsetX = 0;\n        let offsetY = 0;\n\n        if (isFinalTarget)\n        {\n            const offset = this._findPreviousFilterOffset();\n\n            offsetX = offset.x;\n            offsetY = offset.y;\n        }\n\n        this._updateFilterUniforms(input, output, filterData, offsetX, offsetY, resolution, isFinalTarget, clear);\n\n        // If the filter is disabled, we still need to write something into the output surface.\n        // Render a pass-through (copy) so the pipeline remains intact.\n        const filterToApply = filter.enabled\n            ? filter\n            : this._getPassthroughFilter();\n\n        this._setupBindGroupsAndRender(filterToApply, input, renderer);\n    }\n\n    /**\n     * Multiply _input normalized coordinates_ to this matrix to get _sprite texture normalized coordinates_.\n     *\n     * Use `outputMatrix * vTextureCoord` in the shader.\n     * @param outputMatrix - The matrix to output to.\n     * @param {Sprite} sprite - The sprite to map to.\n     * @returns The mapped matrix.\n     */\n    public calculateSpriteMatrix(outputMatrix: Matrix, sprite: Sprite): Matrix\n    {\n        const data = this._activeFilterData;\n\n        const mappedMatrix = outputMatrix.set(\n            data.inputTexture._source.width,\n            0, 0,\n            data.inputTexture._source.height,\n            data.bounds.minX, data.bounds.minY\n        );\n\n        const worldTransform = sprite.worldTransform.copyTo(Matrix.shared);\n\n        const renderGroup = sprite.renderGroup || sprite.parentRenderGroup;\n\n        if (renderGroup && renderGroup.cacheToLocalTransform)\n        {\n            // get the matrix relative to the render group..\n            worldTransform.prepend(renderGroup.cacheToLocalTransform);\n        }\n\n        worldTransform.invert();\n        mappedMatrix.prepend(worldTransform);\n        mappedMatrix.scale(\n            1.0 / sprite.texture.orig.width,\n            1.0 / sprite.texture.orig.height\n        );\n\n        mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y);\n\n        return mappedMatrix;\n    }\n\n    public destroy(): void\n    {\n        this._passthroughFilter?.destroy(true);\n        (this._passthroughFilter as null) = null;\n    }\n\n    private _getPassthroughFilter(): Filter\n    {\n        this._passthroughFilter ??= new PassthroughFilter();\n\n        return this._passthroughFilter;\n    }\n\n    /**\n     * Sets up the bind groups and renders the filter.\n     * @param filter - The filter to apply\n     * @param input - The input texture\n     * @param renderer - The renderer instance\n     */\n    private _setupBindGroupsAndRender(filter: Filter, input: Texture, renderer: WebGLRenderer | WebGPURenderer): void\n    {\n        // TODO - should prolly use a adaptor...\n        if ((renderer as WebGPURenderer).renderPipes.uniformBatch)\n        {\n            const batchUniforms = (renderer as WebGPURenderer).renderPipes.uniformBatch\n                .getUboResource(this._filterGlobalUniforms);\n\n            this._globalFilterBindGroup.setResource(batchUniforms, 0);\n        }\n        else\n        {\n            this._globalFilterBindGroup.setResource(this._filterGlobalUniforms, 0);\n        }\n\n        // now lets update the output texture...\n\n        // set bind group..\n        this._globalFilterBindGroup.setResource(input.source, 1);\n        this._globalFilterBindGroup.setResource(input.source.style, 2);\n\n        filter.groups[0] = this._globalFilterBindGroup;\n\n        renderer.encoder.draw({\n            geometry: quadGeometry,\n            shader: filter,\n            state: filter._state,\n            topology: 'triangle-list'\n        });\n\n        // WebGPU blit's automatically, but WebGL does not!\n        if (renderer.type === RendererType.WEBGL)\n        {\n            renderer.renderTarget.finishRenderPass();\n        }\n    }\n\n    /**\n     * Sets up the filter textures including input texture and back texture if needed.\n     * @param filterData - The filter data to update\n     * @param bounds - The bounds for the texture\n     * @param renderer - The renderer instance\n     * @param previousFilterData - The previous filter data for back texture calculation\n     */\n    private _setupFilterTextures(\n        filterData: FilterData,\n        bounds: Bounds,\n        renderer: WebGLRenderer | WebGPURenderer,\n        previousFilterData: FilterData | null\n    ): void\n    {\n        // set all the filter data\n        filterData.backTexture = Texture.EMPTY;\n\n        /// ///\n        // bind...\n        // get a P02 texture from our pool...\n        filterData.inputTexture = TexturePool.getOptimalTexture(\n            bounds.width,\n            bounds.height,\n            filterData.resolution,\n            filterData.antialias,\n        );\n\n        // Very cryptic, but important(!) moment.\n        //\n        // If we try to pull texture from the pool for backTexture before inputTexture,\n        // it will be unbounded later by startRenderPass. It happens because in such a case - the current backTexture\n        // is actually inputTexture from the previous filter application (check `pop` method).\n        //\n        // So maintaining the order (inputTexture -> backTexture) helps us to prevent unwanted texture unbinding.\n        if (filterData.blendRequired)\n        {\n            renderer.renderTarget.finishRenderPass();\n            // this actually forces the current commandQueue to render everything so far.\n            // if we don't do this, we won't be able to copy pixels for the background\n            const renderTarget = renderer.renderTarget.getRenderTarget(filterData.outputRenderSurface);\n\n            filterData.backTexture = this.getBackTexture(renderTarget, bounds, previousFilterData?.bounds);\n        }\n\n        renderer.renderTarget.bind(filterData.inputTexture, true);\n\n        // set the global uniforms to take into account the bounds offset required\n        renderer.globalUniforms.push({\n            offset: bounds,\n        });\n    }\n\n    /**\n     * Calculates and sets the global frame for the filter.\n     * @param filterData - The filter data to update\n     * @param offsetX - The X offset\n     * @param offsetY - The Y offset\n     * @param globalResolution - The global resolution\n     * @param sourceWidth - The source texture width\n     * @param sourceHeight - The source texture height\n     */\n    private _calculateGlobalFrame(\n        filterData: FilterData,\n        offsetX: number,\n        offsetY: number,\n        globalResolution: number,\n        sourceWidth: number,\n        sourceHeight: number\n    ): void\n    {\n        const globalFrame = filterData.globalFrame;\n\n        globalFrame.x = offsetX * globalResolution;\n        globalFrame.y = offsetY * globalResolution;\n        globalFrame.width = sourceWidth * globalResolution;\n        globalFrame.height = sourceHeight * globalResolution;\n    }\n\n    /**\n     * Updates the filter uniforms with the current filter state.\n     * @param input - The input texture\n     * @param output - The output render surface\n     * @param filterData - The current filter data\n     * @param offsetX - The X offset for positioning\n     * @param offsetY - The Y offset for positioning\n     * @param resolution - The current resolution\n     * @param isFinalTarget - Whether this is the final render target\n     * @param clear - Whether to clear the output surface\n     */\n    private _updateFilterUniforms(\n        input: Texture,\n        output: RenderSurface,\n        filterData: FilterData,\n        offsetX: number,\n        offsetY: number,\n        resolution: number,\n        isFinalTarget: boolean,\n        clear: boolean\n    ): void\n    {\n        const uniforms = this._filterGlobalUniforms.uniforms;\n        const outputFrame = uniforms.uOutputFrame;\n        const inputSize = uniforms.uInputSize;\n        const inputPixel = uniforms.uInputPixel;\n        const inputClamp = uniforms.uInputClamp;\n        const globalFrame = uniforms.uGlobalFrame;\n        const outputTexture = uniforms.uOutputTexture;\n\n        // are we rendering back to the original surface?\n        if (isFinalTarget)\n        {\n            outputFrame[0] = filterData.bounds.minX - offsetX;\n            outputFrame[1] = filterData.bounds.minY - offsetY;\n        }\n        else\n        {\n            outputFrame[0] = 0;\n            outputFrame[1] = 0;\n        }\n\n        outputFrame[2] = input.frame.width;\n        outputFrame[3] = input.frame.height;\n\n        inputSize[0] = input.source.width;\n        inputSize[1] = input.source.height;\n        inputSize[2] = 1 / inputSize[0];\n        inputSize[3] = 1 / inputSize[1];\n\n        inputPixel[0] = input.source.pixelWidth;\n        inputPixel[1] = input.source.pixelHeight;\n        inputPixel[2] = 1.0 / inputPixel[0];\n        inputPixel[3] = 1.0 / inputPixel[1];\n\n        inputClamp[0] = 0.5 * inputPixel[2];\n        inputClamp[1] = 0.5 * inputPixel[3];\n        inputClamp[2] = (input.frame.width * inputSize[2]) - (0.5 * inputPixel[2]);\n        inputClamp[3] = (input.frame.height * inputSize[3]) - (0.5 * inputPixel[3]);\n\n        const rootTexture = this.renderer.renderTarget.rootRenderTarget.colorTexture;\n\n        globalFrame[0] = offsetX * resolution;\n        globalFrame[1] = offsetY * resolution;\n        globalFrame[2] = rootTexture.source.width * resolution;\n        globalFrame[3] = rootTexture.source.height * resolution;\n\n        // we are going to overwrite resource we can set it to null!\n        if (output instanceof Texture) output.source.resource = null;\n\n        // set the output texture - this is where we are going to render to\n        const renderTarget = this.renderer.renderTarget.getRenderTarget(output);\n\n        this.renderer.renderTarget.bind(output, !!clear);\n\n        if (output instanceof Texture)\n        {\n            outputTexture[0] = output.frame.width;\n            outputTexture[1] = output.frame.height;\n        }\n        else\n        {\n            // this means a renderTarget was passed directly\n            outputTexture[0] = renderTarget.width;\n            outputTexture[1] = renderTarget.height;\n        }\n\n        outputTexture[2] = renderTarget.isRoot ? -1 : 1;\n\n        this._filterGlobalUniforms.update();\n    }\n\n    /**\n     * Finds the correct resolution by looking back through the filter stack.\n     * @param rootResolution - The fallback root resolution to use\n     * @returns The resolution from the previous filter or root resolution\n     */\n    private _findFilterResolution(rootResolution: number): number\n    {\n        let currentIndex = this._filterStackIndex - 1;\n\n        while (currentIndex > 0 && this._filterStack[currentIndex].skip)\n        {\n            --currentIndex;\n        }\n\n        return currentIndex > 0 && this._filterStack[currentIndex].inputTexture\n            ? this._filterStack[currentIndex].inputTexture.source._resolution\n            : rootResolution;\n    }\n\n    /**\n     * Finds the offset from the previous non-skipped filter in the stack.\n     * @returns The offset coordinates from the previous filter\n     */\n    private _findPreviousFilterOffset(): { x: number, y: number }\n    {\n        let offsetX = 0;\n        let offsetY = 0;\n        let lastIndex = this._filterStackIndex;\n\n        while (lastIndex > 0)\n        {\n            lastIndex--;\n            const prevFilterData = this._filterStack[lastIndex];\n\n            if (!prevFilterData.skip)\n            {\n                offsetX = prevFilterData.bounds.minX;\n                offsetY = prevFilterData.bounds.minY;\n                break;\n            }\n        }\n\n        return { x: offsetX, y: offsetY };\n    }\n\n    /**\n     * Calculates the filter area bounds based on the instruction type.\n     * @param instruction - The filter instruction\n     * @param bounds - The bounds object to populate\n     */\n    private _calculateFilterArea(instruction: FilterInstruction, bounds: Bounds): void\n    {\n        // this path is used by the blend modes mostly!\n        // they collect all renderables and push them into a list.\n        // this list is then used to calculate the bounds of the filter area\n        if (instruction.renderables)\n        {\n            getGlobalRenderableBounds(instruction.renderables, bounds);\n        }\n        // if a filterArea is provided, we save our selves some measuring and just use that area supplied\n        else if (instruction.filterEffect.filterArea)\n        {\n            bounds.clear();\n\n            // transform the filterArea into global space..\n            bounds.addRect(instruction.filterEffect.filterArea);\n\n            // new for v8, we transform the bounds into the space of the container\n            bounds.applyMatrix(instruction.container.worldTransform);\n        }\n        // classic filter path, we get the bounds of the container and use it by recursively\n        // measuring.\n        else\n        {\n            // we want to factor render layers to get the real visual bounds of this container.\n            // so the last param is true..\n            instruction.container.getFastGlobalBounds(true, bounds);\n        }\n\n        if (instruction.container)\n        {\n            // When a container is cached as a texture, its filters need to be applied relative to its\n            // cached parent's coordinate space rather than world space. This transform adjustment ensures\n            // filters are applied in the correct coordinate system.\n            const renderGroup = instruction.container.renderGroup || instruction.container.parentRenderGroup;\n            const filterFrameTransform = renderGroup.cacheToLocalTransform;\n\n            if (filterFrameTransform)\n            {\n                bounds.applyMatrix(filterFrameTransform);\n            }\n        }\n    }\n\n    private _applyFiltersToTexture(filterData: FilterData, clear: boolean)\n    {\n        const inputTexture = filterData.inputTexture;\n\n        const bounds = filterData.bounds;\n\n        const filters = filterData.filters;\n        const firstEnabled = filterData.firstEnabledIndex;\n        const lastEnabled = filterData.lastEnabledIndex;\n\n        // get a BufferResource from the uniformBatch.\n        // this will batch the shader uniform data and give us a buffer resource we can\n        // set on our globalUniform Bind Group\n        // update the resources on the bind group...\n        this._globalFilterBindGroup.setResource(inputTexture.source.style, 2);\n        this._globalFilterBindGroup.setResource(filterData.backTexture.source, 3);\n\n        if (firstEnabled === lastEnabled)\n        {\n            // render a single filter...\n            filters[firstEnabled].apply(this, inputTexture, filterData.outputRenderSurface, clear);\n        }\n        else\n        {\n            let flip = filterData.inputTexture;\n\n            const tempTexture = TexturePool.getOptimalTexture(\n                bounds.width,\n                bounds.height,\n                flip.source._resolution,\n                false\n            );\n\n            // get another texture that we will render the next filter too\n            let flop = tempTexture;\n\n            // loop and apply the filters, omitting the last one as we will render that to the final target\n            for (let i = firstEnabled; i < lastEnabled; i++)\n            {\n                const filter = filters[i];\n\n                if (!filter.enabled) continue;\n\n                filter.apply(this, flip, flop, true);\n                const t = flip;\n\n                flip = flop;\n                flop = t;\n            }\n            // apply the last enabled filter to the output\n            filters[lastEnabled].apply(this, flip, filterData.outputRenderSurface, clear);\n\n            // return those textures for later!\n            TexturePool.returnTexture(tempTexture);\n        }\n    }\n\n    private _calculateFilterBounds(\n        filterData: FilterData,\n        viewPort: Rectangle,\n        rootAntialias: boolean,\n        rootResolution: number,\n        // a multiplier padding for the bounds calculation\n        // this prop is used when applying filters to textures\n        // as the should have padding applied to them already (until we fix padding when applying them to textures)\n        // set to 0 to remove padding from the bounds calculation\n        paddingMultiplier: number\n    )\n    {\n        const renderer = this.renderer;\n\n        const bounds = filterData.bounds;\n        const filters = filterData.filters;\n\n        // get GLOBAL bounds of the item we are going to apply the filter to\n\n        // next we get the settings for the filter\n        // we need to find the LOWEST resolution for the filter list\n        let resolution = Infinity;\n        // Padding is additive to add padding to our padding\n        let padding = 0;\n        // if this is true for all filter, it should be true, and otherwise false\n        let antialias = true;\n        // true if any filter requires the previous render target\n        let blendRequired = false;\n        // true if any filter in the list is enabled\n        let enabled = false;\n        // false if any filter in the list has false\n        let clipToViewport = true;\n        // cache first/last enabled indices for later passes\n        let firstEnabledIndex = -1;\n        let lastEnabledIndex = -1;\n\n        for (let i = 0; i < filters.length; i++)\n        {\n            const filter = filters[i];\n\n            // Only enabled filters should influence pipeline characteristics\n            if (!filter.enabled) continue;\n\n            if (firstEnabledIndex === -1) firstEnabledIndex = i;\n            lastEnabledIndex = i;\n            resolution = Math.min(resolution, filter.resolution === 'inherit'\n                ? rootResolution : filter.resolution);\n            padding += filter.padding;\n\n            if (filter.antialias === 'off')\n            {\n                antialias = false;\n            }\n            else if (filter.antialias === 'inherit')\n            {\n                antialias &&= rootAntialias;\n            }\n\n            if (!filter.clipToViewport)\n            {\n                clipToViewport = false;\n            }\n\n            const isCompatible = !!(filter.compatibleRenderers & renderer.type);\n\n            if (!isCompatible)\n            {\n                enabled = false;\n                break;\n            }\n\n            if (filter.blendRequired && !((renderer as WebGLRenderer).backBuffer?.useBackBuffer ?? true))\n            {\n                // #if _DEBUG\n                // eslint-disable-next-line max-len\n                warn('Blend filter requires backBuffer on WebGL renderer to be enabled. Set `useBackBuffer: true` in the renderer options.');\n                // #endif\n\n                enabled = false;\n                break;\n            }\n\n            enabled = true;\n            blendRequired ||= filter.blendRequired;\n        }\n\n        // if no filters are enabled lets skip!\n        if (!enabled)\n        {\n            filterData.skip = true;\n\n            return;\n        }\n\n        // here we constrain the bounds to the viewport we will render too\n        // this should not take into account the x, y offset of the viewport - as this is\n        // handled by the viewport on the gpu.\n        if (clipToViewport)\n        {\n            bounds.fitBounds(0, viewPort.width / rootResolution, 0, viewPort.height / rootResolution);\n        }\n\n        // round the bounds to the nearest pixel\n        bounds\n            .scale(resolution)\n            .ceil()\n            .scale(1 / resolution)\n            .pad((padding | 0) * paddingMultiplier);\n\n        // skip if the bounds are negative or zero as this means they are\n        // not visible on the screen\n        if (!bounds.isPositive)\n        {\n            filterData.skip = true;\n\n            return;\n        }\n\n        // set the global frame to the root texture\n\n        // get previous bounds.. we must take into account skipped filters also..\n\n        // // to find the previous resolution we need to account for the skipped filters\n        // // the following will find the last non skipped filter...\n\n        // store the values that will be used to apply the filters\n        filterData.antialias = antialias;\n        filterData.resolution = resolution;\n        filterData.blendRequired = blendRequired;\n        filterData.firstEnabledIndex = firstEnabledIndex;\n        filterData.lastEnabledIndex = lastEnabledIndex;\n    }\n\n    private _popFilterData(): FilterData\n    {\n        this._filterStackIndex--;\n\n        return this._filterStack[this._filterStackIndex];\n    }\n\n    private _getPreviousFilterData(): FilterData | null\n    {\n        let previousFilterData: FilterData;\n\n        let index = this._filterStackIndex - 1;\n\n        while (index > 0)\n        {\n            index--;\n            previousFilterData = this._filterStack[index];\n\n            if (!previousFilterData.skip)\n            {\n                break;\n            }\n        }\n\n        return previousFilterData;\n    }\n\n    private _pushFilterData(): FilterData\n    {\n        let filterData = this._filterStack[this._filterStackIndex];\n\n        if (!filterData)\n        {\n            filterData = this._filterStack[this._filterStackIndex] = new FilterData();\n        }\n\n        this._filterStackIndex++;\n\n        return filterData;\n    }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;AA0BA,MAAM,YAAA,GAAe,IAAI,QAAA,CAAS;AAAA,EAC9B,UAAA,EAAY;AAAA,IACR,SAAA,EAAW;AAAA,MACP,MAAA,EAAQ,IAAI,YAAA,CAAa,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,MACjD,MAAA,EAAQ,WAAA;AAAA,MACR,QAAQ,CAAA,GAAI,CAAA;AAAA,MACZ,MAAA,EAAQ;AAAA;AACZ,GACJ;AAAA,EACA,WAAA,EAAa,IAAI,WAAA,CAAY,CAAC,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAC;AACnD,CAAC,CAAA;AAsCD,MAAM,UAAA,CACN;AAAA,EADA,WAAA,GAAA;AAMI;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,IAAA,GAAO,KAAA;AAMd;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,YAAA,GAAwB,IAAA;AAM/B;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,WAAA,GAAwB,IAAA;AAM/B;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,OAAA,GAAoB,IAAA;AAM3B;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,MAAA,GAAS,IAAI,MAAA,EAAO;AAM3B;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,SAAA,GAAuB,IAAA;AAM9B;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,aAAA,GAAyB,KAAA;AAMhC;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,mBAAA,GAAqC,IAAA;AAM5C;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,WAAA,GAAc,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAG,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE;AAevD;AAAA,IAAA,IAAA,CAAO,iBAAA,GAAoB,CAAA,CAAA;AAG3B;AAAA,IAAA,IAAA,CAAO,gBAAA,GAAmB,CAAA,CAAA;AAAA,EAAA;AAC9B;AAOO,MAAM,YAAA,CACb;AAAA,EA4BI,YAAY,QAAA,EACZ;AAjBA,IAAA,IAAA,CAAQ,iBAAA,GAAoB,CAAA;AAC5B,IAAA,IAAA,CAAQ,eAA6B,EAAC;AAEtC,IAAA,IAAA,CAAiB,qBAAA,GAAwB,IAAI,YAAA,CAAa;AAAA,MACtD,UAAA,EAAY,EAAE,KAAA,EAAO,IAAI,aAAa,CAAC,CAAA,EAAG,MAAM,WAAA,EAAY;AAAA,MAC5D,WAAA,EAAa,EAAE,KAAA,EAAO,IAAI,aAAa,CAAC,CAAA,EAAG,MAAM,WAAA,EAAY;AAAA,MAC7D,WAAA,EAAa,EAAE,KAAA,EAAO,IAAI,aAAa,CAAC,CAAA,EAAG,MAAM,WAAA,EAAY;AAAA,MAC7D,YAAA,EAAc,EAAE,KAAA,EAAO,IAAI,aAAa,CAAC,CAAA,EAAG,MAAM,WAAA,EAAY;AAAA,MAC9D,YAAA,EAAc,EAAE,KAAA,EAAO,IAAI,aAAa,CAAC,CAAA,EAAG,MAAM,WAAA,EAAY;AAAA,MAC9D,cAAA,EAAgB,EAAE,KAAA,EAAO,IAAI,aAAa,CAAC,CAAA,EAAG,MAAM,WAAA;AAAY,KACnE,CAAA;AAED,IAAA,IAAA,CAAiB,sBAAA,GAAoC,IAAI,SAAA,CAAU,EAAE,CAAA;AAMjE,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,iBAAA,GACX;AACI,IAAA,OAAO,KAAK,iBAAA,EAAmB,WAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,KAAK,WAAA,EACZ;AACI,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AAEtB,IAAA,MAAM,OAAA,GAAU,YAAY,YAAA,CAAa,OAAA;AAIzC,IAAA,MAAM,UAAA,GAAa,KAAK,eAAA,EAAgB;AAExC,IAAA,UAAA,CAAW,IAAA,GAAO,KAAA;AAElB,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,IAAA,UAAA,CAAW,YAAY,WAAA,CAAY,SAAA;AACnC,IAAA,UAAA,CAAW,mBAAA,GAAsB,SAAS,YAAA,CAAa,aAAA;AAEvD,IAAA,MAAM,kBAAA,GAAqB,QAAA,CAAS,YAAA,CAAa,YAAA,CAAa,YAAA,CAAa,MAAA;AAE3E,IAAA,MAAM,iBAAiB,kBAAA,CAAmB,UAAA;AAC1C,IAAA,MAAM,gBAAgB,kBAAA,CAAmB,SAAA;AAGzC,IAAA,IAAI,QAAQ,KAAA,CAAM,CAAC,WAAW,CAAC,MAAA,CAAO,OAAO,CAAA,EAC7C;AACI,MAAA,UAAA,CAAW,IAAA,GAAO,IAAA;AAElB,MAAA;AAAA,IACJ;AAEA,IAAA,MAAM,SAAS,UAAA,CAAW,MAAA;AAE1B,IAAA,IAAA,CAAK,oBAAA,CAAqB,aAAa,MAAM,CAAA;AAE7C,IAAA,IAAA,CAAK,uBAAuB,UAAA,EAAY,QAAA,CAAS,aAAa,YAAA,EAAc,aAAA,EAAe,gBAAgB,CAAC,CAAA;AAE5G,IAAA,IAAI,WAAW,IAAA,EACf;AACI,MAAA;AAAA,IACJ;AAEA,IAAA,MAAM,kBAAA,GAAqB,KAAK,sBAAA,EAAuB;AAEvD,IAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,qBAAA,CAAsB,cAAc,CAAA;AAClE,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,IAAI,OAAA,GAAU,CAAA;AAEd,IAAA,IAAI,kBAAA,EACJ;AACI,MAAA,OAAA,GAAU,mBAAmB,MAAA,CAAO,IAAA;AACpC,MAAA,OAAA,GAAU,mBAAmB,MAAA,CAAO,IAAA;AAAA,IACxC;AAEA,IAAA,IAAA,CAAK,qBAAA;AAAA,MACD,UAAA;AAAA,MACA,OAAA;AAAA,MAAS,OAAA;AAAA,MACT,gBAAA;AAAA,MACA,kBAAA,CAAmB,KAAA;AAAA,MACnB,kBAAA,CAAmB;AAAA,KACvB;AAIA,IAAA,IAAA,CAAK,oBAAA,CAAqB,UAAA,EAAY,MAAA,EAAQ,QAAA,EAAU,kBAAkB,CAAA;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BO,uBAAA,CAAwB,EAAE,OAAA,EAAS,OAAA,EAAQ,EAClD;AAGI,IAAA,MAAM,UAAA,GAAa,KAAK,eAAA,EAAgB;AAExC,IAAA,IAAA,CAAK,iBAAA,GAAoB,UAAA;AACzB,IAAA,UAAA,CAAW,IAAA,GAAO,KAAA;AAElB,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAErB,IAAA,MAAM,qBAAqB,OAAA,CAAQ,MAAA;AAEnC,IAAA,MAAM,iBAAiB,kBAAA,CAAmB,UAAA;AAC1C,IAAA,MAAM,gBAAgB,kBAAA,CAAmB,SAAA;AAGzC,IAAA,IAAI,QAAQ,KAAA,CAAM,CAAC,WAAW,CAAC,MAAA,CAAO,OAAO,CAAA,EAC7C;AACI,MAAA,UAAA,CAAW,IAAA,GAAO,IAAA;AAElB,MAAA,OAAO,OAAA;AAAA,IACX;AAEA,IAAA,MAAM,SAAS,UAAA,CAAW,MAAA;AAM1B,IAAA,MAAA,CAAO,OAAA,CAAQ,QAAQ,KAAK,CAAA;AAE5B,IAAA,IAAA,CAAK,uBAAuB,UAAA,EAAY,MAAA,CAAO,SAAA,EAAW,aAAA,EAAe,gBAAgB,CAAC,CAAA;AAE1F,IAAA,IAAI,WAAW,IAAA,EACf;AACI,MAAA,OAAO,OAAA;AAAA,IACX;AAEA,IAAA,MAAM,gBAAA,GAAmB,cAAA;AACzB,IAAA,MAAM,OAAA,GAAU,CAAA;AAChB,IAAA,MAAM,OAAA,GAAU,CAAA;AAEhB,IAAA,IAAA,CAAK,qBAAA;AAAA,MACD,UAAA;AAAA,MACA,OAAA;AAAA,MAAS,OAAA;AAAA,MACT,gBAAA;AAAA,MACA,kBAAA,CAAmB,KAAA;AAAA,MACnB,kBAAA,CAAmB;AAAA,KACvB;AAMA,IAAA,UAAA,CAAW,sBAAsB,WAAA,CAAY,iBAAA;AAAA,MACzC,MAAA,CAAO,KAAA;AAAA,MACP,MAAA,CAAO,MAAA;AAAA,MACP,UAAA,CAAW,UAAA;AAAA,MACX,UAAA,CAAW;AAAA,KACf;AAEA,IAAA,UAAA,CAAW,cAAc,OAAA,CAAQ,KAAA;AAKjC,IAAA,UAAA,CAAW,YAAA,GAAe,OAAA;AAI1B,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AAGtB,IAAA,QAAA,CAAS,aAAa,gBAAA,EAAiB;AAKvC,IAAA,IAAA,CAAK,sBAAA,CAAuB,YAAY,IAAI,CAAA;AAE5C,IAAA,MAAM,gBAAgB,UAAA,CAAW,mBAAA;AAEjC,IAAA,aAAA,CAAc,OAAO,SAAA,GAAY,qBAAA;AAEjC,IAAA,OAAO,aAAA;AAAA,EACX;AAAA;AAAA,EAGO,GAAA,GACP;AACI,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AAEtB,IAAA,MAAM,UAAA,GAAa,KAAK,cAAA,EAAe;AAGvC,IAAA,IAAI,WAAW,IAAA,EACf;AACI,MAAA;AAAA,IACJ;AAEA,IAAA,QAAA,CAAS,eAAe,GAAA,EAAI;AAE5B,IAAA,QAAA,CAAS,aAAa,gBAAA,EAAiB;AAEvC,IAAA,IAAA,CAAK,iBAAA,GAAoB,UAAA;AAEzB,IAAA,IAAA,CAAK,sBAAA,CAAuB,YAAY,KAAK,CAAA;AAG7C,IAAA,IAAI,WAAW,aAAA,EACf;AACI,MAAA,WAAA,CAAY,aAAA,CAAc,WAAW,WAAW,CAAA;AAAA,IACpD;AAGA,IAAA,WAAA,CAAY,aAAA,CAAc,WAAW,YAAY,CAAA;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,cAAA,CAAe,iBAAA,EAAiC,MAAA,EAAgB,cAAA,EACvE;AACI,IAAA,MAAM,oBAAA,GAAuB,iBAAA,CAAkB,YAAA,CAAa,MAAA,CAAO,WAAA;AAEnE,IAAA,MAAM,cAAc,WAAA,CAAY,iBAAA;AAAA,MAC5B,MAAA,CAAO,KAAA;AAAA,MACP,MAAA,CAAO,MAAA;AAAA,MACP,oBAAA;AAAA,MACA;AAAA,KACJ;AAEA,IAAA,IAAI,IAAI,MAAA,CAAO,IAAA;AACf,IAAA,IAAI,IAAI,MAAA,CAAO,IAAA;AAEf,IAAA,IAAI,cAAA,EACJ;AACI,MAAA,CAAA,IAAK,cAAA,CAAe,IAAA;AACpB,MAAA,CAAA,IAAK,cAAA,CAAe,IAAA;AAAA,IACxB;AAEA,IAAA,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,oBAAoB,CAAA;AACvC,IAAA,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,oBAAoB,CAAA;AAEvC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,QAAQ,oBAAoB,CAAA;AAC3D,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,SAAS,oBAAoB,CAAA;AAE7D,IAAA,IAAA,CAAK,SAAS,YAAA,CAAa,aAAA;AAAA,MACvB,iBAAA;AAAA,MACA,WAAA;AAAA,MACA,EAAE,GAAG,CAAA,EAAE;AAAA,MACP,EAAE,OAAO,MAAA,EAAO;AAAA,MAChB,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA;AAAE,KACjB;AAEA,IAAA,OAAO,WAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,WAAA,CAAY,MAAA,EAAgB,KAAA,EAAgB,MAAA,EAAuB,KAAA,EAC1E;AACI,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AAEtB,IAAA,MAAM,aAAa,IAAA,CAAK,iBAAA;AAExB,IAAA,MAAM,sBAAsB,UAAA,CAAW,mBAAA;AAEvC,IAAA,MAAM,gBAAgB,mBAAA,KAAwB,MAAA;AAG9C,IAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,YAAA,CAAa,gBAAA,CAAiB,aAAa,MAAA,CAAO,WAAA;AAClF,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,qBAAA,CAAsB,cAAc,CAAA;AAG5D,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,IAAI,OAAA,GAAU,CAAA;AAEd,IAAA,IAAI,aAAA,EACJ;AACI,MAAA,MAAM,MAAA,GAAS,KAAK,yBAAA,EAA0B;AAE9C,MAAA,OAAA,GAAU,MAAA,CAAO,CAAA;AACjB,MAAA,OAAA,GAAU,MAAA,CAAO,CAAA;AAAA,IACrB;AAEA,IAAA,IAAA,CAAK,qBAAA,CAAsB,OAAO,MAAA,EAAQ,UAAA,EAAY,SAAS,OAAA,EAAS,UAAA,EAAY,eAAe,KAAK,CAAA;AAIxG,IAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,OAAA,GACvB,MAAA,GACA,KAAK,qBAAA,EAAsB;AAEjC,IAAA,IAAA,CAAK,yBAAA,CAA0B,aAAA,EAAe,KAAA,EAAO,QAAQ,CAAA;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,qBAAA,CAAsB,cAAsB,MAAA,EACnD;AACI,IAAA,MAAM,OAAO,IAAA,CAAK,iBAAA;AAElB,IAAA,MAAM,eAAe,YAAA,CAAa,GAAA;AAAA,MAC9B,IAAA,CAAK,aAAa,OAAA,CAAQ,KAAA;AAAA,MAC1B,CAAA;AAAA,MAAG,CAAA;AAAA,MACH,IAAA,CAAK,aAAa,OAAA,CAAQ,MAAA;AAAA,MAC1B,KAAK,MAAA,CAAO,IAAA;AAAA,MAAM,KAAK,MAAA,CAAO;AAAA,KAClC;AAEA,IAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,cAAA,CAAe,MAAA,CAAO,OAAO,MAAM,CAAA;AAEjE,IAAA,MAAM,WAAA,GAAc,MAAA,CAAO,WAAA,IAAe,MAAA,CAAO,iBAAA;AAEjD,IAAA,IAAI,WAAA,IAAe,YAAY,qBAAA,EAC/B;AAEI,MAAA,cAAA,CAAe,OAAA,CAAQ,YAAY,qBAAqB,CAAA;AAAA,IAC5D;AAEA,IAAA,cAAA,CAAe,MAAA,EAAO;AACtB,IAAA,YAAA,CAAa,QAAQ,cAAc,CAAA;AACnC,IAAA,YAAA,CAAa,KAAA;AAAA,MACT,CAAA,GAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,KAAA;AAAA,MAC1B,CAAA,GAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK;AAAA,KAC9B;AAEA,IAAA,YAAA,CAAa,UAAU,MAAA,CAAO,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,OAAO,CAAC,CAAA;AAEvD,IAAA,OAAO,YAAA;AAAA,EACX;AAAA,EAEO,OAAA,GACP;AACI,IAAA,IAAA,CAAK,kBAAA,EAAoB,QAAQ,IAAI,CAAA;AACrC,IAAC,KAAK,kBAAA,GAA8B,IAAA;AAAA,EACxC;AAAA,EAEQ,qBAAA,GACR;AACI,IAAA,IAAA,CAAK,kBAAA,KAAL,IAAA,CAAK,kBAAA,GAAuB,IAAI,iBAAA,EAAkB,CAAA;AAElD,IAAA,OAAO,IAAA,CAAK,kBAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,yBAAA,CAA0B,MAAA,EAAgB,KAAA,EAAgB,QAAA,EAClE;AAEI,IAAA,IAAK,QAAA,CAA4B,YAAY,YAAA,EAC7C;AACI,MAAA,MAAM,gBAAiB,QAAA,CAA4B,WAAA,CAAY,YAAA,CAC1D,cAAA,CAAe,KAAK,qBAAqB,CAAA;AAE9C,MAAA,IAAA,CAAK,sBAAA,CAAuB,WAAA,CAAY,aAAA,EAAe,CAAC,CAAA;AAAA,IAC5D,CAAA,MAEA;AACI,MAAA,IAAA,CAAK,sBAAA,CAAuB,WAAA,CAAY,IAAA,CAAK,qBAAA,EAAuB,CAAC,CAAA;AAAA,IACzE;AAKA,IAAA,IAAA,CAAK,sBAAA,CAAuB,WAAA,CAAY,KAAA,CAAM,MAAA,EAAQ,CAAC,CAAA;AACvD,IAAA,IAAA,CAAK,sBAAA,CAAuB,WAAA,CAAY,KAAA,CAAM,MAAA,CAAO,OAAO,CAAC,CAAA;AAE7D,IAAA,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,GAAI,IAAA,CAAK,sBAAA;AAExB,IAAA,QAAA,CAAS,QAAQ,IAAA,CAAK;AAAA,MAClB,QAAA,EAAU,YAAA;AAAA,MACV,MAAA,EAAQ,MAAA;AAAA,MACR,OAAO,MAAA,CAAO,MAAA;AAAA,MACd,QAAA,EAAU;AAAA,KACb,CAAA;AAGD,IAAA,IAAI,QAAA,CAAS,IAAA,KAAS,YAAA,CAAa,KAAA,EACnC;AACI,MAAA,QAAA,CAAS,aAAa,gBAAA,EAAiB;AAAA,IAC3C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,oBAAA,CACJ,UAAA,EACA,MAAA,EACA,QAAA,EACA,kBAAA,EAEJ;AAEI,IAAA,UAAA,CAAW,cAAc,OAAA,CAAQ,KAAA;AAKjC,IAAA,UAAA,CAAW,eAAe,WAAA,CAAY,iBAAA;AAAA,MAClC,MAAA,CAAO,KAAA;AAAA,MACP,MAAA,CAAO,MAAA;AAAA,MACP,UAAA,CAAW,UAAA;AAAA,MACX,UAAA,CAAW;AAAA,KACf;AASA,IAAA,IAAI,WAAW,aAAA,EACf;AACI,MAAA,QAAA,CAAS,aAAa,gBAAA,EAAiB;AAGvC,MAAA,MAAM,YAAA,GAAe,QAAA,CAAS,YAAA,CAAa,eAAA,CAAgB,WAAW,mBAAmB,CAAA;AAEzF,MAAA,UAAA,CAAW,cAAc,IAAA,CAAK,cAAA,CAAe,YAAA,EAAc,MAAA,EAAQ,oBAAoB,MAAM,CAAA;AAAA,IACjG;AAEA,IAAA,QAAA,CAAS,YAAA,CAAa,IAAA,CAAK,UAAA,CAAW,YAAA,EAAc,IAAI,CAAA;AAGxD,IAAA,QAAA,CAAS,eAAe,IAAA,CAAK;AAAA,MACzB,MAAA,EAAQ;AAAA,KACX,CAAA;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,sBACJ,UAAA,EACA,OAAA,EACA,OAAA,EACA,gBAAA,EACA,aACA,YAAA,EAEJ;AACI,IAAA,MAAM,cAAc,UAAA,CAAW,WAAA;AAE/B,IAAA,WAAA,CAAY,IAAI,OAAA,GAAU,gBAAA;AAC1B,IAAA,WAAA,CAAY,IAAI,OAAA,GAAU,gBAAA;AAC1B,IAAA,WAAA,CAAY,QAAQ,WAAA,GAAc,gBAAA;AAClC,IAAA,WAAA,CAAY,SAAS,YAAA,GAAe,gBAAA;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaQ,qBAAA,CACJ,OACA,MAAA,EACA,UAAA,EACA,SACA,OAAA,EACA,UAAA,EACA,eACA,KAAA,EAEJ;AACI,IAAA,MAAM,QAAA,GAAW,KAAK,qBAAA,CAAsB,QAAA;AAC5C,IAAA,MAAM,cAAc,QAAA,CAAS,YAAA;AAC7B,IAAA,MAAM,YAAY,QAAA,CAAS,UAAA;AAC3B,IAAA,MAAM,aAAa,QAAA,CAAS,WAAA;AAC5B,IAAA,MAAM,aAAa,QAAA,CAAS,WAAA;AAC5B,IAAA,MAAM,cAAc,QAAA,CAAS,YAAA;AAC7B,IAAA,MAAM,gBAAgB,QAAA,CAAS,cAAA;AAG/B,IAAA,IAAI,aAAA,EACJ;AACI,MAAA,WAAA,CAAY,CAAC,CAAA,GAAI,UAAA,CAAW,MAAA,CAAO,IAAA,GAAO,OAAA;AAC1C,MAAA,WAAA,CAAY,CAAC,CAAA,GAAI,UAAA,CAAW,MAAA,CAAO,IAAA,GAAO,OAAA;AAAA,IAC9C,CAAA,MAEA;AACI,MAAA,WAAA,CAAY,CAAC,CAAA,GAAI,CAAA;AACjB,MAAA,WAAA,CAAY,CAAC,CAAA,GAAI,CAAA;AAAA,IACrB;AAEA,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,KAAA,CAAM,KAAA,CAAM,KAAA;AAC7B,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,KAAA,CAAM,KAAA,CAAM,MAAA;AAE7B,IAAA,SAAA,CAAU,CAAC,CAAA,GAAI,KAAA,CAAM,MAAA,CAAO,KAAA;AAC5B,IAAA,SAAA,CAAU,CAAC,CAAA,GAAI,KAAA,CAAM,MAAA,CAAO,MAAA;AAC5B,IAAA,SAAA,CAAU,CAAC,CAAA,GAAI,CAAA,GAAI,SAAA,CAAU,CAAC,CAAA;AAC9B,IAAA,SAAA,CAAU,CAAC,CAAA,GAAI,CAAA,GAAI,SAAA,CAAU,CAAC,CAAA;AAE9B,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,KAAA,CAAM,MAAA,CAAO,UAAA;AAC7B,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,KAAA,CAAM,MAAA,CAAO,WAAA;AAC7B,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,CAAA,GAAM,UAAA,CAAW,CAAC,CAAA;AAClC,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,CAAA,GAAM,UAAA,CAAW,CAAC,CAAA;AAElC,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,GAAA,GAAM,UAAA,CAAW,CAAC,CAAA;AAClC,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,GAAA,GAAM,UAAA,CAAW,CAAC,CAAA;AAClC,IAAA,UAAA,CAAW,CAAC,CAAA,GAAK,KAAA,CAAM,KAAA,CAAM,KAAA,GAAQ,UAAU,CAAC,CAAA,GAAM,GAAA,GAAM,UAAA,CAAW,CAAC,CAAA;AACxE,IAAA,UAAA,CAAW,CAAC,CAAA,GAAK,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,UAAU,CAAC,CAAA,GAAM,GAAA,GAAM,UAAA,CAAW,CAAC,CAAA;AAEzE,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,YAAA,CAAa,gBAAA,CAAiB,YAAA;AAEhE,IAAA,WAAA,CAAY,CAAC,IAAI,OAAA,GAAU,UAAA;AAC3B,IAAA,WAAA,CAAY,CAAC,IAAI,OAAA,GAAU,UAAA;AAC3B,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,WAAA,CAAY,MAAA,CAAO,KAAA,GAAQ,UAAA;AAC5C,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,WAAA,CAAY,MAAA,CAAO,MAAA,GAAS,UAAA;AAG7C,IAAA,IAAI,MAAA,YAAkB,OAAA,EAAS,MAAA,CAAO,MAAA,CAAO,QAAA,GAAW,IAAA;AAGxD,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,QAAA,CAAS,YAAA,CAAa,gBAAgB,MAAM,CAAA;AAEtE,IAAA,IAAA,CAAK,SAAS,YAAA,CAAa,IAAA,CAAK,MAAA,EAAQ,CAAC,CAAC,KAAK,CAAA;AAE/C,IAAA,IAAI,kBAAkB,OAAA,EACtB;AACI,MAAA,aAAA,CAAc,CAAC,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,KAAA;AAChC,MAAA,aAAA,CAAc,CAAC,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,MAAA;AAAA,IACpC,CAAA,MAEA;AAEI,MAAA,aAAA,CAAc,CAAC,IAAI,YAAA,CAAa,KAAA;AAChC,MAAA,aAAA,CAAc,CAAC,IAAI,YAAA,CAAa,MAAA;AAAA,IACpC;AAEA,IAAA,aAAA,CAAc,CAAC,CAAA,GAAI,YAAA,CAAa,MAAA,GAAS,CAAA,CAAA,GAAK,CAAA;AAE9C,IAAA,IAAA,CAAK,sBAAsB,MAAA,EAAO;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,sBAAsB,cAAA,EAC9B;AACI,IAAA,IAAI,YAAA,GAAe,KAAK,iBAAA,GAAoB,CAAA;AAE5C,IAAA,OAAO,eAAe,CAAA,IAAK,IAAA,CAAK,YAAA,CAAa,YAAY,EAAE,IAAA,EAC3D;AACI,MAAA,EAAE,YAAA;AAAA,IACN;AAEA,IAAA,OAAO,YAAA,GAAe,CAAA,IAAK,IAAA,CAAK,YAAA,CAAa,YAAY,CAAA,CAAE,YAAA,GACrD,IAAA,CAAK,YAAA,CAAa,YAAY,CAAA,CAAE,YAAA,CAAa,OAAO,WAAA,GACpD,cAAA;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,yBAAA,GACR;AACI,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,IAAI,YAAY,IAAA,CAAK,iBAAA;AAErB,IAAA,OAAO,YAAY,CAAA,EACnB;AACI,MAAA,SAAA,EAAA;AACA,MAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,YAAA,CAAa,SAAS,CAAA;AAElD,MAAA,IAAI,CAAC,eAAe,IAAA,EACpB;AACI,QAAA,OAAA,GAAU,eAAe,MAAA,CAAO,IAAA;AAChC,QAAA,OAAA,GAAU,eAAe,MAAA,CAAO,IAAA;AAChC,QAAA;AAAA,MACJ;AAAA,IACJ;AAEA,IAAA,OAAO,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA,EAAG,OAAA,EAAQ;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,oBAAA,CAAqB,aAAgC,MAAA,EAC7D;AAII,IAAA,IAAI,YAAY,WAAA,EAChB;AACI,MAAA,yBAAA,CAA0B,WAAA,CAAY,aAAa,MAAM,CAAA;AAAA,IAC7D,CAAA,MAAA,IAES,WAAA,CAAY,YAAA,CAAa,UAAA,EAClC;AACI,MAAA,MAAA,CAAO,KAAA,EAAM;AAGb,MAAA,MAAA,CAAO,OAAA,CAAQ,WAAA,CAAY,YAAA,CAAa,UAAU,CAAA;AAGlD,MAAA,MAAA,CAAO,WAAA,CAAY,WAAA,CAAY,SAAA,CAAU,cAAc,CAAA;AAAA,IAC3D,CAAA,MAIA;AAGI,MAAA,WAAA,CAAY,SAAA,CAAU,mBAAA,CAAoB,IAAA,EAAM,MAAM,CAAA;AAAA,IAC1D;AAEA,IAAA,IAAI,YAAY,SAAA,EAChB;AAII,MAAA,MAAM,WAAA,GAAc,WAAA,CAAY,SAAA,CAAU,WAAA,IAAe,YAAY,SAAA,CAAU,iBAAA;AAC/E,MAAA,MAAM,uBAAuB,WAAA,CAAY,qBAAA;AAEzC,MAAA,IAAI,oBAAA,EACJ;AACI,QAAA,MAAA,CAAO,YAAY,oBAAoB,CAAA;AAAA,MAC3C;AAAA,IACJ;AAAA,EACJ;AAAA,EAEQ,sBAAA,CAAuB,YAAwB,KAAA,EACvD;AACI,IAAA,MAAM,eAAe,UAAA,CAAW,YAAA;AAEhC,IAAA,MAAM,SAAS,UAAA,CAAW,MAAA;AAE1B,IAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,IAAA,MAAM,eAAe,UAAA,CAAW,iBAAA;AAChC,IAAA,MAAM,cAAc,UAAA,CAAW,gBAAA;AAM/B,IAAA,IAAA,CAAK,sBAAA,CAAuB,WAAA,CAAY,YAAA,CAAa,MAAA,CAAO,OAAO,CAAC,CAAA;AACpE,IAAA,IAAA,CAAK,sBAAA,CAAuB,WAAA,CAAY,UAAA,CAAW,WAAA,CAAY,QAAQ,CAAC,CAAA;AAExE,IAAA,IAAI,iBAAiB,WAAA,EACrB;AAEI,MAAA,OAAA,CAAQ,YAAY,CAAA,CAAE,KAAA,CAAM,MAAM,YAAA,EAAc,UAAA,CAAW,qBAAqB,KAAK,CAAA;AAAA,IACzF,CAAA,MAEA;AACI,MAAA,IAAI,OAAO,UAAA,CAAW,YAAA;AAEtB,MAAA,MAAM,cAAc,WAAA,CAAY,iBAAA;AAAA,QAC5B,MAAA,CAAO,KAAA;AAAA,QACP,MAAA,CAAO,MAAA;AAAA,QACP,KAAK,MAAA,CAAO,WAAA;AAAA,QACZ;AAAA,OACJ;AAGA,MAAA,IAAI,IAAA,GAAO,WAAA;AAGX,MAAA,KAAA,IAAS,CAAA,GAAI,YAAA,EAAc,CAAA,GAAI,WAAA,EAAa,CAAA,EAAA,EAC5C;AACI,QAAA,MAAM,MAAA,GAAS,QAAQ,CAAC,CAAA;AAExB,QAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AAErB,QAAA,MAAA,CAAO,KAAA,CAAM,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA;AACnC,QAAA,MAAM,CAAA,GAAI,IAAA;AAEV,QAAA,IAAA,GAAO,IAAA;AACP,QAAA,IAAA,GAAO,CAAA;AAAA,MACX;AAEA,MAAA,OAAA,CAAQ,WAAW,CAAA,CAAE,KAAA,CAAM,MAAM,IAAA,EAAM,UAAA,CAAW,qBAAqB,KAAK,CAAA;AAG5E,MAAA,WAAA,CAAY,cAAc,WAAW,CAAA;AAAA,IACzC;AAAA,EACJ;AAAA,EAEQ,sBAAA,CACJ,UAAA,EACA,QAAA,EACA,aAAA,EACA,gBAKA,iBAAA,EAEJ;AACI,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AAEtB,IAAA,MAAM,SAAS,UAAA,CAAW,MAAA;AAC1B,IAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAM3B,IAAA,IAAI,UAAA,GAAa,QAAA;AAEjB,IAAA,IAAI,OAAA,GAAU,CAAA;AAEd,IAAA,IAAI,SAAA,GAAY,IAAA;AAEhB,IAAA,IAAI,aAAA,GAAgB,KAAA;AAEpB,IAAA,IAAI,OAAA,GAAU,KAAA;AAEd,IAAA,IAAI,cAAA,GAAiB,IAAA;AAErB,IAAA,IAAI,iBAAA,GAAoB,CAAA,CAAA;AACxB,IAAA,IAAI,gBAAA,GAAmB,CAAA,CAAA;AAEvB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EACpC;AACI,MAAA,MAAM,MAAA,GAAS,QAAQ,CAAC,CAAA;AAGxB,MAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AAErB,MAAA,IAAI,iBAAA,KAAsB,IAAI,iBAAA,GAAoB,CAAA;AAClD,MAAA,gBAAA,GAAmB,CAAA;AACnB,MAAA,UAAA,GAAa,IAAA,CAAK,IAAI,UAAA,EAAY,MAAA,CAAO,eAAe,SAAA,GAClD,cAAA,GAAiB,OAAO,UAAU,CAAA;AACxC,MAAA,OAAA,IAAW,MAAA,CAAO,OAAA;AAElB,MAAA,IAAI,MAAA,CAAO,cAAc,KAAA,EACzB;AACI,QAAA,SAAA,GAAY,KAAA;AAAA,MAChB,CAAA,MAAA,IACS,MAAA,CAAO,SAAA,KAAc,SAAA,EAC9B;AACI,QAAA,SAAA,KAAA,SAAA,GAAc,aAAA,CAAA;AAAA,MAClB;AAEA,MAAA,IAAI,CAAC,OAAO,cAAA,EACZ;AACI,QAAA,cAAA,GAAiB,KAAA;AAAA,MACrB;AAEA,MAAA,MAAM,YAAA,GAAe,CAAC,EAAE,MAAA,CAAO,sBAAsB,QAAA,CAAS,IAAA,CAAA;AAE9D,MAAA,IAAI,CAAC,YAAA,EACL;AACI,QAAA,OAAA,GAAU,KAAA;AACV,QAAA;AAAA,MACJ;AAEA,MAAA,IAAI,OAAO,aAAA,IAAiB,EAAG,QAAA,CAA2B,UAAA,EAAY,iBAAiB,IAAA,CAAA,EACvF;AAGI,QAAA,IAAA,CAAK,sHAAsH,CAAA;AAG3H,QAAA,OAAA,GAAU,KAAA;AACV,QAAA;AAAA,MACJ;AAEA,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,aAAA,KAAA,aAAA,GAAkB,MAAA,CAAO,aAAA,CAAA;AAAA,IAC7B;AAGA,IAAA,IAAI,CAAC,OAAA,EACL;AACI,MAAA,UAAA,CAAW,IAAA,GAAO,IAAA;AAElB,MAAA;AAAA,IACJ;AAKA,IAAA,IAAI,cAAA,EACJ;AACI,MAAA,MAAA,CAAO,SAAA,CAAU,GAAG,QAAA,CAAS,KAAA,GAAQ,gBAAgB,CAAA,EAAG,QAAA,CAAS,SAAS,cAAc,CAAA;AAAA,IAC5F;AAGA,IAAA,MAAA,CACK,KAAA,CAAM,UAAU,CAAA,CAChB,IAAA,EAAK,CACL,KAAA,CAAM,CAAA,GAAI,UAAU,CAAA,CACpB,GAAA,CAAA,CAAK,OAAA,GAAU,CAAA,IAAK,iBAAiB,CAAA;AAI1C,IAAA,IAAI,CAAC,OAAO,UAAA,EACZ;AACI,MAAA,UAAA,CAAW,IAAA,GAAO,IAAA;AAElB,MAAA;AAAA,IACJ;AAUA,IAAA,UAAA,CAAW,SAAA,GAAY,SAAA;AACvB,IAAA,UAAA,CAAW,UAAA,GAAa,UAAA;AACxB,IAAA,UAAA,CAAW,aAAA,GAAgB,aAAA;AAC3B,IAAA,UAAA,CAAW,iBAAA,GAAoB,iBAAA;AAC/B,IAAA,UAAA,CAAW,gBAAA,GAAmB,gBAAA;AAAA,EAClC;AAAA,EAEQ,cAAA,GACR;AACI,IAAA,IAAA,CAAK,iBAAA,EAAA;AAEL,IAAA,OAAO,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,iBAAiB,CAAA;AAAA,EACnD;AAAA,EAEQ,sBAAA,GACR;AACI,IAAA,IAAI,kBAAA;AAEJ,IAAA,IAAI,KAAA,GAAQ,KAAK,iBAAA,GAAoB,CAAA;AAErC,IAAA,OAAO,QAAQ,CAAA,EACf;AACI,MAAA,KAAA,EAAA;AACA,MAAA,kBAAA,GAAqB,IAAA,CAAK,aAAa,KAAK,CAAA;AAE5C,MAAA,IAAI,CAAC,mBAAmB,IAAA,EACxB;AACI,QAAA;AAAA,MACJ;AAAA,IACJ;AAEA,IAAA,OAAO,kBAAA;AAAA,EACX;AAAA,EAEQ,eAAA,GACR;AACI,IAAA,IAAI,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,iBAAiB,CAAA;AAEzD,IAAA,IAAI,CAAC,UAAA,EACL;AACI,MAAA,UAAA,GAAa,KAAK,YAAA,CAAa,IAAA,CAAK,iBAAiB,CAAA,GAAI,IAAI,UAAA,EAAW;AAAA,IAC5E;AAEA,IAAA,IAAA,CAAK,iBAAA,EAAA;AAEL,IAAA,OAAO,UAAA;AAAA,EACX;AACJ;AAAA;AAz6Ba,YAAA,CAGK,SAAA,GAAY;AAAA,EACtB,IAAA,EAAM;AAAA,IACF,aAAA,CAAc,WAAA;AAAA,IACd,aAAA,CAAc;AAAA,GAClB;AAAA,EACA,IAAA,EAAM;AACV,CAAA;;;;"}