{"version":3,"file":"ful.min.mjs","sources":["../src/ful/storage.mjs","../src/ful/events/async.mjs","../src/ful/timing.mjs","../src/ful/elements/bindings.mjs","../src/ful/elements/form.mjs","../src/ful/elements/input.mjs","../src/ful/elements/temporals.mjs","../src/ful/elements/files.mjs","../src/ful/elements/select.mjs","../src/ful/elements/radio.mjs","../src/ful/elements/checkbox.mjs","../src/ful/elements/spinner.mjs","../src/ful/elements/table.mjs","../src/ful/elements/filters.mjs","../src/ful/elements/l10n.mjs","../src/ful/elements/plugin.mjs"],"sourcesContent":["class LocalStorage extends Storage {\n    static save(k, v) {\n        localStorage.setItem(k, JSON.stringify(v));\n    }\n    static load(k) {\n        const got = localStorage.getItem(k);\n        return got === null ? undefined : JSON.parse(got);\n    }\n    static remove(k) {\n        localStorage.removeItem(k);\n    }\n    static pop(k) {\n        const decoded = LocalStorage.load(k);\n        LocalStorage.remove(k);\n        return decoded;\n    }\n}\n\nclass SessionStorage extends Storage {\n    static save(k, v) {\n        sessionStorage.setItem(k, JSON.stringify(v));\n    }\n    static load(k) {\n        const got = sessionStorage.getItem(k);\n        return got === null ? undefined : JSON.parse(got);\n    }\n    static remove(k) {\n        sessionStorage.removeItem(k);\n    }\n    static pop(k) {\n        const decoded = SessionStorage.load(k);\n        SessionStorage.remove(k);\n        return decoded;\n    }\n}\n\nclass VersionedLocalStorage {\n    static save(key, revision, data) {\n        LocalStorage.save(key, { revision, data });\n    }\n    static load(key, revision) {\n        const stored = LocalStorage.load(key);\n        if (stored === undefined) {\n            return undefined;\n        }\n        if (stored.revision !== revision) {\n            localStorage.removeItem(key);\n            return undefined;\n        }\n        return stored.data;\n    }\n}\n\nclass VersionedSessionStorage {\n    static save(key, revision, data) {\n        SessionStorage.save(key, { revision, data });\n    }\n    static load(key, revision) {\n        const stored = SessionStorage.load(key);\n        if (stored === undefined) {\n            return undefined;\n        }\n        if (stored.revision !== revision) {\n            localStorage.removeItem(key);\n            return undefined;\n        }\n        return stored.data;\n    }\n}\n\nexport { LocalStorage, VersionedLocalStorage, SessionStorage, VersionedSessionStorage };\n","/**\n * @typedef {Object} AsyncExtension\n * @property {Promise<any>[]} promises\n * @typedef {Event & { async?: AsyncExtension }} AsyncEvent\n */\nclass AsyncEvents {\n    /**\n     * Dispatches an event and handles asynchronous resolution based on the execution mode.\n     * @param {HTMLElement} el - The target element dispatching the event.\n     * @param {AsyncEvent} evt - The event instance.\n     * @param {{mode?: 'broadcast' | 'pipeline' | 'delegate'}} [options] - Configuration options (defaults to 'broadcast').\n     * @returns {Promise<any>} Resolves with an array of values for broadcasts, a single value for pipelines/delegates, or undefined.\n     */\n    static async fireAsync(el, evt, options) {\n        el.dispatchEvent(evt);\n        const promises = evt.async?.promises ?? [];\n        const mode = options?.mode ?? 'broadcast';\n        if (mode === 'pipeline' && promises.length > 1) {\n            throw new Error(\n                `[AsyncEvents] Event \"${evt.type}\" is configured in 'pipeline' mode and expects at most one async listener, but ${promises.length} listeners were triggered on this element.`,\n            );\n        }\n        if (mode === 'delegate' && promises.length !== 1) {\n            throw new Error(\n                `[AsyncEvents] Event \"${evt.type}\" is configured in 'delegate' mode and requires exactly one async listener, but ${promises.length} were registered.`,\n            );\n        }\n        return mode === 'broadcast' ? Promise.all(promises) : Promise.resolve(promises[0]);\n    }\n\n    /**\n     * Registers an asynchronous event listener wrapper.\n     * @param {HTMLElement} el - The target element.\n     * @param {string} type - The event name/type.\n     * @param {Function} fn - The async listener middleware function returning the execution result.\n     * @param {AddEventListenerOptions} [options] - Native addEventListener options.\n     * @returns {EventListener} The underlying proxy listener function needed for cleanup via asyncOff.\n     */\n    static asyncOn(el, type, fn, options) {\n        /** @type {(evt: Event) => Promise<void>} */\n        const listener = async (event) => {\n            const ae = /** @type {AsyncEvent} */ (event);\n            if (!ae.async) {\n                ae.async = { promises: [] };\n            }\n            const { promise, resolve, reject } = Promise.withResolvers();\n            ae.async.promises.push(promise);\n            try {\n                resolve(await fn(ae));\n            } catch (e) {\n                reject(e);\n            }\n        };\n\n        el.addEventListener(type, listener, options);\n        return listener;\n    }\n\n    /**\n     * Unregisters an asynchronous event listener proxy.\n     * @param {HTMLElement} el - The target element.\n     * @param {string} type - The event name/type.\n     * @param {EventListener} listener - The proxy listener instance previously returned by asyncOn.\n     * @param {EventListenerOptions} [options] - Native removeEventListener options.\n     */\n    static asyncOff(el, type, listener, options) {\n        el.removeEventListener(type, listener, options);\n    }\n\n    /**\n     * Mixes the asynchronous execution engine extensions into target class prototypes.\n     * @param {...Function} classes - The target class constructors to decorate.\n     */\n    static mixInto(...classes) {\n        for (const k of classes) {\n            Object.assign(k.prototype, {\n                /**\n                 * @this {HTMLElement}\n                 * @param {AsyncEvent} evt\n                 * @param {{mode?: 'broadcast' | 'pipeline' | 'delegate'}} [options]\n                 * @returns {Promise<any>}\n                 */\n                async fireAsync(evt, options) {\n                    return await AsyncEvents.fireAsync(this, evt, options);\n                },\n\n                /**\n                 * @this {HTMLElement}\n                 * @param {string} type\n                 * @param {Function} fn\n                 * @param {AddEventListenerOptions} [options]\n                 * @returns {EventListener}\n                 */\n                asyncOn(type, fn, options) {\n                    return AsyncEvents.asyncOn(this, type, fn, options);\n                },\n\n                /**\n                 * @this {HTMLElement}\n                 * @param {string} type\n                 * @param {EventListener} listener\n                 * @param {EventListenerOptions} [options]\n                 * @returns {void}\n                 */\n                asyncOff(type, listener, options) {\n                    AsyncEvents.asyncOff(this, type, listener, options);\n                },\n            });\n        }\n    }\n}\n\nexport { AsyncEvents };\n","class Timing {\n    static sleep(ms) {\n        return new Promise((resolve) => setTimeout(resolve, ms));\n    }\n    static DEBOUNCE_DEFAULT = 0;\n    static DEBOUNCE_IMMEDIATE = 1;\n    /**\n     * Executes only after a period of inactivity (pause in events).\n     * Respond to the \"end\" of a series of events.\n     * @param {*} timeoutMs\n     * @param {*} func\n     * @param {*} [options]\n     * @returns {[function, function]}\n     */\n    static debounce(timeoutMs, func, options) {\n        const opts = options ?? Timing.DEBOUNCE_DEFAULT;\n        let tid = null;\n        let args = [];\n        let previousTimestamp = 0;\n\n        const later = () => {\n            const elapsed = performance.now() - previousTimestamp;\n            if (timeoutMs > elapsed) {\n                tid = setTimeout(later, timeoutMs - elapsed);\n                return;\n            }\n            tid = null;\n            if (opts !== Timing.DEBOUNCE_IMMEDIATE) {\n                func(...args);\n            }\n            // This check is needed because `func` can recursively invoke `debounced`.\n            if (tid === null) {\n                args = [];\n            }\n        };\n\n        const debounced = function () {\n            args = [...arguments];\n            previousTimestamp = performance.now();\n            if (tid === null) {\n                tid = setTimeout(later, timeoutMs);\n                if (opts === Timing.DEBOUNCE_IMMEDIATE) {\n                    func(...args);\n                }\n            }\n        };\n        const abort = () => clearTimeout(tid);\n        return [debounced, abort];\n    }\n    static THROTTLE_DEFAULT = 0;\n    static THROTTLE_NO_LEADING = 1;\n    static THROTTLE_NO_TRAILING = 2;\n    /**\n     * Executes at most once per specified time interval, regardless of ongoing events.\n     * @param {*} timeoutMs\n     * @param {*} func\n     * @param {*} [options]\n     * @returns {[function, function]}\n     */\n    static throttle(timeoutMs, func, options) {\n        const opts = options ?? Timing.THROTTLE_DEFAULT;\n        let tid = null;\n        let args = [];\n        let previousTimestamp = 0;\n\n        const later = () => {\n            previousTimestamp = opts & Timing.THROTTLE_NO_LEADING ? 0 : performance.now();\n            tid = null;\n            func(...args);\n            if (tid === null) {\n                args = [];\n            }\n        };\n        const throttled = function () {\n            const now = performance.now();\n            if (!previousTimestamp && opts & Timing.THROTTLE_NO_LEADING) {\n                previousTimestamp = now;\n            }\n            const remaining = previousTimestamp === 0 ? 0 : timeoutMs - (now - previousTimestamp);\n            args = [...arguments];\n            if (remaining <= 0 || remaining > timeoutMs) {\n                if (tid !== null) {\n                    clearTimeout(tid);\n                    tid = null;\n                }\n                previousTimestamp = now;\n                func(...args);\n                if (tid === null) {\n                    args = [];\n                }\n            } else if (tid === null && !(opts & Timing.THROTTLE_NO_TRAILING)) {\n                tid = setTimeout(later, remaining);\n            }\n        };\n        const abort = () => clearTimeout(tid);\n        return [throttled, abort];\n    }\n}\n\nexport { Timing };\n","class Bindings {\n    /**\n     * @param {{ [x: string]: any; }} obj\n     * @param {string} prefix\n     * @param {Set<String>} stops\n     * @return {{ [x: string]: any; }}\n     */\n    static flatten(obj, prefix, stops) {\n        return Object.keys(obj).reduce((acc, k) => {\n            const pre = prefix.length ? prefix + '.' + k : k;\n            if (!stops.has(pre) && typeof obj[k] === 'object' && obj[k] !== null) {\n                Object.assign(acc, Bindings.flatten(obj[k], pre, stops));\n            } else {\n                acc[pre] = obj[k];\n            }\n            return acc;\n        }, {});\n    }\n\n    /**\n     * @param {any} result\n     * @param {string} path\n     * @param {any} value\n     */\n    static providePath(result, path, value) {\n        const keys = path.split('.').map((k) => (/^[0-9]+$/.test(k) ? +k : k));\n        let current = result ?? {};\n        let previous = null;\n        for (let i = 0; ; ++i) {\n            const ckey = keys[i];\n            const pkey = keys[i - 1];\n            if (Number.isInteger(ckey) && !Array.isArray(current)) {\n                if (previous !== null) {\n                    previous[pkey] = current = [];\n                } else {\n                    result = current = [];\n                }\n            }\n            if (i === keys.length - 1) {\n                //when value is undefined we only want to define the property if it's not defined\n                current[ckey] = value !== undefined ? value : ckey in current ? current[ckey] : null;\n                return result;\n            }\n            if (current[ckey] === undefined) {\n                current[ckey] = {};\n            }\n            previous = current;\n            current = current[ckey];\n        }\n    }\n    /**\n     *\n     * @param {Element & {dataset?: any} & {checked?: boolean} & {value?: any}} el\n     * @returns\n     */\n    static extract(el) {\n        if (el.getAttribute('type') === 'radio') {\n            if (!el.checked) {\n                return undefined;\n            }\n            return el.dataset['fulBindType'] === 'boolean' ? el.value === 'true' : el.value;\n        }\n        if (el.getAttribute('type') === 'checkbox') {\n            return el.checked;\n        }\n        if (el.dataset['fulBindType'] === 'boolean') {\n            return !el.value ? null : el.value === 'true';\n        }\n        if (el.tagName === 'INPUT' || el.tagName === 'SELECT' || el.tagName === 'TEXTAREA') {\n            return el.value === '' || el.value === undefined ? null : el.value;\n        }\n        return el.value;\n    }\n\n    /**\n     *\n     * @param {HTMLFormElement} form\n     * @param {HTMLElement} [submitter]\n     * @returns\n     */\n    static extractFrom(form, submitter) {\n        let result = {};\n        for (const el of form.elements) {\n            // we are assuming submitters are disabled during submit.\n            if (!el.hasAttribute('name') || (el.matches(':disabled') && el !== submitter)) {\n                continue;\n            }\n            result = Bindings.providePath(\n                result,\n                /** @type {string} */ (el.getAttribute('name')),\n                Bindings.extract(el),\n            );\n        }\n        return result;\n    }\n\n    /**\n     *\n     * @param {Element  & {checked?: boolean} & {value?: any}} el\n     * @returns\n     */\n    static mutate(el, raw) {\n        if (el.getAttribute('type') === 'radio') {\n            el.checked = el.getAttribute('value') === raw;\n            return;\n        }\n        if (el.getAttribute('type') === 'checkbox') {\n            el.checked = raw;\n            return;\n        }\n        el.value = raw;\n    }\n\n    static mutateIn(form, values) {\n        const names = Array.from(form.elements)\n            .map((el) => el.getAttribute('name'))\n            .filter((n) => n);\n        for (const [flattenedKey, value] of Object.entries(Bindings.flatten(values, '', new Set(names)))) {\n            for (const el of form.querySelectorAll(`[name='${CSS.escape(flattenedKey)}']`)) {\n                Bindings.mutate(el, value);\n            }\n        }\n    }\n\n    static errors(form, es, scrollOnError) {\n        const fieldErrors = es.filter((e) => e.type === 'FIELD_ERROR' || e.type === 'INVALID_FORMAT');\n        const globalErrors = es.filter((e) => e.type !== 'FIELD_ERROR' && e.type !== 'INVALID_FORMAT');\n        form.querySelectorAll(`[name]`).forEach((el) => el.setCustomValidity?.(''));\n        form.querySelectorAll('ful-errors').forEach((el) => {\n            el.replaceChildren();\n            el.setAttribute('hidden', '');\n        });\n        fieldErrors.forEach((e) => {\n            const name = e.context.replace(/\\[/g, '.').replace(/\\]\\./g, '.').replace(/\\]/g, '')\n            const parts = name.split('.');\n            for (let i = parts.length; i != 0; --i) {\n                const prefix = parts.slice(0, i).join('.');\n                const suffix = parts.slice(i, parts.length).join('.');\n                form.querySelectorAll(`[name='${CSS.escape(prefix)}']`).forEach((input) =>\n                    input.setCustomValidity?.(e.reason, suffix),\n                );\n            }\n        });\n        form.querySelectorAll('ful-errors').forEach((el) => {\n            const hel = /** @type HTMLElement} */ (el);\n            hel.innerText = globalErrors.map((e) => e.reason).join('\\n');\n            if (globalErrors.length !== 0) {\n                el.removeAttribute('hidden');\n            }\n        });\n        if (es.length == 0 || !scrollOnError) {\n            return;\n        }\n        Array.from(form.querySelectorAll(`:invalid`))\n            .sort((a, b) => a.getBoundingClientRect().y - b.getBoundingClientRect().y)[0]\n            ?.focus();\n    }\n}\n\nexport { Bindings };\n","import { Attributes, ParsedElement, registry } from '../../ftl/index.mjs';\nimport { Failure } from '../../httpc/index.mjs';\nimport { Bindings } from './bindings.mjs';\nimport { AsyncEvents } from '../events/async.mjs';\n\nclass RemoteJsonFormLoader {\n    #http;\n    #url;\n    #method;\n    #requestMapper;\n    #responseMapper;\n    constructor(http, url, method, requestMapper, responseMapper) {\n        this.#http = http;\n        this.#url = url;\n        this.#method = method;\n        this.#requestMapper = requestMapper;\n        this.#responseMapper = responseMapper;\n    }\n    prepare(values, form) {\n        return this.#requestMapper(values, form);\n    }\n    async submit(values, form) {\n        return await this.#http.request(this.#method, this.#url).json(values).fetch();\n    }\n    transform(response, form) {\n        return this.#responseMapper(response, form);\n    }\n}\n\nclass LocalFormLoader {\n    #requestMapper;\n    #responseMapper;\n    constructor(requestMapper, responseMapper) {\n        this.#requestMapper = requestMapper;\n        this.#responseMapper = responseMapper;\n    }\n    async prepare(values, form) {\n        return await this.#requestMapper(values, form);\n    }\n    async submit(values, form, response) {\n        return response;\n    }\n    async transform(response, form) {\n        return await this.#responseMapper(response, form);\n    }\n}\n\nclass FormLoader {\n    static create(el, conf) {\n        const http = registry.component('http-client');\n        const requestMapper = el.hasAttribute('request-mapper')\n            ? registry.component(el.getAttribute('request-mapper'))\n            : (v) => v;\n        const responseMapper = el.hasAttribute('response-mapper')\n            ? registry.component(el.getAttribute('response-mapper'))\n            : (v) => v;\n        const url = el.getAttribute('action');\n        if (!url) {\n            return new LocalFormLoader(requestMapper, responseMapper);\n        }\n        const method = el.getAttribute('method') ?? 'POST';\n        return new RemoteJsonFormLoader(http, url, method, requestMapper, responseMapper);\n    }\n}\n\nclass Form extends ParsedElement {\n    form;\n    render() {\n        const form = (this.form = document.createElement('form'));\n        form.setAttribute('novalidate', '');\n        Attributes.forward('form-', this, form);\n        form.replaceChildren(...this.childNodes);\n        form.addEventListener('submit', async (e) => {\n            e.preventDefault();\n            e.stopPropagation();\n            await this.submit(e.submitter ?? undefined);\n        });\n        if (this.hasAttribute('clear-invalid-on-change')) {\n            this.addEventListener('change', (/** @type any */ evt) => {\n                evt.target.setCustomValidity?.('');\n            });\n        }\n        this.replaceChildren(form);\n    }\n    /**\n     *\n     * @param {HTMLElement} [submitter]\n     * @returns\n     */\n    async submit(submitter) {\n        this.spinner(true);\n        try {\n            const loader = registry.component(this.getAttribute('loader') ?? 'loaders:form').create(this);\n            const values = Bindings.extractFrom(this.form, submitter);\n            let request = await loader.prepare(values, this);\n            try {\n                const se = new CustomEvent('submit', {\n                    bubbles: true,\n                    cancelable: true,\n                    detail: { submitter, values, request },\n                });\n                if (!this.dispatchEvent(se)) {\n                    return;\n                }\n                this.errors = [];\n                const sre = new CustomEvent('submit:requested', {\n                    bubbles: true,\n                    cancelable: false,\n                    detail: { submitter, values: se.detail.values, request: se.detail.request },\n                });\n                let response = await AsyncEvents.fireAsync(this, sre, { mode: 'pipeline' });\n                request = sre.detail.request;\n\n                response = await loader.submit(request, this, response);\n                const mapped = await loader.transform(response, this);\n                this.dispatchEvent(\n                    new CustomEvent('submit:success', {\n                        bubbles: true,\n                        cancelable: false,\n                        detail: { submitter, values, request, response: mapped },\n                    }),\n                );\n            } catch (e) {\n                this.dispatchEvent(\n                    new CustomEvent('submit:failure', {\n                        bubbles: true,\n                        cancelable: false,\n                        detail: { submitter, values, request, exception: e },\n                    }),\n                );\n                if (e instanceof Failure) {\n                    this.errors = e.problems;\n                }\n                console.warn('failed to submit form', this, 'reason:', e);\n            }\n        } finally {\n            this.spinner(false);\n        }\n    }\n    reset() {\n        this.form.reset();\n    }\n    spinner(spin) {\n        this.querySelectorAll('ful-spinner').forEach((el) => {\n            const hel = /** @type HTMLElement */ (el);\n            hel.hidden = !spin;\n        });\n        this.querySelectorAll('input,button').forEach((el) => {\n            const hel = /** @type HTMLButtonElement|HTMLInputElement */ (el);\n            if (hel.type !== 'submit' && hel.type !== 'reset') {\n                return;\n            }\n            if (spin) {\n                hel.dataset.wd = String(hel.disabled);\n                hel.disabled = true;\n            } else {\n                hel.disabled = hel.dataset.wd === 'true';\n                delete hel.dataset.wd;\n            }\n        });\n    }\n    set values(vs) {\n        Bindings.mutateIn(this.form, vs);\n    }\n    get values() {\n        return Bindings.extractFrom(this.form);\n    }\n    set errors(es) {\n        Bindings.errors(this.form, es, this.hasAttribute('scroll-on-error'));\n    }\n}\n\nexport { FormLoader, Form };\n","import { Attributes, ParsedElement } from '../../ftl/index.mjs';\n\nclass Input extends ParsedElement {\n    static observed = ['value', 'readonly:presence', 'required:presence'];\n    static slots = true;\n    static template = `\n        <div class=\"form-label\">\n            <label>{{{{ slots.default }}}}</label>\n            {{{{ slots.info }}}}\n        </div>\n        <div class=\"input-group\">\n            <span data-tpl-if=\"slots.ibefore\" class=\"input-group-text\">{{{{ slots.ibefore }}}}</span>\n            {{{{ slots.before }}}}\n            <input data-tpl-if=\"type != 'textarea'\" class=\"form-control\" data-tpl-type=\"type\" placeholder=\" \" form=\"\">\n            <textarea data-tpl-if=\"type == 'textarea'\" class=\"form-control\" placeholder=\" \" form=\"\"></textarea>\n            {{{{ slots.after }}}}\n            <span data-tpl-if=\"slots.iafter\" class=\"input-group-text\">{{{{ slots.iafter }}}}</span>\n        </div>\n        <ful-field-error></ful-field-error>\n    `;\n    static formAssociated = true;\n    _input;\n    _fieldError;\n    constructor() {\n        super();\n        this.internals = this.attachInternals();\n        this.internals.role = 'presentation';\n    }\n    _type() {\n        return this.getAttribute('type') ?? 'text';\n    }\n    _fragment(type, slots) {\n        return this.template().withOverlay({ type, slots }).render();\n    }\n    render({ slots, observed, disabled, skipObservedSetup }) {\n        const type = this._type();\n        const fragment = this._fragment(type, slots);\n        this._input = fragment.querySelector('input,textarea');\n\n        Attributes.forward('input-', this, this._input);\n        if (!skipObservedSetup) {\n            this.disabled = disabled;\n            this.readonly = observed.readonly;\n            this.required = observed.required;\n            this.value = observed.value;\n        }\n        this._input.addEventListener('keydown', (evt) => {\n            if (evt.key !== 'Enter' || this._type() === 'textarea') {\n                return;\n            }\n            const form = this.internals.form;\n            if (!form) {\n                return;\n            }\n            const candidates = /** @type [HTMLButtonElement|HTMLInputElement] */ (\n                Array.from(form.querySelectorAll('button:not(:disabled), input:not(:disabled)'))\n            );\n            const submitter = candidates.find((el) => el.type === 'submit');\n            form.requestSubmit(submitter);\n        });\n        this._input.addEventListener('input', (evt) => {\n            const re = this.getAttribute('mask');\n            if (!re) {\n                return;\n            }\n            const before = evt.target.value;\n            const after = before.replace(new RegExp(re, 'g'), '');\n            if (before === after) {\n                return;\n            }\n            const start = evt.target.selectionStart;\n            const offset = before.length - after.length;\n            evt.target.value = after;\n            evt.target.setSelectionRange(start - offset, start - offset);\n        });\n        this._input.addEventListener('change', (evt) => {\n            evt.stopPropagation();\n            this.dispatchEvent(\n                new CustomEvent('change', {\n                    bubbles: true,\n                    cancelable: false,\n                    detail: {\n                        value: this.value,\n                    },\n                }),\n            );\n        });\n        const label = fragment.querySelector('label');\n        label.addEventListener('click', () => this.focus());\n        this._fieldError = fragment.querySelector('ful-field-error');\n        this._input.ariaDescribedByElements = [this._fieldError];\n        this._input.ariaLabelledByElements = [label];\n        this.replaceChildren(fragment);\n    }\n    get value() {\n        const uppercase = this.hasAttribute('uppercase');\n        const trim = this.hasAttribute('trim');\n        const v = this._input.value;\n        const uppercased = uppercase ? v.toUpperCase() : v;\n        const trimmed = trim ? uppercased.trim() : uppercased;\n        return trimmed === '' ? null : trimmed;\n    }\n    set value(value) {\n        this._input.value = value === '' ? null : value;\n    }\n    get readonly() {\n        return this._input.readOnly;\n    }\n    set readonly(v) {\n        this._input.readOnly = v;\n        this.reflect(() => {\n            Attributes.toggle(this, 'readonly', v);\n        });\n    }\n    get disabled() {\n        return this._input.hasAttribute('disabled');\n    }\n    set disabled(d) {\n        Attributes.toggle(this._input, 'disabled', d);\n    }\n    get required() {\n        return this._input.getAttribute('aria-required') === 'true';\n    }\n    set required(d) {\n        Attributes.set(this._input, 'aria-required', d ? 'true' : null);\n        this.reflect(() => {\n            Attributes.toggle(this, 'required', d);\n        });\n    }\n    focus(options) {\n        this._input.focus(options);\n    }\n    setCustomValidity(error) {\n        if (!error) {\n            this.internals.setValidity({});\n            this._fieldError.innerText = '';\n            return;\n        }\n        this.internals.setValidity({ customError: true }, ' ');\n        this._fieldError.innerText = error;\n    }\n    formResetCallback() {\n        this.value = this.unmarshal('value', this.getAttribute('value'));\n    }\n}\n\nexport { Input };\n","import { ParsedElement } from '../../ftl/index.mjs';\nimport { Input } from './input.mjs';\n\nclass LocalDate extends ParsedElement {\n    render() {\n        const content = this.innerHTML.trim();\n        if (content === '') {\n            this.innerHTML = this.getAttribute('default') ?? '';\n            return;\n        }\n        const locale = this.getAttribute('locale') ?? Intl.DateTimeFormat().resolvedOptions().locale;\n        const formatter = new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'numeric', day: 'numeric' });\n        const [y, m, d] = content.split('-').map(Number);\n        this.innerHTML = formatter.format(new Date(y, m - 1, d));\n    }\n}\n\nclass Instant extends ParsedElement {\n    render() {\n        const content = this.innerHTML.trim();\n        if (content === '') {\n            this.innerHTML = this.getAttribute('default') ?? '';\n            return;\n        }\n        const locale = this.getAttribute('locale') ?? Intl.DateTimeFormat().resolvedOptions().locale;\n        const format = new Intl.DateTimeFormat(locale, {\n            year: 'numeric',\n            month: 'numeric',\n            day: 'numeric',\n            hour: 'numeric',\n            minute: 'numeric',\n            second: 'numeric',\n            hour12: false,\n        });\n        this.innerHTML = format.format(new Date(Instant.isoToLocal(content)));\n    }\n    static isoToLocal(iso) {\n        //this is so sad\n        const d = new Date(iso);\n        const pad = (n, v) => String(v).padStart(n, '0');\n        const date = `${d.getFullYear()}-${pad(2, d.getMonth() + 1)}-${pad(2, d.getDate())}`;\n        const time = `${pad(2, d.getHours())}:${pad(2, d.getMinutes())}:${pad(2, d.getSeconds())}.${pad(3, d.getMilliseconds())}`;\n        return `${date}T${time}`;\n    }\n}\n\nclass InputLocalDate extends Input {\n    static observed = ['value', 'readonly:presence', 'required:presence', 'min', 'max', 'step'];\n    _type() {\n        return 'date';\n    }\n    render(conf) {\n        const { observed } = conf;\n        super.render(conf);\n        this.min = observed.min;\n        this.max = observed.max;\n        this.step = observed.step;\n    }\n    get min() {\n        const v = this._input.min;\n        return v === '' ? null : v;\n    }\n    set min(v) {\n        this._input.min = InputLocalDate.#fromIsoOrOffset(v);\n    }\n    get max() {\n        const v = this._input.max;\n        return v === '' ? null : v;\n    }\n    set max(v) {\n        this._input.max = InputLocalDate.#fromIsoOrOffset(v);\n    }\n    get step() {\n        const v = this._input.step;\n        return v === '' ? null : v;\n    }\n    set step(v) {\n        this._input.step = v ?? '';\n    }\n    static #fromIsoOrOffset(v) {\n        if (!v) {\n            return '';\n        }\n        //this could be date.toLocaleDateString('en-CA')\n        const formatLocalDate = (date) =>\n            new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().split('T')[0];\n        if (v === 'now') {\n            return formatLocalDate(new Date());\n        }\n        const re = /^([+-])(\\d+)([dmy])$/;\n        const match = re.exec(v);\n        if (!match) {\n            return v;\n        }\n        const sign = match[1] === '-' ? -1 : 1;\n        const offset = +match[2];\n        const r = new Date();\n        r.setHours(0, 0, 0, 0);\n        switch (match[3]) {\n            case 'd':\n                r.setDate(r.getDate() + offset * sign);\n                break;\n            case 'm':\n                const originalDay = r.getDate();\n                r.setMonth(r.getMonth() + offset * sign);\n                if (r.getDate() !== originalDay) {\n                    r.setDate(0);\n                }\n                break;\n            case 'y':\n                r.setFullYear(r.getFullYear() + offset * sign);\n                break;\n        }\n        return formatLocalDate(r);\n    }\n}\n\nclass InputLocalTime extends InputLocalDate {\n    _type() {\n        return 'time';\n    }\n}\n\nclass InputInstant extends Input {\n    static observed = ['value', 'readonly:presence', 'required:presence', 'min', 'max', 'step'];\n    _type() {\n        return 'datetime-local';\n    }\n    render(conf) {\n        const { observed } = conf;\n        super.render(conf);\n        this.min = observed.min;\n        this.max = observed.max;\n        this.step = observed.step;\n    }\n    get value() {\n        const v = this._input.value;\n        return v === '' ? null : new Date(v).toISOString();\n    }\n    set value(v) {\n        this._input.value = v ? Instant.isoToLocal(v) : '';\n    }\n    get min() {\n        const v = this._input.min;\n        return v === '' ? null : new Date(v).toISOString();\n    }\n    set min(v) {\n        this._input.min = v ? Instant.isoToLocal(v) : '';\n    }\n    get max() {\n        const v = this._input.max;\n        return v === '' ? null : new Date(v).toISOString();\n    }\n    set max(v) {\n        this._input.max = v ? Instant.isoToLocal(v) : '';\n    }\n    get step() {\n        const v = this._input.step;\n        return v === '' ? null : v;\n    }\n    set step(v) {\n        this._input.step = v ?? '';\n    }\n}\n\nexport { Instant, LocalDate, InputLocalDate, InputLocalTime, InputInstant };\n","import { Attributes } from '../../ftl/index.mjs';\nimport { Input } from './input.mjs';\n\nclass InputFile extends Input {\n    static l10n = {\n        en: {\n            dropzonelabel: 'Click or drop your files here',\n            unaccepptablefiletype: 'Only files of type {0} are supported',\n            maxfilesizeexceeded: 'Maximum supported file size is {0}',\n            maxtotalsizeexceeded: 'Maximum supported total file size is {0}',\n            maxfilesexceeded: 'Maximum files count exceeded',\n        },\n        it: {\n            dropzonelabel: 'Clicca o trascina i file qui',\n            unaccepptablefiletype: 'Solo i file di tipo {0} sono supportati',\n            maxfilesizeexceeded: 'La dimensione massima di un file è di {0}',\n            maxtotalsizeexceeded: 'La dimensione massima complessiva dei file è di {0}',\n            maxfilesexceeded: 'Numero massimo di file superato',\n        },\n        es: {\n            dropzonelabel: 'Haz clic o arrastra tus archivos aquí',\n            unaccepptablefiletype: 'Solo se admiten archivos de tipo {0}',\n            maxfilesizeexceeded: 'El tamaño máximo de archivo admitido es {0}',\n            maxtotalsizeexceeded: 'El tamaño total máximo admitido es {0}',\n            maxfilesexceeded: 'Se ha superado el número máximo de archivos',\n        },\n        fr: {\n            dropzonelabel: 'Cliquez ou déposez vos fichiers ici',\n            unaccepptablefiletype: 'Seuls les fichiers de type {0} sont pris en charge',\n            maxfilesizeexceeded: 'La taille maximale de fichier prise en charge est {0}',\n            maxtotalsizeexceeded: 'La taille totale maximale prise en charge est {0}',\n            maxfilesexceeded: 'Nombre maximal de fichiers dépassé',\n        },\n    };\n    static observed = [\n        'value',\n        'readonly:presence',\n        'required:presence',\n        'accept:csv',\n        'multiple:presence',\n        'itemlist:presence',\n        'dropzone:presence',\n        'maxfiles:number',\n        'maxfilesize:number',\n        'maxtotalsize:number',\n    ];\n    #accept;\n    #items;\n    #dropzone;\n    #warnings;\n    _type() {\n        return 'file';\n    }\n    static template = `\n        <div class=\"form-label\">\n            <label>{{{{ slots.default }}}}</label>\n            {{{{ slots.info }}}}\n        </div>\n        <div class=\"input-group\">\n            <span data-tpl-if=\"slots.ibefore\" class=\"input-group-text\">{{{{ slots.ibefore }}}}</span>\n            {{{{ slots.before }}}}\n            <input class=\"form-control\" data-tpl-type=\"type\" placeholder=\" \" form=\"\">\n            {{{{ slots.after }}}}\n            <span data-tpl-if=\"slots.iafter\" class=\"input-group-text\">{{{{ slots.iafter }}}}</span>\n        </div>\n        <div data-ref=\"dropzone\" class=\"dropzone\" data-tpl-if=\"slots.dropzone\">\n            {{{{ slots.dropzone }}}}\n        </div>\n        <div data-ref=\"dropzone\" class=\"default-dropzone\" data-tpl-if=\"!slots.dropzone\">\n            {{ #l10n:t('dropzonelabel') }}\n        </div>\n        <ful-item-list></ful-item-list>\n        <ful-field-warnings></ful-field-warnings>\n        <ful-field-error></ful-field-error>\n    `;\n    static templates = {\n        items: `\n            <ful-item data-tpl-each=\"files\" data-tpl-var=\"file\" data-tpl-data-name=\"file.name\">\n                <div>{{ file.name }}</div>\n                <div>{{ #bytes:format(file.size) }}</div>\n                <button type=\"button\" class=\"btn btn-sm btn-outline-danger bi bi-x-lg\" alt=\"Rimuovi\"></button>\n            </ful-item>\n        `,\n        warning: `<ful-field-warning>{{ #l10n:t(key, args) }}</ful-field-warning>`,\n    };\n    render(conf) {\n        const { observed } = conf;\n        super.render(conf);\n        this.#items = this.querySelector('ful-item-list');\n        this.#dropzone = this.querySelector('[data-ref=dropzone]');\n        this.#warnings = this.querySelector('ful-field-warnings');\n        this.accept = observed.accept;\n        this.multiple = observed.multiple;\n        this.itemlist = observed.itemlist;\n        this.dropzone = observed.dropzone;\n        this.maxfiles = observed.maxfiles;\n        this.maxfilesize = observed.maxfilesize;\n        this.maxtotalsize = observed.maxtotalsize;\n        this.#warnings.addEventListener('animationend', (e) => {\n            e.target.remove();\n        });\n        this.#items.addEventListener('click', (e) => {\n            if (!e.target.closest('button')) {\n                return;\n            }\n            const fileName = e.target.closest('ful-item').dataset.name;\n            const dt = new DataTransfer();\n            [...this.files].filter((f) => f.name !== fileName).forEach((f) => dt.items.add(f));\n            this.files = dt.files;\n            this.#update();\n        });\n        this.#dropzone.addEventListener('click', (e) => {\n            this.querySelector('input')?.click();\n        });\n\n        this.#dropzone.addEventListener('dragover', (e) => {\n            e.preventDefault();\n        });\n        this.#dropzone.addEventListener('drop', (e) => {\n            e.preventDefault();\n            const dt = new DataTransfer();\n            [...e.dataTransfer.items].filter((i) => i.kind === 'file').forEach((i) => dt.items.add(i.getAsFile()));\n            this.files = dt.files;\n            this.#update();\n        });\n        this._input.addEventListener('change', (e) => {\n            this.#update();\n        });\n    }\n    #formatByteSize(v) {\n        return v > 1024 * 1024\n            ? `${Math.round((v / 1024 / 1024) * 100) / 100}MiB`\n            : v > 1024\n              ? `${Math.round((v / 1024) * 100) / 100}KiB`\n              : `${v}B`;\n    }\n    #update() {\n        this.setCustomValidity();\n        this.#ensureAcceptable();\n        this.#ensureFileSizes();\n        this.#ensureTotalSize();\n        this.#ensureFilesCount();\n        this.template('items')\n            .withOverlay({ files: this.files })\n            .withModule('bytes', { format: this.#formatByteSize })\n            .renderTo(this.#items);\n    }\n    warning(key, args) {\n        this.template('warning').withOverlay({ key, args }).renderTo(this.#warnings);\n    }\n    #ensureAcceptable() {\n        if (!this.#accept.length) {\n            return;\n        }\n        const unacceptable = [...this.files].filter(\n            (file) => !this.#accept.some((type) => file.name.toLowerCase().endsWith(type.toLowerCase())),\n        );\n\n        if (unacceptable.length === 0) {\n            return;\n        }\n        this.warning('unaccepptablefiletype', this.#accept.join(', '));\n        const dt = new DataTransfer();\n        [...this.files].filter((f) => !unacceptable.includes(f)).forEach((f) => dt.items.add(f));\n        this.files = dt.files;\n    }\n    #ensureFilesCount() {\n        if (this.#maxfiles === null) {\n            return;\n        }\n        if (this.files.length <= this.#maxfiles) {\n            return;\n        }\n        this.warning('maxfilesexceeded');\n        const dt = new DataTransfer();\n        this.files = dt.files;\n    }\n\n    #ensureFileSizes() {\n        if (this.#maxfilesize === null) {\n            return;\n        }\n        const oversized = [...this.files].filter((file) => file.size > this.#maxfilesize);\n        if (oversized.length === 0) {\n            return;\n        }\n        this.warning('maxfilesizeexceeded', this.#formatByteSize(this.#maxfilesize));\n        const dt = new DataTransfer();\n        [...this.files].filter((f) => !oversized.includes(f)).forEach((f) => dt.items.add(f));\n        this.files = dt.files;\n    }\n    #ensureTotalSize() {\n        if (this.#maxtotalsize === null) {\n            return;\n        }\n        const totalSize = [...this.files].reduce((acc, file) => acc + file.size, 0);\n        if (totalSize <= this.#maxtotalsize) {\n            return;\n        }\n        this.warning('maxtotalsizeexceeded', this.#formatByteSize(this.#maxtotalsize));\n        this.files = new DataTransfer().files;\n    }\n    get accept() {\n        return this.#accept;\n    }\n    set accept(vs) {\n        this._input.accept = vs.join(',');\n        this.#accept = vs;\n        this.reflect(() => {\n            this.setAttribute('accept', this._input.accept);\n        });\n    }\n    get multiple() {\n        return this._input.multiple;\n    }\n    set multiple(v) {\n        this._input.multiple = v;\n        this.reflect(() => {\n            Attributes.toggle(this, 'multiple', v);\n        });\n    }\n    get files() {\n        return this._input.files;\n    }\n    set files(vs) {\n        this._input.files = vs;\n    }\n    get file() {\n        return this.files[0] ?? null;\n    }\n    set file(v) {\n        const dt = new DataTransfer();\n        if (v) {\n            dt.items.add(v);\n        }\n        this.files = dt.files;\n    }\n    get value() {\n        const names = Array.from(this._input.files).map((f) => f.name);\n        return this.multiple ? names : (names[0] ?? null);\n    }\n    set value(v) {\n        if (v) {\n            return;\n        }\n        this.files = new DataTransfer().files;\n        this.#update();\n    }\n    get totalsize() {\n        return Array.from(this.files).reduce((a, f) => a + f.size, 0);\n    }\n    #maxfiles;\n    get maxfiles() {\n        return this.#maxfiles;\n    }\n    set maxfiles(v) {\n        this.#maxfiles = v;\n        this.reflect(() => {\n            Attributes.set(this, 'maxfiles', v);\n        });\n    }\n    #maxfilesize;\n    get maxfilesize() {\n        return this.#maxfilesize;\n    }\n    set maxfilesize(v) {\n        this.#maxfilesize = v;\n        this.reflect(() => {\n            Attributes.set(this, 'maxfilesize', v);\n        });\n    }\n    #maxtotalsize;\n    get maxtotalsize() {\n        return this.#maxtotalsize;\n    }\n    set maxtotalsize(v) {\n        this.#maxtotalsize = v;\n        this.reflect(() => {\n            Attributes.set(this, 'maxtotalsize', v);\n        });\n    }\n    #useItemlist;\n    get itemlist() {\n        return this.#useItemlist;\n    }\n    set itemlist(v) {\n        this.#useItemlist = v;\n        this.reflect(() => {\n            Attributes.toggle(this, 'itemlist', v);\n        });\n    }\n    #useDropzone;\n    get dropzone() {\n        return this.#useDropzone;\n    }\n    set dropzone(v) {\n        this.#useDropzone = v;\n        this.reflect(() => {\n            Attributes.toggle(this, 'dropzone', v);\n        });\n    }\n}\n\nexport { InputFile };\n","import { Attributes, Fragments, ParsedElement, registry, Templates } from '../../ftl/index.mjs';\nimport { VersionedLocalStorage } from '../storage.mjs';\nimport { Timing } from '../timing.mjs';\n\nclass RemoteLoader {\n    #http;\n    #url;\n    #method;\n    #responseMapper;\n    #prefetch;\n    #revision;\n    #data;\n    constructor({ http, url, method, responseMapper, prefetch, revision }) {\n        this.#http = http;\n        this.#url = url;\n        this.#method = method;\n        this.#responseMapper = responseMapper;\n        this.#prefetch = prefetch;\n        this.#revision = revision;\n        this.#data = null;\n    }\n    async prefetch() {\n        if (!this.#prefetch) {\n            return;\n        }\n        await this.#ensureFetched();\n    }\n    async exact(...keys) {\n        await this.#ensureFetched();\n        return this.#data.filter(([k, v]) => keys.some((r) => r == k));\n    }\n    async load(needle) {\n        await this.#ensureFetched();\n        return this.#data.filter(([k, v]) => (v ?? '').toLowerCase().includes(needle?.toLowerCase()));\n    }\n    async reconfigureUrl(url) {\n        this.#data = null;\n        this.#url = url;\n    }\n    async #ensureFetched() {\n        if (this.#data !== null) {\n            return;\n        }\n        const raw = await RemoteLoader.#revisionedData(this.#http, this.#method, this.#url, this.#revision);\n        this.#data = this.#responseMapper(raw);\n    }\n    static async #revisionedData(http, method, url, revision) {\n        const storageKey = `${method}@${url}`;\n        if (revision !== null) {\n            const data = VersionedLocalStorage.load(storageKey, revision);\n            if (data !== undefined) {\n                return data;\n            }\n        }\n        const data = await http.request(method, url).fetchJson();\n        if (revision !== null) {\n            VersionedLocalStorage.save(storageKey, revision, data);\n        }\n        return data;\n    }\n}\n\nclass PartialRemoteLoader {\n    #http;\n    #url;\n    #method;\n    #responseMapper;\n    constructor({ http, url, method, responseMapper }) {\n        this.#http = http;\n        this.#url = url;\n        this.#method = method;\n        this.#responseMapper = responseMapper;\n    }\n    async exact(...keys) {\n        const response = await this.#http\n            .request(this.#method, this.#url)\n            .param('k', ...keys)\n            .fetchJson();\n        return this.#responseMapper(response);\n    }\n    async load(needle) {\n        const response = await this.#http.request(this.#method, this.#url).param('s', needle).fetchJson();\n        return this.#responseMapper(response);\n    }\n}\n\nclass InMemoryLoader {\n    #data;\n    constructor(data) {\n        this.#data = data;\n    }\n    update(data) {\n        this.#data = data;\n    }\n    exact(...keys) {\n        return this.#data.filter(([k, v]) => keys.some((r) => r == k));\n    }\n    load(needle) {\n        return this.#data.filter(([k, v]) => (v ?? '').toLowerCase().includes(needle?.toLowerCase()));\n    }\n}\n\nclass SelectLoader {\n    static create(el, conf) {\n        if (!el.hasAttribute('src')) {\n            const els = Array.from(conf.options?.querySelectorAll('option') ?? []);\n            const data = els.map((e) => {\n                return [e.getAttribute('value') ?? e.innerText.trim(), e.innerText.trim()];\n            });\n            return new InMemoryLoader(data);\n        }\n        const http = registry.component('http-client');\n        const responseMapper = SelectLoader.#responseMapperFrom(el);\n\n        if ('chunked' == el.getAttribute('mode')) {\n            return new PartialRemoteLoader({\n                http,\n                url: el.getAttribute('src'),\n                method: el.getAttribute('method') ?? 'POST',\n                responseMapper,\n            });\n        }\n        return new RemoteLoader({\n            http,\n            url: el.getAttribute('src'),\n            method: el.getAttribute('method') ?? 'POST',\n            responseMapper,\n            prefetch: el.hasAttribute('preload'),\n            revision: el.getAttribute('revision'),\n        });\n    }\n    static #responseMapperFrom(el) {\n        if (el.hasAttribute('k-expr') && el.hasAttribute('l-expr')) {\n            return (response) => {\n                const rows = registry\n                    .evaluator()\n                    .withOverlay(response)\n                    .evaluateExpression(el.getAttribute('d-expr') ?? 'self');\n                return rows.map((row) => {\n                    const evaluator = registry.evaluator().withOverlay(row);\n                    return [\n                        evaluator.evaluateExpression(el.getAttribute('k-expr')),\n                        evaluator.evaluateExpression(el.getAttribute('l-expr')),\n                        evaluator.evaluateExpression(el.getAttribute('m-expr') ?? 'self'),\n                    ];\n                });\n            };\n        }\n        if (el.hasAttribute('response-mapper')) {\n            return registry.component(el.getAttribute('response-mapper'));\n        }\n        return (response) => response;\n    }\n}\n\nclass Dropdown extends ParsedElement {\n    static slots = true;\n    static template = `\n        <ful-spinner class=\"centered\" hidden></ful-spinner>\n        <menu tabindex=\"-1\" role=\"listbox\" hidden></menu>\n    `;\n    static templates = {\n        options: `\n            <li data-tpl-each=\"self\" data-tpl-selected=\"index == 0\" data-tpl-value=\"index\" role=\"option\" data-tpl-aria-selected=\"index == 0 ? 'true' : 'false'\">\n                {{ label }}\n            </li>\n        `,\n    };\n    #spinner;\n    #menu;\n    #optionstemplate;\n    #options = new Map();\n    render({ slots }) {\n        const fragment = this.template().render();\n        this.#optionstemplate = Fragments.isBlank(slots.default)\n            ? this.template('options')\n            : Templates.fromFragment(slots.default);\n        this.#spinner = fragment.querySelector('ful-spinner');\n        this.#menu = fragment.querySelector('menu');\n        this.#menu.addEventListener('click', (evt) => {\n            evt.stopPropagation();\n            const li = evt.target.closest('li');\n            if (!li) {\n                this.hide();\n                return;\n            }\n            this.#change(li);\n        });\n        this.replaceChildren(fragment);\n    }\n    acceptSelection() {\n        const selected = this.#menu.querySelector('[selected]') ?? this.#menu.firstElementChild;\n        this.#change(selected);\n    }\n    update(values) {\n        if (values === undefined) {\n            throw new Error('null data');\n        }\n        this.#options = new Map(values.map((v, i) => [String(i), v]));\n        const data = values.map(([key, label, metadata], index) => ({ index, key, label, metadata }));\n        this.#optionstemplate.withOverlay(data).renderTo(this.#menu);\n    }\n    #change(target) {\n        const index = target.getAttribute('value');\n        const data = this.#options.get(index);\n        this.hide();\n        this.dispatchEvent(\n            new CustomEvent('change', {\n                bubbles: true,\n                cancelable: false,\n                detail: { index, data },\n            }),\n        );\n    }\n    hide() {\n        this.setAttribute('hidden', '');\n    }\n    get shown() {\n        return !this.hasAttribute('hidden');\n    }\n    async show(loader) {\n        this.removeAttribute('hidden');\n        this.#menu.setAttribute('hidden', '');\n        this.#spinner.removeAttribute('hidden');\n        try {\n            const data = await loader();\n            this.update(data);\n        } finally {\n            this.#spinner.setAttribute('hidden', '');\n            this.#menu.removeAttribute('hidden');\n        }\n    }\n    async moveOrShow(forward, loader) {\n        if (this.shown) {\n            const selected = this.#menu.querySelector('[selected]') ?? this.#menu.firstElementChild;\n            const candidate = selected[`${forward ? 'next' : 'previous'}ElementSibling`];\n            if (candidate) {\n                selected.removeAttribute('selected');\n                candidate.setAttribute('selected', '');\n                candidate.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n            }\n            return;\n        }\n        await this.show(loader);\n    }\n}\n\nclass Select extends ParsedElement {\n    static observed = ['value:csvm', 'readonly:presence', 'required:presence', 'itemlist:presence'];\n    static slots = true;\n    static template = `\n        <div class=\"form-label\">\n            <label>{{{{ slots.default }}}}</label>\n            {{{{ slots.info }}}}\n        </div>\n        <div class=\"input-group flex-nowrap\" tabindex=\"-1\">\n            <span data-tpl-if=\"slots.ibefore\" class=\"input-group-text\">{{{{ slots.ibefore }}}}</span>\n            {{{{ slots.before }}}}\n            <div class=\"ful-select-input-container\">\n                <div class=\"ful-select-input\">\n                    <badges></badges>\n                    <input type=\"text\" form=\"\" role=\"combobox\" aria-autocomplete=\"list\" aria-haspopup=\"listbox\" aria-expanded=\"false\">\n                </div>\n                <ful-dropdown hidden popover=\"manual\">{{{{ slots.dropdown }}}}</ful-dropdown>\n            </div>\n            {{{{ slots.after }}}}\n            <span data-tpl-if=\"slots.iafter\" class=\"input-group-text\">{{{{ slots.iafter }}}}</span>\n        </div>\n        <ful-item-list></ful-item-list>\n        <ful-field-error></ful-field-error>\n    `;\n    static templates = {\n        items: `\n            <ful-item data-tpl-each=\"entries\" data-tpl-var=\"entry\" data-tpl-data-key=\"entry[0]\">\n                <div>{{ entry[1][0] }}</div>\n                <button type=\"button\" class=\"btn btn-sm btn-outline-danger bi bi-x-lg\"></button>\n            </ful-item>\n        `,\n    };\n    static formAssociated = true;\n    internals;\n    #loader;\n    #badges;\n    #ddmenu;\n    #input;\n    #items;\n    #multiple;\n    #fieldError;\n    #values = new Map();\n    constructor() {\n        super();\n        this.internals = this.attachInternals();\n        this.internals.role = 'presentation';\n    }\n    async render({ slots, observed, disabled }) {\n        const name = this.getAttribute('name');\n        this.#loader = registry\n            .component(this.getAttribute('loader') ?? 'loaders:select')\n            .create(this, { options: slots.options });\n\n        this.#multiple = this.hasAttribute('multiple');\n        await this.#loader.prefetch?.();\n        const fragment = this.template().withOverlay({ slots, name }).render();\n        this.#input = fragment.querySelector('input');\n        this.#items = fragment.querySelector('ful-item-list');\n        Attributes.forward('input-', this, this.#input);\n        this.#badges = fragment.querySelector('badges');\n\n        this.value = observed.value;\n        this.disabled = disabled;\n        this.readonly = observed.readonly;\n        this.required = observed.required;\n        this.itemlist = observed.itemlist;\n\n        this.#ddmenu = fragment.querySelector('ful-dropdown');\n        const label = fragment.querySelector('label');\n        label.addEventListener('click', () => this.focus());\n        this.#fieldError = fragment.querySelector('ful-field-error');\n        this.#input.ariaDescribedByElements = [this.#fieldError];\n        this.#input.ariaLabelledByElements = [label];\n\n        const self = this;\n        const [dload, abortdload] = Timing.throttle(400, () => {\n            self.#input.setAttribute('aria-expanded', 'true');\n            self.#ddmenu.show(() => self.#loader.load(self.#input.value));\n        });\n        this.addEventListener('click', (/** @type any */ e) => {\n            if (e.target.matches('input')) {\n                return;\n            }\n            if (this.disabled || this.readonly) {\n                return;\n            }\n            if (this.#ddmenu.shown) {\n                this.#input.setAttribute('aria-expanded', 'false');\n                this.#ddmenu.hide();\n                return;\n            }\n            this.#input.focus();\n            dload();\n        });\n        this.#items.addEventListener('click', (e) => {\n            e.stopPropagation();\n            if (!e.target.closest('button')) {\n                return;\n            }\n            if (this.disabled || this.readonly) {\n                return;\n            }\n            const idx = [...this.#items.children].indexOf(e.target.closest('ful-item'));\n            if (idx === -1) {\n                return;\n            }\n            this.#values.delete(Array.from(this.#values.keys())[idx]);\n            this.#changed();\n            this.#syncBadges();\n        });\n        this.#badges.addEventListener('click', (e) => {\n            e.stopPropagation();\n            if (this.disabled || this.readonly) {\n                return;\n            }\n            const idx = [...this.#badges.children].indexOf(e.target);\n            if (idx === -1) {\n                return;\n            }\n            this.#values.delete(Array.from(this.#values.keys())[idx]);\n            this.#changed();\n            this.#syncBadges();\n        });\n        this.#input.addEventListener('change', (e) => {\n            e.stopPropagation();\n        });\n        this.#input.addEventListener('blur', (e) => {\n            e.stopPropagation();\n            if (e.relatedTarget && this.contains(e.relatedTarget)) {\n                return;\n            }\n            abortdload();\n            this.#input.setAttribute('aria-expanded', 'false');\n            this.#ddmenu.hide();\n            this.#input.value = '';\n        });\n        this.#input.addEventListener('keydown', (e) => {\n            if (this.disabled || this.readonly) {\n                return;\n            }\n            switch (e.code) {\n                case 'ArrowUp': {\n                    e.preventDefault();\n                    this.#input.setAttribute('aria-expanded', 'true');\n                    this.#ddmenu.moveOrShow(false, () => self.#loader.load(self.#input.value));\n                    break;\n                }\n                case 'ArrowDown': {\n                    e.preventDefault();\n                    this.#input.setAttribute('aria-expanded', 'true');\n                    this.#ddmenu.moveOrShow(true, () => self.#loader.load(self.#input.value));\n                    break;\n                }\n                case 'Escape': {\n                    this.#input.setAttribute('aria-expanded', 'false');                    \n                    this.#ddmenu.hide();\n                    break;\n                }\n                case 'Enter': {\n                    e.preventDefault();\n                    this.#input.setAttribute('aria-expanded', 'false');\n                    this.#ddmenu.acceptSelection();\n                    this.#input.value = '';\n                    break;\n                }\n                case 'Backspace': {\n                    //remove last if caret at position 0\n                    if (this.#values.size && this.#input.selectionStart === 0 && this.#input.selectionEnd === 0) {\n                        this.#values.delete(Array.from(this.#values.keys()).pop());\n                        this.#changed();\n                        this.#syncBadges();\n                    }\n                    break;\n                }\n                case 'Tab': {\n                    this.#input.setAttribute('aria-expanded', 'false');\n                    this.#ddmenu.hide();\n                    abortdload();\n                    break;\n                }\n            }\n        });\n        this.#input.addEventListener('input', (e) => {\n            e.stopPropagation();\n            if (this.disabled || this.readonly) {\n                return;\n            }\n            dload();\n        });\n        this.#ddmenu.addEventListener('change', (e) => {\n            e.stopPropagation();\n            if (!this.#multiple) {\n                this.#values.clear();\n            }\n            this.#values.set(e.detail.data[0], e.detail.data.slice(1));\n            this.#changed();\n            this.#syncBadges();\n            this.#input.focus();\n            this.#input.setAttribute('aria-expanded', 'false');\n            this.#ddmenu.hide();\n            this.#input.value = '';\n        });\n        this.replaceChildren(fragment);\n    }\n    async withLoader(fn) {\n        return await fn(this.#loader);\n    }\n    #changed() {\n        const selection = [...this.#values.entries()].map((e) => ({\n            key: e[0],\n            label: e[1][0],\n            metadata: e[1].slice(1),\n        }));\n        const value = this.#multiple ? selection : (selection[0] ?? null);\n        this.dispatchEvent(\n            new CustomEvent('change', {\n                bubbles: true,\n                cancelable: false,\n                detail: { value },\n            }),\n        );\n    }\n    #syncBadges() {\n        const badges = Array.from(this.#values.entries()).map(([k, v]) => {\n            const b = document.createElement('badge');\n            b.setAttribute('role', 'button');\n            b.setAttribute('value', k);\n            b.innerText = v[0];\n            return b;\n        });\n        this.#badges.replaceChildren();\n        this.#badges.append(...badges);\n        this.#items.replaceChildren();\n        this.template('items').withOverlay({ entries: this.#values.entries() }).renderTo(this.#items);\n    }\n    set value(vs) {\n        if (vs === null) {\n            this.#values = new Map();\n            this.#syncBadges();\n            return;\n        }\n        (async () => {\n            const entries = await (this.#multiple ? this.#loader.exact(...vs) : this.#loader.exact(vs));\n            this.#values = new Map(entries.map((e) => [e[0], e.slice(1)]));\n            this.#syncBadges();\n        })();\n    }\n    get value() {\n        if (this.#multiple) {\n            return [...this.#values.keys()];\n        }\n        return [...this.#values.keys()][0] ?? null;\n    }\n    get entry() {\n        if (this.#multiple) {\n            return [...this.#values.entries()];\n        }\n        return [...this.#values.entries()][0] ?? null;\n    }\n    get disabled() {\n        return this.#input.hasAttribute('disabled');\n    }\n    set disabled(d) {\n        Attributes.toggle(this.#input, 'disabled', d);\n    }\n    get readonly() {\n        return this.#input.readOnly;\n    }\n    set readonly(v) {\n        this.#input.readOnly = v;\n        this.reflect(() => {\n            Attributes.toggle(this, 'readonly', v);\n        });\n    }\n    get required() {\n        return this.#input.getAttribute('aria-required') === 'true';\n    }\n    set required(d) {\n        Attributes.set(this.#input, 'aria-required', d ? 'true' : null);\n        this.reflect(() => {\n            Attributes.toggle(this, 'required', d);\n        });\n    }\n    #useItemlist;\n    get itemlist() {\n        return this.#useItemlist;\n    }\n    set itemlist(v) {\n        this.#useItemlist = v;\n        this.reflect(() => {\n            Attributes.toggle(this, 'itemlist', v);\n        });\n    }\n    focus(options) {\n        this.#input.focus(options);\n    }\n    setCustomValidity(error) {\n        if (!error) {\n            this.internals.setValidity({});\n            this.#fieldError.innerText = '';\n            return;\n        }\n        this.internals.setValidity({ customError: true }, ' ');\n        this.#fieldError.innerText = error;\n    }\n}\n\nexport { Dropdown, Select, SelectLoader };\n","import { Attributes, Fragments, ParsedElement } from '../../ftl/index.mjs';\n\nclass RadioGroup extends ParsedElement {\n    static observed = ['value', 'readonly:presence', 'required:presence'];\n    static slots = true;\n    static template = `\n        <fieldset>\n            <legend class=\"form-label\">\n                {{{{ slots.default }}}}\n            </legend>\n            <header data-tpl-if=\"slots.header\">\n                {{{{ slots.header }}}}\n            </header>\n            <section>\n                <div class=\"label-wrapper\" data-tpl-each=\"inputsAndLabels\" data-tpl-var=\"ial\">\n                    <label>\n                        {{{{ ial[0] }}}}\n                        <div>{{{{ ial[1] }}}}</div>\n                    </label>\n                </div>\n            </section>\n            <ful-field-error></ful-field-error>\n            <footer data-tpl-if=\"slots.footer\">\n                {{{{ slots.footer }}}}\n            </footer>\n        </fieldset>\n    `;\n    static formAssociated = true;\n    #fieldset;\n    #fieldError;\n    #firstRadio;\n    #booleanType;\n    constructor() {\n        super();\n        this.internals = this.attachInternals();\n        this.internals.role = 'radiogroup';\n    }\n    render({ slots, observed, disabled }) {\n        const name = this.getAttribute('name') ?? Attributes.uid('ful-radiogroup');\n        const radioEls = Array.from(slots.default.querySelectorAll('ful-radio'));\n        const inputsAndLabels = radioEls.map((el) => {\n            const input = document.createElement('input');\n            input.setAttribute('type', 'radio');\n            Attributes.forward('input-', this, input);\n            Attributes.forward('', el, input);\n            input.setAttribute('name', `${name}-ignore`);\n            input.setAttribute('form', ``);\n            input.addEventListener('change', (evt) => {\n                evt.stopPropagation();\n                //change is not cancelable\n                this.dispatchEvent(\n                    new CustomEvent('change', {\n                        bubbles: true,\n                        cancelable: false,\n                        detail: {\n                            value: this.value,\n                        },\n                    }),\n                );\n            });\n            const label = Fragments.fromChildNodes(el);\n            return [input, label];\n        });\n\n        radioEls.forEach((el) => el.remove());\n        this.template().withOverlay({ name, slots, inputsAndLabels }).renderTo(this);\n        this.#fieldset = this.firstElementChild;\n        this.disabled = disabled;\n        this.readonly = observed.readonly;\n        this.required = observed.required;\n        this.value = observed.value;\n        this.#fieldError = this.querySelector('ful-field-error');\n        this.ariaDescribedByElements = [this.#fieldError];\n        this.#firstRadio = this.querySelector('input[type=radio]');\n        this.#booleanType = this.getAttribute('type') === 'boolean';\n    }\n    get value() {\n        /** @type {HTMLInputElement|null} */\n        const checked = this.querySelector('input[type=radio]:checked');\n        return checked ? (this.#booleanType ? checked.value === 'true' : checked.value) : null;\n    }\n    set value(value) {\n        if (value === null) {\n            this.querySelectorAll(`input[type=radio]`).forEach((el) => {\n                /** @type {HTMLInputElement} */ (el).checked = false;\n            });\n            return;\n        }\n        /** @type {HTMLInputElement|null} */\n        const el = this.querySelector(`input[type=radio][value=${CSS.escape(String(value))}]`);\n        if (el) {\n            el.checked = true;\n        }\n    }\n    get readonly() {\n        return this.#fieldset.inert;\n    }\n    set readonly(v) {\n        this.#fieldset.inert = v;\n        this.reflect(() => {\n            Attributes.toggle(this, 'readonly', v);\n        });\n    }\n    get disabled() {\n        return this.#fieldset.hasAttribute('disabled');\n    }\n    set disabled(d) {\n        Attributes.toggle(this.#fieldset, 'disabled', d);\n    }\n    get required() {\n        return this.#fieldset.getAttribute('aria-required') === 'true';\n    }\n    set required(d) {\n        Attributes.set(this.#fieldset, 'aria-required', d ? 'true' : null);\n        this.reflect(() => {\n            Attributes.toggle(this, 'required', d);\n        });\n    }\n    focus(options) {\n        this.#firstRadio.focus(options);\n    }\n    setCustomValidity(error) {\n        if (!error) {\n            this.internals.setValidity({});\n            this.#fieldError.innerText = '';\n            return;\n        }\n        this.internals.setValidity({ customError: true }, ' ');\n        this.#fieldError.innerText = error;\n    }\n}\n\nexport { RadioGroup };\n","import { Attributes, ParsedElement } from '../../ftl/index.mjs';\n\nclass Checkbox extends ParsedElement {\n    static observed = ['value:bool', 'readonly:presence', 'required:presence'];\n    static slots = true;\n    static template = `\n        <div data-tpl-class=\"klass\">\n            <div class=\"input-container\">\n                <input class=\"form-check-input\" type=\"checkbox\" data-tpl-role=\"isSwitch ? 'switch' : false\" form=\"\" placeholder=\" \">\n            </div>\n            <div class=\"form-check-label\">\n                <label>{{{{ slots.default }}}}</label>\n                {{{{ slots.info }}}}\n            </div>\n        </div>\n        <ful-field-error></ful-field-error>\n    `;\n    #container;\n    #input;\n    #fieldError;\n    static formAssociated = true;\n    constructor() {\n        super();\n        this.internals = this.attachInternals();\n        this.internals.role = 'presentation';\n    }\n    render({ slots, observed, disabled }) {\n        const isSwitch = this.getAttribute('type') == 'switch';\n        const klass = isSwitch ? 'form-check form-switch' : 'form-check';\n        const fragment = this.template().withOverlay({ slots, klass, isSwitch }).render();\n        this.#container = fragment.firstElementChild;\n        this.#input = fragment.querySelector('input');\n        Attributes.forward('input-', this, this.#input);\n        this.disabled = disabled;\n        this.readonly = observed.readonly;\n        this.required = observed.required;\n        this.value = observed.value;\n        this.#input.addEventListener('change', (evt) => {\n            evt.stopPropagation();\n            this.dispatchEvent(\n                new CustomEvent('change', {\n                    bubbles: true,\n                    cancelable: false,\n                    detail: {\n                        value: this.value,\n                    },\n                }),\n            );\n        });\n        const label = fragment.querySelector('label');\n        label.addEventListener('click', () => {\n            this.focus();\n            if (this.disabled || this.readonly) {\n                return;\n            }\n            this.value = !this.value;\n            this.dispatchEvent(\n                new CustomEvent('change', {\n                    bubbles: true,\n                    cancelable: false,\n                    detail: {\n                        value: this.value,\n                    },\n                }),\n            );\n        });\n        this.#fieldError = fragment.querySelector('ful-field-error');\n        this.#input.ariaDescribedByElements = [this.#fieldError];\n        this.#input.ariaLabelledByElements = [label];\n        this.replaceChildren(fragment);\n    }\n    get value() {\n        return this.#input.checked;\n    }\n    set value(value) {\n        this.#input.checked = value;\n    }\n    get readonly() {\n        return this.#container.inert;\n    }\n    set readonly(v) {\n        this.#container.inert = v;\n        this.reflect(() => {\n            Attributes.toggle(this, 'readonly', v);\n        });\n    }\n    get disabled() {\n        return this.#input.hasAttribute('disabled');\n    }\n    set disabled(d) {\n        Attributes.toggle(this.#input, 'disabled', d);\n    }\n    get required() {\n        return this.#input.getAttribute('aria-required') === 'true';\n    }\n    set required(d) {\n        Attributes.set(this.#input, 'aria-required', d ? 'true' : null);\n        this.reflect(() => {\n            Attributes.toggle(this, 'required', d);\n        });\n    }\n    focus(options) {\n        this.#input.focus(options);\n    }\n    setCustomValidity(error) {\n        if (!error) {\n            this.internals.setValidity({});\n            this.#fieldError.innerText = '';\n            return;\n        }\n        this.internals.setValidity({ customError: true }, ' ');\n        this.#fieldError.innerText = error;\n    }\n}\n\nexport { Checkbox };\n","import { ParsedElement } from '../../ftl/index.mjs';\n\nclass Spinner extends ParsedElement {\n    static slots = true;\n    static template = `\n        <div class=\"ful-spinner-wrapper\" role=\"status\">\n            <div class=\"ful-spinner-text\">{{{{ slots.default }}}}</div>\n            <div class=\"ful-spinner-icon\"></div>\n        </div>\n    `;\n    render({ slots }) {\n        this.template().withOverlay({ slots }).renderTo(this);\n    }\n}\n\nexport { Spinner };\n","import { Attributes, Fragments, Nodes, ParsedElement, registry, Rendering } from '../../ftl/index.mjs';\n\nclass SortButton extends ParsedElement {\n    static observed = ['order'];\n    #order;\n    render() {\n        const sorter = this.getAttribute('sorter');\n        const orders = ['asc', 'desc', null];\n        this.addEventListener('click', () => {\n            const nextOrder = orders[(orders.indexOf(this.order) + 1) % 3];\n            this.dispatchEvent(\n                new CustomEvent('sort-requested', {\n                    bubbles: true,\n                    cancelable: true,\n                    detail: {\n                        value: { sorter, order: nextOrder },\n                    },\n                }),\n            );\n        });\n    }\n\n    get order() {\n        return this.#order || null;\n    }\n\n    set order(value) {\n        this.#order = value || null;\n        this.reflect(() => {\n            if (this.#order) {\n                this.setAttribute('order', value);\n            } else {\n                this.removeAttribute('order');\n            }\n        });\n    }\n}\n\nclass Pagination extends ParsedElement {\n    static observed = ['total:number', 'current:number'];\n    static l10n = {\n        en: {\n            showing: 'Page {0} of {1}',\n            navigation: 'Page navigation',\n            previous: 'Previous',\n            next: 'Next',\n        },\n        it: {\n            showing: 'Pagina {0} di {1}',\n            navigation: 'Navigazione pagine',\n            previous: 'Precedente',\n            next: 'Successivo',\n        },\n        es: {\n            showing: 'Página {0} de {1}',\n            navigation: 'Navegación de páginas',\n            previous: 'Anterior',\n            next: 'Siguiente',\n        },\n        fr: {\n            showing: 'Page {0} sur {1}',\n            navigation: 'Navigation des pages',\n            previous: 'Précédent',\n            next: 'Suivant',\n        },\n    };\n    static config = {\n        prevIcon: 'bi bi-chevron-left',\n        nextIcon: 'bi bi-chevron-right',\n        reloadIcon: 'bi bi-arrow-clockwise',\n    };\n    static template = `\n        <nav data-tpl-aria-label=\"#l10n:t('navigation')\" class=\"user-select-none\">\n            <ul class=\"pagination\">\n                <li class=\"page-item ms-auto me-2 pagination-index\"> {{ #l10n:t('showing', curr.label, total) }}</li>\n                <li class=\"page-item me-2 reload\"><a role=\"button\"><i data-tpl-class=\"config.reloadIcon\"></i></a></li>\n                <li class=\"page-item prev\">\n                    <a data-tpl-class=\"prev.enabled?'page-link':'page-link disabled'\" data-tpl-aria-label=\"#l10n:t('previous')\" role=\"button\" data-tpl-data-page=\"prev.index\">\n                        <i aria-hidden=\"true\" data-tpl-class=\"config.prevIcon\"></i>\n                    </a>\n                </li>\n                <li class=\"page-item\" data-tpl-each=\"pages\" data-tpl-var=\"page\">\n                    <a data-tpl-class=\"curr.index != page.index ? 'page-link': 'page-link disabled'\" role=\"button\" data-tpl-data-page=\"page.index\" >\n                        {{ page.label }}\n                    </a>\n                </li>\n                <li class=\"page-item next\">\n                    <a data-tpl-class=\"next.enabled?'page-link':'page-link disabled'\" data-tpl-aria-label=\"#l10n:t('next')\" role=\"button\" data-tpl-data-page=\"next.index\">\n                        <i aria-hidden=\"true\" data-tpl-class=\"config.nextIcon\"></i>\n                    </a>\n                </li>\n            </ul>\n        </nav>\n    `;\n    #total = 0;\n    #current = 0;\n    render({ observed }) {\n        this.update(observed.current ?? 0, observed.total ?? 0);\n        this.addEventListener('click', (/** @type any */ evt) => {\n            const el = evt.target.closest('a');\n            if (!el) {\n                return;\n            }\n            this.dispatchEvent(\n                new CustomEvent('page-requested', {\n                    bubbles: true,\n                    cancelable: true,\n                    detail: {\n                        value: Number(el.dataset.page ?? this.#current),\n                    },\n                }),\n            );\n        });\n    }\n    update(current, total) {\n        const maxRender = Number(this.getAttribute('pages') ?? '5');\n        const prev = { index: Math.max(0, current - 1), enabled: current > 0 };\n        const curr = { index: current, label: current + 1 };\n        const next = { index: Math.min(total, current + 1), enabled: current + 1 < total };\n        const pages = [\n            {\n                index: current,\n                label: current + 1,\n            },\n        ];\n        for (let mid = current, offset = 1; offset !== maxRender && pages.length != maxRender; ++offset) {\n            const p = mid - offset;\n            if (p >= 0) {\n                pages.unshift({ index: p, label: p + 1 });\n            }\n            const n = mid + offset;\n            if (n < total) {\n                pages.push({ index: n, label: n + 1 });\n            }\n        }\n        this.template().withOverlay({ total, prev, curr, next, pages }).renderTo(this);\n    }\n    get total() {\n        return this.#total;\n    }\n    set total(value) {\n        this.#total = value;\n        this.reflect(() => {\n            this.setAttribute('total', String(value));\n            this.update(this.#current ?? 0, this.#total);\n        });\n    }\n    get current() {\n        return this.#current;\n    }\n    set current(value) {\n        this.#current = value;\n        this.reflect(() => {\n            this.setAttribute('current', String(value));\n            this.update(this.#current, this.#total ?? 0);\n        });\n    }\n}\n\nclass TableSchemaParser {\n    static parse(nodeOrFragment, template) {\n        const schema = Nodes.queryChildren(nodeOrFragment, 'schema');\n        if (!schema) {\n            throw new Error(`missing expected <schema> in ${nodeOrFragment}`);\n        }\n        const headersTr = document.createElement('tr');\n        const rowsTr = document.createElement('tr');\n        rowsTr.setAttribute('data-tpl-each', 'rows');\n        for (const attr of schema.getAttributeNames()) {\n            const value = schema.getAttribute(attr);\n            headersTr.setAttribute(attr, value ?? '');\n            rowsTr.setAttribute(attr, value ?? '');\n        }\n        const columns = Nodes.queryChildrenAll(schema, 'column');\n        const sort =\n            columns\n                .filter((v) => v.hasAttribute('order'))\n                .map((v) => ({ sorter: v.getAttribute('sorter'), order: v.getAttribute('order') }))[0] ?? null;\n        for (var column of columns) {\n            const maybeTitleTag = Nodes.queryChildren(column, 'title');\n            const sorter = column.getAttribute('sorter');\n            const order = column.getAttribute('order');\n            const titleNode = maybeTitleTag ?? document.createTextNode(column.getAttribute('title') ?? '');\n            maybeTitleTag?.remove();\n            column.removeAttribute('sorter');\n            column.removeAttribute('order');\n            column.removeAttribute('title');\n            const wrappedTitleNode =\n                !sorter && !order\n                    ? titleNode\n                    : (() => {\n                          const fulSorter = document.createElement('ful-sorter');\n                          if (sorter) {\n                              fulSorter.setAttribute('sorter', sorter);\n                          }\n                          if (order) {\n                              fulSorter.setAttribute('order', order);\n                          }\n                          fulSorter.append(titleNode);\n                          return fulSorter;\n                      })();\n            const th = document.createElement('th');\n            const td = document.createElement('td');\n            for (const attr of column.getAttributeNames()) {\n                const value = column.getAttribute(attr);\n                th.setAttribute(attr, value ?? '');\n                td.setAttribute(attr, value ?? '');\n            }\n            th.append(wrappedTitleNode);\n            td.append(...column.childNodes);\n            headersTr.append(th);\n            rowsTr.append(td);\n        }\n\n        return {\n            headersTemplate: template\n                .withOverlay({ inHeaders: true, inRows: false })\n                .withFragment(Fragments.from(headersTr)),\n            rowsTemplate: template.withOverlay({ inHeaders: false, inRows: true }).withFragment(Fragments.from(rowsTr)),\n            sort: sort,\n            length: columns.length,\n        };\n    }\n}\n\nclass InMemoryTableLoader {\n    #data;\n    constructor(data) {\n        this.#data = data;\n    }\n    async load(pageRequest, sortRequest, filterRequest) {\n        const begin = pageRequest.page * pageRequest.size;\n        const end = begin + pageRequest.size;\n        const page = this.#data.slice(begin, end);\n        const totalElements = this.#data.length;\n        return {\n            data: page,\n            size: totalElements\n        };\n    }\n    update(data) {\n        this.#data = data;\n    }\n}\n\nclass RemoteTableLoader {\n    #http;\n    #url;\n    #method;\n    constructor(http, url, method) {\n        this.#http = http;\n        this.#url = url;\n        this.#method = method;\n    }\n    async load(pageRequest, sortRequest, filterRequest) {\n        const filters = Object.entries(filterRequest).filter(([k, v]) => v);\n        return await this.#http\n            .request(this.#method, this.#url)\n            .param('page', pageRequest.page)\n            .param('size', pageRequest.size)\n            .param('sort', sortRequest ? `${sortRequest.sorter},${sortRequest.order}` : null)\n            .param('filters', filters.length > 0 ? JSON.stringify(Object.fromEntries(filters)) : null)\n            .fetchJson();\n    }\n}\n\nclass TableLoader {\n    static create(el, conf) {\n        const url = el.getAttribute('src');\n        if (url) {\n            const http = registry.component('http-client');\n            const method = el.getAttribute('method') ?? 'GET';\n            return new RemoteTableLoader(http, url, method);\n        }\n        return new InMemoryTableLoader([]);\n    }\n}\n\nclass Table extends ParsedElement {\n    static slots = true;\n    static l10n = {\n        en: {\n            initial: 'Start searching to see results.',\n            error: 'Error while loading data:',\n            nodata: 'No elements found.',\n        },\n        it: {\n            initial: 'Avvia la ricerca per visualizzare i risultati.',\n            error: 'Errore nel caricamento dei dati:',\n            nodata: 'Nessun elemento trovato.',\n        },\n        es: {\n            initial: 'Inicia la búsqueda para ver los resultados.',\n            error: 'Error al cargar los datos:',\n            nodata: 'No se encontraron elementos.',\n        },\n        fr: {\n            initial: 'Lancez la recherche pour voir les résultats.',\n            error: 'Erreur lors du chargement des données :',\n            nodata: 'Aucun élément trouvé.',\n        },\n    };\n    static config = {\n        searchIcon: 'bi bi-search',\n    };\n    static template = `\n        <ful-form data-tpl-if=\"slots.filters\">\n            {{{{ slots.filters }}}}\n        </ful-form>\n        <div class=\"table-wrapper\">\n            <table class=\"table\">\n                <caption data-tpl-if=\"slots.caption\">{{{{ slots.caption }}}}</caption>\n                <thead></thead>\n                <tbody></tbody>\n                <tbody data-ref=\"initial\">\n                    <tr>\n                        <td data-tpl-colspan=\"schema.length\">\n                            <div>\n                                <p data-tpl-if=\"config.searchIcon\"><i data-tpl-class=\"config.searchIcon\"></i></p>\n                                {{{ #l10n:t('initial') }}}\n                            </div>\n                        </td>\n                    </tr>\n                </tbody>\n                <tbody data-ref=\"loading\" hidden>\n                    <tr>\n                        <td data-tpl-colspan=\"schema.length\">\n                            <ful-spinner class=\"big\"></ful-spinner>\n                        </td>\n                    </tr>\n                </tbody>\n                <tbody data-ref=\"feedback\" hidden>\n                    <tr>\n                        <td data-tpl-colspan=\"schema.length\">\n                            <div class=\"alert alert-danger\">\n                                <p>{{ #l10n:t('error') }}</p>\n                                <div data-ref=\"feedback-error\"></div>\n                            </div>\n                        </td>\n                    </tr>\n                </tbody>\n                <tfoot data-tpl-if=\"slots.footer\">\n                    {{{{ slots.footer }}}}\n                </tfoot>\n            </table>\n        </div>\n        <ful-pagination current=\"0\" total=\"1\"></ful-pagination>\n    `;\n    static templates = {\n        row: `\n            <tr data-tpl-if=\"pageResponse.data.length == 0\">\n                <td data-tpl-colspan=\"schema.length\" class=\"text-center align-middle p-4\">\n                    {{ #l10n:t('nodata') }}\n                </td>\n            </tr>\n            {{{{ schema.rowsTemplate.withOverlay({'rows': pageResponse.data}).render() }}}}\n        `,\n    };\n    #loader;\n    #schema;\n    #body;\n    #loading;\n    #noAutoload;\n    #feedback;\n    #paginator;\n    #sorters;\n    #latestRequest;\n    async render({ slots, observed }) {\n        const template = this.template();\n        const schema = TableSchemaParser.parse(slots.schema, template);\n        const fragment = template.withOverlay({ slots, schema }).render();\n        const tableWrapper = /** @type HTMLTableElement */ (Nodes.queryChildren(fragment, '.table-wrapper'));\n        const table = /** @type HTMLTableElement */ (tableWrapper.querySelector('table'));\n        Attributes.forward('table-', this, table);\n        this.#loader = registry.component(this.getAttribute('loader') ?? 'loaders:table').create(this);\n\n        this.#schema = schema;\n        this.#body = table.querySelector(':scope > tbody');\n        this.#loading = table.querySelector(':scope > tbody[data-ref=loading]');\n        this.#noAutoload = table.querySelector(':scope > tbody[data-ref=initial]');\n        this.#feedback = table.querySelector(':scope > tbody[data-ref=feedback]');\n        this.#paginator = Nodes.queryChildren(fragment, 'ful-pagination');\n        this.#sorters = table.querySelectorAll(':scope > thead ful-sorter') ?? [];\n        this.replaceChildren(fragment);\n        schema.headersTemplate.renderTo(this.querySelector('thead'));\n        await Rendering.waitForChildren(this);\n\n        const maybeForm = /** @type any */ (Nodes.queryChildren(this, 'ful-form'));\n        this.#latestRequest = {\n            pageRequest: {\n                page: 0,\n                size: this.getAttribute('page-size') ? Number(this.getAttribute('page-size')) : 10,\n            },\n            sortRequest: schema.sort,\n            filterRequest: maybeForm?.values ?? {},\n        };\n        maybeForm?.addEventListener('submit:success', async (evt) => {\n            await this.load(\n                {\n                    page: 0,\n                    size: this.#latestRequest.pageRequest.size,\n                },\n                this.#latestRequest.sortRequest,\n                evt.detail.request,\n            );\n        });\n        this.addEventListener('page-requested', async (/** @type any */ e) => {\n            await this.load(\n                {\n                    page: e.detail.value,\n                    size: this.#latestRequest.pageRequest.size,\n                },\n                this.#latestRequest.sortRequest,\n                this.#latestRequest.filterRequest,\n            );\n        });\n        this.addEventListener('sort-requested', async (/** @type any */ e) => {\n            const sortRequest = e.detail.value.order ? e.detail.value : null;\n            await this.load(this.#latestRequest.pageRequest, sortRequest, this.#latestRequest.filterRequest);\n            this.#sorters.forEach((s) => (s.order = null));\n            e.target.order = e.detail.value.order;\n        });\n        if (this.hasAttribute('autoload')) {\n            await this.reload();\n        }\n    }\n\n    async reload() {\n        return await this.load(\n            this.#latestRequest.pageRequest,\n            this.#latestRequest.sortRequest,\n            this.#latestRequest.filterRequest,\n        );\n    }\n    async load(pageRequest, sortRequest, filterRequest) {\n        this.#body.replaceChildren();\n        this.#loading.removeAttribute('hidden', '');\n        this.#feedback.setAttribute('hidden', '');\n        this.#noAutoload.setAttribute('hidden', '');\n        try {\n            const pageResponse = await this.#loader.load(pageRequest, sortRequest, filterRequest);\n            this.#latestRequest = { pageRequest, sortRequest, filterRequest };\n            this.#update(pageRequest, sortRequest, filterRequest, pageResponse);\n        } catch (/** @type any */ error) {\n            this.#loading.setAttribute('hidden', '');\n            this.#feedback.removeAttribute('hidden', '');\n            if (!error.problems) {\n                this.#feedback.querySelector('[data-ref=feedback-error]').textContent = error;\n            } else {\n                this.#feedback.querySelector('[data-ref=feedback-error]').textContent = error.problems.map(\n                    (p) => `${p.reason}`,\n                );\n            }\n            throw error;\n        }\n    }\n    async withLoader(fn) {\n        return await fn(this.#loader);\n    }\n    async resetWithFilter(filterRequest) {\n        return await this.load(\n            {\n                page: 0,\n                size: this.#latestRequest.pageRequest.size,\n            },\n            this.#latestRequest.sortRequest,\n            filterRequest,\n        );\n    }\n    #update(pageRequest, sortRequest, filterRequest, pageResponse) {\n        this.#loading.setAttribute('hidden', '');\n        this.#body.replaceChildren(\n            this.template('row')\n                .withOverlay({\n                    schema: this.#schema,\n                    pageRequest,\n                    filterRequest,\n                    pageResponse,\n                })\n                .render(),\n        );\n        this.#paginator.current = pageRequest.page;\n        this.#paginator.total = Math.ceil(pageResponse.size / pageRequest.size);\n    }\n}\n\nexport { TableLoader, SortButton, Table, TableSchemaParser, Pagination };\n","import { Attributes } from '../../ftl/index.mjs';\nimport { Instant } from './temporals.mjs';\nimport { Input } from './input.mjs';\n\nclass InstantFilter extends Input {\n    static observed = ['value:json', 'readonly:presence', 'required:presence'];\n    static template = `\n        <div class=\"form-label\">\n            <label>{{{{ slots.default }}}}</label>\n            {{{{ slots.info }}}}\n        </div>\n        <div class=\"input-group\">\n            <span data-tpl-if=\"slots.ibefore\" class=\"input-group-text\">{{{{ slots.ibefore }}}}</span>\n            {{{{ slots.before }}}}\n            <button data-ref=\"operator\" class=\"btn btn-outline-secondary dropdown-toggle\" type=\"button\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\" value=\"LTE\" form=\"\">&PrecedesSlantEqual;</button>\n            <ul class=\"dropdown-menu\">\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"EQ\">=</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"NEQ\">&ne;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"LT\">&prec;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"GT\">&succ;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"LTE\">&PrecedesSlantEqual;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"GTE\">&SucceedsSlantEqual;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"BETWEEN\">&LeftRightArrow;</a></li>\n            </ul>\n            <input data-ref=\"value1\" type=\"datetime-local\" class=\"form-control\" form=\"\">\n            <input data-ref=\"value2\" type=\"datetime-local\" class=\"form-control\" form=\"\" hidden>\n            {{{{ slots.after }}}}\n            <span data-tpl-if=\"slots.iafter\" class=\"input-group-text\">{{{{ slots.iafter }}}}</span>\n        </div>\n        <ful-field-error></ful-field-error>\n    `;\n    #operator;\n    #value1;\n    #value2;\n    render(conf) {\n        super.render({ ...conf, skipObservedSetup: true });\n        this.#operator = this.querySelector('[data-ref=operator]');\n        this.#value1 = this.querySelector('[data-ref=value1]');\n        this.#value2 = this.querySelector('[data-ref=value2]');\n\n        this.disabled = conf.disabled;\n        this.readonly = conf.observed.readonly;\n        this.required = conf.observed.required;\n        this.value = conf.observed.value;\n\n        this.addEventListener('click', (evt) => {\n            const target = /** @type HTMLElement */ (evt.target);\n            if (!target.matches('ul > li > a')) {\n                return;\n            }\n            const btn = /** @type HTMLButtonElement */ (target.closest('ul')?.previousElementSibling);\n            const value = /** @type String */ (target.getAttribute('value'));\n            Attributes.toggle(this.#value2, 'hidden', value !== 'BETWEEN');\n            btn.setAttribute('value', value);\n            btn.innerHTML = target.innerHTML;\n        });\n    }\n\n    get value() {\n        const operator = this.#operator.getAttribute('value');\n        const values = operator === 'BETWEEN' ? [this.#value1.value, this.#value2.value] : [this.#value1.value];\n        return values.some((v) => v === '') ? undefined : [operator, ...values.map((v) => new Date(v).toISOString())];\n    }\n    set value(v) {\n        if (v == null) {\n            this.#value1.value = '';\n            this.#value2.value = '';\n            return;\n        }\n        const [operator, ...values] = v;\n        this.#operator.setAttribute('value', operator);\n        this.#value1.value = values[0] ? Instant.isoToLocal(values[0]) : values[0];\n        this.#value2.value = values[1] ? Instant.isoToLocal(values[1]) : values[1];\n    }\n    set readonly(v) {\n        this.#value2.readOnly = v;\n        super.readonly = v;\n    }\n    set disabled(d) {\n        Attributes.toggle(this.#value2, 'disabled', d);\n        super.disabled = d;\n    }\n}\n\nclass LocalDateFilter extends Input {\n    static observed = ['value:json', 'readonly:presence', 'required:presence'];\n    static template = `\n        <div class=\"form-label\">\n            <label>{{{{ slots.default }}}}</label>\n            {{{{ slots.info }}}}\n        </div>\n        <div class=\"input-group\">\n            <span data-tpl-if=\"slots.ibefore\" class=\"input-group-text\">{{{{ slots.ibefore }}}}</span>\n            {{{{ slots.before }}}}\n            <button data-ref=\"operator\" class=\"btn btn-outline-secondary dropdown-toggle\" type=\"button\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\" value=\"EQ\" form=\"\">=</button>\n            <ul class=\"dropdown-menu\">\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"EQ\">=</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"NEQ\">&ne;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"LT\">&prec;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"GT\">&succ;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"LTE\">&PrecedesSlantEqual;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"GTE\">&SucceedsSlantEqual;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"BETWEEN\">&LeftRightArrow;</a></li>\n            </ul>\n            <input data-ref=\"value1\" type=\"date\" class=\"form-control\" form=\"\">\n            <input data-ref=\"value2\" type=\"date\" class=\"form-control\" form=\"\" hidden>\n            {{{{ slots.after }}}}\n            <span data-tpl-if=\"slots.iafter\" class=\"input-group-text\">{{{{ slots.iafter }}}}</span>\n        </div>\n        <ful-field-error></ful-field-error>\n    `;\n    #operator;\n    #value1;\n    #value2;\n    render(conf) {\n        super.render({ ...conf, skipObservedSetup: true });\n\n        this.#operator = this.querySelector('[data-ref=operator]');\n        this.#value1 = this.querySelector('[data-ref=value1]');\n        this.#value2 = this.querySelector('[data-ref=value2]');\n\n        this.disabled = conf.disabled;\n        this.readonly = conf.observed.readonly;\n        this.required = conf.observed.required;\n        this.value = conf.observed.value;\n\n        this.addEventListener('click', (evt) => {\n            const target = /** @type HTMLElement */ (evt.target);\n            if (!target.matches('ul > li > a')) {\n                return;\n            }\n            const btn = /** @type HTMLButtonElement */ (target.closest('ul')?.previousElementSibling);\n            const value = /** @type String */ (target.getAttribute('value'));\n            Attributes.toggle(this.#value2, 'hidden', value !== 'BETWEEN');\n            btn.setAttribute('value', value);\n            btn.innerHTML = target.innerHTML;\n        });\n    }\n    get value() {\n        const operator = this.#operator.getAttribute('value');\n        const values = operator == 'BETWEEN' ? [this.#value1.value, this.#value2.value] : [this.#value1.value];\n        return values.some((v) => v === '') ? undefined : [operator, ...values];\n    }\n    set value(v) {\n        if (v == null) {\n            this.#value1.value = '';\n            this.#value2.value = '';\n            return;\n        }\n        const [operator, ...values] = v;\n        this.#operator.setAttribute('value', operator);\n        this.#value1.value = values[0];\n        this.#value2.value = values[1];\n    }\n    set readonly(v) {\n        this.#value2.readOnly = v;\n        super.readonly = v;\n    }\n    set disabled(d) {\n        Attributes.toggle(this.#value2, 'disabled', d);\n        super.disabled = d;\n    }\n}\n\nclass TextFilter extends Input {\n    static observed = ['value:json', 'readonly:presence', 'required:presence'];\n    static template = `\n        <div class=\"form-label\">\n            <label>{{{{ slots.default }}}}</label>\n            {{{{ slots.info }}}}\n        </div>\n        <div class=\"input-group\">\n            <span data-tpl-if=\"slots.ibefore\" class=\"input-group-text\">{{{{ slots.ibefore }}}}</span>\n            {{{{ slots.before }}}}\n            <button data-ref=\"operator\" class=\"btn btn-outline-secondary dropdown-toggle\" type=\"button\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\" value=\"CONTAINS\" form=\"\">&mldr;a&mldr;</button>\n            <ul class=\"dropdown-menu\">\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"CONTAINS\">&mldr;a&mldr;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"STARTS_WITH\">a&mldr;</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"ENDS_WITH\">&mldr;a</a></li>\n                <li><a class=\"dropdown-item\" role=\"button\" value=\"EQ\">=</a></li>\n            </ul>\n            <input data-ref=\"value\" type=\"text\" class=\"form-control\" form=\"\">\n            {{{{ slots.after }}}}\n            <span data-tpl-if=\"slots.iafter\" class=\"input-group-text\">{{{{ slots.iafter }}}}</span>\n        </div>\n        <ful-field-error></ful-field-error>\n    `;\n    #operator;\n    #value;\n    render(conf) {\n        super.render({ ...conf, skipObservedSetup: true });\n\n        this.#operator = this.querySelector('[data-ref=operator]');\n        this.#value = this.querySelector('[data-ref=value]');\n\n        this.disabled = conf.disabled;\n        this.readonly = conf.observed.readonly;\n        this.required = conf.observed.required;\n        this.value = conf.observed.value;\n\n        this.addEventListener('click', (evt) => {\n            const target = /** @type HTMLElement */ (evt.target);\n            if (!target.matches('ul > li > a')) {\n                return;\n            }\n            const btn = /** @type HTMLButtonElement */ (target.closest('ul')?.previousElementSibling);\n            const value = /** @type String */ (target.getAttribute('value'));\n            btn.setAttribute('value', value);\n            btn.innerHTML = target.innerHTML;\n        });\n    }\n    get value() {\n        const operator = this.#operator.getAttribute('value');\n        return this.#value.value === '' ? undefined : [operator, 'IGNORE_CASE', this.#value.value];\n    }\n    set value(v) {\n        if (v == null) {\n            this.#value.value = '';\n            return;\n        }\n        const [operator, sensitivity, value] = v;\n        this.#operator.setAttribute('value', operator);\n        this.#value.value = value;\n    }\n}\n\nexport { InstantFilter, LocalDateFilter, TextFilter };\n","class LocalizationModule {\n    static t(k, ...args) {\n        //@ts-ignore\n        const format = this.l10n?.[this.language]?.[k] ?? this.l10n?.['en']?.[k] ?? k;\n        if (args.length === 0) {\n            return format;\n        }\n        return format.replace(/{(\\d+)}/g, (m, is) => {\n            return args[Number(is)];\n        });\n    }\n    static tl(k, args = []) {\n        return LocalizationModule.t.apply(this, [k, ...args]);\n    }\n}\n\nexport { LocalizationModule };\n","import { HttpClient } from '../../httpc/index.mjs';\nimport { Checkbox } from './checkbox.mjs';\nimport { LocalDate, Instant, InputLocalDate, InputLocalTime, InputInstant } from './temporals.mjs';\nimport { InstantFilter, LocalDateFilter, TextFilter } from './filters.mjs';\nimport { FormLoader, Form } from './form.mjs';\nimport { Input } from './input.mjs';\nimport { InputFile } from './files.mjs';\nimport { RadioGroup } from './radio.mjs';\nimport { SelectLoader, Dropdown, Select } from './select.mjs';\nimport { Spinner } from './spinner.mjs';\nimport { TableLoader, Table, Pagination, SortButton } from './table.mjs';\nimport { LocalizationModule } from './l10n.mjs';\n\nclass Plugin {\n    configure(registry) {\n        const httpClient = HttpClient.builder().withCsrfToken().withRedirectOnUnauthorized('/').build();\n        registry\n            .defineModule('l10n', LocalizationModule)\n            .defineComponent('http-client', httpClient)\n            .defineElement('ful-spinner', Spinner)\n            .defineElement('ful-form', Form)\n            .defineElement('ful-checkbox', Checkbox)\n            .defineElement('ful-input', Input)\n            .defineElement('ful-input-file', InputFile)\n            .defineElement('ful-local-date', LocalDate)\n            .defineElement('ful-instant', Instant)\n            .defineElement('ful-input-local-date', InputLocalDate)\n            .defineElement('ful-input-local-time', InputLocalTime)\n            .defineElement('ful-input-instant', InputInstant)\n            .defineElement('ful-radio-group', RadioGroup)\n            .defineElement('ful-table', Table)\n            .defineElement('ful-pagination', Pagination)\n            .defineElement('ful-sorter', SortButton)\n            .defineElement('ful-filter-instant', InstantFilter)\n            .defineElement('ful-filter-local-date', LocalDateFilter)\n            .defineElement('ful-filter-text', TextFilter)\n            .defineElement('ful-select', Select)\n            .defineElement('ful-dropdown', Dropdown)\n            .defineComponent('loaders:select', SelectLoader)\n            .defineComponent('loaders:form', FormLoader)\n            .defineComponent('loaders:table', TableLoader)\n            .defineOverlay({\n                language: navigator?.language?.split('-')?.[0] ?? 'en',\n            });\n    }\n}\n\nexport { Plugin };\n"],"names":["LocalStorage","Storage","save","k","v","localStorage","setItem","JSON","stringify","load","got","getItem","undefined","parse","remove","removeItem","pop","decoded","SessionStorage","sessionStorage","VersionedLocalStorage","key","revision","data","stored","VersionedSessionStorage","AsyncEvents","fireAsync","el","evt","options","dispatchEvent","promises","async","mode","length","Error","type","Promise","all","resolve","asyncOn","fn","listener","event","ae","promise","reject","withResolvers","push","e","addEventListener","asyncOff","removeEventListener","mixInto","classes","Object","assign","prototype","this","Timing","sleep","ms","setTimeout","static","debounce","timeoutMs","func","opts","DEBOUNCE_DEFAULT","tid","args","previousTimestamp","later","elapsed","performance","now","DEBOUNCE_IMMEDIATE","arguments","clearTimeout","throttle","THROTTLE_DEFAULT","THROTTLE_NO_LEADING","remaining","THROTTLE_NO_TRAILING","Bindings","flatten","obj","prefix","stops","keys","reduce","acc","pre","has","providePath","result","path","value","split","map","test","current","previous","i","ckey","pkey","Number","isInteger","Array","isArray","extract","getAttribute","checked","dataset","tagName","extractFrom","form","submitter","elements","hasAttribute","matches","mutate","raw","mutateIn","values","names","from","filter","n","flattenedKey","entries","Set","querySelectorAll","CSS","escape","errors","es","scrollOnError","fieldErrors","globalErrors","forEach","setCustomValidity","replaceChildren","setAttribute","parts","context","replace","slice","join","suffix","input","reason","innerText","removeAttribute","sort","a","b","getBoundingClientRect","y","focus","RemoteJsonFormLoader","http","url","method","requestMapper","responseMapper","constructor","prepare","submit","request","json","fetch","transform","response","LocalFormLoader","FormLoader","create","conf","registry","component","Form","ParsedElement","render","document","createElement","Attributes","forward","childNodes","preventDefault","stopPropagation","target","spinner","loader","se","CustomEvent","bubbles","cancelable","detail","sre","mapped","exception","Failure","problems","console","warn","reset","spin","hidden","hel","wd","String","disabled","vs","Input","_input","_fieldError","super","internals","attachInternals","role","_type","_fragment","slots","template","withOverlay","observed","skipObservedSetup","fragment","querySelector","readonly","required","find","requestSubmit","re","before","after","RegExp","start","selectionStart","offset","setSelectionRange","label","ariaDescribedByElements","ariaLabelledByElements","uppercase","trim","uppercased","toUpperCase","trimmed","readOnly","reflect","toggle","d","set","error","setValidity","customError","formResetCallback","unmarshal","LocalDate","content","innerHTML","locale","Intl","DateTimeFormat","resolvedOptions","formatter","year","month","day","m","format","Date","Instant","hour","minute","second","hour12","isoToLocal","iso","pad","padStart","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","InputLocalDate","min","max","step","fromIsoOrOffset","formatLocalDate","date","getTime","getTimezoneOffset","toISOString","match","exec","sign","r","setHours","setDate","originalDay","setMonth","setFullYear","InputLocalTime","InputInstant","InputFile","en","dropzonelabel","unaccepptablefiletype","maxfilesizeexceeded","maxtotalsizeexceeded","maxfilesexceeded","it","fr","accept","items","dropzone","warnings","warning","multiple","itemlist","maxfiles","maxfilesize","maxtotalsize","closest","fileName","name","dt","DataTransfer","files","f","add","update","click","dataTransfer","kind","getAsFile","formatByteSize","Math","round","ensureAcceptable","ensureFileSizes","ensureTotalSize","ensureFilesCount","withModule","renderTo","unacceptable","file","some","toLowerCase","endsWith","includes","oversized","size","totalsize","useItemlist","useDropzone","RemoteLoader","prefetch","ensureFetched","exact","needle","reconfigureUrl","revisionedData","storageKey","fetchJson","PartialRemoteLoader","param","InMemoryLoader","SelectLoader","responseMapperFrom","evaluator","evaluateExpression","row","Dropdown","menu","optionstemplate","Map","Fragments","isBlank","default","Templates","fromFragment","li","change","hide","acceptSelection","selected","firstElementChild","metadata","index","get","shown","show","moveOrShow","candidate","scrollIntoView","block","behavior","Select","badges","ddmenu","fieldError","self","dload","abortdload","idx","children","indexOf","delete","changed","syncBadges","relatedTarget","contains","code","selectionEnd","clear","withLoader","selection","append","entry","RadioGroup","fieldset","firstRadio","booleanType","uid","radioEls","inputsAndLabels","fromChildNodes","inert","Checkbox","container","isSwitch","klass","Spinner","SortButton","order","sorter","orders","nextOrder","Pagination","showing","navigation","next","prevIcon","nextIcon","reloadIcon","total","page","maxRender","prev","enabled","curr","pages","mid","p","unshift","TableSchemaParser","nodeOrFragment","schema","Nodes","queryChildren","headersTr","rowsTr","attr","getAttributeNames","columns","queryChildrenAll","column","maybeTitleTag","titleNode","createTextNode","wrappedTitleNode","fulSorter","th","td","headersTemplate","inHeaders","inRows","withFragment","rowsTemplate","InMemoryTableLoader","pageRequest","sortRequest","filterRequest","begin","end","RemoteTableLoader","filters","fromEntries","TableLoader","Table","initial","nodata","searchIcon","body","loading","noAutoload","feedback","paginator","sorters","latestRequest","table","Rendering","waitForChildren","maybeForm","s","reload","pageResponse","textContent","resetWithFilter","ceil","InstantFilter","operator","value1","value2","btn","previousElementSibling","LocalDateFilter","TextFilter","sensitivity","LocalizationModule","t","l10n","language","is","tl","apply","Plugin","configure","httpClient","HttpClient","builder","withCsrfToken","withRedirectOnUnauthorized","build","defineModule","defineComponent","defineElement","defineOverlay","navigator"],"mappings":"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"}