{"version":3,"file":"polyfill.mjs","sources":["../node_modules/ts-browser-helpers/dist/bundle.esm.js","../src/syncFormState.ts","../src/htmlRenderer.ts","../src/htmlInCanvasPolyfill.ts"],"sourcesContent":["/**\n * @license\n * ts-browser-helpers v0.12.0\n * Copyright 2022-2024 repalash <palash@shaders.app>\n * MIT License\n */\n\n/**\n * A simple event dispatcher with typed event types, see {@link IEventDispatcher}.\n */\nclass SimpleEventDispatcher {\n    constructor() {\n        this._eventListeners = {};\n        this.dispatchEvent = this.dispatchEvent.bind(this);\n        this.addEventListener = this.addEventListener.bind(this);\n        this.removeEventListener = this.removeEventListener.bind(this);\n        this.hasEventListener = this.hasEventListener.bind(this);\n    }\n    addEventListener(type, listener) {\n        const listeners = this._eventListeners;\n        if (listeners[type] === undefined)\n            listeners[type] = [];\n        if (!listeners[type].includes(listener))\n            listeners[type].push(listener);\n    }\n    hasEventListener(type, listener) {\n        const listeners = this._eventListeners;\n        return listeners[type] !== undefined && listeners[type].includes(listener);\n    }\n    removeEventListener(type, listener) {\n        const listeners = this._eventListeners;\n        const listenerArray = listeners[type];\n        if (listenerArray !== undefined) {\n            const index = listenerArray.indexOf(listener);\n            if (index !== -1)\n                listenerArray.splice(index, 1);\n        }\n    }\n    dispatchEvent(event) {\n        const listeners = this._eventListeners;\n        const listenerArray = listeners[event.type];\n        if (listenerArray !== undefined) {\n            event.target = this;\n            // Make a copy, in case listeners are removed while iterating.\n            const array = listenerArray.slice(0);\n            for (let i = 0, l = array.length; i < l; i++)\n                array[i].call(this, event);\n        }\n    }\n}\n\n/**\n * Returns a promise that resolves after the given duration. Basically a setTimeout that returns a promise.\n * @param duration - in ms\n *\n * @category Time\n */\nasync function timeout(duration) {\n    return new Promise(resolve => setTimeout(resolve, Math.max(0, duration)));\n}\n/**\n * Returns the current time in milliseconds. If performance.now() is available, it is used, otherwise Date.now() is used.\n *\n * @category Time\n */\nfunction now() {\n    return (typeof performance === 'undefined' ? Date : performance).now(); // see threejs  #10732\n}\n\n/**\n * A helper class to handle pointer events and dispatch drag events: `drag`, `dragStart` and `dragEnd` with NDC coordinates and time.\n *\n * To use, create an object of the class, set `element` with the HTML element(like canvas) and add event listeners to drag events.\n *\n * @example\n * ```ts\n * const pointerDragHelper = new PointerDragHelper()\n * pointerDragHelper.element = canvas\n * pointerDragHelper.addEventListener('dragStart', (e) => {\n *    console.log('dragStart', e.pointer)\n *    // {x: -0.5, y: 0.5, time: 123456789}\n *    // x and y are NDC coordinates, time is the time when the event is fired.\n *    // x and y are in the range of [-1, 1].\n *    // x is left to right, y is bottom to top.\n *    // time is in milliseconds.\n * })\n * pointerDragHelper.addEventListener('drag', (e) => {\n *   console.log('drag', e.pointer)\n *   // {x: -0.5, y: 0.5, time: 123456789}\n * })\n * pointerDragHelper.addEventListener('dragEnd', (e) => {\n *  console.log('dragEnd', e.pointer)\n *  // {x: -0.5, y: 0.5, time: 123456789}\n * })\n * ```\n */\nclass PointerDragHelper extends SimpleEventDispatcher {\n    constructor() {\n        super(...arguments);\n        this._onPointerDown = (e) => {\n            if (e.button !== 0)\n                return;\n            if (!this._element)\n                return;\n            this._pointerUp = undefined;\n            const x = e.clientX / this._element.clientWidth * 2 - 1;\n            const y = -(e.clientY / this._element.clientHeight) * 2 + 1;\n            const time = now();\n            this._pointerDown = { x, y, time };\n            this._pointer = this._pointerDown;\n            this.dispatchEvent({ type: 'dragStart', pointer: this._pointerDown });\n        };\n        this._onPointerMove = (e) => {\n            if (!this._pointerDown || !this._pointer)\n                return;\n            if (!this._element)\n                return;\n            const x = e.clientX / this._element.clientWidth * 2 - 1;\n            const y = -(e.clientY / this._element.clientHeight) * 2 + 1;\n            const time = now();\n            this.dispatchEvent({\n                type: 'drag', pointer: this._pointer,\n                drag: { x: x - this._pointerDown.x, y: y - this._pointerDown.y, time: time - this._pointerDown.time },\n                delta: { x: x - this._pointer.x, y: y - this._pointer.y, time: time - this._pointer.time },\n            });\n            this._pointer = { x: x, y: y, time: now() };\n            if (e.buttons % 2 === 0)\n                this._onPointerUp(e);\n        };\n        this._onPointerUp = (e) => {\n            if (e.button !== 0)\n                return;\n            if (!this._pointerDown)\n                return;\n            if (!this._element)\n                return;\n            const x = e.clientX / this._element.clientWidth * 2 - 1;\n            const y = -(e.clientY / this._element.clientHeight) * 2 + 1;\n            const time = now();\n            this._pointerUp = { x: x, y: y, time };\n            this.dispatchEvent({\n                type: 'dragEnd', pointer: this._pointerUp,\n                drag: {\n                    x: this._pointerUp.x - this._pointerDown.x,\n                    y: this._pointerUp.y - this._pointerDown.y,\n                    time: this._pointerUp.time - this._pointerDown.time,\n                },\n            });\n            this._pointerDown = undefined;\n            this._pointer = undefined;\n        };\n    }\n    get element() {\n        return this._element;\n    }\n    set element(value) {\n        if (this._element === value)\n            return;\n        if (this._element)\n            this._removeElement();\n        this._element = value;\n        if (this._element)\n            this._addElement();\n    }\n    _removeElement() {\n        var _a, _b, _c, _d, _e;\n        (_a = this._element) === null || _a === void 0 ? void 0 : _a.removeEventListener('pointerdown', this._onPointerDown);\n        (_b = this._element) === null || _b === void 0 ? void 0 : _b.removeEventListener('pointermove', this._onPointerMove);\n        (_c = this._element) === null || _c === void 0 ? void 0 : _c.removeEventListener('pointerup', this._onPointerUp);\n        (_d = this._element) === null || _d === void 0 ? void 0 : _d.removeEventListener('pointercancel', this._onPointerUp);\n        (_e = this._element) === null || _e === void 0 ? void 0 : _e.removeEventListener('pointerout', this._onPointerUp);\n    }\n    _addElement() {\n        var _a, _b, _c, _d, _e;\n        (_a = this._element) === null || _a === void 0 ? void 0 : _a.addEventListener('pointerdown', this._onPointerDown);\n        (_b = this._element) === null || _b === void 0 ? void 0 : _b.addEventListener('pointermove', this._onPointerMove);\n        (_c = this._element) === null || _c === void 0 ? void 0 : _c.addEventListener('pointerup', this._onPointerUp);\n        (_d = this._element) === null || _d === void 0 ? void 0 : _d.addEventListener('pointercancel', this._onPointerUp);\n        (_e = this._element) === null || _e === void 0 ? void 0 : _e.addEventListener('pointerout', this._onPointerUp);\n    }\n    dispose() {\n        this.element = undefined;\n    }\n}\n\n/* @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the 'License');\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an 'AS IS' BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * The Damper class is a generic second-order critically damped system that does\n * one linear step of the desired length of time. The only parameter is\n * DECAY_MILLISECONDS. This common parameter makes all states converge at the\n * same rate regardless of scale. xNormalization is a number to provide the\n * rough scale of x, such that NIL_SPEED clamping also happens at roughly the\n * same convergence for all states.\n *\n * Taken from Google model-viewer.\n *\n * https://github.com/google/model-viewer/blob/ec527bc1d0e1bcb4421fa192a7e62bbc5764db91/packages/model-viewer/src/three-components/Damper.ts#L1\n */\nclass Damper {\n    constructor(decayMilliseconds = Damper.DECAY_MILLISECONDS) {\n        this.velocity = 0;\n        this.naturalFrequency = 0;\n        this.setDecayTime(decayMilliseconds);\n    }\n    setDecayTime(decayMilliseconds) {\n        this.naturalFrequency =\n            1 / Math.max(Damper.MIN_DECAY_MILLISECONDS, decayMilliseconds);\n    }\n    update(v, vGoal, timeStepMilliseconds, xNormalization) {\n        const nilSpeed = 0.0002 * this.naturalFrequency;\n        if (v == null || xNormalization === 0) {\n            return vGoal;\n        }\n        if (v === vGoal && this.velocity === 0) {\n            return vGoal;\n        }\n        if (timeStepMilliseconds < 0) {\n            return v;\n        }\n        // Exact solution to a critically damped second-order system, where:\n        // acceleration = this.naturalFrequency * this.naturalFrequency * (vGoal\n        // - v) - 2 * this.naturalFrequency * this.velocity;\n        const deltaV = (v - vGoal);\n        const intermediateVelocity = this.velocity + this.naturalFrequency * deltaV;\n        const intermediateX = deltaV + timeStepMilliseconds * intermediateVelocity;\n        const decay = Math.exp(-this.naturalFrequency * timeStepMilliseconds);\n        const newVelocity = (intermediateVelocity - this.naturalFrequency * intermediateX) * decay;\n        const acceleration = -this.naturalFrequency * (newVelocity + intermediateVelocity * decay);\n        if (Math.abs(newVelocity) < nilSpeed * Math.abs(xNormalization) &&\n            acceleration * deltaV >= 0) {\n            // This ensures the controls settle and stop calling this function instead\n            // of asymptotically approaching their goal.\n            this.velocity = 0;\n            return vGoal;\n        }\n        else {\n            this.velocity = newVelocity;\n            return vGoal + intermediateX * decay;\n        }\n    }\n}\nDamper.SETTLING_TIME = 10000; // plenty long enough\nDamper.MIN_DECAY_MILLISECONDS = 0.001;\nDamper.DECAY_MILLISECONDS = 50;\n\n/**\n * Creates a HTML canvas element.\n * @category DOM\n */\nfunction createCanvasElement() {\n    const canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');\n    canvas.style.display = 'block';\n    return canvas;\n}\n/**\n * Creates a HTML div element.\n * @param innerHTML - HTML string to add to the div\n * @param id - id of the div\n * @param classList - list of classes to add to the div\n * @param addToBody - add the div to the body\n * @param elementTag - tag of the element to create (default: div)\n *\n * @category DOM\n */\nfunction createDiv({ innerHTML = '', id, classList, addToBody = true, elementTag = 'div' }) {\n    const elem = document.createElement(elementTag);\n    if (id)\n        elem.id = id;\n    elem.innerHTML = innerHTML;\n    if (classList)\n        elem.classList.add(...classList);\n    if (addToBody)\n        document.body.appendChild(elem);\n    return elem;\n}\n/**\n * Creates a HTML image element from a url.\n * @param url - url of the image\n *\n * @category DOM\n */\nasync function createImage(url) {\n    return new Promise((resolve, reject) => {\n        const img = new Image();\n        img.onload = () => resolve(img);\n        img.onerror = reject;\n        img.crossOrigin = 'anonymous';\n        img.decoding = 'sync';\n        img.src = url;\n    });\n}\n/**\n * Creates a HTML style element with the given styles.\n * @param styles - CSS string\n * @param root - root element to add the style to (default: head)\n *\n * @category DOM\n */\nfunction createStyles(styles, root = document.head) {\n    const styleSheet = document.createElement('style');\n    styleSheet.type = 'text/css';\n    styleSheet.innerText = styles;\n    root === null || root === void 0 ? void 0 : root.appendChild(styleSheet);\n    return styleSheet;\n}\n/**\n * Creates a HTML script element from a url.\n * @param url - url of the script\n * @param root - root element to add the script to (default: head)\n *\n * @category DOM\n */\nasync function createScriptFromURL(url, root = document.head) {\n    return new Promise((resolve, reject) => {\n        const s = document.createElement('script');\n        s.setAttribute('src', url);\n        s.addEventListener('load', () => resolve(s));\n        s.addEventListener('error', reject);\n        root.appendChild(s);\n    });\n}\n/**\n * Sets the innerHTML of an element and recreates all script tags so they are executed.\n * @param element - element to set the innerHTML of\n * @param html - innerHTML string to set\n */\nasync function setInnerHTMLWithScripts(element, html) {\n    var _a;\n    element.innerHTML = html;\n    const scripts = element.getElementsByTagName('script');\n    // eslint-disable-next-line @typescript-eslint/prefer-for-of\n    for (let i = 0; i < scripts.length; i++) {\n        const script = scripts[i];\n        const newScript = cloneScriptTag(script);\n        let err = false;\n        await new Promise(resolve => {\n            newScript.onload = resolve;\n            newScript.onerror = () => {\n                err = true;\n                resolve(undefined);\n            };\n        });\n        if (err)\n            continue;\n        (_a = script.parentNode) === null || _a === void 0 ? void 0 : _a.replaceChild(newScript, script);\n    }\n}\n/**\n * Clones a script tag.\n * @param script - script tag to clone\n * @param newScript - optional new script tag to clone into. If not provided a new script tag will be created.\n */\nfunction cloneScriptTag(script, newScript) {\n    newScript = newScript !== null && newScript !== void 0 ? newScript : document.createElement('script');\n    newScript.type = script.type || 'text/javascript';\n    newScript.text = script.text;\n    // eslint-disable-next-line @typescript-eslint/prefer-for-of\n    for (let j = 0; j < script.attributes.length; j++) {\n        const attr = script.attributes[j];\n        newScript.setAttribute(attr.name, attr.value);\n    }\n    return newScript;\n}\n\n/**\n * Convert an ArrayBuffer to Base64 string\n * @param buffer - ArrayBuffer to convert\n * @category ArrayBuffer\n */\nfunction arrayBufferToBase64(buffer) {\n    if (!window) {\n        console.warn('window is required');\n        return '';\n    }\n    let binary = '';\n    const bytes = new Uint8Array(buffer);\n    const len = bytes.byteLength;\n    for (let i = 0; i < len; i++) {\n        binary += String.fromCharCode(bytes[i]);\n    }\n    return window.btoa(binary);\n}\n/**\n * Convert a Base64 string to ArrayBuffer\n * @param base64 - Base64 string to convert\n * @category ArrayBuffer\n */\nfunction base64ToArrayBuffer(base64) {\n    if (!window) {\n        console.warn('window is required');\n        return new Uint8Array(0);\n    }\n    const binaryString = window.atob(base64);\n    const len = binaryString.length;\n    const bytes = new Uint8Array(len);\n    for (let i = 0; i < len; i++) {\n        bytes[i] = binaryString.charCodeAt(i);\n    }\n    return bytes.buffer;\n}\n// if (!ArrayBuffer.prototype.slice)\n//     ArrayBuffer.prototype.slice = function(start, end) {\n//         const that = new Uint8Array(this)\n//         if (end == undefined) end = that.length\n//         const result = new ArrayBuffer(end - start)\n//         const resultArray = new Uint8Array(result)\n//         for (let i = 0; i < resultArray.length; i++)\n//             resultArray[i] = that[i + start]\n//         return result\n//     }\n/**\n * Mapping of typed array constructors by name\n * @category ArrayBuffer\n */\nconst TYPED_ARRAYS = {\n    Int8Array: Int8Array,\n    Uint8Array: Uint8Array,\n    Uint8ClampedArray: Uint8ClampedArray,\n    Int16Array: Int16Array,\n    Uint16Array: Uint16Array,\n    Int32Array: Int32Array,\n    Uint32Array: Uint32Array,\n    Float32Array: Float32Array,\n    Float64Array: Float64Array,\n};\n/**\n * Create a typed array from an ArrayBuffer by name\n * @param type - Name of the typed array constructor\n * @param buffer - ArrayBuffer to use\n * @category ArrayBuffer\n */\nfunction getTypedArray(type, buffer) {\n    return new TYPED_ARRAYS[type](buffer);\n}\n\n/**\n * Convert a string to title case\n * @param str - The string to convert\n *\n * @category Text\n */\nfunction toTitleCase(str) {\n    return str.replace(/\\w\\S*/g, function (txt) {\n        return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();\n    });\n}\n/**\n * Convert a string to camel case\n * @param str - The string to convert\n *\n * @category Text\n */\nfunction toCamelCase(str) {\n    return str.replace(/([-_][a-z])/ig, ($1) => {\n        return $1.toUpperCase()\n            .replace('-', '')\n            .replace('_', '');\n    });\n}\n/**\n * Parse a file extension from a path\n * @param path - The path to parse\n * @returns file extension without the dot (e.g. 'png')\n *\n * @category Text\n */\nfunction parseFileExtension(path) {\n    var _a;\n    if (!path || path === '' || path.match(/__MACOSX\\/.*\\._/))\n        return ''; // todo: proper hidden files checks\n    path = path.replace(/\\?.*$/, ''); // remove query string\n    const basename = (_a = path.split(/[\\\\/]/).pop()) !== null && _a !== void 0 ? _a : '', pos = basename.lastIndexOf('.');\n    if (basename === '' || pos < 1)\n        return '';\n    return basename.slice(pos + 1);\n}\n/**\n * Get the filename from a path, similar to PHP's basename()\n * @param url\n *\n * @category Text\n */\nfunction getFilenameFromPath(url) {\n    return url.substring(url.lastIndexOf('/') + 1);\n}\n/**\n * Escape a string for use in a regular expression\n * @param str\n *\n * @category Text\n */\nfunction escapeRegExp(str) {\n    return str.replace(/([.*+?^=!:${}()|[\\]/\\\\])/g, '\\\\$1');\n}\n/**\n * Replace all occurrences of a string in another string\n * @param str - The string to search\n * @param find - The string to replace\n * @param replace - The replacement string\n *\n * @category Text\n */\nfunction replaceAll(str, find, replace) {\n    return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);\n}\n/**\n * Replace a string in a text, optionally prepending, appending, replacing all occurrences, and/or calling a callback if the string is not found\n * @param source - The source text\n * @param str - The string to replace\n * @param newStr - The replacement string\n * @param replaceAll - Replace all occurrences\n * @param prepend - Prepend the replacement string\n * @param append - Append the replacement string\n * @param notFoundCallback - Callback to call if the string is not found\n */\nfunction safeReplaceString(source, str, newStr, { replaceAll = false, prepend = false, append = false, notFoundCallback = () => { }, } = {}) {\n    if (notFoundCallback) {\n        if (!source.includes(str)) {\n            notFoundCallback();\n            return source;\n        }\n    }\n    let s = newStr;\n    if (prepend) {\n        s = newStr + str;\n    }\n    else if (append) {\n        s = str + newStr;\n    }\n    return replaceAll ? source.replaceAll(str, s) : source.replace(str, s);\n}\n/**\n * Find the longest common prefix in an array of strings\n * https://stackoverflow.com/questions/68702774/longest-common-prefix-in-javascript\n * @param words\n */\nfunction longestCommonPrefix(words) {\n    words.sort(); // shortest string will be first and the longest last\n    return (words[0].split('') // converts shortest word to an array of chars\n        .map((char, idx) => words[words.length - 1][idx] === char ? char : '\\0') // replaces non-matching chars with NULL char\n        .join('') // converts back to a string\n        .split('\\0') // splits the string by NULL characters\n        .at(0) // returns the first part\n        || '');\n}\n\n/**\n * A template literal tag that does nothing. Useful for syntax highlighting of GLSL code.\n *\n * @example\n * ```js\n * const vertexShader = glsl`\n *    void main() {}\n * `\n * ```\n * @category Template Literals\n */\nconst glsl = (strings, ...rest) => String.raw({ raw: strings }, ...rest);\n/**\n * A template literal tag that does nothing. Useful for syntax highlighting of CSS code.\n *\n * @example\n * ```js\n * const vertexShader = css`\n *    .my-class {\n *        color: red;\n *    }\n * `\n * ```\n * @category Template Literals\n */\nconst css = (strings, ...rest) => String.raw({ raw: strings }, ...rest);\n/**\n * A template literal tag that does nothing. Useful for syntax highlighting of HTML code.\n *\n * @example\n * ```js\n * const vertexShader = html`\n *    <div class=\"my-class\">\n *        <p>Some text</p>\n *    </div>\n * `\n * ```\n * @category Template Literals\n */\nconst html = (strings, ...rest) => String.raw({ raw: strings }, ...rest);\n/**\n * Converts an SVG string to data url. This is useful for creating images from SVGs, or using SVGs in CSS.\n * To use put in template string: `url(${svgUrl\\`<svg>...</svg>\\`})`\n * @param strings - template strings\n * @param rest - template values\n *\n * @example\n * ```ts\n * const url = svgUrl\\`\n *  <svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\"> ... </svg>\n * \\`\n * console.log(url) // data:image/svg+xml;charset=UTF-8,...\n * ```\n *\n * @category Template Literals\n */\nconst svgUrl = (strings, ...rest) => {\n    let encoded = String.raw({ raw: strings }, ...rest);\n    encoded = replaceAll(encoded, '%', '%25');\n    encoded = replaceAll(encoded, '> <', '><'); // normalise spaces elements\n    encoded = replaceAll(encoded, '; }', ';}'); // normalise spaces css\n    encoded = replaceAll(encoded, '<', '%3c');\n    encoded = replaceAll(encoded, '>', '%3e');\n    encoded = replaceAll(encoded, '\"', '\\'');\n    encoded = replaceAll(encoded, '#', '%23'); // needed for ie and firefox\n    encoded = replaceAll(encoded, '{', '%7b');\n    encoded = replaceAll(encoded, '}', '%7d');\n    encoded = replaceAll(encoded, '|', '%7c');\n    encoded = replaceAll(encoded, '^', '%5e');\n    encoded = replaceAll(encoded, '`', '%60');\n    encoded = replaceAll(encoded, '@', '%40');\n    encoded = replaceAll(encoded, '&', '&amp;');\n    encoded = replaceAll(encoded, '\\n', '%0A');\n    return 'data:image/svg+xml;charset=UTF-8,' + encoded;\n};\n\n/**\n * Styles the default scrollbar to be more pretty and less intrusive (especially on dark backgrounds), (similar to MacOS)\n */\nfunction prettyScrollbar(root = document.head) {\n    return createStyles(css `\n      ::-webkit-scrollbar\n      {\n        width: 8px;  /* for vertical scrollbars */\n        height: 8px; /* for horizontal scrollbars */\n      }\n      ::-webkit-scrollbar-track\n      {\n        background: rgba(64, 64, 64, 0.4);\n        border-radius: 6px;\n      }\n      ::-webkit-scrollbar-thumb\n      {\n        background: rgba(128, 128, 128, 0.2);\n        border-radius: 6px;\n      }\n      ::-webkit-scrollbar-corner {background: rgba(0,0,0,0.5);}\n    `, root);\n}\n\n/**\n * Download a blob as a file in the browser.\n * @param b - blob to download\n * @param name - name of the file\n * @category Browser\n */\nfunction downloadBlob(b, name) {\n    const url = window.URL.createObjectURL(b);\n    const a = document.createElement('a');\n    a.style.display = 'none';\n    a.href = url;\n    a.download = name;\n    document.body.appendChild(a);\n    a.click();\n    setTimeout(() => {\n        document.body.removeChild(a);\n        window.URL.revokeObjectURL(url);\n    }, 1000);\n}\n/**\n * Convert a blob to a data url.\n * @param blob - blob to convert\n * @category Browser\n */\nasync function blobToDataURL(blob) {\n    return new Promise((resolve, reject) => {\n        const reader = new FileReader();\n        reader.onload = _e => resolve(reader.result);\n        reader.onerror = _e => reject(reader.error);\n        reader.onabort = _e => reject(new Error('Read aborted'));\n        reader.readAsDataURL(blob);\n    });\n}\n/**\n * Download a file in the browser.\n * @param b - file to download\n * @param name - name of the file (optional)\n * @category Browser\n */\nfunction downloadFile(b, name) {\n    return downloadBlob(b, name !== null && name !== void 0 ? name : b.name);\n}\n// todo: add/test options for multiple files and directory upload\n/**\n * Prompt the user to select a file or directory in the browser.\n * @param multiple - allow multiple files\n * @param directory - allow directory\n * @param accept - file types to accept (default: all), e.g. 'image/*'\n * @category Browser\n */\nasync function uploadFile(multiple = false, directory = false, accept) {\n    const input = document.createElement('input');\n    input.type = 'file';\n    input.multiple = multiple;\n    input.accept = accept || '*';\n    input.webkitdirectory = directory;\n    input.style.display = 'none';\n    document.body.appendChild(input);\n    input.click();\n    const files = await new Promise((resolve) => {\n        input.onchange = _e => {\n            resolve(Array.from(input.files || []));\n        };\n    });\n    document.body.removeChild(input);\n    return files;\n}\n/**\n * Check if the browser is running on a mobile or tablet device.\n */\nfunction mobileAndTabletCheck() {\n    let check = false;\n    // @ts-expect-error copied\n    (function (a) { if (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))\n        check = true; })(navigator.userAgent || navigator.vendor || window.opera);\n    return check;\n}\n\n// from three.js\n/**\n * Converts a single color channel from the sRGB color space to linear.\n * @param c - The color channel to be converted.\n * @category Color\n */\nfunction SRGBToLinear(c) {\n    return (c < 0.04045) ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);\n}\n/**\n * Converts a single color channel from the linear color space to sRGB.\n * @param c - The color channel to be converted.\n * @category Color\n */\nfunction LinearToSRGB(c) {\n    return (c < 0.0031308) ? c * 12.92 : 1.055 * (Math.pow(c, 0.41666)) - 0.055;\n}\n/**\n * Creates an image data url from a color string.\n * @param color - color string (css compatible color)\n * @param width - width of the image (default: 1)\n * @param height - height of the image (default: 1)\n * @return data url\n */\nfunction colorToDataUrl(color, width = 1, height = 1) {\n    const canvas = document.createElement('canvas');\n    canvas.width = width;\n    canvas.height = height;\n    const ctx = canvas.getContext('2d');\n    ctx.fillStyle = '#' + color;\n    ctx.fillRect(0, 0, width, height);\n    const url = canvas.toDataURL();\n    canvas.remove();\n    return url;\n}\n\n/**\n * Get property descriptor from object or its prototype chain\n * @param obj\n * @param prop\n *\n * @category JS Object\n */\nfunction getPropertyDescriptor(obj, prop) {\n    let desc;\n    do {\n        desc = Object.getOwnPropertyDescriptor(obj, prop);\n    } while (!desc && (obj = Object.getPrototypeOf(obj)));\n    return desc;\n}\n/**\n * Check if property is writable in object or its prototype chain\n * @param object - object to check\n * @param prop - property to check\n * @param allowWritable - allow writable properties without setter\n * @param allowAny - allow any property (even if it doesn't exist)\n *\n * @category JS Object\n */\nfunction isPropertyWritable(object, prop, allowWritable = true, allowAny = false) {\n    const desc = getPropertyDescriptor(object, prop);\n    return !!(desc === null || desc === void 0 ? void 0 : desc.set)\n        || allowWritable && (desc === null || desc === void 0 ? void 0 : desc.writable) !== false && (desc === null || desc === void 0 ? void 0 : desc.get) === undefined\n        || allowAny && !desc;\n}\n/**\n * Set value only if setter exists\n * @param object - object to set\n * @param prop - property to set\n * @param value - value to set\n * @param allowWritable - allow writable properties without setter\n * @param allowAny - allow any property (even if it doesn't exist)\n *\n * @category JS Object\n */\nfunction safeSetProperty(object, prop, value, allowWritable = true, allowAny = false) {\n    // check type?\n    if (object && isPropertyWritable(object, prop, allowWritable, allowAny)) {\n        object[prop] = value;\n        return true;\n    }\n    return false;\n}\n/**\n * Get value, but if it is a function, call it with args\n * @param s - value or function\n * @param args - arguments to pass to function\n *\n * @category JS Object\n */\nfunction getOrCall(s, ...args) {\n    if (typeof s === 'function')\n        s = s(...args);\n    return s;\n}\n/**\n * Copy properties from source to dest. Similar to Object.assign, but only copies properties that exist in source, dest and propList.\n * @param source - source object\n * @param dest - destination object\n * @param propList - list of properties to copy\n *\n * @category JS Object\n */\nfunction copyProps(source, dest, propList) {\n    for (const str of propList) {\n        const s = source[str];\n        if (s !== undefined)\n            safeSetProperty(dest, str, s, true);\n        // if (s !== undefined) dest[str] = s\n    }\n    return dest;\n}\n\n/**\n * Returns true if the array includes all the elements of the sub array\n * @param arr\n * @param subArr\n */\nfunction includesAll(arr, subArr) {\n    for (const sub of subArr) {\n        if (!arr.includes(sub))\n            return false;\n    }\n    return true;\n}\n/**\n * like Array.prototype.findIndex but from the end\n * @param arr\n * @param predicate\n */\nfunction findLastIndex(arr, predicate) {\n    for (let i = arr.length - 1; i >= 0; i--) {\n        if (predicate(arr[i]))\n            return i;\n    }\n    return -1;\n}\n/**\n * Call f1 before calling f2\n * Sample usage\n * ```\n * const logRender = ()=>console.log('render')\n * obj.render = wrapThisFunction(logRender, obj.beforeRender)\n * // now calling obj.beforeRender(), will log 'render' and then call obj.beforeRender()\n * ```\n * @param f1\n * @param f2\n */\nfunction wrapThisFunction(f1, f2) {\n    return function (...args) {\n        f1();\n        return f2 && f2.call(this, ...args);\n    };\n}\n/**\n * Call f1 with the same params as f2 before calling f2\n * Sample usage\n * ```\n * const logRender = ()=>console.log('render')\n * obj.render = wrapThisFunction(logRender, obj.beforeRender)\n * // now calling obj.beforeRender(), will log 'render' and then call obj.beforeRender()\n * ```\n * @param f1\n * @param f2\n */\nfunction wrapThisFunction2(f1, f2) {\n    return function (...args) {\n        f1(...args);\n        return f2 && f2.call(this, ...args);\n    };\n}\n\n/**\n * Access property in an object using a string path. Similar to lodash.get\n * @param access - path to access\n * @param tar - target object\n * @param throwOnInvalid - throw error if invalid access or property is undefined. Default is false\n *\n * @example\n * ```js\n * const obj = {a: {b: {c: 1}}}\n * const c = deepAccessObject(['a', 'b', 'c'], obj)\n * console.log(c) // 1\n * ```\n *\n * @category JS Object\n */\nfunction deepAccessObject(access, tar, throwOnInvalid = false) {\n    if (typeof access === 'string')\n        access = access.split('.');\n    while (access.length > 0) {\n        if (!tar)\n            return;\n        const p = access.splice(0, 1)[0];\n        if (p.length < 1)\n            continue;\n        if (p in tar) {\n            tar = tar[p];\n        }\n        else {\n            // console.error('invalid access, check', p, tar)\n            if (throwOnInvalid)\n                throw new Error('invalid access, check ' + p + ' in ' + tar);\n            else\n                return undefined;\n            // return tar\n        }\n    }\n    return tar;\n}\n/**\n * Find the key of an object with a given value.\n * @param object - object to search\n * @param value - value to search for\n *\n * @category JS Object\n */\nfunction getKeyByValue(object, value) {\n    return Object.keys(object).find(key => object[key] === value);\n}\n/**\n * Check if an object has a property. Same as {@link Object.hasOwn} or {@link Object.hasOwnProperty}\n * @param o\n * @param v\n */\nfunction objectHasOwn(o, v) {\n    return Object.hasOwn ? Object.hasOwn(o, v) : o.hasOwnProperty(v);\n}\n/**\n * Execute a function on each property of an object and return the result as a new object\n * This allows in place modification of the object.\n * To create a new object, set inPlace to false, or use {@link objectMap2} to modify the keys as well\n * Similar to {@link Array.map} but for objects.\n * @param obj - object\n * @param fn - function to execute on each property\n * @param inPlace - if true, the original object is modified. Default is true\n */\nfunction objectMap(obj, fn, inPlace = true) {\n    const result = inPlace ? obj : {};\n    const keys = Object.keys(obj);\n    for (const key of keys)\n        result[key] = fn(obj[key], key);\n    return result;\n}\n/**\n * Shorthand for `Object.fromEntries(Object.entries(obj).map(fn))`\n * Similar to {@link objectMap} but uses {@link Object.fromEntries} to create the new object, so keys can also be changed.\n * @param obj\n * @param fn\n */\nfunction objectMap2(obj, fn) {\n    return Object.fromEntries(Object.entries(obj).map((v) => fn(v)));\n}\n\nconst objSerializer = {\n    priority: Infinity,\n    serialize: (obj, meta) => objectMap2(obj, ([k, v]) => [k, Serialization.Serialize(v, meta, false)]),\n    deserialize: (data, obj, meta) => Object.assign(obj || {}, objectMap2(data, ([k, v]) => [k, Serialization.Deserialize(v, obj === null || obj === void 0 ? void 0 : obj[k], meta, false)])),\n    isType: (obj) => (obj.constructor || Object) === Object,\n};\n/**\n * Serialization class with static methods for serializing and deserializing objects.\n * Properties and classes can be marked serializable by adding {@link serialize} and {@link serializable} decorators.\n * @category Serialization\n */\nclass Serialization {\n    static GetSerializer(obj) {\n        return Serialization.Serializers.find(s => s.isType(obj));\n    }\n    static RegisterSerializer(...serializers) {\n        var _a;\n        for (const serializer of serializers) {\n            const priority = (_a = serializer.priority) !== null && _a !== void 0 ? _a : 1e10;\n            const i = findLastIndex(Serialization.Serializers, s => s.priority !== undefined && s.priority < priority);\n            if (i >= 0)\n                Serialization.Serializers.splice(i + 1, 0, serializer);\n            else\n                Serialization.Serializers.push(serializer);\n        }\n    }\n    static UnregisterSerializer(...serializers) {\n        for (const serializer of serializers) {\n            const i = Serialization.Serializers.indexOf(serializer);\n            if (i >= 0)\n                Serialization.Serializers.splice(i, 1);\n        }\n    }\n    /**\n     * Serialize an object\n     * @param obj - object to serialize\n     * @param meta - Optional object to store common meta-data/resources across the serialization process of multiple objects\n     @param isThis - true if called from inside the serialization function, like custom {@link IJSONSerializable.toJSON}.\n     */\n    static Serialize(obj, meta, isThis = false) {\n        var _a, _b;\n        if (typeof obj === 'function')\n            return undefined;\n        if (!isThis) {\n            const serializer = Serialization.GetSerializer(obj);\n            if (serializer)\n                return serializer.serialize(obj, meta);\n            // Handle classes with explicit serialization with toJSON and fromJSON functions\n            // toJSON functions can call Serialize(with isThis=true) to serialize the properties with @serialize decorator\n            if (typeof obj.toJSON === 'function') {\n                const res = obj.toJSON(meta);\n                if (obj.serializableClassId && res)\n                    res.serializableClassId = obj.serializableClassId;\n                return res;\n            }\n        }\n        // Handle classes with @serializable decorator and serialize all properties with @serialize decorator\n        let type = (_a = obj.constructor) !== null && _a !== void 0 ? _a : Object;\n        const result = {};\n        // Loop through all parent classes and serialize properties with @serialize decorator\n        while (type && type !== Object) {\n            const Type = (_b = Serialization.TypeMap.get(type)) !== null && _b !== void 0 ? _b : [];\n            for (const [key, propKey] of Type) {\n                result[key] = Serialization.Serialize(obj[propKey], meta, false);\n            }\n            type = Object.getPrototypeOf(type);\n        }\n        if (obj.serializableClassId)\n            result.serializableClassId = obj.serializableClassId;\n        return result;\n    }\n    /**\n     * Deserialize an object\n     * @param data - data to deserialize\n     * @param obj - current object that's set. If of the same class/type the data is deserialized into that instead of creating new objects.\n     * @param meta - Optional object to retrieve common meta-data/resources across the deserialization process of multiple objects. Objects in meta must be class instances, not js objects. (like Material, Texture, Object3D etc)\n     * @param isThis - true if called from inside the deserialization function, like custom {@link IJSONSerializable.fromJSON}\n     */\n    static Deserialize(data, obj, meta, isThis = false) {\n        var _a, _b;\n        if (data === undefined)\n            return obj; // undefined is not deserialized\n        if (obj === data)\n            return obj; // same object\n        // let isResource = false\n        // If data is an embedded resource in meta\n        if (data && typeof data === 'object' && (data.constructor || Object) === Object && data.resource && typeof data.resource === 'string' && data.uuid) {\n            const res = meta === null || meta === void 0 ? void 0 : meta[data.resource];\n            if (res) {\n                // isResource = true\n                data = res[data.uuid];\n                if (typeof data === 'object') {\n                    data.__useCount = data.__useCount ? data.__useCount + 1 : 1; // used for materials for now, see AssetManagerPlugin.importViewerConfig\n                }\n                if (!data)\n                    console.warn(`Resource ${data.resource} with uuid ${data.uuid} not found`);\n                if (obj === data)\n                    return obj; // same object\n                if (data && typeof data === 'object') {\n                    const isDeserializedClass = (data.constructor || Object) !== Object; // data is already deserialized\n                    if (isDeserializedClass) {\n                        if (!obj) {\n                            return data;\n                        }\n                        else {\n                            // todo: if data is deserialized already and !== obj.\n                            // obj is not null, could be a Texture, Material, Object etc\n                            // should we ignore the current object and assign one from meta or copy data from meta to current object\n                            // for textures, it should be replaced. should we copy if uuid is same?\n                            // for materials, if uuid is same and type is same it should be copied otherwise replaced\n                            // for vector3d, copy data\n                            // todo: need to implement.\n                            console.warn(\"replacing object\", obj, 'with deserialized object from meta', data);\n                            return data;\n                        }\n                    }\n                    else { // data is not deserialized, or is a normal object\n                        // this is not supported. meta should only have class instances, not js objects\n                        console.error('Deserialize; meta should only have class instances, not js objects', data, obj, meta);\n                    }\n                }\n            }\n            else {\n                console.warn(`Resource ${data.resource} not found`);\n                return obj;\n            }\n        }\n        if (data && typeof data === 'object' && (data.constructor || Object) !== Object && !Array.isArray(data)) {\n            console.warn('Data might already be deserialized. It will be cloned, or copied to source', data, \"source\", obj, data.constructor, data.constructor !== Object);\n        }\n        // todo handle File/Blob and FS API descriptors (try loading SheenChair.glb from three,js in threepipe)\n        // Create new object if not provided\n        if (data && typeof data === 'object') {\n            // if data is deserialized already and obj is null. then should we clone the data or assign it directly?\n            // if it's a resource from meta then assign it directly(done above), otherwise clone (done just below).\n            if (data.serializableClassId && (!obj || obj.serializableClassId !== data.serializableClassId)) { // if the data is already deserialized, it will be cloned\n                const constructor = Serialization.SerializableClasses.get(data.serializableClassId);\n                if (constructor) {\n                    if (constructor.DataInConstructor) // not used anywhere right now. todo: remove? because we are anyway assigning the data to the object after the constructor using @serialize and support fromJSON\n                        obj = new constructor(data);\n                    else\n                        obj = new constructor();\n                }\n            }\n            else if ((data.constructor || Object) === Object && !obj) {\n                obj = {};\n            }\n            else if (Array.isArray(data) && !obj) {\n                obj = [];\n            }\n        }\n        if (typeof obj === 'function') {\n            console.error('cannot deserialize a function', obj, data);\n            return obj; // throw error maybe?}\n        }\n        if (!isThis) {\n            const serializer = Serialization.GetSerializer(data);\n            if (serializer && serializer !== objSerializer)\n                return serializer.deserialize(data, obj, meta);\n        }\n        if (!data || obj === undefined || obj === null || typeof obj !== 'object') {\n            return data;\n        }\n        // Handle classes with explicit serialization with toJSON and fromJSON functions\n        // fromJSON functions can call Deserialize(with isThis=true) to deserialize the properties with @serialize decorator\n        if (!isThis && typeof (obj === null || obj === void 0 ? void 0 : obj.fromJSON) === 'function') {\n            obj.fromJSON(data, meta);\n            return obj; // cannot be sure what the return value is\n        }\n        let type = (_a = obj.constructor) !== null && _a !== void 0 ? _a : Object;\n        if (type === Object)\n            return objSerializer.deserialize(data, obj, meta);\n        // Loop through all parent classes and deserialize properties with @serialize decorator\n        while (type && type !== Object) {\n            const Type = (_b = Serialization.TypeMap.get(type)) !== null && _b !== void 0 ? _b : [];\n            for (const [key, propKey] of Type) {\n                const current = obj[propKey];\n                const newVal = Serialization.Deserialize(data[key], current, meta, false);\n                if (newVal !== current)\n                    safeSetProperty(obj, propKey, newVal, true);\n            }\n            type = Object.getPrototypeOf(type);\n        }\n        return obj;\n    }\n}\nSerialization.TypeMap = new Map();\nSerialization.SerializableClasses = new Map();\n/**\n * Serializers for primitive, array and struct/custom object types\n */\nSerialization.Serializers = [\n    {\n        priority: 0,\n        isType: (obj) => Array.isArray(obj),\n        serialize: (obj, meta) => obj.map((v) => Serialization.Serialize(v, meta, false)),\n        deserialize: (data, obj, meta) => {\n            const l = data.length;\n            if (!Array.isArray(obj))\n                obj = [];\n            for (let i = 0; i < l; i++) {\n                const d = data[i];\n                const de = obj.length > i ? Serialization.Deserialize(d, obj[i], meta, false) : Serialization.Deserialize(d, undefined, meta, false);\n                if (obj.length <= i)\n                    obj.push(de);\n                else\n                    obj[i] = de;\n            }\n            return obj;\n        },\n    },\n    {\n        priority: 0,\n        isType: (obj) => !obj || typeof obj !== 'object',\n        serialize: (obj) => {\n            if (obj && typeof obj === 'number') {\n                if (obj === Infinity)\n                    return 'Infinity';\n                if (obj === -Infinity)\n                    return '-Infinity';\n                if (isNaN(obj))\n                    return 'NaN';\n            }\n            return obj;\n        },\n        deserialize: (data, obj) => {\n            if (typeof obj === 'number') {\n                if (data === 'Infinity')\n                    return Infinity;\n                if (data === '-Infinity')\n                    return -Infinity;\n                if (data === 'NaN')\n                    return NaN;\n                if (typeof data === 'number' || !data)\n                    return data;\n            }\n            return data;\n        },\n    },\n    objSerializer,\n];\n\n/**\n * Decorator that redefines a property with getter and setter, and calls a function when the property is changed.\n * Parameters passed to the function are the property key and the new value.\n * @note - Does not work with \"target\": \"esnext\" in tsconfig.json\n * @note - Requires \"experimentalDecorators\": true in tsconfig.json\n * @todo add example.\n * @param fnKey - use: `<MyClass>.prototype.<myFunction>` or define an arrow function: `(key, value, oldValue, target) => {}`.\n * @param paramType -\n * if param, the function is called with 4 parameters: `key, value, oldValue, target`, default for {@link onChange}\n * if object, the function is called with an object parameter: `{key, value, oldValue, target}`, default for {@link onChange3}\n * if void then no params are passed. {@link onChange2}\n * Default: false.\n *\n * @category Decorators\n */\nfunction onChange(fnKey // target is this\n//| ((obj:{key: string, value: any, oldValue: any, target: TTarget})=>void)\n, paramType = 'param') {\n    if (!fnKey)\n        throw new Error('onChange: fnKey is undefined, make sure the function exists or provide a string');\n    return (targetPrototype, propertyKey) => {\n        Object.defineProperty(targetPrototype, propertyKey, {\n            get() {\n                return this[`_oc_${propertyKey}`];\n            },\n            set(newVal) {\n                var _a;\n                const oldVal = this[`_oc_${propertyKey}`];\n                if (oldVal === newVal)\n                    return;\n                this[`_oc_${propertyKey}`] = newVal;\n                const params = paramType === 'param' ? [propertyKey, newVal, oldVal, this] : paramType === 'object' ? [{ key: propertyKey, value: newVal, oldValue: oldVal, target: this }] : '';\n                if (typeof fnKey === 'string')\n                    (_a = this[fnKey]) === null || _a === void 0 ? void 0 : _a.call(this, ...params);\n                else if (typeof fnKey === 'function') {\n                    let called = false; // to get functions in the prototype chain\n                    if (fnKey.name) {\n                        let p = this;\n                        while (p) { // todo: memoize?\n                            const fn = p[fnKey.name];\n                            if (fn === fnKey) {\n                                fnKey.call(this, ...params);\n                                called = true;\n                                break;\n                            }\n                            else if (fn && fn.name && fn.name.endsWith(`bound ${fnKey.name}`)) {\n                                fn(...params);\n                                called = true;\n                                break;\n                            }\n                            p = Object.getPrototypeOf(p);\n                        }\n                    }\n                    if (!called) {\n                        if (fnKey.name && this[fnKey.name].name.endsWith(`bound ${fnKey.name}`))\n                            this[fnKey.name](...params);\n                        else\n                            fnKey(...params);\n                    }\n                }\n            },\n        });\n    };\n}\n/**\n * Similar to {@link onChange}, but accepts any function and paramType defaults to 'void'. The function is called with no parameters. if 'void'\n * @param fnKey\n * @param paramType\n */\nfunction onChange2(fnKey, paramType = 'void') {\n    if (!fnKey)\n        throw new Error('onChange: fnKey is undefined, make sure the function exists or provide a string');\n    return onChange(fnKey, paramType);\n}\n/**\n * Similar to {@link onChange}, but accepts any function and paramType defaults to 'object'. The function is called with an object parameter: `{key, value, oldValue, target}`.\n * @param fnKey\n * @param paramType\n */\nfunction onChange3(fnKey, paramType = 'object') {\n    if (!fnKey)\n        throw new Error('onChange: fnKey is undefined, make sure the function exists or provide a string');\n    return onChange(fnKey, paramType);\n}\n/**\n * Similar to onChange but dispatches an event instead of calling a function.\n * Requires `dispatchEvent` to be defined on the target.\n * @param eventName - The name of the event to dispatch. Default: '`key`-changed'\n */\nfunction onChangeDispatchEvent(eventName) {\n    return onChange((key, value, oldValue, target) => {\n        if (!target.dispatchEvent)\n            throw new Error('onChangeDispatchEvent: target does not have dispatchEvent');\n        target.dispatchEvent({ type: eventName || `${key}-changed`, detail: { key, value, oldValue } });\n    }, 'param');\n}\n/**\n * Decorator to mark a class property as serializable using the {@link Serialization} class.\n * @note - Requires \"experimentalDecorators\": true in tsconfig.json\n * @param key - The key to use when serializing the property. If not provided, the property name is used (for this make sure the property name is not mangled during minification).\n * @category Decorators\n */\nfunction serialize(key) {\n    return (targetPrototype, propertyKey) => {\n        const type = targetPrototype.constructor;\n        if (type === Object)\n            throw new Error('All properties in an object are serialized by default');\n        if (!Serialization.TypeMap.has(type))\n            Serialization.TypeMap.set(type, []);\n        Serialization.TypeMap.get(type).push([key || propertyKey, propertyKey]);\n    };\n}\n/**\n * Decorator to mark a class as serializable using the {@link Serialization} class.\n * @note - Requires \"experimentalDecorators\": true in tsconfig.json\n * @param id - The id to use when serializing the class. This is used to identify the class when deserializing. Class names can be mangled during minification, so it is required to provide an id.\n */\nfunction serializable(id) {\n    return (constructor) => {\n        constructor = class extends constructor {\n            constructor() {\n                super(...arguments);\n                // noinspection JSUnusedGlobalSymbols\n                this.serializableClassId = id;\n                // static DataInConstructor = false // if constructor is equivalent to fromJSON, see LUTCubeTextureWrapper.\n            }\n        };\n        Serialization.SerializableClasses.set(id, constructor);\n        return constructor;\n    };\n}\n\n/**\n * Encrypts plaintext using AES-GCM with supplied password, for decryption with aesGcmDecrypt().\n *                                                                      (c) Chris Veness MIT Licence\n * https://gist.github.com/chrisveness/43bcda93af9f646d083fad678071b90a\n * Modified to work with Uint8Array and string content.\n *\n * @param content - Plaintext or Uint8 Buffer to be encrypted.\n * @param password - Plaintext or Uint8 Buffer Password to use to encrypt content.\n * @param prefix - Optional prefix to prepend to the ciphertext.\n * @returns Encrypted ciphertext. If content is a string, the ciphertext is a string. If content is a Uint8Array, the ciphertext is a new Uint8Array.\n *\n *\n * @example\n *   const ciphertext = await aesGcmEncrypt('my secret text', 'pw');\n *   aesGcmEncrypt('my secret text', 'pw').then(function(ciphertext) { console.log(ciphertext); });\n *\n * @category Encryption\n */\nasync function aesGcmEncrypt(content, password, prefix) {\n    const pwUtf8 = typeof password === 'string' ? new TextEncoder().encode(password) : password; // encode password as UTF-8\n    const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8); // hash the password\n    const iv = crypto.getRandomValues(new Uint8Array(12)); // get 96-bit random iv\n    const ivStr = Array.from(iv).map(b => String.fromCharCode(b)).join(''); // iv as utf-8 string\n    const alg = { name: 'AES-GCM', iv: iv }; // specify algorithm to use\n    const key = await crypto.subtle.importKey('raw', pwHash, alg, false, ['encrypt']); // generate key from pw\n    const ptUint8 = typeof content === 'string' ? new TextEncoder().encode(content) : content; // encode plaintext as UTF-8\n    const ctBuffer = await crypto.subtle.encrypt(alg, key, ptUint8); // encrypt plaintext using key\n    const ctUint = new Uint8Array(ctBuffer);\n    const ctArray = Array.from(ctUint); // ciphertext as byte array\n    const ctStr = ctArray.map(byte => String.fromCharCode(byte)).join(''); // ciphertext as string\n    const prefixStr = prefix ? typeof prefix === 'string' ? prefix : new TextDecoder().decode(prefix) : '';\n    const prefixArray = prefix ? typeof prefix === 'string' ? new TextEncoder().encode(prefix) : Array.from(prefix) : [];\n    return typeof content === 'string' ? (prefixStr + ivStr + ctStr) : new Uint8Array([...prefixArray, ...iv, ...ctArray]);\n}\n/**\n * Decrypts ciphertext encrypted with aesGcmEncrypt() using supplied password.\n *                                                                      (c) Chris Veness MIT Licence\n *\n * https://gist.github.com/chrisveness/43bcda93af9f646d083fad678071b90a\n * Modified to work with Uint8Array and string content.\n *\n * @param ciphertext - Ciphertext to be decrypted.\n * @param password - Password to use to decrypt ciphertext.\n * @returns Decrypted content. If ciphertext is a string, the plaintext is a string. If ciphertext is a Uint8Array, the plaintext is a new Uint8Array.\n *\n * @example\n *   const plaintext = await aesGcmDecrypt(ciphertext, 'pw');\n *   aesGcmDecrypt(ciphertext, 'pw').then(function(plaintext) { console.log(plaintext); });\n *\n * @category Encryption\n */\nasync function aesGcmDecrypt(ciphertext, password) {\n    const pwUtf8 = typeof password === 'string' ? new TextEncoder().encode(password) : password; // encode password as UTF-8\n    const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8); // hash the password\n    const ivStr = ciphertext.slice(0, 12);\n    const iv = typeof ivStr === 'string' ? new Uint8Array(Array.from(ivStr).map(ch => ch.charCodeAt(0))) : ivStr; // decode base64 iv\n    const alg = { name: 'AES-GCM', iv: iv }; // specify algorithm to use\n    const key = await crypto.subtle.importKey('raw', pwHash, alg, false, ['decrypt']); // generate key from pw\n    const ctStr = ciphertext.slice(12);\n    const ctUint8 = typeof ctStr === 'string' ? new Uint8Array(Array.from(ctStr).map(ch => ch.charCodeAt(0))) : ctStr;\n    // note: why doesn't ctUint8 = new TextEncoder().encode(ctStr) work?\n    try {\n        const plainBuffer = await crypto.subtle.decrypt(alg, key, ctUint8); // decrypt ciphertext using key\n        return typeof ciphertext === 'string' ? new TextDecoder().decode(plainBuffer) : new Uint8Array(plainBuffer);\n    }\n    catch (e) {\n        throw new Error('Decrypt failed');\n    }\n}\n\n/**\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modified from: https://github.com/GoogleChromeLabs/text-editor/blob/main/src/inline-scripts/fs-helpers.js\n */\n/**\n * Open a handle to an existing file on the local file system.\n *\n * @return {!Promise<FileSystemFileHandle>} Handle to the existing file.\n */\nasync function getFileHandle() {\n    // For Chrome 86 and later...\n    if ('showOpenFilePicker' in window) {\n        return window.showOpenFilePicker().then((handles) => handles[0]);\n    }\n    // For Chrome 85 and earlier...\n    return window.chooseFileSystemEntries();\n}\n/**\n * Create a handle to a new (text) file on the local file system.\n *\n * @return {!Promise<FileSystemFileHandle>} Handle to the new file.\n */\nfunction getNewFileHandle() {\n    // For Chrome 86 and later...\n    if ('showSaveFilePicker' in window) {\n        const opts = {\n            types: [{\n                    description: 'Text file',\n                    accept: { 'text/plain': ['.txt'] },\n                }],\n        };\n        return window.showSaveFilePicker(opts);\n    }\n    // For Chrome 85 and earlier...\n    const opts = {\n        type: 'save-file',\n        accepts: [{\n                description: 'Text file',\n                extensions: ['txt'],\n                mimeTypes: ['text/plain'],\n            }],\n    };\n    return window.chooseFileSystemEntries(opts);\n}\n/**\n * Reads the raw text from a file.\n *\n * @param {File} file\n * @return {!Promise<string>} A promise that resolves to the parsed string.\n */\nfunction readFile(file) {\n    // If the new .text() reader is available, use it.\n    if (file.text) {\n        return file.text();\n    }\n    // Otherwise use the traditional file reading technique.\n    return _readFileLegacy(file);\n}\n/**\n * Reads the raw text from a file.\n *\n * @private\n * @param {File} file\n * @return {Promise<string>} A promise that resolves to the parsed string.\n */\nfunction _readFileLegacy(file) {\n    return new Promise((resolve) => {\n        const reader = new FileReader();\n        reader.addEventListener('loadend', (e) => {\n            const text = (e.srcElement || e.target).result;\n            resolve(text);\n        });\n        reader.readAsText(file);\n    });\n}\n/**\n * Writes the contents to disk.\n *\n * @param {FileSystemFileHandle} fileHandle File handle to write to.\n * @param {string} contents Contents to write.\n */\nasync function writeFile(fileHandle, contents) {\n    // Support for Chrome 82 and earlier.\n    if (fileHandle.createWriter) {\n        // Create a writer (request permission if necessary).\n        const writer = await fileHandle.createWriter();\n        // Write the full length of the contents\n        await writer.write(0, contents);\n        // Close the file and write the contents to disk\n        await writer.close();\n        return;\n    }\n    // For Chrome 83 and later.\n    // Create a FileSystemWritableFileStream to write to.\n    const writable = await fileHandle.createWritable();\n    // Write the contents of the file to the stream.\n    await writable.write(contents);\n    // Close the file and write the contents to disk.\n    await writable.close();\n}\n/**\n * Verify the user has granted permission to read or write to the file, if\n * permission hasn't been granted, request permission.\n *\n * @param fileHandle File handle to check.\n * @param withWrite True if write permission should be checked.\n * @return True if the user has granted read/write permission.\n */\nasync function verifyPermission(fileHandle, withWrite) {\n    const opts = {};\n    if (withWrite) {\n        opts.writable = true;\n        // For Chrome 86 and later...\n        opts.mode = 'readwrite';\n    }\n    // Check if we already have permission, if so, return true.\n    if (await fileHandle.queryPermission(opts) === 'granted') {\n        return true;\n    }\n    // Request permission to the file, if the user grants permission, return true.\n    if (await fileHandle.requestPermission(opts) === 'granted') {\n        return true;\n    }\n    // The user did nt grant permission, return false.\n    return false;\n}\n\n/**\n * Convert an image {@link ImageBitmap} or {@link CanvasImageSource} to a new canvas with a max width. Good for resizing images keeping the aspect ratio and generating previews.\n * @param bitmap - image to convert\n * @param maxWidth - maximum width of the image (default: 8192). Images larger than this will be scaled down. This is because strings can get too long.\n * @param detachBitmap - detach the bitmap after conversion (default: false). This will free up bitmap memory if you don't need it anymore.\n *\n * See also {@link imageUrlToImageData}, {@link imageBitmapToBase64}, {@link imageBitmapToBlob}\n *\n * @category Images\n */\nfunction imageBitmapToCanvas(bitmap, maxWidth = 8192, detachBitmap = false) {\n    var _a;\n    if (!bitmap.width || !bitmap.height)\n        throw new Error('Invalid bitmap');\n    // create a canvas\n    const canvas = document.createElement('canvas');\n    // resize it to the size of our ImageBitmap\n    canvas.width = Math.min(maxWidth, bitmap.width);\n    canvas.height = Math.floor(1.0 + canvas.width * bitmap.height / bitmap.width);\n    // try to get a bitmaprenderer context if same size\n    const isBitmap = bitmap instanceof ImageBitmap;\n    const ctx = isBitmap && detachBitmap && Math.abs(canvas.width - bitmap.width) < 0.5 ? canvas.getContext('bitmaprenderer') : undefined;\n    if (ctx) {\n        // transfer the ImageBitmap to it\n        ctx.transferFromImageBitmap(bitmap); // less memory but it will detach the bitmap\n    }\n    else {\n        // in case someone supports createImageBitmap only\n        // twice in memory...\n        (_a = canvas.getContext('2d')) === null || _a === void 0 ? void 0 : _a.drawImage(bitmap, 0, 0, canvas.width, canvas.height);\n    }\n    if (isBitmap && detachBitmap) {\n        bitmap.close();\n    }\n    return canvas;\n}\n/**\n * Convert an image {@link ImageBitmap} or {@link CanvasImageSource} to a base64 data url.\n * @param bitmap - image to convert\n * @param maxWidth - maximum width of the image (default: 8192). Images larger than this will be scaled down. This is because strings can get too long.\n * @param detachBitmap - detach the bitmap after conversion (default: false). This will free up bitmap memory if you don't need it anymore.\n * @param type - mime type of the data url (default: 'image/png')\n *\n * See also {@link imageUrlToImageData}, {@link imageBitmapToCanvas}, {@link imageBitmapToBlob}\n *\n * @category Images\n */\nfunction imageBitmapToBase64(bitmap, maxWidth = 8192, detachBitmap = false, type = 'image/png') {\n    if (!bitmap.width || !bitmap.height)\n        return '';\n    // create a canvas\n    const canvas = imageBitmapToCanvas(bitmap, maxWidth, false);\n    // get it back as a Blob\n    const url = canvas.toDataURL(type);\n    canvas.remove();\n    if (detachBitmap && bitmap instanceof ImageBitmap) {\n        bitmap.close();\n    }\n    return url;\n}\n/**\n * Convert an image {@link ImageBitmap} or {@link CanvasImageSource} to a blob.\n * @param bitmap - image to convert\n * @param maxWidth - maximum width of the image (default: 8192). Images larger than this will be scaled down. This is because strings can get too long.\n * @param detachBitmap - detach the bitmap after conversion (default: false). This will free up bitmap memory if you don't need it anymore.\n * @param type - mime type of the blob (default: 'image/png')\n *\n * See also {@link imageUrlToImageData}, {@link imageBitmapToCanvas}, {@link imageBitmapToBase64}\n *\n * @category Images\n */\nasync function imageBitmapToBlob(bitmap, maxWidth = 8192, detachBitmap = false, type = 'image/png') {\n    if (!bitmap.width || !bitmap.height)\n        return Promise.reject('Invalid bitmap');\n    // create a canvas\n    const canvas = imageBitmapToCanvas(bitmap, maxWidth, false);\n    // get it back as a Blob\n    return new Promise((resolve, reject) => {\n        canvas.toBlob((blob) => {\n            if (!blob)\n                reject('Could not get blob');\n            else\n                resolve(blob);\n            canvas.remove();\n            if (detachBitmap && bitmap instanceof ImageBitmap) {\n                bitmap.close();\n            }\n        }, type);\n    });\n}\n/**\n * Downloads/parse the image from an url/data url and draw to an {@link ImageData} object.\n * @param url - url or data url of the image\n * @returns ImageData object\n *\n * See also {@link imageBitmapToBase64}\n *\n * @category Images\n */\nasync function imageUrlToImageData(url) {\n    return new Promise((resolve, reject) => {\n        const image = new Image();\n        image.addEventListener('load', () => {\n            const canvas = document.createElement('canvas');\n            canvas.width = image.width;\n            canvas.height = image.height;\n            const context = canvas.getContext('2d');\n            if (!context) {\n                reject(new Error('Could not get 2d context'));\n                return;\n            }\n            context.drawImage(image, 0, 0, canvas.width, canvas.height);\n            const imageData = context.getImageData(0, 0, canvas.width, canvas.height);\n            resolve(imageData);\n            // how do i return this?\n            canvas.remove();\n            image.remove();\n        }, false);\n        image.addEventListener('error', (e) => {\n            image.remove();\n            reject(e);\n        }, false);\n        image.src = url;\n    });\n}\n/**\n * Converts an HTML image to a canvas. This creates a new canvas element and draws the image on it.\n * @param image - image to convert\n * @param backgroundColor - background color of the canvas\n * @param scale - scale of the canvas\n * @param width - width of the canvas\n * @param height - height of the canvas\n * @returns a new canvas element\n *\n * @category Images\n */\nfunction imageToCanvas(image, { backgroundColor = '', scale = 1, width = 512, height = 512, }) {\n    const canvas = document.createElement('canvas');\n    const context = canvas.getContext('2d');\n    const ratio = scale;\n    const canvasWidth = width;\n    const canvasHeight = height;\n    canvas.width = canvasWidth * ratio;\n    canvas.height = canvasHeight * ratio;\n    canvas.style.width = `${canvasWidth}`;\n    canvas.style.height = `${canvasHeight}`;\n    if ((backgroundColor === null || backgroundColor === void 0 ? void 0 : backgroundColor.length) > 0) {\n        context.fillStyle = backgroundColor;\n        context.fillRect(0, 0, canvas.width, canvas.height);\n    }\n    context.drawImage(image, 0, 0, canvas.width, canvas.height);\n    return canvas;\n}\n/**\n * Converts an {@link ImageData} to a canvas. This creates a new canvas element and draws the image data on it.\n * Image Data can be created from image pixels like from gl.readPixels\n * This can be used to convert a WebGL texture/render target to a canvas/data url.\n * Note: if the output is flipped, use {@link canvasFlipY} after this, like `canvasFlipY(imageDataToCanvas(imageData))`\n * @param data - image data to convert\n */\nfunction imageDataToCanvas(data) {\n    const canvas = document.createElement('canvas');\n    canvas.width = data.width;\n    canvas.height = data.height;\n    const context = canvas.getContext('2d');\n    context.putImageData(data, 0, 0);\n    return canvas;\n}\n/**\n * Check if the browser supports exporting to webp, with the canvas.toDataURL('image/webp') method.\n */\nfunction isWebpExportSupported() {\n    const elem = document.createElement('canvas');\n    if (elem.getContext && elem.getContext('2d')) {\n        // was able or not to get WebP representation\n        return elem.toDataURL('image/webp').startsWith('data:image/webp');\n    }\n    else {\n        // very old browser like IE 8, canvas not supported\n        return false;\n    }\n}\n/**\n * Returns a new canvas with the image/canvas-content flipped vertically.\n * Useful for putImageData(as it does not respect scale and translate) and WebGL textures, which are flipped vertically.\n * @param canvas\n */\nfunction canvasFlipY(canvas) {\n    const newCanvas = document.createElement('canvas');\n    newCanvas.width = canvas.width;\n    newCanvas.height = canvas.height;\n    const ctx = newCanvas.getContext('2d');\n    if (!ctx)\n        throw new Error('Unable to get 2d context');\n    ctx.translate(0, canvas.height);\n    ctx.scale(1, -1);\n    ctx.drawImage(canvas, 0, 0);\n    return newCanvas;\n}\n/**\n * Load a Blob or a file containing an image and return an HTMLImageElement.\n * @param blob\n */\nfunction blobToImage(blob) {\n    return new Promise((resolve, reject) => {\n        const img = new Image();\n        const url = URL.createObjectURL(blob);\n        img.onload = () => {\n            URL.revokeObjectURL(url);\n            resolve(img);\n        };\n        img.onerror = (e) => {\n            URL.revokeObjectURL(url);\n            reject(e);\n        };\n        img.src = url;\n    });\n}\n\n/**\n * Returns a data url for a 16x16 svg rectangle with the given color.\n * @param c - color\n *\n * @category SVGs\n */\nconst makeColorSvg = (c) => {\n    return `data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='16' height='16' fill='%23${c}'/%3E%3C/svg%3E%0A`;\n};\n/**\n * Returns a data url for a 16x16 svg circle with the given color.\n * @param c - color\n *\n * @category SVGs\n */\nconst makeColorSvgCircle = (c) => {\n    return `data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='8' cy='8' r='7' fill='%23${c}'/%3E%3C/svg%3E%0A`;\n};\n/**\n * Returns a data url for a svg with the given text.\n * @param text\n *\n * @category SVGs\n */\nconst makeTextSvg = (text) => {\n    return `data:image/svg+xml,%3Csvg viewBox='0 0 80 14' xmlns='http://www.w3.org/2000/svg'%3E%3Ctext style='font: 8px \"Roboto Mono\", \"Source Code Pro\", Menlo, Courier, monospace; fill: white;' x='9' y='9'%3E${text}%3C/text%3E%3C/svg%3E%0A`;\n};\n/**\n * Renders an SVG to a canvas.\n * @param svgDataUrl - data url of the svg. Can be created with {@link svgUrl}\n * @param options - options\n *\n * @category SVGs\n */\nconst svgToCanvas = async (svgDataUrl, options) => {\n    const image = await createImage(svgDataUrl);\n    return imageToCanvas(image, options);\n};\n/**\n * Renders an SVG to a png data url.\n * @param svgDataUrl - data url of the svg. Can be created with {@link svgUrl}\n * @param options - options\n *\n * @category SVGs\n */\nconst svgToPng = async (svgDataUrl, options) => {\n    return await svgToCanvas(svgDataUrl, options).then(canvas => canvas.toDataURL('image/png'));\n};\n\nconst defaultDownloader = async (url) => blobToDataURL(await (await fetch(url)).blob());\n/**\n * Find all URLs in svg, download them and replace with the URL in svg with the downloaded data URLs.\n * @param str - string\n * @param downloader - function to download the URLs in svg and return the data URL\n *\n * @category HTML To Image\n */\nasync function embedUrlRefs(str, downloader = defaultDownloader) {\n    const urls = str.match(/(((ftp|https?):\\/\\/)[\\-\\w@:%_\\+.~#?,&\\/\\/=]+)/g);\n    if (urls) {\n        for (const url of urls) {\n            const dataUrl = await downloader(url);\n            str = str.replace(url, dataUrl);\n        }\n    }\n    return str;\n}\n/**\n * Embeds an HTML string into a svg tag and converts to svg string or svg as data url\n * @param html - HTML string\n * @param style - CSS string\n * @param width - width of the svg\n * @param height - height of the svg\n * @param toDataUrl - if true, returns a data url, otherwise returns the svg string\n * @returns svg string or svg as data url\n *\n * @category HTML To Image\n */\nfunction htmlToSvg(html, style, { width, height }, toDataUrl = true) {\n    const s = `\n<svg viewBox=\"0 0 ${width} ${height}\" xmlns=\"http://www.w3.org/2000/svg\">\n    <style>\n    ${style}\n    </style>\n    <foreignObject x=\"0\" y=\"0\" width=\"100%\" height=\"100%\">\n        <div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"height: 100%; width: 100%; position: absolute: top:0; left:0\">\n            ${html}\n        </div>\n    </foreignObject>\n</svg>\n    `;\n    return toDataUrl ? svgUrl(s) : s;\n}\n/**\n * Renders an HTML string to a canvas. This is done by first embedding HTML into a svg and then rendering the svg to a canvas.\n * @param html - HTML string\n * @param style - CSS string\n * @param options - options for rendering the canvas\n * @returns HTML canvas element\n *\n * @category HTML To Image\n */\nasync function htmlToCanvas(html, style, options) {\n    const svg = htmlToSvg(html, style, options);\n    return await svgToCanvas(svg, options);\n}\n/**\n * Renders an HTML string to a png. This is done by first embedding HTML into a svg and then rendering the svg to a png.\n * @param html\n * @param style\n * @param options\n * @returns png as data url\n *\n * @category HTML To Image\n */\nasync function htmlToPng(html, style, options) {\n    const svg = htmlToSvg(html, style, options);\n    return await svgToPng(svg, options);\n}\n\n/**\n * Returns the number which is larger in absolute value.\n * @param a\n * @param b\n *\n * @category Maths\n */\nfunction absMax(a, b) {\n    return Math.abs(a) > Math.abs(b) ? a : b;\n}\n/**\n * Updates the bit at the given position to the given value.\n * @param number - the number to update\n * @param bitPosition - the bit position to update from the least significant bit (0) to most significant bit (31)\n * @param bitValue - 0 or 1\n */\nfunction updateBit(number, bitPosition, bitValue) {\n    const bitValueNormalized = bitValue ? 1 : 0;\n    const clearMask = ~(1 << bitPosition);\n    return (number & clearMask) | (bitValueNormalized << bitPosition);\n}\n/**\n * Clears the bit at the given position.\n * @param number - the number to update\n * @param bitPosition - the bit position to update from the least significant bit (0) to most significant bit (31)\n */\nfunction clearBit(number, bitPosition) {\n    const clearMask = ~(1 << bitPosition);\n    return number & clearMask;\n}\n/**\n * Generate a UUID v4\n * https://stackoverflow.com/a/53723395/2229899\n */\nfunction uuidV4() {\n    const ho = (n, p) => n.toString(16).padStart(p, '0'); /// Return the hexadecimal text representation of number `n`, padded with zeroes to be of length `p`\n    const data = crypto.getRandomValues(new Uint8Array(16)); /// Fill the buffer with random data\n    data[6] = (data[6] & 0xf) | 0x40; /// Patch the 6th byte to reflect a version 4 UUID\n    data[8] = (data[8] & 0x3f) | 0x80; /// Patch the 8th byte to reflect a variant 1 UUID (version 4 UUIDs are)\n    const view = new DataView(data.buffer); /// Create a view backed by the 16-byte buffer\n    return `${ho(view.getUint32(0), 8)}-${ho(view.getUint16(4), 4)}-${ho(view.getUint16(6), 4)}-${ho(view.getUint16(8), 4)}-${ho(view.getUint32(10), 8)}${ho(view.getUint16(14), 4)}`; /// Compile the canonical textual form from the array data\n}\n\n/**\n * Get URL query parameter. If not found, return default value. Similar to PHP's $_GET\n * @param p - parameter name to get\n * @param def - default value if parameter not found\n *\n * @category URL\n */\nfunction getUrlQueryParam(p, def = null) {\n    var _a;\n    const url = new URL(window.location.href);\n    return (_a = url.searchParams.get(p)) !== null && _a !== void 0 ? _a : def;\n}\n/**\n * Set URL query parameter. If value is null, remove parameter. Similar to PHP's $_GET\n * @param p - parameter name to set\n * @param v - parameter value or null to remove\n * @param reload - reload page after setting parameter, default false. If false, `history.replaceState` is used.\n *\n * @category URL\n */\nfunction setUrlQueryParam(p, v, reload = false) {\n    const params = new URLSearchParams(location.search);\n    if (v === null || v === undefined) {\n        if (params.has(p))\n            params.delete(p);\n    }\n    else\n        params.set(p, v);\n    if (!reload)\n        window.history.replaceState({}, '', '?' + params.toString()); // todo: check if default state and set to /\n    else\n        window.location.search = params.toString();\n}\n/**\n * Join path parts with separator. Similar to PHP's pathJoin\n * @param parts - path parts\n * @param separator - separator, default '/'\n */\nfunction pathJoin(parts, separator = '/') {\n    // const replace = new RegExp(separator + '{1,}', 'g')\n    return parts.join(separator); // .replace(replace, separator) //todo fix: replace breaks https://raw to https:/raw\n}\n/**\n * Returns a blob:// URL which points to a javascript file which will call importScripts with the given URL, to be used for cross-origin workers.\n * https://stackoverflow.com/questions/21913673/execute-web-worker-from-different-origin\n * @param url - URL to the worker js file\n * @param wasmURL - optional wasm file URL, will be passed to a created Module.locateFile (for emscripten)\n */\nfunction remoteWorkerURL(url, wasmURL) {\n    const content = (wasmURL ? `var Module = { locateFile: function(s) { return \"${wasmURL}\"; } }; \\n` : '')\n        + `importScripts( \"${url}\" );`;\n    return URL.createObjectURL(new Blob([content], { type: 'text/javascript' }));\n}\n\nexport { Damper, LinearToSRGB, PointerDragHelper, SRGBToLinear, Serialization, SimpleEventDispatcher, TYPED_ARRAYS, absMax, aesGcmDecrypt, aesGcmEncrypt, arrayBufferToBase64, base64ToArrayBuffer, blobToDataURL, blobToImage, canvasFlipY, clearBit, cloneScriptTag, colorToDataUrl, copyProps, createCanvasElement, createDiv, createImage, createScriptFromURL, createStyles, css, deepAccessObject, downloadBlob, downloadFile, embedUrlRefs, escapeRegExp, findLastIndex, getFileHandle, getFilenameFromPath, getKeyByValue, getNewFileHandle, getOrCall, getPropertyDescriptor, getTypedArray, getUrlQueryParam, glsl, html, htmlToCanvas, htmlToPng, htmlToSvg, imageBitmapToBase64, imageBitmapToBlob, imageBitmapToCanvas, imageDataToCanvas, imageToCanvas, imageUrlToImageData, includesAll, isPropertyWritable, isWebpExportSupported, longestCommonPrefix, makeColorSvg, makeColorSvgCircle, makeTextSvg, mobileAndTabletCheck, now, objectHasOwn, objectMap, objectMap2, onChange, onChange2, onChange3, onChangeDispatchEvent, parseFileExtension, pathJoin, prettyScrollbar, readFile, remoteWorkerURL, replaceAll, safeReplaceString, safeSetProperty, serializable, serialize, setInnerHTMLWithScripts, setUrlQueryParam, svgToCanvas, svgToPng, svgUrl, timeout, toCamelCase, toTitleCase, updateBit, uploadFile, uuidV4, verifyPermission, wrapThisFunction, wrapThisFunction2, writeFile };\n//# sourceMappingURL=bundle.esm.js.map\n","export function syncFormState(src: HTMLElement, dst: HTMLElement) {\n    const srcFields = src.querySelectorAll('input, textarea, select, option')\n    const dstFields = dst.querySelectorAll('input, textarea, select, option')\n    if (srcFields.length !== dstFields.length) return\n\n    for (let i = 0; i < srcFields.length; i++) {\n        const s = srcFields[i] as HTMLElement\n        const d = dstFields[i] as HTMLElement\n        switch (s.tagName) {\n            case 'INPUT': {\n                const si = s as HTMLInputElement\n                const di = d as HTMLInputElement\n                if (si.type === 'checkbox' || si.type === 'radio') {\n                    if (si.checked) di.setAttribute('checked', '')\n                    else di.removeAttribute('checked')\n                } else {\n                    di.setAttribute('value', si.value)\n                }\n                break\n            }\n            case 'TEXTAREA':\n                ;(d as HTMLTextAreaElement).textContent = (s as HTMLTextAreaElement).value\n                break\n            case 'SELECT': {\n                const ss = s as HTMLSelectElement\n                const ds = d as HTMLSelectElement\n                ds.selectedIndex = ss.selectedIndex\n                break\n            }\n            case 'OPTION':\n                if ((s as HTMLOptionElement).selected) d.setAttribute('selected', '')\n                else d.removeAttribute('selected')\n                break\n        }\n    }\n}\n","import {createImage, css, embedUrlRefs} from 'ts-browser-helpers'\nimport {syncFormState} from './syncFormState'\n\nconst _debugHIC = typeof location !== 'undefined' && new URLSearchParams(location.search).has('debugPolyfillHIC')\n\nexport class HtmlRenderer {\n    pixelRatio = typeof window !== 'undefined' ? (window.devicePixelRatio || 1) : 1\n\n    private pageStyles = ''\n    private entries = new Map<HTMLElement, RendererEntry>()\n    private pageStylesCssPromise: Promise<string> | null = null\n\n    async update(node: HTMLElement): Promise<HTMLCanvasElement> {\n        const cssW = node.clientWidth || node.offsetWidth\n        const cssH = node.clientHeight || node.offsetHeight\n        if (cssW === 0 || cssH === 0) {\n            const existing = this.entries.get(node)\n            if (existing) return existing.canvas\n            return this.ensureEntry(node, 1, 1).canvas\n        }\n\n        const entry = this.ensureEntry(node, cssW, cssH)\n        const dpr = Math.max(1, this.pixelRatio)\n        const pxW = entry.canvas.width\n        const pxH = entry.canvas.height\n        const svg = await this.buildSvg(node, cssW, cssH, dpr)\n\n        if (svg === entry.lastSvg) {\n            if (_debugHIC)\n                console.log('[html-in-canvas debug] rasterization skipped (unchanged)')\n            return entry.canvas\n        }\n        if (_debugHIC && entry.lastSvg) {\n            const oldLines = entry.lastSvg.split('<')\n            const newLines = svg.split('<')\n            const diffs: string[] = []\n            const len = Math.max(oldLines.length, newLines.length)\n            for (let i = 0; i < len; i++) {\n                if (oldLines[i] !== newLines[i]) {\n                    diffs.push(`  - ${(oldLines[i] || '').slice(0, 120)}`)\n                    diffs.push(`  + ${(newLines[i] || '').slice(0, 120)}`)\n                }\n                if (diffs.length > 20) { diffs.push('  ...'); break }\n            }\n            console.log('[html-in-canvas debug] SVG changed:\\n' + diffs.join('\\n'))\n        }\n        entry.lastSvg = svg\n\n        const image = await loadSvgAsImage(svg, pxW, pxH)\n        entry.context.clearRect(0, 0, pxW, pxH)\n        entry.context.drawImage(image, 0, 0, pxW, pxH)\n        return entry.canvas\n    }\n\n    getCanvas(node: HTMLElement): HTMLCanvasElement | null {\n        return this.entries.get(node)?.canvas ?? null\n    }\n\n    getCssSize(node: HTMLElement): { width: number; height: number } | null {\n        const e = this.entries.get(node)\n        return e ? {width: e.cssW, height: e.cssH} : null\n    }\n\n    setPageStyles(styles: string) {\n        this.pageStyles = styles\n    }\n\n    async getPageStylesCss(): Promise<string> {\n        if (!this.pageStylesCssPromise) {\n            const promise = collectAndInlinePageStyles()\n            this.pageStylesCssPromise = promise\n            promise.catch(() => {\n                if (this.pageStylesCssPromise === promise) {\n                    this.pageStylesCssPromise = null\n                }\n            })\n        }\n        return this.pageStylesCssPromise\n    }\n\n    invalidatePageStylesCss() {\n        this.pageStylesCssPromise = null\n    }\n\n    cleanup() {\n        this.entries.clear()\n        this.pageStylesCssPromise = null\n        dataUrlCache.clear()\n        if (mirrorDiv) {\n            mirrorDiv.remove()\n            mirrorDiv = null\n        }\n    }\n\n    captureDynamicStateOnClone(src: HTMLElement, dst: HTMLElement) {\n        const srcAll = [src, ...src.querySelectorAll<HTMLElement>('*')]\n        const dstAll = [dst, ...dst.querySelectorAll<HTMLElement>('*')]\n        if (srcAll.length !== dstAll.length) return\n        for (let i = 0; i < srcAll.length; i++) {\n            writeDynamicStateInline(srcAll[i], dstAll[i])\n        }\n        injectCaretAndSelection(src, dst)\n        injectPageSelection(src, dst)\n    }\n\n    readonly svgOnlyStyles = css`\n[style*=\"--scroll-left\"], [style*=\"--scroll-top\"] {\n    overflow: hidden !important;\n}\n[style*=\"--animation-delay\"] {\n    animation-delay: var(--animation-delay, 0s) !important;\n}\n[style*=\"--scroll-left\"] > *, [style*=\"--scroll-top\"] > * {\n    transform: translate(var(--scroll-left, 0), var(--scroll-top, 0));\n}\n`\n\n    private ensureEntry(node: HTMLElement, cssW: number, cssH: number): RendererEntry {\n        const dpr = Math.max(1, this.pixelRatio)\n        const width = Math.max(1, Math.ceil(cssW * dpr))\n        const height = Math.max(1, Math.ceil(cssH * dpr))\n        let entry = this.entries.get(node)\n        if (!entry) {\n            const canvas = document.createElement('canvas')\n            canvas.width = width\n            canvas.height = height\n            const context = canvas.getContext('2d')!\n            entry = {canvas, context, cssW, cssH}\n            this.entries.set(node, entry)\n        } else {\n            if (entry.canvas.width !== width || entry.canvas.height !== height) {\n                entry.canvas.width = width\n                entry.canvas.height = height\n            }\n            entry.cssW = cssW\n            entry.cssH = cssH\n        }\n        return entry\n    }\n\n    private async buildSvg(node: HTMLElement, cssW: number, cssH: number, _dpr = 1): Promise<string> {\n        const clone = await prepareClone(node)\n        this.captureDynamicStateOnClone(node, clone)\n        const innerXml = wrapClone(node, new XMLSerializer().serializeToString(clone))\n\n        const pageStylesCss = await this.getPageStylesCss()\n        const style = BASELINE_CSS + '\\n' + pageStylesCss + '\\n' + this.pageStyles + '\\n' + this.svgOnlyStyles\n\n        const svg = (\n            `<svg xmlns=\"http://www.w3.org/2000/svg\"` +\n            ` width=\"${cssW}\" height=\"${cssH}\" viewBox=\"0 0 ${cssW} ${cssH}\">` +\n            `<style><![CDATA[${style.replace(/]]>/g, ']]]]><![CDATA[>')}]]></style>` +\n            `<foreignObject x=\"0\" y=\"0\" width=\"100%\" height=\"100%\">${innerXml}</foreignObject>` +\n            `</svg>`\n        )\n        if (_debugHIC) {\n            let dbg = document.getElementById('__hic-svg-debug__') as HTMLDivElement\n            if (!dbg) {\n                dbg = document.createElement('div')\n                dbg.id = '__hic-svg-debug__'\n                dbg.style.cssText = 'position:absolute;z-index:99999;pointer-events:none;opacity:0.3;box-sizing:border-box;margin:0;padding:0;border:none;overflow:hidden;'\n                document.body.appendChild(dbg)\n            }\n            const canvasEl = document.querySelector('canvas')\n            if (canvasEl) {\n                const cr = canvasEl.getBoundingClientRect()\n                dbg.style.left = (cr.left + window.scrollX) + 'px'\n                dbg.style.top = (cr.top + window.scrollY) + 'px'\n                dbg.style.width = cr.width + 'px'\n                dbg.style.height = cr.height + 'px'\n            }\n            if (!dbg.innerHTML) {\n                dbg.innerHTML = svg\n                const svgEl = dbg.querySelector('svg')\n                if (svgEl) { svgEl.style.width = '100%'; svgEl.style.height = '100%'; }\n            }\n        }\n        return svg\n\n    }\n}\n\ninterface RendererEntry {\n    canvas: HTMLCanvasElement\n    context: CanvasRenderingContext2D\n    cssW: number\n    cssH: number\n    lastSvg?: string\n}\n\nasync function prepareClone(node: HTMLElement): Promise<HTMLElement> {\n    const clone = node.cloneNode(true) as HTMLElement\n    syncFormState(node, clone)\n    freezeResolvedTextMetrics(node, clone)\n    clone.style.removeProperty('transform')\n    clone.style.opacity = '1'\n    clone.style.visibility = 'visible'\n    await inlineExternalImages(clone)\n    clone.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')\n    return clone\n}\n\nfunction wrapClone(node: HTMLElement, cloneXml: string): string {\n    const parentEl = node.parentElement\n    const parentClass = parentEl?.getAttribute('class') || ''\n    const parentW = parentEl?.clientWidth || node.clientWidth || node.offsetWidth\n    const parentH = parentEl?.clientHeight || node.clientHeight || node.offsetHeight\n\n    const classAttr = parentClass ? ` class=\"${escapeXmlAttr(parentClass)}\"` : ''\n    const ancestorOpen =\n        `<div xmlns=\"http://www.w3.org/1999/xhtml\"${classAttr}` +\n        ` style=\"position:relative;width:${parentW}px;height:${parentH}px;margin:0;padding:0;\">`\n    const ancestorClose = '</div>'\n\n    return (\n        `<html xmlns=\"http://www.w3.org/1999/xhtml\" style=\"margin:0;padding:0;background:transparent !important;\">` +\n        `<body style=\"margin:0;padding:0;background:transparent !important;\">` +\n        ancestorOpen + cloneXml + ancestorClose +\n        `</body></html>`\n    )\n}\n\nasync function loadSvgAsImage(svg: string, cssW: number, cssH: number): Promise<HTMLImageElement> {\n    const dataUrl = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg)\n    try {\n        return await createImage(dataUrl)\n    } catch (e) {\n        const type = (e && typeof e === 'object' && 'type' in (e as any)) ? (e as any).type : typeof e\n        const err = new Error(\n            `HtmlRenderer: SVG image failed to load (${type}). ` +\n            `cssW=${cssW}, cssH=${cssH}, svg.length=${svg.length}. ` +\n            `svg head: ${svg.slice(0, 300).replace(/\\s+/g, ' ')}…`,\n        )\n        ;(err as any).cause = e\n        ;(err as any).svg = svg\n        throw err\n    }\n}\n\nasync function collectAndInlinePageStyles(): Promise<string> {\n    const sheets: string[] = []\n\n    for (const sheet of Array.from(document.styleSheets)) {\n        try {\n            const cssRules = Array.from(sheet.cssRules || [])\n            sheets.push(cssRules.map(r => r.cssText).join('\\n'))\n        } catch {\n            if (!sheet.href) continue\n            try {\n                const res = await fetch(sheet.href)\n                if (res.ok) sheets.push(await res.text())\n            } catch (e) {\n                console.warn('[HtmlRenderer] failed to fetch stylesheet', sheet.href, e)\n            }\n        }\n    }\n\n    if (sheets.length === 0) return ''\n\n    let combined: string\n    try {\n        combined = await embedUrlRefs(sheets.join('\\n'), async (url) => {\n            // Skip W3C namespace URIs — not actual resources\n            if (url.startsWith('http://www.w3.org/')) return url\n            try { return await fetchAsDataUrl(url) }\n            catch { return url }\n        })\n    } catch (e) {\n        console.warn('[HtmlRenderer] URL embedding failed', e)\n        combined = sheets.join('\\n')\n    }\n\n    const pseudoRules = rewritePseudoClasses(combined)\n    return pseudoRules ? combined + '\\n' + pseudoRules : combined\n}\n\nconst BASELINE_CSS = `\na { color: -webkit-link; text-decoration: underline; cursor: pointer; }\n*.pseudo-focus-visible { outline: auto 1px -webkit-focus-ring-color; }\ninput.pseudo-focus-visible, textarea.pseudo-focus-visible, select.pseudo-focus-visible { outline-offset: 0; }\ninput[type=\"checkbox\"].pseudo-focus-visible, input[type=\"radio\"].pseudo-focus-visible { outline-offset: 2px; }\na.pseudo-focus-visible { outline-offset: 1px; }\n@media (prefers-color-scheme: dark) {\n    button.pseudo-hover, select.pseudo-hover,\n    input.pseudo-hover, textarea.pseudo-hover {\n        filter: brightness(1.1);\n    }\n    button.pseudo-active, select.pseudo-active,\n    input.pseudo-active, textarea.pseudo-active {\n        filter: brightness(0.9);\n    }\n}\n@media (prefers-color-scheme: light) {\n    button.pseudo-hover, select.pseudo-hover,\n    input.pseudo-hover, textarea.pseudo-hover {\n        filter: brightness(0.9);\n    }\n    button.pseudo-active, select.pseudo-active,\n    input.pseudo-active, textarea.pseudo-active {\n        filter: brightness(1.1);\n    }\n}\n`\n\nconst PSEUDO_RE = /:(?:hover|focus-visible|focus-within|focus(?!-)|active)\\b/g\nconst PSEUDO_RE_TEST = /:(?:hover|focus-visible|focus-within|focus(?!-)|active)\\b/\n\nfunction rewritePseudoClasses(css: string): string {\n    let sheet: CSSStyleSheet\n    try {\n        sheet = new CSSStyleSheet()\n        sheet.replaceSync(css)\n    } catch {\n        return ''\n    }\n    const out: string[] = []\n    collectRewrittenRules(sheet.cssRules, out)\n    return out.join('\\n')\n}\n\nfunction collectRewrittenRules(rules: CSSRuleList, out: string[]): void {\n    for (let i = 0; i < rules.length; i++) {\n        const rule = rules[i]\n        if (rule instanceof CSSStyleRule) {\n            if (PSEUDO_RE_TEST.test(rule.selectorText)) {\n                const newSelector = rule.selectorText.replace(PSEUDO_RE, m =>\n                    '.pseudo-' + m.slice(1),\n                )\n                out.push(`${newSelector} { ${rule.style.cssText} }`)\n            }\n        } else if ('cssRules' in rule) {\n            const group = rule as CSSGroupingRule\n            const inner: string[] = []\n            collectRewrittenRules(group.cssRules, inner)\n            if (inner.length) {\n                let condText = ''\n                if (rule instanceof CSSMediaRule) condText = `@media ${rule.conditionText}`\n                else if (rule instanceof CSSSupportsRule) condText = `@supports ${rule.conditionText}`\n                else condText = (rule as any).cssText?.split('{')[0]?.trim() ?? ''\n                if (condText) out.push(`${condText} {\\n${inner.join('\\n')}\\n}`)\n            }\n        }\n    }\n}\n\nfunction escapeXmlAttr(s: string): string {\n    return s\n        .replace(/&/g, '&amp;')\n        .replace(/\"/g, '&quot;')\n        .replace(/</g, '&lt;')\n        .replace(/>/g, '&gt;')\n}\n\nfunction writeDynamicStateInline(src: HTMLElement, dst: HTMLElement) {\n    if (src.scrollLeft !== 0 || src.scrollTop !== 0) {\n        dst.style.setProperty('--scroll-left', -src.scrollLeft + 'px')\n        dst.style.setProperty('--scroll-top', -src.scrollTop + 'px')\n    }\n\n    const animations = src.getAnimations()\n    if (animations.length !== 1) return\n    const anim = animations[0]\n    const timeMs = typeof anim.currentTime === 'number' ? anim.currentTime : 0\n    const delayStr = getComputedStyle(src).animationDelay\n    const delaySec = delayStr.endsWith('ms')\n        ? parseFloat(delayStr) / 1000\n        : parseFloat(delayStr)\n    const adjustedDelaySec = (delaySec || 0) - timeMs / 1000\n    dst.style.setProperty('--animation-delay', adjustedDelaySec + 's')\n}\n\nconst MIRROR_PROPS = [\n    'fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'fontVariant',\n    'lineHeight', 'letterSpacing', 'wordSpacing', 'textIndent', 'textTransform',\n    'whiteSpace', 'wordWrap', 'overflowWrap', 'wordBreak',\n    'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',\n    'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth',\n    'boxSizing', 'width', 'direction', 'textAlign',\n] as const\n\nlet mirrorDiv: HTMLDivElement | null = null\n\n/** Measure pixel position of a character index within an input or textarea using a mirror div. */\nfunction measureCharPosition(\n    el: HTMLInputElement | HTMLTextAreaElement,\n    charIndex: number,\n): {x: number; y: number; height: number} {\n    if (!mirrorDiv) {\n        mirrorDiv = document.createElement('div')\n        mirrorDiv.style.cssText = 'position:absolute;left:-9999px;top:-9999px;visibility:hidden;overflow:hidden;'\n        document.body.appendChild(mirrorDiv)\n    }\n\n    const cs = getComputedStyle(el)\n    const isInput = el instanceof HTMLInputElement\n\n    // Copy text-affecting styles to mirror\n    for (const prop of MIRROR_PROPS) mirrorDiv.style[prop as any] = cs[prop as any]\n    mirrorDiv.style.whiteSpace = isInput ? 'pre' : cs.whiteSpace\n    mirrorDiv.style.height = 'auto'\n    mirrorDiv.style.overflowY = 'hidden'\n\n    const text = el.value\n    const before = text.substring(0, charIndex)\n\n    // Insert text before caret, then a marker span\n    mirrorDiv.textContent = ''\n    const textNode = document.createTextNode(before)\n    const marker = document.createElement('span')\n    marker.textContent = '|'\n    mirrorDiv.appendChild(textNode)\n    mirrorDiv.appendChild(marker)\n    // Add remaining text for correct wrapping context\n    mirrorDiv.appendChild(document.createTextNode(text.substring(charIndex) || '.'))\n\n    const fontSize = parseFloat(cs.fontSize)\n    const lhParsed = parseFloat(cs.lineHeight)\n    const lineHeight = isNaN(lhParsed) ? fontSize * 1.2\n        : cs.lineHeight.endsWith('px') ? lhParsed\n        : lhParsed * fontSize\n\n    return {\n        x: marker.offsetLeft,\n        y: marker.offsetTop,\n        height: lineHeight,\n    }\n}\n\nfunction injectCaretAndSelection(rootSrc: HTMLElement, rootDst: HTMLElement) {\n    const active = document.activeElement\n    if (!active) return\n\n    let inputEl: HTMLInputElement | HTMLTextAreaElement\n    if (active instanceof HTMLInputElement) {\n        const t = active.type\n        if (t !== 'text' && t !== 'search' && t !== 'url' && t !== 'tel' && t !== 'password' && t !== '') return\n        inputEl = active\n    } else if (active instanceof HTMLTextAreaElement) {\n        inputEl = active\n    } else {\n        return\n    }\n\n    if (!rootSrc.contains(inputEl)) return\n    const selStart = inputEl.selectionStart\n    const selEnd = inputEl.selectionEnd\n    if (selStart === null || selEnd === null) return\n\n    const cs = getComputedStyle(inputEl)\n    const borderLeft = parseFloat(cs.borderLeftWidth) || 0\n    const borderTop = parseFloat(cs.borderTopWidth) || 0\n\n    // Walk offsetParent chain to get position in layout space relative to rootSrc\n    let offsetX = 0, offsetY = 0\n    let el: HTMLElement | null = inputEl\n    while (el && el !== rootSrc) {\n        offsetX += el.offsetLeft\n        offsetY += el.offsetTop\n        el = el.offsetParent as HTMLElement | null\n    }\n\n    const contentOriginX = offsetX + borderLeft\n    const contentOriginY = offsetY + borderTop\n\n    // Clip bounds (visible content area)\n    const clipLeft = contentOriginX\n    const clipRight = clipLeft + inputEl.clientWidth\n    const clipTop = contentOriginY\n    const clipBottom = clipTop + inputEl.clientHeight\n\n    if (selStart === selEnd) {\n        // Caret\n        const pos = measureCharPosition(inputEl, selStart)\n        const caretX = contentOriginX + pos.x - inputEl.scrollLeft\n        const caretY = contentOriginY + pos.y - inputEl.scrollTop\n\n        const caretVisible = Math.floor(Date.now() / 500) % 2 === 0\n        if (caretVisible && caretX >= clipLeft && caretX <= clipRight\n            && caretY >= clipTop && caretY + pos.height <= clipBottom) {\n            const caret = document.createElement('div')\n            caret.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')\n            caret.style.cssText =\n                `position:absolute;pointer-events:none;` +\n                `left:${caretX}px;top:${caretY}px;` +\n                `width:2px;height:${pos.height}px;` +\n                `background:currentColor;`\n            rootDst.appendChild(caret)\n        }\n    } else {\n        // Selection — may span multiple lines\n        const startPos = measureCharPosition(inputEl, selStart)\n        const endPos = measureCharPosition(inputEl, selEnd)\n\n        const lineHeight = startPos.height\n        const scrollL = inputEl.scrollLeft\n        const scrollT = inputEl.scrollTop\n\n        if (startPos.y === endPos.y) {\n            // Single-line selection\n            const left = Math.max(contentOriginX + startPos.x - scrollL, clipLeft)\n            const right = Math.min(contentOriginX + endPos.x - scrollL, clipRight)\n            const top = contentOriginY + startPos.y - scrollT\n            if (right > left && top >= clipTop && top + lineHeight <= clipBottom) {\n                const highlight = document.createElement('div')\n                highlight.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')\n                highlight.style.cssText =\n                    `position:absolute;pointer-events:none;` +\n                    `left:${left}px;top:${top}px;` +\n                    `width:${right - left}px;height:${lineHeight}px;` +\n                    `background:Highlight;opacity:0.5;`\n                rootDst.appendChild(highlight)\n            }\n        } else {\n            // Multi-line selection: first line, middle lines, last line\n            const lines: {left: number; right: number; top: number}[] = []\n            // First line: from selStart to end of line\n            lines.push({left: contentOriginX + startPos.x - scrollL, right: clipRight, top: contentOriginY + startPos.y - scrollT})\n            // Middle full lines\n            for (let y = startPos.y + lineHeight; y < endPos.y; y += lineHeight) {\n                lines.push({left: clipLeft, right: clipRight, top: contentOriginY + y - scrollT})\n            }\n            // Last line: from start of line to selEnd\n            lines.push({left: clipLeft, right: contentOriginX + endPos.x - scrollL, top: contentOriginY + endPos.y - scrollT})\n\n            for (const line of lines) {\n                const left = Math.max(line.left, clipLeft)\n                const right = Math.min(line.right, clipRight)\n                if (right <= left) continue\n                if (line.top + lineHeight < clipTop || line.top > clipBottom) continue\n                const highlight = document.createElement('div')\n                highlight.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')\n                highlight.style.cssText =\n                    `position:absolute;pointer-events:none;` +\n                    `left:${left}px;top:${line.top}px;` +\n                    `width:${right - left}px;height:${lineHeight}px;` +\n                    `background:Highlight;opacity:0.5;`\n                rootDst.appendChild(highlight)\n            }\n        }\n    }\n}\n\nfunction injectPageSelection(rootSrc: HTMLElement, rootDst: HTMLElement) {\n    const selection = window.getSelection()\n    if (!selection || selection.isCollapsed || selection.rangeCount === 0) return\n\n    // Check if selection intersects our element\n    const range = selection.getRangeAt(0)\n    if (!rootSrc.contains(range.startContainer) && !rootSrc.contains(range.endContainer)) return\n\n    // Temporarily remove 3D transform so getBoundingClientRect/getClientRects\n    // return flat layout-space coordinates, not perspective-distorted ones.\n    const savedTransform = rootSrc.style.transform\n    const savedTransformOrigin = rootSrc.style.transformOrigin\n    rootSrc.style.transform = 'none'\n    rootSrc.style.transformOrigin = ''\n\n    const rootRect = rootSrc.getBoundingClientRect()\n    const scaleX = rootSrc.offsetWidth / rootRect.width\n    const scaleY = rootSrc.offsetHeight / rootRect.height\n\n    // Clip to visible area\n    const clipRight = rootSrc.offsetWidth\n    const clipBottom = rootSrc.offsetHeight\n\n    const rects = range.getClientRects()\n    // Collect rect data before restoring transform\n    const rectData: {left: number; top: number; width: number; height: number}[] = []\n    for (let i = 0; i < rects.length; i++) {\n        const r = rects[i]\n        rectData.push({\n            left: (r.left - rootRect.left) * scaleX + rootSrc.scrollLeft,\n            top: (r.top - rootRect.top) * scaleY + rootSrc.scrollTop,\n            width: r.width * scaleX,\n            height: r.height * scaleY,\n        })\n    }\n\n    // Restore transform immediately\n    rootSrc.style.transform = savedTransform\n    rootSrc.style.transformOrigin = savedTransformOrigin\n\n    for (let i = 0; i < rectData.length; i++) {\n        let {left, top, width, height} = rectData[i]\n\n        // Clip to element bounds\n        if (left < 0) { width += left; left = 0 }\n        if (top < 0) { height += top; top = 0 }\n        if (left + width > clipRight) width = clipRight - left\n        if (top + height > clipBottom) height = clipBottom - top\n        if (width <= 0 || height <= 0) continue\n\n        const highlight = document.createElement('div')\n        highlight.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')\n        highlight.style.cssText =\n            `position:absolute;pointer-events:none;` +\n            `left:${left}px;top:${top}px;` +\n            `width:${width}px;height:${height}px;` +\n            `background:Highlight;opacity:0.5;`\n        rootDst.appendChild(highlight)\n    }\n}\n\nfunction freezeResolvedTextMetrics(src: HTMLElement, dst: HTMLElement) {\n    const srcAll = [src, ...src.querySelectorAll<HTMLElement>('*')]\n    const dstAll = [dst, ...dst.querySelectorAll<HTMLElement>('*')]\n    if (srcAll.length !== dstAll.length) return\n    for (let i = 0; i < srcAll.length; i++) {\n        const cs = getComputedStyle(srcAll[i])\n        // Floor all fractional vertical dimensions to prevent cumulative\n        // sub-pixel drift in SVG-as-image rasterization\n        for (const prop of ['fontSize', 'lineHeight', 'height', 'minHeight', 'maxHeight', 'marginTop', 'marginBottom', 'paddingTop', 'paddingBottom', 'borderTopWidth', 'borderBottomWidth'] as const) {\n            const v = parseFloat(cs[prop])\n            if (isNaN(v)) continue\n            dstAll[i].style[prop] = (v % 1 !== 0) ? Math.floor(v) + 'px' : cs[prop]\n        }\n    }\n}\n\n\nconst dataUrlCache = new Map<string, Promise<string>>()\n\nfunction fetchAsDataUrl(url: string): Promise<string> {\n    const cached = dataUrlCache.get(url)\n    if (cached) return cached\n    const p = fetch(url)\n        .then(r => {\n            if (!r.ok) throw new Error(`fetch ${url} → ${r.status}`)\n            return r.blob()\n        })\n        .then(blob => new Promise<string>((resolve, reject) => {\n            const fr = new FileReader()\n            fr.onload = () => resolve(fr.result as string)\n            fr.onerror = () => reject(fr.error)\n            fr.readAsDataURL(blob)\n        }))\n    dataUrlCache.set(url, p)\n    p.catch(() => {\n        if (dataUrlCache.get(url) === p) dataUrlCache.delete(url)\n    })\n    return p\n}\n\nasync function inlineExternalImages(root: HTMLElement): Promise<void> {\n    const imgs = Array.from(root.querySelectorAll('img'))\n    await Promise.all(imgs.map(async img => {\n        const src = img.getAttribute('src')\n        if (!src || src.startsWith('data:')) return\n        try {\n            const abs = new URL(src, document.baseURI).href\n            img.setAttribute('src', await fetchAsDataUrl(abs))\n        } catch (e) {\n            console.warn('[HtmlRenderer] failed to inline img', src, e)\n            img.removeAttribute('src')\n        }\n    }))\n}\n","import {HtmlRenderer} from './htmlRenderer'\n\nexport interface PolyfillOptions {\n    pageStyles?: string\n    force?: boolean\n}\n\ninterface CanvasState {\n    canvas: HTMLCanvasElement\n    host: HTMLDivElement\n    children: Set<HTMLElement>\n    dirty: Set<HTMLElement>\n    onpaint: ((e: Event) => void) | null\n    rafHandle: number\n    caretBlinkInterval: ReturnType<typeof setInterval> | null\n    positionHost: () => void\n    observers: (MutationObserver | ResizeObserver)[]\n    cleanups: (() => void)[]\n}\n\nconst STATES = new Map<HTMLCanvasElement, CanvasState>()\nconst renderer = new HtmlRenderer()\nlet installed = false\n\nexport function getHtmlRenderer(): HtmlRenderer {\n    return renderer\n}\n\nconst savedDescriptors: Array<[object, string, PropertyDescriptor | undefined]> = []\nconst globalListeners: Array<[EventTarget, string, EventListenerOrEventListenerObject, boolean | AddEventListenerOptions | undefined]> = []\n// Maps elements redirected to a host back to their owning canvas, so\n// patched parentNode/parentElement return the canvas instead of the host.\nconst parentOverrides = new WeakMap<Node, HTMLCanvasElement>()\nlet attributeObserver: MutationObserver | null = null\n\nexport function installHtmlInCanvasPolyfill(options: PolyfillOptions = {}) {\n    if (installed) return\n    // If another copy (e.g. browser extension) already installed, uninstall it\n    // so this bundle's version takes over with its own renderer/state.\n    if ((window as any).__HTML_IN_CANVAS_POLYFILL__) {\n        const prev = (window as any).__HIC_UNINSTALL__\n        if (typeof prev === 'function') prev()\n        else return // no way to cleanly replace, bail\n    }\n    const hasNative =\n        'drawElementImage' in CanvasRenderingContext2D.prototype &&\n        'requestPaint' in HTMLCanvasElement.prototype &&\n        'onpaint' in HTMLCanvasElement.prototype\n    const force = options.force ?? new URLSearchParams(location.search).has('polyfillHIC')\n    if (hasNative && !force) {\n        console.info('[html-in-canvas] Native API detected, polyfill skipped. Add ?polyfillHIC to URL to force.')\n        return\n    }\n    installed = true;\n    (window as any).__HTML_IN_CANVAS_POLYFILL__ = true;\n    (window as any).__HIC_UNINSTALL__ = uninstallHtmlInCanvasPolyfill\n    console.info('[html-in-canvas] Polyfill installed' + (force ? ' (forced)' : ''))\n\n    if (options.pageStyles) renderer.setPageStyles(options.pageStyles)\n\n    patchContext()\n    patchWebGLContext()\n    patchWebGPUQueue()\n    patchCanvasElement()\n    installGlobalListeners()\n    scanAndObserve()\n}\n\nexport function uninstallHtmlInCanvasPolyfill() {\n    if (!installed) return\n\n    for (const state of Array.from(STATES.values())) {\n        teardownCanvasState(state)\n    }\n    STATES.clear()\n\n    for (const [target, prop, desc] of savedDescriptors) {\n        if (desc) Object.defineProperty(target, prop, desc)\n        else delete (target as any)[prop]\n    }\n    savedDescriptors.length = 0\n\n    for (const [target, type, handler, opts] of globalListeners) {\n        target.removeEventListener(type, handler as any, opts as any)\n    }\n    globalListeners.length = 0\n\n    attributeObserver?.disconnect()\n    attributeObserver = null\n\n    resizeScratchCanvas = null\n    renderer.cleanup()\n\n    installed = false;\n    (window as any).__HTML_IN_CANVAS_POLYFILL__ = false\n    delete (window as any).__HIC_UNINSTALL__\n}\n\nfunction requireState(canvas: HTMLCanvasElement, element: HTMLElement): CanvasState {\n    const state = STATES.get(canvas) || ensureState(canvas)\n    if (!state)\n        throw new DOMException('canvas is not [layoutsubtree]', 'InvalidStateError')\n    if (!state.children.has(element))\n        throw new DOMException('element is not a direct child of the canvas', 'InvalidStateError')\n    return state\n}\n\n// M = T_origin^-1 · S_css_to_grid^-1 · T_draw · S_css_to_grid · T_origin\nfunction computeElementTransform(\n    el: HTMLElement, drawTransform: DOMMatrix,\n    sx: number, sy: number, cssW: number, cssH: number,\n): DOMMatrix {\n    const S = new DOMMatrix().scale(sx, sy)\n    const Sinv = new DOMMatrix().scale(1 / sx, 1 / sy)\n    const cs = getComputedStyle(el)\n    const originParts = cs.transformOrigin.split(' ')\n    const ox = parseFloat(originParts[0]) || cssW / 2\n    const oy = parseFloat(originParts[1]) || cssH / 2\n    const T_o = new DOMMatrix().translate(ox, oy)\n    const T_oi = new DOMMatrix().translate(-ox, -oy)\n    return T_oi.multiply(Sinv).multiply(drawTransform).multiply(S).multiply(T_o)\n}\n\nfunction patchContext() {\n    definePatchedProperty(CanvasRenderingContext2D.prototype, 'drawElementImage', {\n        configurable: true,\n        writable: true,\n        value: drawElementImage,\n    })\n}\n\nfunction drawElementImage(\n    this: CanvasRenderingContext2D,\n    el: HTMLElement,\n    dx: number, dy: number,\n    dw?: number, dh?: number,\n): DOMMatrix {\n    const canvas = this.canvas as HTMLCanvasElement\n    requireState(canvas, el)\n\n    const bitmap = renderer.getCanvas(el)\n    const cssSize = renderer.getCssSize(el)\n    if (!bitmap || !cssSize)\n        return new DOMMatrix()\n\n    const cssW = cssSize.width\n    const cssH = cssSize.height\n    const sx = canvas.width / Math.max(1, canvas.clientWidth)\n    const sy = canvas.height / Math.max(1, canvas.clientHeight)\n\n    const dwGrid = dw ?? (cssW * sx)\n    const dhGrid = dh ?? (cssH * sy)\n\n    this.drawImage(bitmap, dx, dy, dwGrid, dhGrid)\n\n    const T_draw = this.getTransform()\n        .translate(dx, dy)\n        .scale(dwGrid / (cssW * sx), dhGrid / (cssH * sy))\n    return computeElementTransform(el, T_draw, sx, sy, cssW, cssH)\n}\n\nfunction patchWebGLContext() {\n    if (typeof WebGLRenderingContext !== 'undefined') {\n        definePatchedProperty(WebGLRenderingContext.prototype, 'texElementImage2D', {\n            configurable: true, writable: true, value: texElementImage2D,\n        })\n    }\n    if (typeof WebGL2RenderingContext !== 'undefined') {\n        definePatchedProperty(WebGL2RenderingContext.prototype, 'texElementImage2D', {\n            configurable: true, writable: true, value: texElementImage2D,\n        })\n    }\n}\n\nfunction texElementImage2D(\n    this: WebGLRenderingContext,\n    target: number,\n    level: number,\n    internalformat: number,\n    ...rest: any[]\n): void {\n    let format: number, type: number, element: HTMLElement\n    if (rest.length === 3) {\n        [format, type, element] = rest\n    } else if (rest.length === 5) {\n        console.warn('[html-in-canvas polyfill] texElementImage2D(width,height,...) overload: dest resize not implemented, uploading at bitmap size')\n        ;[/*width*/, /*height*/, format, type, element] = rest\n    } else if (rest.length === 7) {\n        console.warn('[html-in-canvas polyfill] texElementImage2D(sx,sy,swidth,sheight,...) overload: source crop not implemented, uploading full bitmap')\n        ;[/*sx*/, /*sy*/, /*swidth*/, /*sheight*/, format, type, element] = rest\n    } else if (rest.length === 9) {\n        console.warn('[html-in-canvas polyfill] texElementImage2D(sx,sy,swidth,sheight,width,height,...) overload: source crop + dest resize not implemented, uploading full bitmap')\n        ;[/*sx*/, /*sy*/, /*swidth*/, /*sheight*/, /*width*/, /*height*/, format, type, element] = rest\n    } else {\n        throw new TypeError(`texElementImage2D: unexpected argument count ${3 + rest.length}`)\n    }\n\n    if (!(element instanceof HTMLElement)) {\n        throw new TypeError('texElementImage2D: element must be an HTMLElement')\n    }\n\n    const bitmap = renderer.getCanvas(element)\n    if (!bitmap) {\n        throw new DOMException(\n            'texElementImage2D: no snapshot recorded yet for this element. ' +\n            'Call from inside the canvas `onpaint` handler or after at least one `requestPaint()` + rAF cycle.',\n            'InvalidStateError',\n        )\n    }\n\n    this.texImage2D(target, level, internalformat, format, type, bitmap)\n}\n\nfunction patchWebGPUQueue() {\n    const GPUQueue = (globalThis as any).GPUQueue\n    if (!GPUQueue || !GPUQueue.prototype) return\n    definePatchedProperty(GPUQueue.prototype, 'copyElementImageToTexture', {\n        configurable: true, writable: true, value: copyElementImageToTexture,\n    })\n}\n\nfunction copyElementImageToTexture(\n    this: any, // GPUQueue\n    ...args: any[]\n): void {\n    let element: HTMLElement, destination: any, width: number, height: number\n    if (args.length === 2) {\n        [element, destination] = args\n        width = 0\n        height = 0\n    } else if (args.length === 4) {\n        [element, width, height, destination] = args\n    } else {\n        throw new TypeError(\n            `copyElementImageToTexture: expected 2 or 4 args, got ${args.length}`,\n        )\n    }\n\n    if (!(element instanceof HTMLElement)) {\n        throw new TypeError('copyElementImageToTexture: source must be an HTMLElement')\n    }\n\n    const bitmap = renderer.getCanvas(element)\n    if (!bitmap) {\n        throw new DOMException(\n            'copyElementImageToTexture: no snapshot recorded yet for this element. ' +\n            'Call from inside the canvas `onpaint` handler or after at least one `requestPaint()` + rAF cycle.',\n            'InvalidStateError',\n        )\n    }\n\n    if (width === 0) width = bitmap.width\n    if (height === 0) height = bitmap.height\n\n    let source: HTMLCanvasElement = bitmap\n    if (bitmap.width !== width || bitmap.height !== height) {\n        source = getResizeScratchCanvas(width, height)\n        const ctx = source.getContext('2d')!\n        ctx.clearRect(0, 0, width, height)\n        ctx.imageSmoothingEnabled = true\n        ctx.imageSmoothingQuality = 'high'\n        ctx.drawImage(bitmap, 0, 0, width, height)\n    }\n\n    this.copyExternalImageToTexture(\n        {source},\n        destination,\n        [width, height],\n    )\n}\n\nlet resizeScratchCanvas: HTMLCanvasElement | null = null\nfunction getResizeScratchCanvas(w: number, h: number): HTMLCanvasElement {\n    if (!resizeScratchCanvas) resizeScratchCanvas = document.createElement('canvas')\n    if (resizeScratchCanvas.width !== w) resizeScratchCanvas.width = w\n    if (resizeScratchCanvas.height !== h) resizeScratchCanvas.height = h\n    return resizeScratchCanvas\n}\n\n// M = T_origin^-1 · S_c->g^-1 · drawTransform · S_c->g · T_origin\n//\n//   S_c->g = scale(canvas.width / canvas.clientWidth,\n//                   canvas.height / canvas.clientHeight)  -- CSS px to grid px\n//   T_origin = translate(ox, oy)                          -- the pivot (bitmap center)\nfunction getElementTransform(\n    this: HTMLCanvasElement,\n    element: HTMLElement,\n    drawTransform: DOMMatrix,\n): DOMMatrix {\n    const canvas = this\n    requireState(canvas, element)\n\n    const cssSize = renderer.getCssSize(element)\n    if (!cssSize)\n        throw new DOMException('no snapshot recorded yet', 'InvalidStateError')\n\n    const sx = canvas.width / Math.max(1, canvas.clientWidth)\n    const sy = canvas.height / Math.max(1, canvas.clientHeight)\n    return computeElementTransform(element, drawTransform, sx, sy, cssSize.width, cssSize.height)\n}\n\nfunction patchCanvasElement() {\n    definePatchedProperty(HTMLCanvasElement.prototype, 'layoutSubtree', {\n        configurable: true,\n        get(this: HTMLCanvasElement) { return this.hasAttribute('layoutsubtree') },\n        set(this: HTMLCanvasElement, v: boolean) {\n            if (v) this.setAttribute('layoutsubtree', '')\n            else this.removeAttribute('layoutsubtree')\n        },\n    })\n\n    definePatchedProperty(HTMLCanvasElement.prototype, 'onpaint', {\n        configurable: true,\n        get(this: HTMLCanvasElement) { return STATES.get(this)?.onpaint ?? null },\n        set(this: HTMLCanvasElement, fn: ((e: Event) => void) | null) {\n            const s = ensureState(this)\n            if (s) {\n                s.onpaint = fn\n            } else if (fn) {\n                console.warn(\n                    '[html-in-canvas polyfill] setting onpaint on a canvas without ' +\n                    '`layoutsubtree` — the handler will never fire. Add the ' +\n                    '`layoutsubtree` attribute first.',\n                )\n            }\n        },\n    })\n\n    definePatchedProperty(HTMLCanvasElement.prototype, 'requestPaint', {\n        configurable: true,\n        writable: true,\n        value: function (this: HTMLCanvasElement) {\n            const s = ensureState(this)\n            if (!s) return\n            for (const c of s.children) s.dirty.add(c)\n            schedulePaint(s, 'requestPaint')\n        },\n    })\n\n    definePatchedProperty(HTMLCanvasElement.prototype, 'getElementTransform', {\n        configurable: true,\n        writable: true,\n        value: getElementTransform,\n    })\n\n    definePatchedProperty(HTMLCanvasElement.prototype, 'captureElementImage', {\n        configurable: true,\n        writable: true,\n        value: function (this: HTMLCanvasElement, element: HTMLElement) {\n            requireState(this, element)\n            const canvas = renderer.getCanvas(element)\n            if (!canvas)\n                throw new DOMException('no snapshot recorded yet', 'InvalidStateError')\n            return canvas\n        },\n    })\n\n    interceptCanvasChildAccessor('children', host => host.children)\n    interceptCanvasChildAccessor('firstElementChild', host => host.firstElementChild)\n    interceptCanvasChildAccessor('lastElementChild', host => host.lastElementChild)\n    interceptCanvasChildAccessor('childElementCount', host => host.childElementCount)\n\n    patchCanvasDOMMutations()\n    patchParentNode()\n    patchCanvasEventListeners()\n}\n\nfunction interceptCanvasChildAccessor<K extends keyof Element>(\n    prop: K,\n    fromHost: (host: HTMLElement) => Element[K],\n) {\n    const origDesc = Object.getOwnPropertyDescriptor(Element.prototype, prop)!\n    definePatchedProperty(HTMLCanvasElement.prototype, prop as string, {\n        configurable: true,\n        get(this: HTMLCanvasElement) {\n            const s = STATES.get(this)\n            if (s && this.hasAttribute('layoutsubtree')) return fromHost(s.host)\n            return origDesc.get!.call(this)\n        },\n    })\n}\n\nfunction addChildToState(state: CanvasState, el: HTMLElement, before?: Node | null) {\n    if (state.children.has(el)) return\n    if (before) state.host.insertBefore(el, before)\n    else state.host.appendChild(el)\n    el.style.position = 'absolute'\n    el.style.left = '0'\n    el.style.top = '0'\n    el.style.opacity = '0'\n    el.style.pointerEvents = 'auto'\n    state.children.add(el)\n    state.dirty.add(el)\n    parentOverrides.set(el, state.canvas)\n    schedulePaint(state, 'addChildToState')\n}\n\nfunction removeChildFromState(state: CanvasState, el: HTMLElement) {\n    if (!state.children.has(el)) return false\n    state.host.removeChild(el)\n    state.children.delete(el)\n    state.dirty.delete(el)\n    parentOverrides.delete(el)\n    el.style.removeProperty('position')\n    el.style.removeProperty('left')\n    el.style.removeProperty('top')\n    el.style.removeProperty('opacity')\n    el.style.removeProperty('pointer-events')\n    el.style.removeProperty('transform-origin')\n    return true\n}\n\nfunction patchCanvasDOMMutations() {\n    const origAppendChild = Node.prototype.appendChild\n    definePatchedProperty(HTMLCanvasElement.prototype, 'appendChild', {\n        configurable: true,\n        writable: true,\n        value: function <T extends Node>(this: HTMLCanvasElement, node: T): T {\n            const s = STATES.get(this)\n            if (s && this.hasAttribute('layoutsubtree') && node instanceof HTMLElement) {\n                addChildToState(s, node)\n                return node\n            }\n            return origAppendChild.call(this, node) as T\n        },\n    })\n\n    const origRemoveChild = Node.prototype.removeChild\n    definePatchedProperty(HTMLCanvasElement.prototype, 'removeChild', {\n        configurable: true,\n        writable: true,\n        value: function <T extends Node>(this: HTMLCanvasElement, node: T): T {\n            const s = STATES.get(this)\n            if (s && node instanceof HTMLElement && removeChildFromState(s, node)) {\n                return node\n            }\n            return origRemoveChild.call(this, node) as T\n        },\n    })\n\n    const origInsertBefore = Node.prototype.insertBefore\n    definePatchedProperty(HTMLCanvasElement.prototype, 'insertBefore', {\n        configurable: true,\n        writable: true,\n        value: function <T extends Node>(this: HTMLCanvasElement, node: T, ref: Node | null): T {\n            const s = STATES.get(this)\n            if (s && this.hasAttribute('layoutsubtree') && node instanceof HTMLElement) {\n                addChildToState(s, node, ref)\n                return node\n            }\n            return origInsertBefore.call(this, node, ref) as T\n        },\n    })\n\n    definePatchedProperty(HTMLCanvasElement.prototype, 'contains', {\n        configurable: true,\n        writable: true,\n        value: function (this: HTMLCanvasElement, node: Node | null): boolean {\n            const s = STATES.get(this)\n            if (s && node && s.host.contains(node)) return true\n            return Node.prototype.contains.call(this, node)\n        },\n    })\n}\n\nfunction patchParentNode() {\n    for (const prop of ['parentNode', 'parentElement'] as const) {\n        const orig = Object.getOwnPropertyDescriptor(Node.prototype, prop)!\n        definePatchedProperty(Node.prototype, prop, {\n            configurable: true,\n            get(this: Node) {\n                return parentOverrides.get(this) ?? orig.get!.call(this)\n            },\n        })\n    }\n}\n\nconst MOUSE_EVENT_TYPES = new Set([\n    'mousemove', 'mousedown', 'mouseup', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout',\n    'click', 'dblclick', 'contextmenu', 'wheel',\n    'pointerdown', 'pointerup', 'pointermove', 'pointerenter', 'pointerleave', 'pointerover', 'pointerout',\n])\n\nfunction patchCanvasEventListeners() {\n    const origAdd = EventTarget.prototype.addEventListener\n    const origRemove = EventTarget.prototype.removeEventListener\n    const hostListeners = new WeakMap<EventListenerOrEventListenerObject, EventListenerOrEventListenerObject>()\n\n    definePatchedProperty(HTMLCanvasElement.prototype, 'addEventListener', {\n        configurable: true,\n        writable: true,\n        value: function (this: HTMLCanvasElement, type: string, listener: any, options?: any) {\n            origAdd.call(this, type, listener, options)\n            const s = STATES.get(this)\n            if (s && MOUSE_EVENT_TYPES.has(type) && listener) {\n                const hostFn = typeof listener === 'function' ? listener.bind(this) : listener\n                hostListeners.set(listener, hostFn)\n                origAdd.call(s.host, type, hostFn, options)\n            }\n        },\n    })\n\n    definePatchedProperty(HTMLCanvasElement.prototype, 'removeEventListener', {\n        configurable: true,\n        writable: true,\n        value: function (this: HTMLCanvasElement, type: string, listener: any, options?: any) {\n            origRemove.call(this, type, listener, options)\n            const s = STATES.get(this)\n            if (s && MOUSE_EVENT_TYPES.has(type) && listener) {\n                const hostFn = hostListeners.get(listener)\n                if (hostFn) {\n                    origRemove.call(s.host, type, hostFn, options)\n                    hostListeners.delete(listener)\n                }\n            }\n        },\n    })\n}\n\nfunction definePatchedProperty(target: object, prop: string, descriptor: PropertyDescriptor) {\n    savedDescriptors.push([target, prop, Object.getOwnPropertyDescriptor(target, prop)])\n    Object.defineProperty(target, prop, descriptor)\n}\n\nfunction installGlobalListeners() {\n    const repositionAll = () => {\n        for (const state of STATES.values()) state.positionHost()\n    }\n    // scroll listener\n    addGlobalListener(window, 'scroll', repositionAll, {passive: true})\n    addGlobalListener(window, 'resize', repositionAll)\n\n}\n\nfunction addGlobalListener(\n    target: EventTarget,\n    type: string,\n    handler: EventListener,\n    opts?: boolean | AddEventListenerOptions,\n) {\n    target.addEventListener(type, handler, opts)\n    globalListeners.push([target, type, handler, opts])\n}\n\nfunction scanAndObserve() {\n    const initAll = () => {\n        if (!installed) return\n        document\n            .querySelectorAll<HTMLCanvasElement>('canvas[layoutsubtree]')\n            .forEach(ensureState)\n    }\n    if (document.readyState === 'loading') {\n        addGlobalListener(document, 'DOMContentLoaded', initAll, {once: true})\n    } else {\n        initAll()\n    }\n\n    attributeObserver = new MutationObserver(muts => {\n        for (const m of muts) {\n            if (m.type === 'attributes' && m.attributeName === 'layoutsubtree') {\n                const t = m.target\n                if (!(t instanceof HTMLCanvasElement)) continue\n                if (t.hasAttribute('layoutsubtree')) {\n                    ensureState(t)\n                } else {\n                    const existing = STATES.get(t)\n                    if (existing) {\n                        teardownCanvasState(existing)\n                        STATES.delete(t)\n                    }\n                }\n            } else if (m.type === 'childList') {\n                for (const added of Array.from(m.addedNodes)) {\n                    if (added instanceof HTMLCanvasElement && added.hasAttribute('layoutsubtree')) {\n                        ensureState(added)\n                    } else if (added instanceof Element) {\n                        added\n                            .querySelectorAll<HTMLCanvasElement>('canvas[layoutsubtree]')\n                            .forEach(ensureState)\n                    }\n                }\n            }\n        }\n    })\n    attributeObserver.observe(document.documentElement, {\n        attributes: true, subtree: true, attributeFilter: ['layoutsubtree'],\n        childList: true,\n    })\n}\n\nfunction ensureState(canvas: HTMLCanvasElement): CanvasState | null {\n    const existing = STATES.get(canvas)\n    if (existing) return existing\n    if (!canvas.hasAttribute('layoutsubtree')) return null\n\n    const host = createHost(canvas)\n    const children = new Set<HTMLElement>()\n    const dirty = new Set<HTMLElement>()\n    const observers: (MutationObserver | ResizeObserver)[] = []\n\n    const positionHost = () => {\n        const r = canvas.getBoundingClientRect()\n        host.style.left = (r.left + window.scrollX + canvas.clientLeft) + 'px'\n        host.style.top = (r.top + window.scrollY + canvas.clientTop) + 'px'\n        host.style.width = canvas.clientWidth + 'px'\n        host.style.height = canvas.clientHeight + 'px'\n    }\n\n    const state: CanvasState = {\n        canvas, host, children, dirty,\n        onpaint: null, rafHandle: 0, caretBlinkInterval: null, positionHost, observers, cleanups: [],\n    }\n\n    attachHostListeners(host, state)\n    STATES.set(canvas, state)\n    moveChildrenToHost(state)\n    positionHost()\n    attachObservers(state)\n\n    return state\n}\n\nfunction createHost(canvas: HTMLCanvasElement): HTMLDivElement {\n    const host = document.createElement('div')\n    host.setAttribute('data-html-in-canvas-host', '')\n    if (canvas.className) host.className = canvas.className\n    if (canvas.id) host.setAttribute('data-host-of', canvas.id)\n    host.style.cssText =\n        'position:absolute;left:0;top:0;margin:0;padding:0;' +\n        'pointer-events:auto;transform-style:preserve-3d;'\n    document.body.appendChild(host)\n    return host\n}\n\nfunction attachHostListeners(host: HTMLDivElement, state: CanvasState) {\n    const markAllDirty = (reason = 'hostListener') => {\n        for (const c of state.children) state.dirty.add(c)\n        schedulePaint(state, reason)\n    }\n\n    host.addEventListener('load', e => {\n        if (e.target instanceof HTMLImageElement) markAllDirty('image-load')\n    }, true)\n\n    host.addEventListener('input', () => markAllDirty('input'), true)\n    host.addEventListener('change', () => markAllDirty('change'), true)\n\n    // Caret/selection movement and page-level text selection\n    const onSelectionChange = () => {\n        const sel = window.getSelection()\n        const hasPageSelection = sel && !sel.isCollapsed && sel.rangeCount > 0\n            && host.contains(sel.getRangeAt(0).startContainer)\n        if (host.contains(document.activeElement) || hasPageSelection) markAllDirty('selectionchange')\n    }\n    document.addEventListener('selectionchange', onSelectionChange)\n    state.cleanups.push(() => document.removeEventListener('selectionchange', onSelectionChange))\n\n    // --- Pseudo-class event listeners ---\n    // Class changes are picked up by the existing MutationObserver in attachObservers(),\n    // which marks the affected top-level child dirty and schedules a repaint.\n\n    host.addEventListener('mouseover', e => {\n        const target = e.target as HTMLElement\n        if (!target.classList) return\n        target.classList.add('pseudo-hover')\n        for (const el of ancestorsUpTo(target, host)) el.classList.add('pseudo-hover')\n    }, true)\n\n    host.addEventListener('mouseout', e => {\n        const target = e.target as HTMLElement\n        if (!target.classList) return\n        target.classList.remove('pseudo-hover')\n        for (const el of target.querySelectorAll<HTMLElement>('.pseudo-hover')) {\n            el.classList.remove('pseudo-hover')\n        }\n    }, true)\n\n    host.addEventListener('focusin', e => {\n        const target = e.target as HTMLElement\n        if (!target.classList) return\n        target.classList.add('pseudo-focus')\n        for (const el of ancestorsUpTo(target, host)) el.classList.add('pseudo-focus-within')\n        try {\n            if (target.matches(':focus-visible')) target.classList.add('pseudo-focus-visible')\n        } catch { /* :focus-visible not supported */ }\n\n        // Start caret blink repaint for text inputs\n        if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n            if (state.caretBlinkInterval) clearInterval(state.caretBlinkInterval)\n            state.caretBlinkInterval = setInterval(() => markAllDirty('caret-blink'), 500)\n        }\n    }, true)\n\n    host.addEventListener('focusout', e => {\n        const target = e.target as HTMLElement\n        if (target.classList) target.classList.remove('pseudo-focus', 'pseudo-focus-visible')\n        for (const el of host.querySelectorAll<HTMLElement>('.pseudo-focus-within')) {\n            el.classList.remove('pseudo-focus-within')\n        }\n\n        if (state.caretBlinkInterval) {\n            clearInterval(state.caretBlinkInterval)\n            state.caretBlinkInterval = null\n            markAllDirty('caret-remove') // One final repaint to remove the caret\n        }\n    }, true)\n\n    host.addEventListener('pointerdown', e => {\n        const target = e.target as HTMLElement\n        if (!target.classList) return\n        target.classList.add('pseudo-active')\n        for (const el of ancestorsUpTo(target, host)) el.classList.add('pseudo-active')\n    }, true)\n\n    const clearActive = () => {\n        for (const el of host.querySelectorAll<HTMLElement>('.pseudo-active')) {\n            el.classList.remove('pseudo-active')\n        }\n    }\n    host.addEventListener('pointerup', clearActive, true)\n    host.addEventListener('pointercancel', clearActive, true)\n}\n\nfunction ancestorsUpTo(el: HTMLElement, stop: HTMLElement): HTMLElement[] {\n    const result: HTMLElement[] = []\n    let current = el.parentElement\n    while (current && current !== stop) {\n        result.push(current)\n        current = current.parentElement\n    }\n    return result\n}\n\nconst realChildren = Object.getOwnPropertyDescriptor(Element.prototype, 'children')!.get!\n\nfunction moveChildrenToHost(state: CanvasState) {\n    // Use the real children getter, not our patched one (which would return\n    // host.children — empty at this point since nothing has been moved yet).\n    for (const el of Array.from(realChildren.call(state.canvas)) as HTMLElement[]) {\n        addChildToState(state, el)\n    }\n}\n\nfunction attachObservers(state: CanvasState) {\n    const resizeObs = new ResizeObserver(() => {\n        state.positionHost()\n        for (const c of state.children) state.dirty.add(c)\n        schedulePaint(state, 'ResizeObserver')\n    })\n    resizeObs.observe(state.canvas)\n    state.observers.push(resizeObs)\n\n    const mutationObs = new MutationObserver(muts => {\n        let any = false\n        for (const m of muts) {\n            let n: Node | null = m.target\n            // Walk up to find the direct-child of host. Can't use patched\n            // parentNode here (it would return canvas), so check children set.\n            while (n && !(n instanceof HTMLElement && state.children.has(n))) n = n.parentNode\n            if (n) {\n                state.dirty.add(n as HTMLElement)\n                any = true\n            }\n        }\n        if (any) schedulePaint(state, 'MutationObserver')\n    })\n    mutationObs.observe(state.host, {childList: true, subtree: true, attributes: true, characterData: true})\n    state.observers.push(mutationObs)\n}\n\nfunction teardownCanvasState(state: CanvasState) {\n    if (state.rafHandle) {\n        cancelAnimationFrame(state.rafHandle)\n        state.rafHandle = 0\n    }\n    if (state.caretBlinkInterval) {\n        clearInterval(state.caretBlinkInterval)\n        state.caretBlinkInterval = null\n    }\n    for (const fn of state.cleanups) fn()\n    state.cleanups.length = 0\n    for (const obs of state.observers) obs.disconnect()\n    state.observers.length = 0\n    state.dirty.clear()\n    state.onpaint = null\n\n    const pseudoClasses = ['pseudo-hover', 'pseudo-focus', 'pseudo-focus-visible', 'pseudo-focus-within', 'pseudo-active'] as const\n    for (const child of Array.from(state.children)) {\n        child.classList.remove(...pseudoClasses)\n        for (const el of child.querySelectorAll<HTMLElement>('.pseudo-hover, .pseudo-focus, .pseudo-focus-visible, .pseudo-focus-within, .pseudo-active')) {\n            el.classList.remove(...pseudoClasses)\n        }\n        removeChildFromState(state, child)\n        Node.prototype.appendChild.call(state.canvas, child)\n    }\n    state.host.remove()\n}\n\nconst _debugHIC = typeof location !== 'undefined' && new URLSearchParams(location.search).has('debugPolyfillHIC')\n\nfunction schedulePaint(state: CanvasState, _caller?: string) {\n    if (_debugHIC && _caller) console.trace('[html-in-canvas debug] schedulePaint from:', _caller)\n    if (state.rafHandle) return\n    state.rafHandle = requestAnimationFrame(async () => {\n        state.rafHandle = 0\n\n        if (!STATES.has(state.canvas)) return\n\n        state.positionHost()\n\n        const changed = Array.from(state.dirty)\n        state.dirty.clear()\n\n        if (changed.length) {\n            await Promise.all(changed.map(rasterizeOne))\n        }\n\n        if (!STATES.has(state.canvas)) return\n\n        const ev = new Event('paint') as Event & { changedElements: HTMLElement[] }\n        ;(ev as any).changedElements = changed\n        try { state.onpaint?.call(state.canvas, ev) }\n        catch (e) { console.error('[html-in-canvas polyfill] onpaint threw', e) }\n        state.canvas.dispatchEvent(ev)\n    })\n}\n\nasync function rasterizeOne(el: HTMLElement) {\n    try {\n        await renderer.update(el)\n    } catch (e) {\n        console.error(\n            `[html-in-canvas polyfill] rasterize failed for ${describeElement(el)}:`,\n            e instanceof Error ? (e.message + '\\n' + e.stack) : e,\n        )\n    }\n}\n\nfunction describeElement(el: HTMLElement): string {\n    const tag = el.tagName.toLowerCase()\n    const id = el.id ? `#${el.id}` : ''\n    const classAttr = el.getAttribute('class') || ''\n    const cls = classAttr ? `.${classAttr.trim().replace(/\\s+/g, '.')}` : ''\n    return `<${tag}${id}${cls}>`\n}\n"],"names":["createImage","url","resolve","reject","img","css","strings","rest","blobToDataURL","blob","reader","_e","defaultDownloader","embedUrlRefs","str","downloader","urls","dataUrl","syncFormState","src","dst","srcFields","dstFields","i","s","d","si","di","ss","ds","_debugHIC","HtmlRenderer","__publicField","node","cssW","cssH","existing","entry","dpr","pxW","pxH","svg","oldLines","newLines","diffs","len","image","loadSvgAsImage","_a","e","styles","promise","collectAndInlinePageStyles","dataUrlCache","mirrorDiv","srcAll","dstAll","writeDynamicStateInline","injectCaretAndSelection","injectPageSelection","width","height","canvas","context","_dpr","clone","prepareClone","innerXml","wrapClone","pageStylesCss","style","BASELINE_CSS","dbg","canvasEl","cr","svgEl","freezeResolvedTextMetrics","inlineExternalImages","cloneXml","parentEl","parentClass","parentW","parentH","escapeXmlAttr","type","err","sheets","sheet","cssRules","r","res","combined","fetchAsDataUrl","pseudoRules","rewritePseudoClasses","PSEUDO_RE","PSEUDO_RE_TEST","out","collectRewrittenRules","rules","rule","newSelector","m","group","inner","condText","_b","animations","anim","timeMs","delayStr","adjustedDelaySec","MIRROR_PROPS","measureCharPosition","el","charIndex","cs","isInput","prop","text","before","textNode","marker","fontSize","lhParsed","lineHeight","rootSrc","rootDst","active","inputEl","t","selStart","selEnd","borderLeft","borderTop","offsetX","offsetY","contentOriginX","contentOriginY","clipLeft","clipRight","clipTop","clipBottom","pos","caretX","caretY","caret","startPos","endPos","scrollL","scrollT","left","right","top","highlight","lines","y","line","selection","range","savedTransform","savedTransformOrigin","rootRect","scaleX","scaleY","rects","rectData","v","cached","p","fr","root","imgs","abs","STATES","renderer","installed","getHtmlRenderer","savedDescriptors","globalListeners","parentOverrides","attributeObserver","installHtmlInCanvasPolyfill","options","prev","hasNative","force","uninstallHtmlInCanvasPolyfill","patchContext","patchWebGLContext","patchWebGPUQueue","patchCanvasElement","installGlobalListeners","scanAndObserve","state","teardownCanvasState","target","desc","handler","opts","resizeScratchCanvas","requireState","element","ensureState","computeElementTransform","drawTransform","sx","sy","S","Sinv","originParts","ox","oy","T_o","definePatchedProperty","drawElementImage","dx","dy","dw","dh","bitmap","cssSize","dwGrid","dhGrid","T_draw","texElementImage2D","level","internalformat","format","GPUQueue","copyElementImageToTexture","args","destination","source","getResizeScratchCanvas","ctx","w","h","getElementTransform","fn","c","schedulePaint","interceptCanvasChildAccessor","host","patchCanvasDOMMutations","patchParentNode","patchCanvasEventListeners","fromHost","origDesc","addChildToState","removeChildFromState","origAppendChild","origRemoveChild","origInsertBefore","ref","orig","MOUSE_EVENT_TYPES","origAdd","origRemove","hostListeners","listener","hostFn","descriptor","repositionAll","addGlobalListener","initAll","muts","added","createHost","children","dirty","observers","positionHost","attachHostListeners","moveChildrenToHost","attachObservers","markAllDirty","reason","onSelectionChange","sel","hasPageSelection","ancestorsUpTo","clearActive","stop","result","current","realChildren","resizeObs","mutationObs","any","n","obs","pseudoClasses","child","_caller","changed","rasterizeOne","ev","describeElement","tag","id","classAttr","cls"],"mappings":";;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsSA,eAAeA,GAAYC,GAAK;AAC5B,SAAO,IAAI,QAAQ,CAACC,GAASC,MAAW;AACpC,UAAMC,IAAM,IAAI,MAAK;AACrB,IAAAA,EAAI,SAAS,MAAMF,EAAQE,CAAG,GAC9BA,EAAI,UAAUD,GACdC,EAAI,cAAc,aAClBA,EAAI,WAAW,QACfA,EAAI,MAAMH;AAAA,EACd,CAAC;AACL;AAyRA,MAAMI,KAAM,CAACC,MAAYC,MAAS,OAAO,IAAI,EAAE,KAAKD,KAAW,GAAGC,CAAI;AAmGtE,eAAeC,GAAcC,GAAM;AAC/B,SAAO,IAAI,QAAQ,CAACP,GAASC,MAAW;AACpC,UAAMO,IAAS,IAAI,WAAU;AAC7B,IAAAA,EAAO,SAAS,CAAAC,MAAMT,EAAQQ,EAAO,MAAM,GAC3CA,EAAO,UAAU,CAAAC,MAAMR,EAAOO,EAAO,KAAK,GAC1CA,EAAO,UAAU,CAAAC,MAAMR,EAAO,IAAI,MAAM,cAAc,CAAC,GACvDO,EAAO,cAAcD,CAAI;AAAA,EAC7B,CAAC;AACL;AAgoCA,MAAMG,KAAoB,OAAOX,MAAQO,GAAc,OAAO,MAAM,MAAMP,CAAG,GAAG,MAAM;AAQtF,eAAeY,GAAaC,GAAKC,IAAaH,IAAmB;AAC7D,QAAMI,IAAOF,EAAI,MAAM,gDAAgD;AACvE,MAAIE;AACA,eAAWf,KAAOe,GAAM;AACpB,YAAMC,IAAU,MAAMF,EAAWd,CAAG;AACpC,MAAAa,IAAMA,EAAI,QAAQb,GAAKgB,CAAO;AAAA,IAClC;AAEJ,SAAOH;AACX;ACp0DO,SAASI,GAAcC,GAAkBC,GAAkB;AAC9D,QAAMC,IAAYF,EAAI,iBAAiB,iCAAiC,GAClEG,IAAYF,EAAI,iBAAiB,iCAAiC;AACxE,MAAIC,EAAU,WAAWC,EAAU;AAEnC,aAASC,IAAI,GAAGA,IAAIF,EAAU,QAAQE,KAAK;AACvC,YAAMC,IAAIH,EAAUE,CAAC,GACfE,IAAIH,EAAUC,CAAC;AACrB,cAAQC,EAAE,SAAA;AAAA,QACN,KAAK,SAAS;AACV,gBAAME,IAAKF,GACLG,IAAKF;AACX,UAAIC,EAAG,SAAS,cAAcA,EAAG,SAAS,UAClCA,EAAG,UAASC,EAAG,aAAa,WAAW,EAAE,IACxCA,EAAG,gBAAgB,SAAS,IAEjCA,EAAG,aAAa,SAASD,EAAG,KAAK;AAErC;AAAA,QACJ;AAAA,QACA,KAAK;AACC,UAAAD,EAA0B,cAAeD,EAA0B;AACrE;AAAA,QACJ,KAAK,UAAU;AACX,gBAAMI,IAAKJ,GACLK,IAAKJ;AACX,UAAAI,EAAG,gBAAgBD,EAAG;AACtB;AAAA,QACJ;AAAA,QACA,KAAK;AACD,UAAKJ,EAAwB,WAAUC,EAAE,aAAa,YAAY,EAAE,IAC/DA,EAAE,gBAAgB,UAAU;AACjC;AAAA,MAAA;AAAA,IAEZ;AACJ;AChCA,MAAMK,IAAY,OAAO,WAAa,OAAe,IAAI,gBAAgB,SAAS,MAAM,EAAE,IAAI,kBAAkB;AAEzG,MAAMC,GAAa;AAAA,EAAnB;AACH,IAAAC,EAAA,oBAAa,OAAO,SAAW,OAAe,OAAO,oBAAoB;AAEjE,IAAAA,EAAA,oBAAa;AACb,IAAAA,EAAA,qCAAc,IAAA;AACd,IAAAA,EAAA,8BAA+C;AA+F9C,IAAAA,EAAA,uBAAgB3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA7FzB,MAAM,OAAO4B,GAA+C;AACxD,UAAMC,IAAOD,EAAK,eAAeA,EAAK,aAChCE,IAAOF,EAAK,gBAAgBA,EAAK;AACvC,QAAIC,MAAS,KAAKC,MAAS,GAAG;AAC1B,YAAMC,IAAW,KAAK,QAAQ,IAAIH,CAAI;AACtC,aAAIG,IAAiBA,EAAS,SACvB,KAAK,YAAYH,GAAM,GAAG,CAAC,EAAE;AAAA,IACxC;AAEA,UAAMI,IAAQ,KAAK,YAAYJ,GAAMC,GAAMC,CAAI,GACzCG,IAAM,KAAK,IAAI,GAAG,KAAK,UAAU,GACjCC,IAAMF,EAAM,OAAO,OACnBG,IAAMH,EAAM,OAAO,QACnBI,IAAM,MAAM,KAAK,SAASR,GAAMC,GAAMC,GAAMG,CAAG;AAErD,QAAIG,MAAQJ,EAAM;AACd,aAAIP,KACA,QAAQ,IAAI,0DAA0D,GACnEO,EAAM;AAEjB,QAAIP,KAAaO,EAAM,SAAS;AAC5B,YAAMK,IAAWL,EAAM,QAAQ,MAAM,GAAG,GAClCM,IAAWF,EAAI,MAAM,GAAG,GACxBG,IAAkB,CAAA,GAClBC,IAAM,KAAK,IAAIH,EAAS,QAAQC,EAAS,MAAM;AACrD,eAASpB,IAAI,GAAGA,IAAIsB,GAAKtB;AAKrB,YAJImB,EAASnB,CAAC,MAAMoB,EAASpB,CAAC,MAC1BqB,EAAM,KAAK,QAAQF,EAASnB,CAAC,KAAK,IAAI,MAAM,GAAG,GAAG,CAAC,EAAE,GACrDqB,EAAM,KAAK,QAAQD,EAASpB,CAAC,KAAK,IAAI,MAAM,GAAG,GAAG,CAAC,EAAE,IAErDqB,EAAM,SAAS,IAAI;AAAE,UAAAA,EAAM,KAAK,OAAO;AAAG;AAAA,QAAM;AAExD,cAAQ,IAAI;AAAA,IAA0CA,EAAM,KAAK;AAAA,CAAI,CAAC;AAAA,IAC1E;AACA,IAAAP,EAAM,UAAUI;AAEhB,UAAMK,IAAQ,MAAMC,GAAeN,GAAKF,GAAKC,CAAG;AAChD,WAAAH,EAAM,QAAQ,UAAU,GAAG,GAAGE,GAAKC,CAAG,GACtCH,EAAM,QAAQ,UAAUS,GAAO,GAAG,GAAGP,GAAKC,CAAG,GACtCH,EAAM;AAAA,EACjB;AAAA,EAEA,UAAUJ,GAA6C;;AACnD,aAAOe,IAAA,KAAK,QAAQ,IAAIf,CAAI,MAArB,gBAAAe,EAAwB,WAAU;AAAA,EAC7C;AAAA,EAEA,WAAWf,GAA6D;AACpE,UAAMgB,IAAI,KAAK,QAAQ,IAAIhB,CAAI;AAC/B,WAAOgB,IAAI,EAAC,OAAOA,EAAE,MAAM,QAAQA,EAAE,SAAQ;AAAA,EACjD;AAAA,EAEA,cAAcC,GAAgB;AAC1B,SAAK,aAAaA;AAAA,EACtB;AAAA,EAEA,MAAM,mBAAoC;AACtC,QAAI,CAAC,KAAK,sBAAsB;AAC5B,YAAMC,IAAUC,GAAA;AAChB,WAAK,uBAAuBD,GAC5BA,EAAQ,MAAM,MAAM;AAChB,QAAI,KAAK,yBAAyBA,MAC9B,KAAK,uBAAuB;AAAA,MAEpC,CAAC;AAAA,IACL;AACA,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,0BAA0B;AACtB,SAAK,uBAAuB;AAAA,EAChC;AAAA,EAEA,UAAU;AACN,SAAK,QAAQ,MAAA,GACb,KAAK,uBAAuB,MAC5BE,EAAa,MAAA,GACTC,MACAA,EAAU,OAAA,GACVA,IAAY;AAAA,EAEpB;AAAA,EAEA,2BAA2BnC,GAAkBC,GAAkB;AAC3D,UAAMmC,IAAS,CAACpC,GAAK,GAAGA,EAAI,iBAA8B,GAAG,CAAC,GACxDqC,IAAS,CAACpC,GAAK,GAAGA,EAAI,iBAA8B,GAAG,CAAC;AAC9D,QAAImC,EAAO,WAAWC,EAAO,QAC7B;AAAA,eAAS,IAAI,GAAG,IAAID,EAAO,QAAQ;AAC/B,QAAAE,GAAwBF,EAAO,CAAC,GAAGC,EAAO,CAAC,CAAC;AAEhD,MAAAE,GAAwBvC,GAAKC,CAAG,GAChCuC,GAAoBxC,GAAKC,CAAG;AAAA;AAAA,EAChC;AAAA,EAcQ,YAAYa,GAAmBC,GAAcC,GAA6B;AAC9E,UAAMG,IAAM,KAAK,IAAI,GAAG,KAAK,UAAU,GACjCsB,IAAQ,KAAK,IAAI,GAAG,KAAK,KAAK1B,IAAOI,CAAG,CAAC,GACzCuB,IAAS,KAAK,IAAI,GAAG,KAAK,KAAK1B,IAAOG,CAAG,CAAC;AAChD,QAAID,IAAQ,KAAK,QAAQ,IAAIJ,CAAI;AACjC,QAAKI;AAQD,OAAIA,EAAM,OAAO,UAAUuB,KAASvB,EAAM,OAAO,WAAWwB,OACxDxB,EAAM,OAAO,QAAQuB,GACrBvB,EAAM,OAAO,SAASwB,IAE1BxB,EAAM,OAAOH,GACbG,EAAM,OAAOF;AAAA,SAbL;AACR,YAAM2B,IAAS,SAAS,cAAc,QAAQ;AAC9C,MAAAA,EAAO,QAAQF,GACfE,EAAO,SAASD;AAChB,YAAME,IAAUD,EAAO,WAAW,IAAI;AACtC,MAAAzB,IAAQ,EAAC,QAAAyB,GAAQ,SAAAC,GAAS,MAAA7B,GAAM,MAAAC,EAAA,GAChC,KAAK,QAAQ,IAAIF,GAAMI,CAAK;AAAA,IAChC;AAQA,WAAOA;AAAA,EACX;AAAA,EAEA,MAAc,SAASJ,GAAmBC,GAAcC,GAAc6B,IAAO,GAAoB;AAC7F,UAAMC,IAAQ,MAAMC,GAAajC,CAAI;AACrC,SAAK,2BAA2BA,GAAMgC,CAAK;AAC3C,UAAME,IAAWC,GAAUnC,GAAM,IAAI,gBAAgB,kBAAkBgC,CAAK,CAAC,GAEvEI,IAAgB,MAAM,KAAK,iBAAA,GAC3BC,IAAQC,KAAe;AAAA,IAAOF,IAAgB;AAAA,IAAO,KAAK,aAAa;AAAA,IAAO,KAAK,eAEnF5B,IACF,kDACWP,CAAI,aAAaC,CAAI,kBAAkBD,CAAI,IAAIC,CAAI,qBAC3CmC,EAAM,QAAQ,QAAQ,iBAAiB,CAAC,oEACFH,CAAQ;AAGrE,QAAIrC,GAAW;AACX,UAAI0C,IAAM,SAAS,eAAe,mBAAmB;AACrD,MAAKA,MACDA,IAAM,SAAS,cAAc,KAAK,GAClCA,EAAI,KAAK,qBACTA,EAAI,MAAM,UAAU,yIACpB,SAAS,KAAK,YAAYA,CAAG;AAEjC,YAAMC,IAAW,SAAS,cAAc,QAAQ;AAChD,UAAIA,GAAU;AACV,cAAMC,IAAKD,EAAS,sBAAA;AACpB,QAAAD,EAAI,MAAM,OAAQE,EAAG,OAAO,OAAO,UAAW,MAC9CF,EAAI,MAAM,MAAOE,EAAG,MAAM,OAAO,UAAW,MAC5CF,EAAI,MAAM,QAAQE,EAAG,QAAQ,MAC7BF,EAAI,MAAM,SAASE,EAAG,SAAS;AAAA,MACnC;AACA,UAAI,CAACF,EAAI,WAAW;AAChB,QAAAA,EAAI,YAAY/B;AAChB,cAAMkC,IAAQH,EAAI,cAAc,KAAK;AACrC,QAAIG,MAASA,EAAM,MAAM,QAAQ,QAAQA,EAAM,MAAM,SAAS;AAAA,MAClE;AAAA,IACJ;AACA,WAAOlC;AAAA,EAEX;AACJ;AAUA,eAAeyB,GAAajC,GAAyC;AACjE,QAAMgC,IAAQhC,EAAK,UAAU,EAAI;AACjC,SAAAf,GAAce,GAAMgC,CAAK,GACzBW,GAA0B3C,GAAMgC,CAAK,GACrCA,EAAM,MAAM,eAAe,WAAW,GACtCA,EAAM,MAAM,UAAU,KACtBA,EAAM,MAAM,aAAa,WACzB,MAAMY,GAAqBZ,CAAK,GAChCA,EAAM,aAAa,SAAS,8BAA8B,GACnDA;AACX;AAEA,SAASG,GAAUnC,GAAmB6C,GAA0B;AAC5D,QAAMC,IAAW9C,EAAK,eAChB+C,KAAcD,KAAA,gBAAAA,EAAU,aAAa,aAAY,IACjDE,KAAUF,KAAA,gBAAAA,EAAU,gBAAe9C,EAAK,eAAeA,EAAK,aAC5DiD,KAAUH,KAAA,gBAAAA,EAAU,iBAAgB9C,EAAK,gBAAgBA,EAAK;AAQpE,SACI,kLALA,4CAFc+C,IAAc,WAAWG,GAAcH,CAAW,CAAC,MAAM,EAElB,mCAClBC,CAAO,aAAaC,CAAO,6BAM/CJ,IALG,WAMlB;AAER;AAEA,eAAe/B,GAAeN,GAAaP,GAAcC,GAAyC;AAC9F,QAAMlB,IAAU,sCAAsC,mBAAmBwB,CAAG;AAC5E,MAAI;AACA,WAAO,MAAMzC,GAAYiB,CAAO;AAAA,EACpC,SAASgC,GAAG;AACR,UAAMmC,IAAQnC,KAAK,OAAOA,KAAM,YAAY,UAAWA,IAAcA,EAAU,OAAO,OAAOA,GACvFoC,IAAM,IAAI;AAAA,MACZ,2CAA2CD,CAAI,WACvClD,CAAI,UAAUC,CAAI,gBAAgBM,EAAI,MAAM,eACvCA,EAAI,MAAM,GAAG,GAAG,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAAA,IAAA;AAErD,UAAA4C,EAAY,QAAQpC,GACpBoC,EAAY,MAAM5C,GACd4C;AAAA,EACV;AACJ;AAEA,eAAejC,KAA8C;AACzD,QAAMkC,IAAmB,CAAA;AAEzB,aAAWC,KAAS,MAAM,KAAK,SAAS,WAAW;AAC/C,QAAI;AACA,YAAMC,IAAW,MAAM,KAAKD,EAAM,YAAY,CAAA,CAAE;AAChD,MAAAD,EAAO,KAAKE,EAAS,IAAI,CAAAC,MAAKA,EAAE,OAAO,EAAE,KAAK;AAAA,CAAI,CAAC;AAAA,IACvD,QAAQ;AACJ,UAAI,CAACF,EAAM,KAAM;AACjB,UAAI;AACA,cAAMG,IAAM,MAAM,MAAMH,EAAM,IAAI;AAClC,QAAIG,EAAI,MAAIJ,EAAO,KAAK,MAAMI,EAAI,MAAM;AAAA,MAC5C,SAASzC,GAAG;AACR,gBAAQ,KAAK,6CAA6CsC,EAAM,MAAMtC,CAAC;AAAA,MAC3E;AAAA,IACJ;AAGJ,MAAIqC,EAAO,WAAW,EAAG,QAAO;AAEhC,MAAIK;AACJ,MAAI;AACA,IAAAA,IAAW,MAAM9E,GAAayE,EAAO,KAAK;AAAA,CAAI,GAAG,OAAOrF,MAAQ;AAE5D,UAAIA,EAAI,WAAW,oBAAoB,EAAG,QAAOA;AACjD,UAAI;AAAE,eAAO,MAAM2F,EAAe3F,CAAG;AAAA,MAAE,QACjC;AAAE,eAAOA;AAAA,MAAI;AAAA,IACvB,CAAC;AAAA,EACL,SAASgD,GAAG;AACR,YAAQ,KAAK,uCAAuCA,CAAC,GACrD0C,IAAWL,EAAO,KAAK;AAAA,CAAI;AAAA,EAC/B;AAEA,QAAMO,IAAcC,GAAqBH,CAAQ;AACjD,SAAOE,IAAcF,IAAW;AAAA,IAAOE,IAAcF;AACzD;AAEA,MAAMpB,KAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GA4BfwB,KAAY,8DACZC,KAAiB;AAEvB,SAASF,GAAqBzF,GAAqB;AAC/C,MAAIkF;AACJ,MAAI;AACA,IAAAA,IAAQ,IAAI,cAAA,GACZA,EAAM,YAAYlF,CAAG;AAAA,EACzB,QAAQ;AACJ,WAAO;AAAA,EACX;AACA,QAAM4F,IAAgB,CAAA;AACtB,SAAAC,EAAsBX,EAAM,UAAUU,CAAG,GAClCA,EAAI,KAAK;AAAA,CAAI;AACxB;AAEA,SAASC,EAAsBC,GAAoBF,GAAqB;;AACpE,WAAS1E,IAAI,GAAGA,IAAI4E,EAAM,QAAQ5E,KAAK;AACnC,UAAM6E,IAAOD,EAAM5E,CAAC;AACpB,QAAI6E,aAAgB;AAChB,UAAIJ,GAAe,KAAKI,EAAK,YAAY,GAAG;AACxC,cAAMC,IAAcD,EAAK,aAAa;AAAA,UAAQL;AAAA,UAAW,CAAAO,MACrD,aAAaA,EAAE,MAAM,CAAC;AAAA,QAAA;AAE1B,QAAAL,EAAI,KAAK,GAAGI,CAAW,MAAMD,EAAK,MAAM,OAAO,IAAI;AAAA,MACvD;AAAA,eACO,cAAcA,GAAM;AAC3B,YAAMG,IAAQH,GACRI,IAAkB,CAAA;AAExB,UADAN,EAAsBK,EAAM,UAAUC,CAAK,GACvCA,EAAM,QAAQ;AACd,YAAIC,IAAW;AACf,QAAIL,aAAgB,eAAcK,IAAW,UAAUL,EAAK,aAAa,KAChEA,aAAgB,kBAAiBK,IAAW,aAAaL,EAAK,aAAa,KAC/EK,MAAYC,KAAA1D,IAAAoD,EAAa,YAAb,gBAAApD,EAAsB,MAAM,KAAK,OAAjC,gBAAA0D,EAAqC,WAAU,IAC5DD,KAAUR,EAAI,KAAK,GAAGQ,CAAQ;AAAA,EAAOD,EAAM,KAAK;AAAA,CAAI,CAAC;AAAA,EAAK;AAAA,MAClE;AAAA,IACJ;AAAA,EACJ;AACJ;AAEA,SAASrB,GAAc3D,GAAmB;AACtC,SAAOA,EACF,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM;AAC7B;AAEA,SAASiC,GAAwBtC,GAAkBC,GAAkB;AACjE,GAAID,EAAI,eAAe,KAAKA,EAAI,cAAc,OAC1CC,EAAI,MAAM,YAAY,iBAAiB,CAACD,EAAI,aAAa,IAAI,GAC7DC,EAAI,MAAM,YAAY,gBAAgB,CAACD,EAAI,YAAY,IAAI;AAG/D,QAAMwF,IAAaxF,EAAI,cAAA;AACvB,MAAIwF,EAAW,WAAW,EAAG;AAC7B,QAAMC,IAAOD,EAAW,CAAC,GACnBE,IAAS,OAAOD,EAAK,eAAgB,WAAWA,EAAK,cAAc,GACnEE,IAAW,iBAAiB3F,CAAG,EAAE,gBAIjC4F,MAHWD,EAAS,SAAS,IAAI,IACjC,WAAWA,CAAQ,IAAI,MACvB,WAAWA,CAAQ,MACa,KAAKD,IAAS;AACpD,EAAAzF,EAAI,MAAM,YAAY,qBAAqB2F,IAAmB,GAAG;AACrE;AAEA,MAAMC,KAAe;AAAA,EACjB;AAAA,EAAc;AAAA,EAAY;AAAA,EAAc;AAAA,EAAa;AAAA,EACrD;AAAA,EAAc;AAAA,EAAiB;AAAA,EAAe;AAAA,EAAc;AAAA,EAC5D;AAAA,EAAc;AAAA,EAAY;AAAA,EAAgB;AAAA,EAC1C;AAAA,EAAc;AAAA,EAAgB;AAAA,EAAiB;AAAA,EAC/C;AAAA,EAAkB;AAAA,EAAoB;AAAA,EAAqB;AAAA,EAC3D;AAAA,EAAa;AAAA,EAAS;AAAA,EAAa;AACvC;AAEA,IAAI1D,IAAmC;AAGvC,SAAS2D,EACLC,GACAC,GACsC;AACtC,EAAK7D,MACDA,IAAY,SAAS,cAAc,KAAK,GACxCA,EAAU,MAAM,UAAU,iFAC1B,SAAS,KAAK,YAAYA,CAAS;AAGvC,QAAM8D,IAAK,iBAAiBF,CAAE,GACxBG,IAAUH,aAAc;AAG9B,aAAWI,KAAQN,GAAc,CAAA1D,EAAU,MAAMgE,CAAW,IAAIF,EAAGE,CAAW;AAC9E,EAAAhE,EAAU,MAAM,aAAa+D,IAAU,QAAQD,EAAG,YAClD9D,EAAU,MAAM,SAAS,QACzBA,EAAU,MAAM,YAAY;AAE5B,QAAMiE,IAAOL,EAAG,OACVM,IAASD,EAAK,UAAU,GAAGJ,CAAS;AAG1C,EAAA7D,EAAU,cAAc;AACxB,QAAMmE,IAAW,SAAS,eAAeD,CAAM,GACzCE,IAAS,SAAS,cAAc,MAAM;AAC5C,EAAAA,EAAO,cAAc,KACrBpE,EAAU,YAAYmE,CAAQ,GAC9BnE,EAAU,YAAYoE,CAAM,GAE5BpE,EAAU,YAAY,SAAS,eAAeiE,EAAK,UAAUJ,CAAS,KAAK,GAAG,CAAC;AAE/E,QAAMQ,IAAW,WAAWP,EAAG,QAAQ,GACjCQ,IAAW,WAAWR,EAAG,UAAU,GACnCS,IAAa,MAAMD,CAAQ,IAAID,IAAW,MAC1CP,EAAG,WAAW,SAAS,IAAI,IAAIQ,IAC/BA,IAAWD;AAEjB,SAAO;AAAA,IACH,GAAGD,EAAO;AAAA,IACV,GAAGA,EAAO;AAAA,IACV,QAAQG;AAAA,EAAA;AAEhB;AAEA,SAASnE,GAAwBoE,GAAsBC,GAAsB;AACzE,QAAMC,IAAS,SAAS;AACxB,MAAI,CAACA,EAAQ;AAEb,MAAIC;AACJ,MAAID,aAAkB,kBAAkB;AACpC,UAAME,IAAIF,EAAO;AACjB,QAAIE,MAAM,UAAUA,MAAM,YAAYA,MAAM,SAASA,MAAM,SAASA,MAAM,cAAcA,MAAM,GAAI;AAClG,IAAAD,IAAUD;AAAA,EACd,WAAWA,aAAkB;AACzB,IAAAC,IAAUD;AAAA;AAEV;AAGJ,MAAI,CAACF,EAAQ,SAASG,CAAO,EAAG;AAChC,QAAME,IAAWF,EAAQ,gBACnBG,IAASH,EAAQ;AACvB,MAAIE,MAAa,QAAQC,MAAW,KAAM;AAE1C,QAAMhB,IAAK,iBAAiBa,CAAO,GAC7BI,IAAa,WAAWjB,EAAG,eAAe,KAAK,GAC/CkB,IAAY,WAAWlB,EAAG,cAAc,KAAK;AAGnD,MAAImB,IAAU,GAAGC,IAAU,GACvBtB,IAAyBe;AAC7B,SAAOf,KAAMA,MAAOY;AAChB,IAAAS,KAAWrB,EAAG,YACdsB,KAAWtB,EAAG,WACdA,IAAKA,EAAG;AAGZ,QAAMuB,IAAiBF,IAAUF,GAC3BK,IAAiBF,IAAUF,GAG3BK,IAAWF,GACXG,IAAYD,IAAWV,EAAQ,aAC/BY,IAAUH,GACVI,IAAaD,IAAUZ,EAAQ;AAErC,MAAIE,MAAaC,GAAQ;AAErB,UAAMW,IAAM9B,EAAoBgB,GAASE,CAAQ,GAC3Ca,IAASP,IAAiBM,EAAI,IAAId,EAAQ,YAC1CgB,IAASP,IAAiBK,EAAI,IAAId,EAAQ;AAGhD,QADqB,KAAK,MAAM,KAAK,QAAQ,GAAG,IAAI,MAAM,KACtCe,KAAUL,KAAYK,KAAUJ,KAC7CK,KAAUJ,KAAWI,IAASF,EAAI,UAAUD,GAAY;AAC3D,YAAMI,IAAQ,SAAS,cAAc,KAAK;AAC1C,MAAAA,EAAM,aAAa,SAAS,8BAA8B,GAC1DA,EAAM,MAAM,UACR,8CACQF,CAAM,UAAUC,CAAM,uBACVF,EAAI,MAAM,+BAElChB,EAAQ,YAAYmB,CAAK;AAAA,IAC7B;AAAA,EACJ,OAAO;AAEH,UAAMC,IAAWlC,EAAoBgB,GAASE,CAAQ,GAChDiB,IAASnC,EAAoBgB,GAASG,CAAM,GAE5CP,IAAasB,EAAS,QACtBE,IAAUpB,EAAQ,YAClBqB,IAAUrB,EAAQ;AAExB,QAAIkB,EAAS,MAAMC,EAAO,GAAG;AAEzB,YAAMG,IAAO,KAAK,IAAId,IAAiBU,EAAS,IAAIE,GAASV,CAAQ,GAC/Da,IAAQ,KAAK,IAAIf,IAAiBW,EAAO,IAAIC,GAAST,CAAS,GAC/Da,IAAMf,IAAiBS,EAAS,IAAIG;AAC1C,UAAIE,IAAQD,KAAQE,KAAOZ,KAAWY,IAAM5B,KAAciB,GAAY;AAClE,cAAMY,IAAY,SAAS,cAAc,KAAK;AAC9C,QAAAA,EAAU,aAAa,SAAS,8BAA8B,GAC9DA,EAAU,MAAM,UACZ,8CACQH,CAAI,UAAUE,CAAG,YAChBD,IAAQD,CAAI,aAAa1B,CAAU,wCAEhDE,EAAQ,YAAY2B,CAAS;AAAA,MACjC;AAAA,IACJ,OAAO;AAEH,YAAMC,IAAsD,CAAA;AAE5D,MAAAA,EAAM,KAAK,EAAC,MAAMlB,IAAiBU,EAAS,IAAIE,GAAS,OAAOT,GAAW,KAAKF,IAAiBS,EAAS,IAAIG,GAAQ;AAEtH,eAASM,IAAIT,EAAS,IAAItB,GAAY+B,IAAIR,EAAO,GAAGQ,KAAK/B;AACrD,QAAA8B,EAAM,KAAK,EAAC,MAAMhB,GAAU,OAAOC,GAAW,KAAKF,IAAiBkB,IAAIN,EAAA,CAAQ;AAGpF,MAAAK,EAAM,KAAK,EAAC,MAAMhB,GAAU,OAAOF,IAAiBW,EAAO,IAAIC,GAAS,KAAKX,IAAiBU,EAAO,IAAIE,GAAQ;AAEjH,iBAAWO,KAAQF,GAAO;AACtB,cAAMJ,IAAO,KAAK,IAAIM,EAAK,MAAMlB,CAAQ,GACnCa,IAAQ,KAAK,IAAIK,EAAK,OAAOjB,CAAS;AAE5C,YADIY,KAASD,KACTM,EAAK,MAAMhC,IAAagB,KAAWgB,EAAK,MAAMf,EAAY;AAC9D,cAAMY,IAAY,SAAS,cAAc,KAAK;AAC9C,QAAAA,EAAU,aAAa,SAAS,8BAA8B,GAC9DA,EAAU,MAAM,UACZ,8CACQH,CAAI,UAAUM,EAAK,GAAG,YACrBL,IAAQD,CAAI,aAAa1B,CAAU,wCAEhDE,EAAQ,YAAY2B,CAAS;AAAA,MACjC;AAAA,IACJ;AAAA,EACJ;AACJ;AAEA,SAAS/F,GAAoBmE,GAAsBC,GAAsB;AACrE,QAAM+B,IAAY,OAAO,aAAA;AACzB,MAAI,CAACA,KAAaA,EAAU,eAAeA,EAAU,eAAe,EAAG;AAGvE,QAAMC,IAAQD,EAAU,WAAW,CAAC;AACpC,MAAI,CAAChC,EAAQ,SAASiC,EAAM,cAAc,KAAK,CAACjC,EAAQ,SAASiC,EAAM,YAAY,EAAG;AAItF,QAAMC,IAAiBlC,EAAQ,MAAM,WAC/BmC,IAAuBnC,EAAQ,MAAM;AAC3C,EAAAA,EAAQ,MAAM,YAAY,QAC1BA,EAAQ,MAAM,kBAAkB;AAEhC,QAAMoC,IAAWpC,EAAQ,sBAAA,GACnBqC,IAASrC,EAAQ,cAAcoC,EAAS,OACxCE,IAAStC,EAAQ,eAAeoC,EAAS,QAGzCtB,IAAYd,EAAQ,aACpBgB,IAAahB,EAAQ,cAErBuC,IAAQN,EAAM,eAAA,GAEdO,IAAyE,CAAA;AAC/E,WAAS/I,IAAI,GAAGA,IAAI8I,EAAM,QAAQ9I,KAAK;AACnC,UAAMkE,IAAI4E,EAAM9I,CAAC;AACjB,IAAA+I,EAAS,KAAK;AAAA,MACV,OAAO7E,EAAE,OAAOyE,EAAS,QAAQC,IAASrC,EAAQ;AAAA,MAClD,MAAMrC,EAAE,MAAMyE,EAAS,OAAOE,IAAStC,EAAQ;AAAA,MAC/C,OAAOrC,EAAE,QAAQ0E;AAAA,MACjB,QAAQ1E,EAAE,SAAS2E;AAAA,IAAA,CACtB;AAAA,EACL;AAGA,EAAAtC,EAAQ,MAAM,YAAYkC,GAC1BlC,EAAQ,MAAM,kBAAkBmC;AAEhC,WAAS1I,IAAI,GAAGA,IAAI+I,EAAS,QAAQ/I,KAAK;AACtC,QAAI,EAAC,MAAAgI,GAAM,KAAAE,GAAK,OAAA7F,GAAO,QAAAC,EAAA,IAAUyG,EAAS/I,CAAC;AAO3C,QAJIgI,IAAO,MAAK3F,KAAS2F,GAAMA,IAAO,IAClCE,IAAM,MAAK5F,KAAU4F,GAAKA,IAAM,IAChCF,IAAO3F,IAAQgF,MAAWhF,IAAQgF,IAAYW,IAC9CE,IAAM5F,IAASiF,MAAYjF,IAASiF,IAAaW,IACjD7F,KAAS,KAAKC,KAAU,EAAG;AAE/B,UAAM6F,IAAY,SAAS,cAAc,KAAK;AAC9C,IAAAA,EAAU,aAAa,SAAS,8BAA8B,GAC9DA,EAAU,MAAM,UACZ,8CACQH,CAAI,UAAUE,CAAG,YAChB7F,CAAK,aAAaC,CAAM,wCAErCkE,EAAQ,YAAY2B,CAAS;AAAA,EACjC;AACJ;AAEA,SAAS9E,GAA0BzD,GAAkBC,GAAkB;AACnE,QAAMmC,IAAS,CAACpC,GAAK,GAAGA,EAAI,iBAA8B,GAAG,CAAC,GACxDqC,IAAS,CAACpC,GAAK,GAAGA,EAAI,iBAA8B,GAAG,CAAC;AAC9D,MAAImC,EAAO,WAAWC,EAAO;AAC7B,aAASjC,IAAI,GAAGA,IAAIgC,EAAO,QAAQhC,KAAK;AACpC,YAAM6F,IAAK,iBAAiB7D,EAAOhC,CAAC,CAAC;AAGrC,iBAAW+F,KAAQ,CAAC,YAAY,cAAc,UAAU,aAAa,aAAa,aAAa,gBAAgB,cAAc,iBAAiB,kBAAkB,mBAAmB,GAAY;AAC3L,cAAMiD,IAAI,WAAWnD,EAAGE,CAAI,CAAC;AAC7B,QAAI,MAAMiD,CAAC,MACX/G,EAAOjC,CAAC,EAAE,MAAM+F,CAAI,IAAKiD,IAAI,MAAM,IAAK,KAAK,MAAMA,CAAC,IAAI,OAAOnD,EAAGE,CAAI;AAAA,MAC1E;AAAA,IACJ;AACJ;AAGA,MAAMjE,wBAAmB,IAAA;AAEzB,SAASuC,EAAe3F,GAA8B;AAClD,QAAMuK,IAASnH,EAAa,IAAIpD,CAAG;AACnC,MAAIuK,EAAQ,QAAOA;AACnB,QAAMC,IAAI,MAAMxK,CAAG,EACd,KAAK,CAAAwF,MAAK;AACP,QAAI,CAACA,EAAE,GAAI,OAAM,IAAI,MAAM,SAASxF,CAAG,MAAMwF,EAAE,MAAM,EAAE;AACvD,WAAOA,EAAE,KAAA;AAAA,EACb,CAAC,EACA,KAAK,CAAAhF,MAAQ,IAAI,QAAgB,CAACP,GAASC,MAAW;AACnD,UAAMuK,IAAK,IAAI,WAAA;AACf,IAAAA,EAAG,SAAS,MAAMxK,EAAQwK,EAAG,MAAgB,GAC7CA,EAAG,UAAU,MAAMvK,EAAOuK,EAAG,KAAK,GAClCA,EAAG,cAAcjK,CAAI;AAAA,EACzB,CAAC,CAAC;AACN,SAAA4C,EAAa,IAAIpD,GAAKwK,CAAC,GACvBA,EAAE,MAAM,MAAM;AACV,IAAIpH,EAAa,IAAIpD,CAAG,MAAMwK,KAAGpH,EAAa,OAAOpD,CAAG;AAAA,EAC5D,CAAC,GACMwK;AACX;AAEA,eAAe5F,GAAqB8F,GAAkC;AAClE,QAAMC,IAAO,MAAM,KAAKD,EAAK,iBAAiB,KAAK,CAAC;AACpD,QAAM,QAAQ,IAAIC,EAAK,IAAI,OAAMxK,MAAO;AACpC,UAAMe,IAAMf,EAAI,aAAa,KAAK;AAClC,QAAI,GAACe,KAAOA,EAAI,WAAW,OAAO;AAClC,UAAI;AACA,cAAM0J,IAAM,IAAI,IAAI1J,GAAK,SAAS,OAAO,EAAE;AAC3C,QAAAf,EAAI,aAAa,OAAO,MAAMwF,EAAeiF,CAAG,CAAC;AAAA,MACrD,SAAS5H,GAAG;AACR,gBAAQ,KAAK,uCAAuC9B,GAAK8B,CAAC,GAC1D7C,EAAI,gBAAgB,KAAK;AAAA,MAC7B;AAAA,EACJ,CAAC,CAAC;AACN;AC5nBA,MAAM0K,wBAAa,IAAA,GACbC,IAAW,IAAIhJ,GAAA;AACrB,IAAIiJ,IAAY;AAET,SAASC,KAAgC;AAC5C,SAAOF;AACX;AAEA,MAAMG,IAA4E,CAAA,GAC5EC,IAAmI,CAAA,GAGnIC,wBAAsB,QAAA;AAC5B,IAAIC,IAA6C;AAE1C,SAASC,GAA4BC,IAA2B,IAAI;AACvE,MAAIP,EAAW;AAGf,MAAK,OAAe,6BAA6B;AAC7C,UAAMQ,IAAQ,OAAe;AAC7B,QAAI,OAAOA,KAAS,WAAY,CAAAA,EAAA;AAAA,QAC3B;AAAA,EACT;AACA,QAAMC,IACF,sBAAsB,yBAAyB,aAC/C,kBAAkB,kBAAkB,aACpC,aAAa,kBAAkB,WAC7BC,IAAQH,EAAQ,SAAS,IAAI,gBAAgB,SAAS,MAAM,EAAE,IAAI,aAAa;AACrF,MAAIE,KAAa,CAACC,GAAO;AACrB,YAAQ,KAAK,2FAA2F;AACxG;AAAA,EACJ;AACA,EAAAV,IAAY,IACX,OAAe,8BAA8B,IAC7C,OAAe,oBAAoBW,IACpC,QAAQ,KAAK,yCAAyCD,IAAQ,cAAc,GAAG,GAE3EH,EAAQ,cAAYR,EAAS,cAAcQ,EAAQ,UAAU,GAEjEK,GAAA,GACAC,GAAA,GACAC,GAAA,GACAC,GAAA,GACAC,GAAA,GACAC,GAAA;AACJ;AAEO,SAASN,KAAgC;AAC5C,MAAKX,GAEL;AAAA,eAAWkB,KAAS,MAAM,KAAKpB,EAAO,OAAA,CAAQ;AAC1C,MAAAqB,GAAoBD,CAAK;AAE7B,IAAApB,EAAO,MAAA;AAEP,eAAW,CAACsB,GAAQ9E,GAAM+E,CAAI,KAAKnB;AAC/B,MAAImB,IAAM,OAAO,eAAeD,GAAQ9E,GAAM+E,CAAI,IAC7C,OAAQD,EAAe9E,CAAI;AAEpC,IAAA4D,EAAiB,SAAS;AAE1B,eAAW,CAACkB,GAAQhH,GAAMkH,GAASC,CAAI,KAAKpB;AACxC,MAAAiB,EAAO,oBAAoBhH,GAAMkH,GAAgBC,CAAW;AAEhE,IAAApB,EAAgB,SAAS,GAEzBE,KAAA,QAAAA,EAAmB,cACnBA,IAAoB,MAEpBmB,IAAsB,MACtBzB,EAAS,QAAA,GAETC,IAAY,IACX,OAAe,8BAA8B,IAC9C,OAAQ,OAAe;AAAA;AAC3B;AAEA,SAASyB,EAAa3I,GAA2B4I,GAAmC;AAChF,QAAMR,IAAQpB,EAAO,IAAIhH,CAAM,KAAK6I,EAAY7I,CAAM;AACtD,MAAI,CAACoI;AACD,UAAM,IAAI,aAAa,iCAAiC,mBAAmB;AAC/E,MAAI,CAACA,EAAM,SAAS,IAAIQ,CAAO;AAC3B,UAAM,IAAI,aAAa,+CAA+C,mBAAmB;AAC7F,SAAOR;AACX;AAGA,SAASU,EACL1F,GAAiB2F,GACjBC,GAAYC,GAAY7K,GAAcC,GAC7B;AACT,QAAM6K,IAAI,IAAI,UAAA,EAAY,MAAMF,GAAIC,CAAE,GAChCE,IAAO,IAAI,YAAY,MAAM,IAAIH,GAAI,IAAIC,CAAE,GAE3CG,IADK,iBAAiBhG,CAAE,EACP,gBAAgB,MAAM,GAAG,GAC1CiG,IAAK,WAAWD,EAAY,CAAC,CAAC,KAAKhL,IAAO,GAC1CkL,IAAK,WAAWF,EAAY,CAAC,CAAC,KAAK/K,IAAO,GAC1CkL,IAAM,IAAI,UAAA,EAAY,UAAUF,GAAIC,CAAE;AAE5C,SADa,IAAI,UAAA,EAAY,UAAU,CAACD,GAAI,CAACC,CAAE,EACnC,SAASH,CAAI,EAAE,SAASJ,CAAa,EAAE,SAASG,CAAC,EAAE,SAASK,CAAG;AAC/E;AAEA,SAASzB,KAAe;AACpB,EAAA0B,EAAsB,yBAAyB,WAAW,oBAAoB;AAAA,IAC1E,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAOC;AAAA,EAAA,CACV;AACL;AAEA,SAASA,GAELrG,GACAsG,GAAYC,GACZC,GAAaC,GACJ;AACT,QAAM7J,IAAS,KAAK;AACpB,EAAA2I,EAAa3I,GAAQoD,CAAE;AAEvB,QAAM0G,IAAS7C,EAAS,UAAU7D,CAAE,GAC9B2G,IAAU9C,EAAS,WAAW7D,CAAE;AACtC,MAAI,CAAC0G,KAAU,CAACC;AACZ,WAAO,IAAI,UAAA;AAEf,QAAM3L,IAAO2L,EAAQ,OACf1L,IAAO0L,EAAQ,QACff,IAAKhJ,EAAO,QAAQ,KAAK,IAAI,GAAGA,EAAO,WAAW,GAClDiJ,IAAKjJ,EAAO,SAAS,KAAK,IAAI,GAAGA,EAAO,YAAY,GAEpDgK,IAASJ,KAAOxL,IAAO4K,GACvBiB,IAASJ,KAAOxL,IAAO4K;AAE7B,OAAK,UAAUa,GAAQJ,GAAIC,GAAIK,GAAQC,CAAM;AAE7C,QAAMC,IAAS,KAAK,aAAA,EACf,UAAUR,GAAIC,CAAE,EAChB,MAAMK,KAAU5L,IAAO4K,IAAKiB,KAAU5L,IAAO4K,EAAG;AACrD,SAAOH,EAAwB1F,GAAI8G,GAAQlB,GAAIC,GAAI7K,GAAMC,CAAI;AACjE;AAEA,SAAS0J,KAAoB;AACzB,EAAI,OAAO,wBAA0B,OACjCyB,EAAsB,sBAAsB,WAAW,qBAAqB;AAAA,IACxE,cAAc;AAAA,IAAM,UAAU;AAAA,IAAM,OAAOW;AAAA,EAAA,CAC9C,GAED,OAAO,yBAA2B,OAClCX,EAAsB,uBAAuB,WAAW,qBAAqB;AAAA,IACzE,cAAc;AAAA,IAAM,UAAU;AAAA,IAAM,OAAOW;AAAA,EAAA,CAC9C;AAET;AAEA,SAASA,EAEL7B,GACA8B,GACAC,MACG5N,GACC;AACJ,MAAI6N,GAAgBhJ,GAAcsH;AAClC,MAAInM,EAAK,WAAW;AAChB,KAAC6N,GAAQhJ,GAAMsH,CAAO,IAAInM;AAAA,WACnBA,EAAK,WAAW;AACvB,YAAQ,KAAK,+HAA+H,GAC3I,CAAA,EAAA,EAAwB6N,GAAQhJ,GAAMsH,CAAO,IAAInM;AAAA,WAC3CA,EAAK,WAAW;AACvB,YAAQ,KAAK,oIAAoI,GAChJ,CAAA,EAAA,EAAA,EAAA,EAA0C6N,GAAQhJ,GAAMsH,CAAO,IAAInM;AAAA,WAC7DA,EAAK,WAAW;AACvB,YAAQ,KAAK,+JAA+J,GAC3K,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAiE6N,GAAQhJ,GAAMsH,CAAO,IAAInM;AAAA;AAE3F,UAAM,IAAI,UAAU,gDAAgD,IAAIA,EAAK,MAAM,EAAE;AAGzF,MAAI,EAAEmM,aAAmB;AACrB,UAAM,IAAI,UAAU,mDAAmD;AAG3E,QAAMkB,IAAS7C,EAAS,UAAU2B,CAAO;AACzC,MAAI,CAACkB;AACD,UAAM,IAAI;AAAA,MACN;AAAA,MAEA;AAAA,IAAA;AAIR,OAAK,WAAWxB,GAAQ8B,GAAOC,GAAgBC,GAAQhJ,GAAMwI,CAAM;AACvE;AAEA,SAAS9B,KAAmB;AACxB,QAAMuC,IAAY,WAAmB;AACrC,EAAI,CAACA,KAAY,CAACA,EAAS,aAC3Bf,EAAsBe,EAAS,WAAW,6BAA6B;AAAA,IACnE,cAAc;AAAA,IAAM,UAAU;AAAA,IAAM,OAAOC;AAAA,EAAA,CAC9C;AACL;AAEA,SAASA,MAEFC,GACC;AACJ,MAAI7B,GAAsB8B,GAAkB5K,GAAeC;AAC3D,MAAI0K,EAAK,WAAW;AAChB,KAAC7B,GAAS8B,CAAW,IAAID,GACzB3K,IAAQ,GACRC,IAAS;AAAA,WACF0K,EAAK,WAAW;AACvB,KAAC7B,GAAS9I,GAAOC,GAAQ2K,CAAW,IAAID;AAAA;AAExC,UAAM,IAAI;AAAA,MACN,wDAAwDA,EAAK,MAAM;AAAA,IAAA;AAI3E,MAAI,EAAE7B,aAAmB;AACrB,UAAM,IAAI,UAAU,0DAA0D;AAGlF,QAAMkB,IAAS7C,EAAS,UAAU2B,CAAO;AACzC,MAAI,CAACkB;AACD,UAAM,IAAI;AAAA,MACN;AAAA,MAEA;AAAA,IAAA;AAIR,EAAIhK,MAAU,MAAGA,IAAQgK,EAAO,QAC5B/J,MAAW,MAAGA,IAAS+J,EAAO;AAElC,MAAIa,IAA4Bb;AAChC,MAAIA,EAAO,UAAUhK,KAASgK,EAAO,WAAW/J,GAAQ;AACpD,IAAA4K,IAASC,GAAuB9K,GAAOC,CAAM;AAC7C,UAAM8K,IAAMF,EAAO,WAAW,IAAI;AAClC,IAAAE,EAAI,UAAU,GAAG,GAAG/K,GAAOC,CAAM,GACjC8K,EAAI,wBAAwB,IAC5BA,EAAI,wBAAwB,QAC5BA,EAAI,UAAUf,GAAQ,GAAG,GAAGhK,GAAOC,CAAM;AAAA,EAC7C;AAEA,OAAK;AAAA,IACD,EAAC,QAAA4K,EAAA;AAAA,IACDD;AAAA,IACA,CAAC5K,GAAOC,CAAM;AAAA,EAAA;AAEtB;AAEA,IAAI2I,IAAgD;AACpD,SAASkC,GAAuBE,GAAWC,GAA8B;AACrE,SAAKrC,MAAqBA,IAAsB,SAAS,cAAc,QAAQ,IAC3EA,EAAoB,UAAUoC,MAAGpC,EAAoB,QAAQoC,IAC7DpC,EAAoB,WAAWqC,MAAGrC,EAAoB,SAASqC,IAC5DrC;AACX;AAOA,SAASsC,GAELpC,GACAG,GACS;AACT,QAAM/I,IAAS;AACf,EAAA2I,EAAa3I,GAAQ4I,CAAO;AAE5B,QAAMmB,IAAU9C,EAAS,WAAW2B,CAAO;AAC3C,MAAI,CAACmB;AACD,UAAM,IAAI,aAAa,4BAA4B,mBAAmB;AAE1E,QAAMf,IAAKhJ,EAAO,QAAQ,KAAK,IAAI,GAAGA,EAAO,WAAW,GAClDiJ,IAAKjJ,EAAO,SAAS,KAAK,IAAI,GAAGA,EAAO,YAAY;AAC1D,SAAO8I,EAAwBF,GAASG,GAAeC,GAAIC,GAAIc,EAAQ,OAAOA,EAAQ,MAAM;AAChG;AAEA,SAAS9B,KAAqB;AAC1B,EAAAuB,EAAsB,kBAAkB,WAAW,iBAAiB;AAAA,IAChE,cAAc;AAAA,IACd,MAA6B;AAAE,aAAO,KAAK,aAAa,eAAe;AAAA,IAAE;AAAA,IACzE,IAA6B/C,GAAY;AACrC,MAAIA,IAAG,KAAK,aAAa,iBAAiB,EAAE,IACvC,KAAK,gBAAgB,eAAe;AAAA,IAC7C;AAAA,EAAA,CACH,GAED+C,EAAsB,kBAAkB,WAAW,WAAW;AAAA,IAC1D,cAAc;AAAA,IACd,MAA6B;;AAAE,eAAOtK,IAAA8H,EAAO,IAAI,IAAI,MAAf,gBAAA9H,EAAkB,YAAW;AAAA,IAAK;AAAA,IACxE,IAA6B+L,GAAiC;AAC1D,YAAMvN,IAAImL,EAAY,IAAI;AAC1B,MAAInL,IACAA,EAAE,UAAUuN,IACLA,KACP,QAAQ;AAAA,QACJ;AAAA,MAAA;AAAA,IAKZ;AAAA,EAAA,CACH,GAEDzB,EAAsB,kBAAkB,WAAW,gBAAgB;AAAA,IAC/D,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO,WAAmC;AACtC,YAAM9L,IAAImL,EAAY,IAAI;AAC1B,UAAKnL,GACL;AAAA,mBAAWwN,KAAKxN,EAAE,SAAU,CAAAA,EAAE,MAAM,IAAIwN,CAAC;AACzC,QAAAC,EAAczN,GAAG,cAAc;AAAA;AAAA,IACnC;AAAA,EAAA,CACH,GAED8L,EAAsB,kBAAkB,WAAW,uBAAuB;AAAA,IACtE,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAOwB;AAAA,EAAA,CACV,GAEDxB,EAAsB,kBAAkB,WAAW,uBAAuB;AAAA,IACtE,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO,SAAmCZ,GAAsB;AAC5D,MAAAD,EAAa,MAAMC,CAAO;AAC1B,YAAM5I,IAASiH,EAAS,UAAU2B,CAAO;AACzC,UAAI,CAAC5I;AACD,cAAM,IAAI,aAAa,4BAA4B,mBAAmB;AAC1E,aAAOA;AAAA,IACX;AAAA,EAAA,CACH,GAEDoL,EAA6B,YAAY,CAAAC,MAAQA,EAAK,QAAQ,GAC9DD,EAA6B,qBAAqB,CAAAC,MAAQA,EAAK,iBAAiB,GAChFD,EAA6B,oBAAoB,CAAAC,MAAQA,EAAK,gBAAgB,GAC9ED,EAA6B,qBAAqB,CAAAC,MAAQA,EAAK,iBAAiB,GAEhFC,GAAA,GACAC,GAAA,GACAC,GAAA;AACJ;AAEA,SAASJ,EACL5H,GACAiI,GACF;AACE,QAAMC,IAAW,OAAO,yBAAyB,QAAQ,WAAWlI,CAAI;AACxE,EAAAgG,EAAsB,kBAAkB,WAAWhG,GAAgB;AAAA,IAC/D,cAAc;AAAA,IACd,MAA6B;AACzB,YAAM9F,IAAIsJ,EAAO,IAAI,IAAI;AACzB,aAAItJ,KAAK,KAAK,aAAa,eAAe,IAAU+N,EAAS/N,EAAE,IAAI,IAC5DgO,EAAS,IAAK,KAAK,IAAI;AAAA,IAClC;AAAA,EAAA,CACH;AACL;AAEA,SAASC,EAAgBvD,GAAoBhF,GAAiBM,GAAsB;AAChF,EAAI0E,EAAM,SAAS,IAAIhF,CAAE,MACrBM,IAAQ0E,EAAM,KAAK,aAAahF,GAAIM,CAAM,IACzC0E,EAAM,KAAK,YAAYhF,CAAE,GAC9BA,EAAG,MAAM,WAAW,YACpBA,EAAG,MAAM,OAAO,KAChBA,EAAG,MAAM,MAAM,KACfA,EAAG,MAAM,UAAU,KACnBA,EAAG,MAAM,gBAAgB,QACzBgF,EAAM,SAAS,IAAIhF,CAAE,GACrBgF,EAAM,MAAM,IAAIhF,CAAE,GAClBkE,EAAgB,IAAIlE,GAAIgF,EAAM,MAAM,GACpC+C,EAAc/C,GAAO,iBAAiB;AAC1C;AAEA,SAASwD,GAAqBxD,GAAoBhF,GAAiB;AAC/D,SAAKgF,EAAM,SAAS,IAAIhF,CAAE,KAC1BgF,EAAM,KAAK,YAAYhF,CAAE,GACzBgF,EAAM,SAAS,OAAOhF,CAAE,GACxBgF,EAAM,MAAM,OAAOhF,CAAE,GACrBkE,EAAgB,OAAOlE,CAAE,GACzBA,EAAG,MAAM,eAAe,UAAU,GAClCA,EAAG,MAAM,eAAe,MAAM,GAC9BA,EAAG,MAAM,eAAe,KAAK,GAC7BA,EAAG,MAAM,eAAe,SAAS,GACjCA,EAAG,MAAM,eAAe,gBAAgB,GACxCA,EAAG,MAAM,eAAe,kBAAkB,GACnC,MAX6B;AAYxC;AAEA,SAASkI,KAA0B;AAC/B,QAAMO,IAAkB,KAAK,UAAU;AACvC,EAAArC,EAAsB,kBAAkB,WAAW,eAAe;AAAA,IAC9D,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO,SAAmDrL,GAAY;AAClE,YAAM,IAAI6I,EAAO,IAAI,IAAI;AACzB,aAAI,KAAK,KAAK,aAAa,eAAe,KAAK7I,aAAgB,eAC3DwN,EAAgB,GAAGxN,CAAI,GAChBA,KAEJ0N,EAAgB,KAAK,MAAM1N,CAAI;AAAA,IAC1C;AAAA,EAAA,CACH;AAED,QAAM2N,IAAkB,KAAK,UAAU;AACvC,EAAAtC,EAAsB,kBAAkB,WAAW,eAAe;AAAA,IAC9D,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO,SAAmDrL,GAAY;AAClE,YAAM,IAAI6I,EAAO,IAAI,IAAI;AACzB,aAAI,KAAK7I,aAAgB,eAAeyN,GAAqB,GAAGzN,CAAI,IACzDA,IAEJ2N,EAAgB,KAAK,MAAM3N,CAAI;AAAA,IAC1C;AAAA,EAAA,CACH;AAED,QAAM4N,IAAmB,KAAK,UAAU;AACxC,EAAAvC,EAAsB,kBAAkB,WAAW,gBAAgB;AAAA,IAC/D,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO,SAAmDrL,GAAS6N,GAAqB;AACpF,YAAMtO,IAAIsJ,EAAO,IAAI,IAAI;AACzB,aAAItJ,KAAK,KAAK,aAAa,eAAe,KAAKS,aAAgB,eAC3DwN,EAAgBjO,GAAGS,GAAM6N,CAAG,GACrB7N,KAEJ4N,EAAiB,KAAK,MAAM5N,GAAM6N,CAAG;AAAA,IAChD;AAAA,EAAA,CACH,GAEDxC,EAAsB,kBAAkB,WAAW,YAAY;AAAA,IAC3D,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO,SAAmCrL,GAA4B;AAClE,YAAM,IAAI6I,EAAO,IAAI,IAAI;AACzB,aAAI,KAAK7I,KAAQ,EAAE,KAAK,SAASA,CAAI,IAAU,KACxC,KAAK,UAAU,SAAS,KAAK,MAAMA,CAAI;AAAA,IAClD;AAAA,EAAA,CACH;AACL;AAEA,SAASoN,KAAkB;AACvB,aAAW/H,KAAQ,CAAC,cAAc,eAAe,GAAY;AACzD,UAAMyI,IAAO,OAAO,yBAAyB,KAAK,WAAWzI,CAAI;AACjE,IAAAgG,EAAsB,KAAK,WAAWhG,GAAM;AAAA,MACxC,cAAc;AAAA,MACd,MAAgB;AACZ,eAAO8D,EAAgB,IAAI,IAAI,KAAK2E,EAAK,IAAK,KAAK,IAAI;AAAA,MAC3D;AAAA,IAAA,CACH;AAAA,EACL;AACJ;AAEA,MAAMC,wBAAwB,IAAI;AAAA,EAC9B;AAAA,EAAa;AAAA,EAAa;AAAA,EAAW;AAAA,EAAc;AAAA,EAAc;AAAA,EAAa;AAAA,EAC9E;AAAA,EAAS;AAAA,EAAY;AAAA,EAAe;AAAA,EACpC;AAAA,EAAe;AAAA,EAAa;AAAA,EAAe;AAAA,EAAgB;AAAA,EAAgB;AAAA,EAAe;AAC9F,CAAC;AAED,SAASV,KAA4B;AACjC,QAAMW,IAAU,YAAY,UAAU,kBAChCC,IAAa,YAAY,UAAU,qBACnCC,wBAAoB,QAAA;AAE1B,EAAA7C,EAAsB,kBAAkB,WAAW,oBAAoB;AAAA,IACnE,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO,SAAmClI,GAAcgL,GAAe7E,GAAe;AAClF,MAAA0E,EAAQ,KAAK,MAAM7K,GAAMgL,GAAU7E,CAAO;AAC1C,YAAM/J,IAAIsJ,EAAO,IAAI,IAAI;AACzB,UAAItJ,KAAKwO,EAAkB,IAAI5K,CAAI,KAAKgL,GAAU;AAC9C,cAAMC,IAAS,OAAOD,KAAa,aAAaA,EAAS,KAAK,IAAI,IAAIA;AACtE,QAAAD,EAAc,IAAIC,GAAUC,CAAM,GAClCJ,EAAQ,KAAKzO,EAAE,MAAM4D,GAAMiL,GAAQ9E,CAAO;AAAA,MAC9C;AAAA,IACJ;AAAA,EAAA,CACH,GAED+B,EAAsB,kBAAkB,WAAW,uBAAuB;AAAA,IACtE,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO,SAAmClI,GAAcgL,GAAe7E,GAAe;AAClF,MAAA2E,EAAW,KAAK,MAAM9K,GAAMgL,GAAU7E,CAAO;AAC7C,YAAM/J,IAAIsJ,EAAO,IAAI,IAAI;AACzB,UAAItJ,KAAKwO,EAAkB,IAAI5K,CAAI,KAAKgL,GAAU;AAC9C,cAAMC,IAASF,EAAc,IAAIC,CAAQ;AACzC,QAAIC,MACAH,EAAW,KAAK1O,EAAE,MAAM4D,GAAMiL,GAAQ9E,CAAO,GAC7C4E,EAAc,OAAOC,CAAQ;AAAA,MAErC;AAAA,IACJ;AAAA,EAAA,CACH;AACL;AAEA,SAAS9C,EAAsBlB,GAAgB9E,GAAcgJ,GAAgC;AACzF,EAAApF,EAAiB,KAAK,CAACkB,GAAQ9E,GAAM,OAAO,yBAAyB8E,GAAQ9E,CAAI,CAAC,CAAC,GACnF,OAAO,eAAe8E,GAAQ9E,GAAMgJ,CAAU;AAClD;AAEA,SAAStE,KAAyB;AAC9B,QAAMuE,IAAgB,MAAM;AACxB,eAAWrE,KAASpB,EAAO,OAAA,KAAgB,aAAA;AAAA,EAC/C;AAEA,EAAA0F,EAAkB,QAAQ,UAAUD,GAAe,EAAC,SAAS,IAAK,GAClEC,EAAkB,QAAQ,UAAUD,CAAa;AAErD;AAEA,SAASC,EACLpE,GACAhH,GACAkH,GACAC,GACF;AACE,EAAAH,EAAO,iBAAiBhH,GAAMkH,GAASC,CAAI,GAC3CpB,EAAgB,KAAK,CAACiB,GAAQhH,GAAMkH,GAASC,CAAI,CAAC;AACtD;AAEA,SAASN,KAAiB;AACtB,QAAMwE,IAAU,MAAM;AAClB,IAAKzF,KACL,SACK,iBAAoC,uBAAuB,EAC3D,QAAQ2B,CAAW;AAAA,EAC5B;AACA,EAAI,SAAS,eAAe,YACxB6D,EAAkB,UAAU,oBAAoBC,GAAS,EAAC,MAAM,IAAK,IAErEA,EAAA,GAGJpF,IAAoB,IAAI,iBAAiB,CAAAqF,MAAQ;AAC7C,eAAWpK,KAAKoK;AACZ,UAAIpK,EAAE,SAAS,gBAAgBA,EAAE,kBAAkB,iBAAiB;AAChE,cAAM4B,IAAI5B,EAAE;AACZ,YAAI,EAAE4B,aAAa,mBAAoB;AACvC,YAAIA,EAAE,aAAa,eAAe;AAC9B,UAAAyE,EAAYzE,CAAC;AAAA,aACV;AACH,gBAAM9F,IAAW0I,EAAO,IAAI5C,CAAC;AAC7B,UAAI9F,MACA+J,GAAoB/J,CAAQ,GAC5B0I,EAAO,OAAO5C,CAAC;AAAA,QAEvB;AAAA,MACJ,WAAW5B,EAAE,SAAS;AAClB,mBAAWqK,KAAS,MAAM,KAAKrK,EAAE,UAAU;AACvC,UAAIqK,aAAiB,qBAAqBA,EAAM,aAAa,eAAe,IACxEhE,EAAYgE,CAAK,IACVA,aAAiB,WACxBA,EACK,iBAAoC,uBAAuB,EAC3D,QAAQhE,CAAW;AAAA,EAK5C,CAAC,GACDtB,EAAkB,QAAQ,SAAS,iBAAiB;AAAA,IAChD,YAAY;AAAA,IAAM,SAAS;AAAA,IAAM,iBAAiB,CAAC,eAAe;AAAA,IAClE,WAAW;AAAA,EAAA,CACd;AACL;AAEA,SAASsB,EAAY7I,GAA+C;AAChE,QAAM1B,IAAW0I,EAAO,IAAIhH,CAAM;AAClC,MAAI1B,EAAU,QAAOA;AACrB,MAAI,CAAC0B,EAAO,aAAa,eAAe,EAAG,QAAO;AAElD,QAAMqL,IAAOyB,GAAW9M,CAAM,GACxB+M,wBAAe,IAAA,GACfC,wBAAY,IAAA,GACZC,IAAmD,CAAA,GAEnDC,IAAe,MAAM;AACvB,UAAMvL,IAAI3B,EAAO,sBAAA;AACjB,IAAAqL,EAAK,MAAM,OAAQ1J,EAAE,OAAO,OAAO,UAAU3B,EAAO,aAAc,MAClEqL,EAAK,MAAM,MAAO1J,EAAE,MAAM,OAAO,UAAU3B,EAAO,YAAa,MAC/DqL,EAAK,MAAM,QAAQrL,EAAO,cAAc,MACxCqL,EAAK,MAAM,SAASrL,EAAO,eAAe;AAAA,EAC9C,GAEMoI,IAAqB;AAAA,IACvB,QAAApI;AAAA,IAAQ,MAAAqL;AAAA,IAAM,UAAA0B;AAAA,IAAU,OAAAC;AAAA,IACxB,SAAS;AAAA,IAAM,WAAW;AAAA,IAAG,oBAAoB;AAAA,IAAM,cAAAE;AAAA,IAAc,WAAAD;AAAA,IAAW,UAAU,CAAA;AAAA,EAAC;AAG/F,SAAAE,GAAoB9B,GAAMjD,CAAK,GAC/BpB,EAAO,IAAIhH,GAAQoI,CAAK,GACxBgF,GAAmBhF,CAAK,GACxB8E,EAAA,GACAG,GAAgBjF,CAAK,GAEdA;AACX;AAEA,SAAS0E,GAAW9M,GAA2C;AAC3D,QAAMqL,IAAO,SAAS,cAAc,KAAK;AACzC,SAAAA,EAAK,aAAa,4BAA4B,EAAE,GAC5CrL,EAAO,cAAWqL,EAAK,YAAYrL,EAAO,YAC1CA,EAAO,MAAIqL,EAAK,aAAa,gBAAgBrL,EAAO,EAAE,GAC1DqL,EAAK,MAAM,UACP,sGAEJ,SAAS,KAAK,YAAYA,CAAI,GACvBA;AACX;AAEA,SAAS8B,GAAoB9B,GAAsBjD,GAAoB;AACnE,QAAMkF,IAAe,CAACC,IAAS,mBAAmB;AAC9C,eAAWrC,KAAK9C,EAAM,SAAU,CAAAA,EAAM,MAAM,IAAI8C,CAAC;AACjD,IAAAC,EAAc/C,GAAOmF,CAAM;AAAA,EAC/B;AAEA,EAAAlC,EAAK,iBAAiB,QAAQ,CAAAlM,MAAK;AAC/B,IAAIA,EAAE,kBAAkB,oBAAkBmO,EAAa,YAAY;AAAA,EACvE,GAAG,EAAI,GAEPjC,EAAK,iBAAiB,SAAS,MAAMiC,EAAa,OAAO,GAAG,EAAI,GAChEjC,EAAK,iBAAiB,UAAU,MAAMiC,EAAa,QAAQ,GAAG,EAAI;AAGlE,QAAME,IAAoB,MAAM;AAC5B,UAAMC,IAAM,OAAO,aAAA,GACbC,IAAmBD,KAAO,CAACA,EAAI,eAAeA,EAAI,aAAa,KAC9DpC,EAAK,SAASoC,EAAI,WAAW,CAAC,EAAE,cAAc;AACrD,KAAIpC,EAAK,SAAS,SAAS,aAAa,KAAKqC,QAA+B,iBAAiB;AAAA,EACjG;AACA,WAAS,iBAAiB,mBAAmBF,CAAiB,GAC9DpF,EAAM,SAAS,KAAK,MAAM,SAAS,oBAAoB,mBAAmBoF,CAAiB,CAAC,GAM5FnC,EAAK,iBAAiB,aAAa,CAAAlM,MAAK;AACpC,UAAMmJ,IAASnJ,EAAE;AACjB,QAAKmJ,EAAO,WACZ;AAAA,MAAAA,EAAO,UAAU,IAAI,cAAc;AACnC,iBAAWlF,KAAMuK,EAAcrF,GAAQ+C,CAAI,EAAG,CAAAjI,EAAG,UAAU,IAAI,cAAc;AAAA;AAAA,EACjF,GAAG,EAAI,GAEPiI,EAAK,iBAAiB,YAAY,CAAAlM,MAAK;AACnC,UAAMmJ,IAASnJ,EAAE;AACjB,QAAKmJ,EAAO,WACZ;AAAA,MAAAA,EAAO,UAAU,OAAO,cAAc;AACtC,iBAAWlF,KAAMkF,EAAO,iBAA8B,eAAe;AACjE,QAAAlF,EAAG,UAAU,OAAO,cAAc;AAAA;AAAA,EAE1C,GAAG,EAAI,GAEPiI,EAAK,iBAAiB,WAAW,CAAAlM,MAAK;AAClC,UAAMmJ,IAASnJ,EAAE;AACjB,QAAKmJ,EAAO,WACZ;AAAA,MAAAA,EAAO,UAAU,IAAI,cAAc;AACnC,iBAAWlF,KAAMuK,EAAcrF,GAAQ+C,CAAI,EAAG,CAAAjI,EAAG,UAAU,IAAI,qBAAqB;AACpF,UAAI;AACA,QAAIkF,EAAO,QAAQ,gBAAgB,KAAGA,EAAO,UAAU,IAAI,sBAAsB;AAAA,MACrF,QAAQ;AAAA,MAAqC;AAG7C,OAAIA,aAAkB,oBAAoBA,aAAkB,yBACpDF,EAAM,sBAAoB,cAAcA,EAAM,kBAAkB,GACpEA,EAAM,qBAAqB,YAAY,MAAMkF,EAAa,aAAa,GAAG,GAAG;AAAA;AAAA,EAErF,GAAG,EAAI,GAEPjC,EAAK,iBAAiB,YAAY,CAAAlM,MAAK;AACnC,UAAMmJ,IAASnJ,EAAE;AACjB,IAAImJ,EAAO,aAAWA,EAAO,UAAU,OAAO,gBAAgB,sBAAsB;AACpF,eAAWlF,KAAMiI,EAAK,iBAA8B,sBAAsB;AACtE,MAAAjI,EAAG,UAAU,OAAO,qBAAqB;AAG7C,IAAIgF,EAAM,uBACN,cAAcA,EAAM,kBAAkB,GACtCA,EAAM,qBAAqB,MAC3BkF,EAAa,cAAc;AAAA,EAEnC,GAAG,EAAI,GAEPjC,EAAK,iBAAiB,eAAe,CAAAlM,MAAK;AACtC,UAAMmJ,IAASnJ,EAAE;AACjB,QAAKmJ,EAAO,WACZ;AAAA,MAAAA,EAAO,UAAU,IAAI,eAAe;AACpC,iBAAWlF,KAAMuK,EAAcrF,GAAQ+C,CAAI,EAAG,CAAAjI,EAAG,UAAU,IAAI,eAAe;AAAA;AAAA,EAClF,GAAG,EAAI;AAEP,QAAMwK,IAAc,MAAM;AACtB,eAAWxK,KAAMiI,EAAK,iBAA8B,gBAAgB;AAChE,MAAAjI,EAAG,UAAU,OAAO,eAAe;AAAA,EAE3C;AACA,EAAAiI,EAAK,iBAAiB,aAAauC,GAAa,EAAI,GACpDvC,EAAK,iBAAiB,iBAAiBuC,GAAa,EAAI;AAC5D;AAEA,SAASD,EAAcvK,GAAiByK,GAAkC;AACtE,QAAMC,IAAwB,CAAA;AAC9B,MAAIC,IAAU3K,EAAG;AACjB,SAAO2K,KAAWA,MAAYF;AAC1B,IAAAC,EAAO,KAAKC,CAAO,GACnBA,IAAUA,EAAQ;AAEtB,SAAOD;AACX;AAEA,MAAME,KAAe,OAAO,yBAAyB,QAAQ,WAAW,UAAU,EAAG;AAErF,SAASZ,GAAmBhF,GAAoB;AAG5C,aAAWhF,KAAM,MAAM,KAAK4K,GAAa,KAAK5F,EAAM,MAAM,CAAC;AACvD,IAAAuD,EAAgBvD,GAAOhF,CAAE;AAEjC;AAEA,SAASiK,GAAgBjF,GAAoB;AACzC,QAAM6F,IAAY,IAAI,eAAe,MAAM;AACvC,IAAA7F,EAAM,aAAA;AACN,eAAW8C,KAAK9C,EAAM,SAAU,CAAAA,EAAM,MAAM,IAAI8C,CAAC;AACjD,IAAAC,EAAc/C,GAAO,gBAAgB;AAAA,EACzC,CAAC;AACD,EAAA6F,EAAU,QAAQ7F,EAAM,MAAM,GAC9BA,EAAM,UAAU,KAAK6F,CAAS;AAE9B,QAAMC,IAAc,IAAI,iBAAiB,CAAAtB,MAAQ;AAC7C,QAAIuB,IAAM;AACV,eAAW3L,KAAKoK,GAAM;AAClB,UAAIwB,IAAiB5L,EAAE;AAGvB,aAAO4L,KAAK,EAAEA,aAAa,eAAehG,EAAM,SAAS,IAAIgG,CAAC,KAAI,CAAAA,IAAIA,EAAE;AACxE,MAAIA,MACAhG,EAAM,MAAM,IAAIgG,CAAgB,GAChCD,IAAM;AAAA,IAEd;AACA,IAAIA,KAAKhD,EAAc/C,GAAO,kBAAkB;AAAA,EACpD,CAAC;AACD,EAAA8F,EAAY,QAAQ9F,EAAM,MAAM,EAAC,WAAW,IAAM,SAAS,IAAM,YAAY,IAAM,eAAe,GAAA,CAAK,GACvGA,EAAM,UAAU,KAAK8F,CAAW;AACpC;AAEA,SAAS7F,GAAoBD,GAAoB;AAC7C,EAAIA,EAAM,cACN,qBAAqBA,EAAM,SAAS,GACpCA,EAAM,YAAY,IAElBA,EAAM,uBACN,cAAcA,EAAM,kBAAkB,GACtCA,EAAM,qBAAqB;AAE/B,aAAW6C,KAAM7C,EAAM,SAAU,CAAA6C,EAAA;AACjC,EAAA7C,EAAM,SAAS,SAAS;AACxB,aAAWiG,KAAOjG,EAAM,UAAW,CAAAiG,EAAI,WAAA;AACvC,EAAAjG,EAAM,UAAU,SAAS,GACzBA,EAAM,MAAM,MAAA,GACZA,EAAM,UAAU;AAEhB,QAAMkG,IAAgB,CAAC,gBAAgB,gBAAgB,wBAAwB,uBAAuB,eAAe;AACrH,aAAWC,KAAS,MAAM,KAAKnG,EAAM,QAAQ,GAAG;AAC5C,IAAAmG,EAAM,UAAU,OAAO,GAAGD,CAAa;AACvC,eAAWlL,KAAMmL,EAAM,iBAA8B,2FAA2F;AAC5I,MAAAnL,EAAG,UAAU,OAAO,GAAGkL,CAAa;AAExC,IAAA1C,GAAqBxD,GAAOmG,CAAK,GACjC,KAAK,UAAU,YAAY,KAAKnG,EAAM,QAAQmG,CAAK;AAAA,EACvD;AACA,EAAAnG,EAAM,KAAK,OAAA;AACf;AAEA,MAAMpK,KAAY,OAAO,WAAa,OAAe,IAAI,gBAAgB,SAAS,MAAM,EAAE,IAAI,kBAAkB;AAEhH,SAASmN,EAAc/C,GAAoBoG,GAAkB;AAEzD,EADIxQ,MAAawQ,KAAS,QAAQ,MAAM,8CAA8CA,CAAO,GACzF,CAAApG,EAAM,cACVA,EAAM,YAAY,sBAAsB,YAAY;;AAGhD,QAFAA,EAAM,YAAY,GAEd,CAACpB,EAAO,IAAIoB,EAAM,MAAM,EAAG;AAE/B,IAAAA,EAAM,aAAA;AAEN,UAAMqG,IAAU,MAAM,KAAKrG,EAAM,KAAK;AAOtC,QANAA,EAAM,MAAM,MAAA,GAERqG,EAAQ,UACR,MAAM,QAAQ,IAAIA,EAAQ,IAAIC,EAAY,CAAC,GAG3C,CAAC1H,EAAO,IAAIoB,EAAM,MAAM,EAAG;AAE/B,UAAMuG,IAAK,IAAI,MAAM,OAAO;AAC1B,IAAAA,EAAW,kBAAkBF;AAC/B,QAAI;AAAE,OAAAvP,IAAAkJ,EAAM,YAAN,QAAAlJ,EAAe,KAAKkJ,EAAM,QAAQuG;AAAA,IAAI,SACrCxP,GAAG;AAAE,cAAQ,MAAM,2CAA2CA,CAAC;AAAA,IAAE;AACxE,IAAAiJ,EAAM,OAAO,cAAcuG,CAAE;AAAA,EACjC,CAAC;AACL;AAEA,eAAeD,GAAatL,GAAiB;AACzC,MAAI;AACA,UAAM6D,EAAS,OAAO7D,CAAE;AAAA,EAC5B,SAASjE,GAAG;AACR,YAAQ;AAAA,MACJ,kDAAkDyP,GAAgBxL,CAAE,CAAC;AAAA,MACrEjE,aAAa,QAASA,EAAE,UAAU;AAAA,IAAOA,EAAE,QAASA;AAAA,IAAA;AAAA,EAE5D;AACJ;AAEA,SAASyP,GAAgBxL,GAAyB;AAC9C,QAAMyL,IAAMzL,EAAG,QAAQ,YAAA,GACjB0L,IAAK1L,EAAG,KAAK,IAAIA,EAAG,EAAE,KAAK,IAC3B2L,IAAY3L,EAAG,aAAa,OAAO,KAAK,IACxC4L,IAAMD,IAAY,IAAIA,EAAU,OAAO,QAAQ,QAAQ,GAAG,CAAC,KAAK;AACtE,SAAO,IAAIF,CAAG,GAAGC,CAAE,GAAGE,CAAG;AAC7B;","x_google_ignoreList":[0]}