@optionfactory/ful 5.0.5 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"ful.iife.min.js","sources":["../src/encodings.mjs","../src/failure.mjs","../src/http-client.mjs","../src/storage.mjs","../src/oauth-authorization-code.mjs","../src/events/async.mjs","../src/timing.mjs","../src/elements/bindings.mjs","../src/elements/form.mjs","../src/elements/input.mjs","../src/elements/temporals.mjs","../src/elements/files.mjs","../src/elements/select.mjs","../src/elements/radio.mjs","../src/elements/checkbox.mjs","../src/elements/spinner.mjs","../src/elements/table.mjs","../src/elements/filters.mjs","../src/elements/l10n.mjs","../src/elements/plugin.mjs"],"sourcesContent":["\n\nclass Base64 {\n static encode(arrayBuffer, dialect) {\n const d = dialect || Base64.URL_SAFE;\n const len = arrayBuffer.byteLength;\n const view = new Uint8Array(arrayBuffer);\n let res = '';\n for (let i = 0; i < len; i += 3) {\n const v1 = d[view[i] >> 2];\n const v2 = d[((view[i] & 3) << 4) | (view[i + 1] >> 4)];\n const v3 = d[((view[i + 1] & 15) << 2) | (view[i + 2] >> 6)];\n const v4 = d[view[i + 2] & 63];\n res += v1 + v2 + v3 + v4;\n }\n if (len % 3 === 2) {\n res = res.substring(0, res.length - 1);\n } else if (len % 3 === 1) {\n res = res.substring(0, res.length - 2);\n }\n return res;\n }\n static decode(str, dialect) {\n const d = dialect || Base64.URL_SAFE;\n let nbytes = Math.floor(str.length * 0.75);\n for (let i = 0; i !== str.length; ++i) {\n if (str[str.length - i - 1] !== '=') {\n break;\n }\n --nbytes;\n }\n const view = new Uint8Array(nbytes);\n\n let vi = 0;\n let si = 0;\n while (vi < str.length * 0.75) {\n const v1 = d.indexOf(str.charAt(si++));\n const v2 = d.indexOf(str.charAt(si++));\n const v3 = d.indexOf(str.charAt(si++));\n const v4 = d.indexOf(str.charAt(si++));\n view[vi++] = (v1 << 2) | (v2 >> 4);\n view[vi++] = ((v2 & 15) << 4) | (v3 >> 2);\n view[vi++] = ((v3 & 3) << 6) | v4;\n }\n\n return view.buffer;\n }\n}\n\nBase64.STANDARD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nBase64.URL_SAFE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n\nclass Hex {\n static decode(hex) {\n if (hex.length % 2 !== 0) {\n throw new Error(\"invalid length\");\n }\n const lenInBytes = hex.length / 2;\n return new Uint8Array(lenInBytes).map((e, i) => {\n const offset = i * 2;\n const octet = hex.substring(offset, offset + 2);\n return parseInt(octet, 16);\n });\n }\n static encode(bytes, upper) {\n return Array.from(bytes)\n .map(b => b.toString(16))\n .map(b => upper ? b.toUpperCase() : b)\n .map(o => o.padStart(2, 0))\n .join('');\n }\n}\n\nexport { Base64, Hex };","\n\n/**\n * @typedef {{ type: string; context: string?; reason: string; details: any?; }} Problem\n */\nclass Failure extends Error {\n /**\n * \n * @param {string} message \n * @param {Problem[]} problems \n * @param {*} cause\n */\n constructor(message, problems, cause) {\n super(message, { cause });\n this.name = 'Failure';\n this.problems = problems;\n }\n dropping(prefix){\n return new Failure(this.message, Failure.dropProblemsContext(this.problems, prefix), this);\n }\n static dropProblemsContext(problems, prefix){\n return problems.map(({type, context, reason, details}) => {\n const nctx = context?.startsWith(prefix) ? context.substring(prefix.length) : context;\n return {type, context: nctx, reason, details};\n })\n }\n\n}\n\nexport { Failure };","import { Failure } from \"./failure.mjs\";\n\nclass MediaType {\n #type;\n #subtype;\n constructor(type, subtype) {\n this.#type = type;\n this.#subtype = subtype;\n }\n get normalized() {\n return `${this.#type}/${this.#subtype}`;\n }\n get type() {\n return this.#type;\n }\n get subtype() {\n return this.#subtype;\n }\n /**\n * \n * @param {string|null|undefined} v \n * @returns \n */\n static parse(v) {\n if (!v) {\n return new MediaType(\"unknown\", \"unknown\");\n }\n const [prefix, _] = v.split(\";\");\n const [ptype, psubtype] = prefix.trim().split(\"/\");\n return new MediaType(ptype.toLowerCase(), psubtype?.toLowerCase());\n }\n}\n\n/**\n * @typedef {Int8Array| Uint8Array| Uint8ClampedArray| Int16Array| Uint16Array| Int32Array| Uint32Array| Float32Array| Float64Array| BigInt64Array| BigUint64Array} TypedArray\n */\n/**\n * @typedef HttpInterceptor\n * @property {function(URL,RequestInit|undefined,HttpInterceptorChain):Promise<Response>} intercept \n */\n\nclass HttpClientError extends Failure {\n /**\n * @param {string} message\n * @param {number} status\n * @param {{ type: string; context: string?; reason: string; details: any?; }[]} problems\n * @param {Error|undefined} [cause]\n */\n constructor(message, status, problems, cause) {\n super(message, problems, cause);\n this.name = 'HttpClientError';\n this.status = status;\n }\n dropping(prefix){\n return new HttpClientError(this.message, this.status, Failure.dropProblemsContext(this.problems, prefix), this);\n }\n /**\n * \n * @param {string} type \n * @param {any} cause \n * @returns \n */\n static of(type, cause) {\n return new HttpClientError(cause.message, 0, [{\n type,\n context: null,\n reason: cause.message,\n details: null\n }], cause);\n }\n /**\n * Creates an HttpClientError from a Response.\n * @param {Response} response \n * @returns an HttpClientError\n */\n static async fromResponse(response) {\n switch (MediaType.parse(response.headers.get(\"Content-Type\")).normalized) {\n case 'application/failures+json': {\n const data = await response.json();\n const message = `${response.status} ${response.statusText}: ${data.length} failures`;\n return new HttpClientError(message, response.status, data);\n }\n case 'application/problem+json': {\n const data = await response.json();\n const message = `${response.status} ${response.statusText}: ${data.title} ${data.detail}`;\n return new HttpClientError(message, response.status, data.problems || [{\n type: \"GENERIC_PROBLEM\",\n context: null,\n reason: message,\n details: null\n }]);\n }\n default: {\n const text = await response.text();\n const message = `${response.status} ${response.statusText}: ${text}`;\n return new HttpClientError(message, response.status, [{\n type: \"GENERIC_PROBLEM\",\n context: null,\n reason: message,\n details: null\n }]);\n }\n }\n }\n}\n\n/**\n * @implements {HttpInterceptor}\n */\nclass CsrfTokenInterceptor {\n #k; #v;\n constructor() {\n this.#k = document.querySelector(\"meta[name='_csrf_header']\")?.getAttribute(\"content\");\n this.#v = document.querySelector(\"meta[name='_csrf']\")?.getAttribute(\"content\");\n }\n async intercept(url, request, chain) {\n if (this.#k && this.#v) {\n request.headers.set(this.#k, this.#v);\n }\n return await chain.proceed(url, request);\n }\n}\n/**\n * @implements {HttpInterceptor}\n */\nclass RedirectOnUnauthorizedInterceptor {\n #redirectUri;\n /**\n * @param {string} redirectUri\n */\n constructor(redirectUri) {\n this.#redirectUri = redirectUri;\n }\n async intercept(url, request, chain) {\n const response = await chain.proceed(url, request);\n if (response.status === 401) {\n window.location.href = this.#redirectUri;\n }\n return response;\n }\n}\n\nclass HttpClientBuilder {\n /**\n * @type {HttpInterceptor[]}\n */\n #interceptors;\n constructor() {\n this.#interceptors = [];\n }\n withCsrfToken() {\n this.#interceptors.push(new CsrfTokenInterceptor());\n return this;\n }\n withRedirectOnUnauthorized(redirectUri) {\n this.#interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));\n return this;\n }\n /**\n * @param {...HttpInterceptor} interceptors\n */\n withInterceptors(...interceptors) {\n this.#interceptors.push(...interceptors);\n return this;\n }\n build() {\n return new HttpClient(this.#interceptors);\n }\n}\n\n/**\n * @implements {HttpInterceptor}\n */\nclass HttpCall {\n async intercept(url, request, chain) {\n return await fetch(new Request(url, request));\n }\n}\n\nclass HttpInterceptorChain {\n #interceptors;\n #current;\n /**\n * \n * @param {HttpInterceptor[]} interceptors \n * @param {number} current \n */\n constructor(interceptors, current) {\n this.#interceptors = interceptors;\n this.#current = current;\n }\n /**\n * \n * @param {URL} url\n * @param {RequestInit} request \n * @returns {Promise<Response>} the response\n */\n async proceed(url, request) {\n const interceptor = this.#interceptors[this.#current];\n return await interceptor.intercept(url, request, new HttpInterceptorChain(this.#interceptors, this.#current + 1));\n }\n}\n\nclass HttpClient {\n #interceptors;\n /**\n * Creates a builder for an HttpClient.\n * @returns {HttpClientBuilder} the client builder\n */\n static builder() {\n return new HttpClientBuilder();\n }\n /**\n * Creates an HttpClient.\n * @param {HttpInterceptor[]|undefined} interceptors - a list of interceptors to be registered for every request performed by the created client. \n */\n constructor(interceptors) {\n this.#interceptors = interceptors || [];\n }\n /**\n * Performs an HTTP exchange.\n * @async\n * @param {string} uri - the (possibly relative) request url\n * @param {RequestInit|undefined} options - fetch options\n * @param {HttpInterceptor[]|undefined} interceptors - the HttpInterceptors to be registered for this exchange.\n * @returns {Promise<Response>} the response\n */\n async exchange(uri, options, interceptors) {\n const is = [...this.#interceptors, ...interceptors || [], new HttpCall()];\n const chain = new HttpInterceptorChain(is, 0);\n const url = new URL(new Request(uri).url);\n return await chain.proceed(url, options ?? {});\n }\n /**\n * Creates a request builder.\n * @param {string} method - the HTTP method to be used\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n request(method, uri) {\n return HttpRequestBuilder.create(this, method, uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url \n * @returns {HttpRequestBuilder} the request builder\n */\n get(uri) {\n return HttpRequestBuilder.create(this, 'GET', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n head(uri) {\n return HttpRequestBuilder.create(this, 'HEAD', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n post(uri) {\n return HttpRequestBuilder.create(this, 'POST', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n put(uri) {\n return HttpRequestBuilder.create(this, 'PUT', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n patch(uri) {\n return HttpRequestBuilder.create(this, 'PATCH', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n delete(uri) {\n return HttpRequestBuilder.create(this, 'DELETE', uri);\n }\n}\n\n/**\n * \n * @param {Response} response \n * @param {'text'|'json'|'blob'|'arrayBuffer'} type \n * @returns \n */\nconst unmarshal = async (response, type) => {\n try {\n return await response[type]();\n } catch (ex) {\n throw HttpClientError.of(\"UNMARSHALING_PROBLEM\", ex);\n }\n}\n\nclass HttpRequestBuilder {\n #client;\n #method;\n #uri;\n #params;\n #headers;\n #body;\n #options;\n #interceptors;\n /**\n * Creates an HttpRequestBuilder.\n * @param {HttpClient} client \n * @param {string} method - the HTTP method to be used\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the builder\n */\n static create(client, method, uri) {\n const [baseUri, queryString = ''] = uri.split('?');\n return new HttpRequestBuilder(\n client,\n method,\n baseUri,\n new URLSearchParams(queryString),\n new Headers(),\n undefined,\n {},\n []\n );\n }\n /**\n * Creates an HttpRequestBuilder.\n * @param {HttpClient} client \n * @param {string} method - the HTTP method to be used\n * @param {string} uri - the (possibly relative) request url\n * @param {URLSearchParams} params \n * @param {Headers} headers \n * @param {any} body \n * @param {Omit<RequestInit,\"headers\"|\"method\"|\"body\">} options \n * @param {HttpInterceptor[]} interceptors \n */\n constructor(client, method, uri, params, headers, body, options, interceptors) {\n this.#client = client;\n this.#method = method;\n this.#uri = uri;\n this.#params = params;\n this.#body = body;\n this.#headers = headers;\n this.#options = options;\n this.#interceptors = interceptors;\n }\n /**\n * Add all passed headers to the request, overriding existing ones if that key already exists. Null and undefined values cause the key to be removed.\n * @param {HeadersInit} hs \n * @returns {HttpRequestBuilder} this builder\n */\n headers(hs) {\n for (const [k, v] of new Headers(hs).entries()) {\n if (v == null) {\n this.#headers.delete(k);\n } else {\n this.#headers.set(k, v);\n }\n }\n return this;\n }\n /**\n * Adds an header to the request, overriding it if it already exists. Null and undefined values cause the key to be removed\n * @param {string} k \n * @param {string} v \n * @returns {HttpRequestBuilder} this builder\n */\n header(k, v) {\n if (v == null) {\n this.#headers.delete(k);\n } else {\n this.#headers.set(k, v);\n }\n return this;\n }\n /**\n * Add all query parameters to the request, overriding existing ones if that key already exists. Null and undefined values cause the key to be removed\n * @param {URLSearchParams|Record<string,string>|string[][]|string} ps \n * @returns {HttpRequestBuilder} this builder\n */\n params(ps) {\n for (const [k, v] of new URLSearchParams(ps).entries()) {\n if (v == null) {\n this.#params.delete(k);\n } else {\n this.#params.set(k, v);\n }\n }\n return this;\n }\n /**\n * Adds a query parameter to the request, overriding it if it already exists. Empty vs, or a single null or undefined value cause the key to be removed.\n * @param {string} k \n * @param {...string} vs\n * @returns {HttpRequestBuilder} this builder\n */\n param(k, ...vs) {\n if (vs.length === 0 || vs[0] == null) {\n this.#params.delete(k);\n return this;\n }\n for (const v of vs) {\n this.#params.append(k, v);\n }\n return this;\n }\n /**\n * Sets the request body. \n * `Content-Type: multipart/form-data` header is automatically added by fetch when data is a FormData instance if not explicitly set.\n * `Content-Type: application/x-www-form-urlencoded` header is automatically added by fetch when data is an URLSearchParams instance if not explicitly set.\n * `Content-Type: text/plain` header is automatically added by fetch when data is a string instance if not explicitly set.\n * @param {string|ArrayBuffer|Blob|DataView|File|FormData|TypedArray|URLSearchParams|ReadableStream} data \n * @returns {HttpRequestBuilder} this builder\n */\n body(data) {\n this.#body = data;\n return this;\n }\n /**\n * Sets the request body that will be serialized as json. Calling this method adds the `Content-Type application/json` header for the request.\n * @param {any} body - the body to be serialized as json\n * @returns {HttpRequestBuilder} this builder\n */\n json(body) {\n this.#headers.set(\"Content-Type\", \"application/json\");\n this.#body = JSON.stringify(body);\n return this;\n }\n /**\n * Sets the request body as a FormData configured using the callback.\n * `Content-Type: multipart/form-data` header is automatically added by fetch if not explicitly set.\n * @param {function(HttpMultipartRequestCustomizer):void} callback\n */\n multipart(callback) {\n const formData = new FormData();\n const builder = new HttpMultipartRequestCustomizer(formData);\n callback(builder);\n this.#body = formData;\n return this;\n }\n /**\n * Sets a fetch options for the request.\n * @param {Omit<RequestInit,\"headers\"|\"method\"|\"body\">} kvs\n * @returns {HttpRequestBuilder} this builder\n */\n options(kvs) {\n for (const [k, v] of Object.entries(kvs)) {\n this.#options[k] = v;\n }\n return this;\n }\n /**\n * Sets a fetch option for the request.\n * @param {keyof Omit<RequestInit,\"headers\"|\"method\"|\"body\">} k \n * @param {*} v \n * @returns {HttpRequestBuilder} this builder\n */\n option(k, v) {\n this.#options[k] = v;\n return this;\n }\n /**\n * Adds interceptors to the request.\n * @param {[HttpInterceptor]} is - the interceptor to be regisered\n * @returns {HttpRequestBuilder} this builder\n */\n interceptors(is) {\n for (const i of is) {\n this.#interceptors.push(i);\n }\n return this;\n }\n /**\n * Adds an interceptor to the request.\n * @param {HttpInterceptor} i - the interceptor to be regisered\n * @returns {HttpRequestBuilder} this builder\n */\n interceptor(i) {\n this.#interceptors.push(i);\n return this;\n }\n /**\n * Performs an HTTP exchange using the configured client, request and interceptors.\n * @returns {Promise<Response>} the response\n */\n async exchange() {\n const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;\n const opts = {\n ...this.#options,\n headers: this.#headers,\n method: this.#method,\n body: this.#body,\n };\n return await this.#client.exchange(uri, opts, this.#interceptors);\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<Response>} the response\n */\n async fetch() {\n const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;\n const opts = {\n ...this.#options,\n headers: this.#headers,\n method: this.#method,\n body: this.#body,\n };\n try {\n const response = await this.#client.exchange(uri, opts, this.#interceptors);\n if (!response.ok) {\n throw await HttpClientError.fromResponse(response);\n }\n return response;\n } catch (ex) {\n if (ex instanceof Failure) {\n throw ex;\n }\n throw HttpClientError.of(\"CONNECTION_PROBLEM\", ex);\n }\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<string>} the response body, as text\n */\n async fetchText() {\n const response = await this.fetch();\n return await unmarshal(response, 'text');\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<any>} the response body, deserialized as JSON\n */\n async fetchJson() {\n const response = await this.fetch();\n return await unmarshal(response, 'json');\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<Blob>} the response body, as a Blob\n */\n async fetchBlob() {\n const response = await this.fetch();\n return await unmarshal(response, 'blob');\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<ArrayBuffer>} the response body, as an ArrayBuffer\n */\n async fetchArrayBuffer() {\n const response = await this.fetch();\n return await unmarshal(response, 'arrayBuffer');\n }\n}\n\nclass HttpMultipartRequestCustomizer {\n #formData;\n /**\n * \n * @param {FormData} formData \n */\n constructor(formData) {\n this.#formData = formData;\n }\n /**\n * Appends a value to the FormData.\n * @param {string} name \n * @param {*} value \n * @returns this builder\n */\n field(name, value) {\n this.#formData.append(name, value);\n return this;\n }\n /**\n * Appends a Blob to the FormData. \n * If `filename` is omitted, FormData defaults are applied:\n * The default filename for Blob objects is \"blob\"; \n * The default filename for File objects is the file's filename.\n * @param {string} name \n * @param {Blob} value \n * @param {string|undefined} filename \n * @returns this builder\n */\n blob(name, value, filename) {\n this.#formData.append(name, value, filename);\n return this;\n }\n /**\n * Appends multiple Blobs to the FormData with the same name. \n * The default filename for Blob objects is \"blob\"; \n * The default filename for File objects is the file's filename.\n * @param {string} name \n * @param {Blob[]} values\n * @returns this builder\n */\n blobs(name, values) {\n for (let v of values) {\n this.#formData.append(name, v);\n }\n return this;\n }\n /**\n * Appends a JSON serialized blob to the FormData.\n * @param {string} name \n * @param {any} value \n * @param {string|undefined} filename \n * @returns this builder\n */\n json(name, value, filename) {\n const blob = new Blob([JSON.stringify(value)], { type: 'application/json' });\n this.#formData.append(name, blob, filename);\n return this;\n }\n}\n\nexport { MediaType, HttpClient, HttpClientError };\n","\nclass 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}\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\n\nexport { LocalStorage, VersionedLocalStorage, SessionStorage, VersionedSessionStorage };","import { Base64 } from \"./encodings.mjs\";\nimport { SessionStorage } from \"./storage.mjs\";\n\n\nclass AuthorizationCodeFlow {\n static forKeycloak(clientId, realmBaseUrl, redirectUri, maybeScope) {\n const scope = maybeScope ?? \"openid profile\";\n return new AuthorizationCodeFlow(clientId, scope, {\n auth: new URL(\"protocol/openid-connect/auth\", realmBaseUrl),\n token: new URL(\"protocol/openid-connect/token\", realmBaseUrl),\n logout: new URL(\"protocol/openid-connect/logout\", realmBaseUrl),\n registration: new URL(\"protocol/openid-connect/registrations\", realmBaseUrl),\n redirect: redirectUri\n });\n }\n constructor(clientId, scope, { auth, token, registration, logout, redirect }) {\n this.clientId = clientId;\n this.scope = scope;\n this.uri = { auth, token, registration, logout, redirect };\n }\n async action(uri, additionalParams) {\n const pkceVerifier = Base64.encode(crypto.getRandomValues(new Uint8Array(32)).buffer);\n const pkceChallenge = Base64.encode(await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(pkceVerifier)));\n const state = this.clientId + Base64.encode(crypto.getRandomValues(new Uint8Array(16)).buffer);\n SessionStorage.save(`${AuthorizationCodeFlow.PKCE_AND_STATE_KEY}-${this.clientId}`, {\n state: state,\n verifier: pkceVerifier\n });\n const url = new URL(uri);\n url.searchParams.set(\"client_id\", this.clientId);\n url.searchParams.set(\"redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"response_type\", 'code');\n url.searchParams.set(\"scope\", this.scope);\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", pkceChallenge);\n url.searchParams.set(\"code_challenge_method\", 'S256');\n Object.entries(additionalParams || {}).forEach(kv => {\n url.searchParams.set(kv[0], kv[1]);\n });\n window.location.href = url.toString();\n }\n async registration(additionalParams) {\n await this.action(this.uri.registration, additionalParams);\n }\n async applicationInitiatedAction(kcAction, additionalParams) {\n await this.action(this.uri.auth, {\n ...additionalParams,\n kc_action: kcAction,\n });\n }\n async #tokenExchange(code, state) {\n window.history.replaceState('', \"\", this.uri.redirect);\n const stateAndVerifier = SessionStorage.pop(`${AuthorizationCodeFlow.PKCE_AND_STATE_KEY}-${this.clientId}`);\n if (stateAndVerifier.state !== state) {\n throw new Error(\"State mismatch\");\n }\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"code\", code],\n [\"grant_type\", \"authorization_code\"],\n [\"code_verifier\", stateAndVerifier.verifier],\n [\"state\", stateAndVerifier.state],\n [\"redirect_uri\", this.uri.redirect]\n ])\n });\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\"Error:\" + response.status + \": \" + text);\n }\n const token = await response.json();\n return new AuthorizationCodeFlowSession(this.clientId, token, this.uri);\n }\n async ensureLoggedIn() {\n const url = new URL(window.location.href);\n const code = url.searchParams.get(\"code\");\n if (code && SessionStorage.load(`${AuthorizationCodeFlow.PKCE_AND_STATE_KEY}-${this.clientId}`)) {\n //if callback from keycloak and we have our state still stored\n const state = url.searchParams.get(\"state\");\n return await this.#tokenExchange(code, state);\n }\n //if not authorized\n await this.action(this.uri.auth, {});\n return null;\n }\n}\nAuthorizationCodeFlow.PKCE_AND_STATE_KEY = \"state-and-verifier\";\n\nclass AuthorizationCodeFlowSession {\n static parseToken(token) {\n const [rawHeader, rawPayload, signature] = token.split(\".\");\n const utf8decoder = new TextDecoder(\"utf-8\");\n return {\n header: JSON.parse(utf8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),\n payload: JSON.parse(utf8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),\n signature: signature\n };\n }\n constructor(clientId, t, { token, logout, redirect }) {\n this.clientId = clientId;\n this.token = t;\n this.idToken = AuthorizationCodeFlowSession.parseToken(t.id_token);\n this.accessToken = AuthorizationCodeFlowSession.parseToken(t.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(t.refresh_token);\n this.uri = { token, logout, redirect }\n this.refreshCallback = null;\n }\n onRefresh(callback) {\n this.refreshCallback = callback;\n }\n async refresh() {\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"grant_type\", \"refresh_token\"],\n [\"refresh_token\", this.token.refresh_token]\n ])\n });\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\"Error:\" + response.status + \": \" + text);\n }\n const token = await response.json();\n this.token = token;\n this.idToken = AuthorizationCodeFlowSession.parseToken(token.id_token);\n this.accessToken = AuthorizationCodeFlowSession.parseToken(token.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(token.refresh_token);\n if (this.refreshCallback) {\n this.refreshCallback(this.token, this.accessToken, this.refreshToken);\n }\n }\n shouldBeRefreshed(gracePeriod) {\n const now = new Date().getTime();\n const refreshTokenExpiresAt = this.refreshToken.payload.exp * 1000;\n const expired = now > refreshTokenExpiresAt;\n const shouldRefresh = now - gracePeriod > refreshTokenExpiresAt;\n return !expired && shouldRefresh;\n }\n async refreshIf(gracePeriod) {\n if (!this.shouldBeRefreshed(gracePeriod)) {\n return;\n }\n await this.refresh();\n }\n logout() {\n const url = new URL(this.uri.logout);\n url.searchParams.set(\"post_logout_redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"id_token_hint\", this.token.id_token);\n window.location.href = url.toString();\n }\n\n bearerToken() {\n return `Bearer ${this.token.access_token}`;\n }\n\n interceptor(gracePeriodBefore, gracePeriodAfter) {\n return new AuthorizationCodeFlowInterceptor(this, gracePeriodBefore, gracePeriodAfter);\n }\n}\n\nclass AuthorizationCodeFlowInterceptor {\n #session;\n #gracePeriodBefore;\n #gracePeriodAfter;\n constructor(session, gracePeriodBefore, gracePeriodAfter) {\n this.#session = session;\n this.#gracePeriodBefore = gracePeriodBefore || 2000;\n this.#gracePeriodAfter = gracePeriodAfter || 30000;\n }\n async intercept(url, request, chain) {\n await this.#session.refreshIf(this.#gracePeriodBefore);\n request.headers.set(\"Authorization\", this.#session.bearerToken());\n const response = await chain.proceed(url, request);\n await this.#session.refreshIf(this.#gracePeriodAfter);\n return response;\n }\n}\n\nexport { AuthorizationCodeFlow, AuthorizationCodeFlowSession, AuthorizationCodeFlowInterceptor };","class AsyncEvents {\n static async fireAsync(el, evt) {\n el.dispatchEvent(evt);\n return await evt.async?.promise;\n }\n /**\n * \n * @param {*} el \n * @param {*} type \n * @param {*} fn returning the result\n * @param {*} options \n * @returns \n */\n static asyncOn(el, type, fn, options) {\n const listener = async (event) => {\n let resolve, reject;\n const promise = new Promise((res, rej) => {\n resolve = res;\n reject = rej;\n });\n event.async = { promise };\n try {\n //@ts-ignore\n resolve(await fn(event));\n } catch (e) {\n //@ts-ignore\n reject(e);\n }\n };\n el.addEventListener(type, listener, options);\n return listener;\n }\n /**\n * \n * @param {*} el \n * @param {*} type \n * @param {*} listener the listener returned by asyncOn\n * @param {*} options \n */ \n static asyncOff(el, type, listener, options) {\n el.removeEventListener(type, listener, options);\n }\n static mixInto(...classes) {\n for (const k of classes) {\n Object.assign(k.prototype, {\n async fireAsync(evt) {\n return await AsyncEvents.fireAsync(this, evt);\n },\n asyncOn(type, fn, options) {\n return AsyncEvents.asyncOn(this, type, fn, options);\n },\n asyncOff(type, listener, options) {\n return AsyncEvents.asyncOff(this, type, listener, options);\n }\n });\n }\n }\n}\n\nexport { AsyncEvents }","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 = new Date().getTime() - 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 = new Date().getTime();\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 : new Date().getTime();\n tid = null;\n func(...args);\n if (tid === null) {\n args = [];\n }\n };\n const throttled = function () {\n const now = new Date().getTime();\n if (!previousTimestamp && (opts & Timing.THROTTLE_NO_LEADING)) {\n previousTimestamp = now;\n }\n const remaining = 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 };","\nclass Bindings {\n\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') {\n return el.value === '' || el.value === undefined ? null : el.value;\n }\n return el.value;\n }\n\n /**\n * \n * @param {HTMLFormElement} form \n * @returns \n */\n static extractFrom(form){\n let result = {};\n for(const el of form.elements){\n if(!el.hasAttribute(\"name\") || el.matches(\":disabled\")){\n continue;\n }\n result = Bindings.providePath(result, /** @type {string} */(el.getAttribute('name')), Bindings.extract(el))\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\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(\"[\", \".\").replace(\"].\", \".\").replace(\"]\", \"\");\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 => input.setCustomValidity?.(e.reason, suffix));\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`)).sort((a,b) => a.getBoundingClientRect().y - b.getBoundingClientRect().y)[0]?.focus();\n }\n}\n\n\nexport { Bindings }\n","import { Attributes, ParsedElement, registry } from \"@optionfactory/ftl\"\nimport { Failure } from \"../failure.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)\n .json(values)\n .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\") ? registry.component(el.getAttribute(\"request-mapper\")) : v => v;\n const responseMapper = el.hasAttribute(\"response-mapper\") ? registry.component(el.getAttribute(\"response-mapper\")) : 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();\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 async submit() {\n this.spinner(true)\n try {\n const loader = registry.component(this.getAttribute(\"loader\") ?? 'loaders:form').create(this);\n const values = this.values;\n let request = await loader.prepare(values, this)\n try {\n const se = new CustomEvent('submit', { bubbles: true, cancelable: true, detail: { values, request } });\n if (!this.dispatchEvent(se)) {\n return;\n }\n const sre = new CustomEvent('submit:requested', { bubbles: true, cancelable: false, detail: { values: se.detail.values, request: se.detail.request} })\n let response = await AsyncEvents.fireAsync(this, sre);\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(new CustomEvent('submit:success', { bubbles: true, cancelable: false, detail: { values, request, response: mapped } }))\n } catch (e) {\n this.dispatchEvent(new CustomEvent('submit:failure', { bubbles: true, cancelable: false, detail: { values, request, exception: e } }));\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('[type=submit],[type=reset]').forEach(el => {\n const hel = /** @type HTMLButtonElement */ (el);\n hel.disabled = spin\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 \"@optionfactory/ftl\"\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\n this._input.addEventListener('change', (evt) => {\n evt.stopPropagation();\n this.dispatchEvent(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: {\n value: this.value\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 return this._input.value === '' ? null : this._input.value;\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 //@ts-ignore\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 \"@optionfactory/ftl\";\nimport { Input } from \"./input.mjs\";\n\n\n\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\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 if (v === 'now') {\n return new Date().toISOString().split(\"T\")[0];\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 switch (match[3]) {\n case 'd':\n r.setDate(r.getDate() + offset * sign);\n break;\n case 'm':\n r.setMonth(r.getMonth() + offset * sign);\n break;\n case 'y':\n r.setFullYear(r.getFullYear() + offset * sign);\n break;\n }\n return r.toISOString().split(\"T\")[0];\n }\n}\n\nclass InputLocalTime extends InputLocalDate {\n _type() {\n return 'time';\n }\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.min;\n this.step = observed.min;\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\n\n\n\nexport { Instant, LocalDate, InputLocalDate, InputLocalTime, InputInstant }","import { Attributes } from \"@optionfactory/ftl\";\nimport { Input } from \"./input.mjs\";\n\n\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 }\n static observed = ['value', 'readonly:presence', 'required:presence', \"accept:csv\", 'multiple:presence', \"itemlist:presence\", \"dropzone:presence\", \"maxfiles:number\", \"maxfilesize:number\", \"maxtotalsize:number\"];\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\"></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) ? `${Math.round(v / 1024 / 1024 * 100) / 100}MiB` : (v > 1024 ? `${Math.round(v / 1024 * 100) / 100}KiB` : `${v}B`);\n }\n #update() {\n this.setCustomValidity();\n this.#ensureAcceptable();\n this.#ensureFileSizes();\n this.#ensureTotalSize();\n this.#ensureFilesCount();\n this.template('items').withOverlay({ files: this.files }).withModule('bytes', { format: this.#formatByteSize }).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]\n .filter(file => !this.#accept.some(type => file.name.toLowerCase().endsWith(type.toLowerCase())));\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]\n .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 dt.items.add(v);\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 //TODO:\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 }","import { Attributes, ParsedElement, registry } from \"@optionfactory/ftl\"\nimport { Timing } from \"../timing.mjs\";\nimport { VersionedLocalStorage } from \"../storage.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 storageKey = `${this.#method}@${this.#url}`;\n if (this.#revision !== null) {\n const data = VersionedLocalStorage.load(storageKey, this.#revision);\n if (data !== undefined) {\n this.#data = data;\n return;\n }\n }\n const data = await this.#http.request(this.#method, this.#url)\n .fetchJson()\n this.#data = this.#responseMapper(data);\n if (this.#revision !== null) {\n VersionedLocalStorage.save(storageKey, this.#revision, this.#data);\n }\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.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)\n .param(\"s\", needle)\n .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\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.evaluator().withOverlay(response).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\" hidden></menu>\n `;\n #spinner;\n #menu;\n #options = new Map();\n render({ slots }) {\n const fragment = this.template().render();\n this.#spinner = fragment.querySelector(\"ful-spinner\");\n this.#menu = fragment.querySelector(\"menu\");\n this.#menu.addEventListener('click', evt => {\n evt.stopPropagation();\n if (!evt.target.matches('li')) {\n this.hide();\n return;\n }\n this.#change(evt.target);\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 if (values.length === 0) {\n const el = document.createElement('div');\n el.classList.add('text-center', 'py-2', 'bi', 'bi-database-slash');\n this.#menu.replaceChildren(el);\n return;\n }\n this.#menu.replaceChildren(...values.map(([k, v, m], i) => {\n const el = document.createElement('li');\n if (i === 0) {\n el.setAttribute(\"selected\", '');\n }\n el.setAttribute(\"value\", i);\n el.innerText = v;\n return el;\n }));\n }\n #change(target) {\n const index = target.getAttribute('value');\n const data = this.#options.get(index)\n this.hide();\n this.dispatchEvent(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: { index, data }\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=\"\">\n </div>\n <ful-dropdown hidden popover=\"manual\"></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.component(this.getAttribute(\"loader\") ?? 'loaders:select').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, () => self.#ddmenu.show(() => self.#loader.load(self.#input.value)));\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.#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.#ddmenu.hide();\n this.#input.value = '';\n });\n this.#input.addEventListener('keydown', e => {\n e.stopPropagation();\n if (this.disabled || this.readonly) {\n return;\n }\n switch (e.code) {\n case 'ArrowUp': {\n this.#ddmenu.moveOrShow(false, () => self.#loader.load(self.#input.value));\n break;\n }\n case 'ArrowDown': {\n this.#ddmenu.moveOrShow(true, () => self.#loader.load(self.#input.value));\n break;\n }\n case 'Escape': {\n this.#ddmenu.hide();\n break;\n }\n case 'Enter': {\n this.#ddmenu.acceptSelection();\n this.#input.value = '';\n break;\n }\n case 'Backspace': {\n //remove last if caret a 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.#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.#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 => ({ key: e[0], label: e[1][0], metadata: e[1].slice(1) }))\n const value = this.#multiple ? selection : (selection[0] ?? null);\n this.dispatchEvent(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: { value }\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 //@ts-ignore\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 { SelectLoader, Select, Dropdown };","import { Attributes, Fragments, ParsedElement } from \"@optionfactory/ftl\"\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(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: {\n value: this.value\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 //@ts-ignore\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 };","import { Attributes, ParsedElement } from \"@optionfactory/ftl\";\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\" role=\"switch\" 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 klass = this.getAttribute('type') == 'switch' ? \"form-check form-switch\" : \"form-check\";\n const fragment = this.template().withOverlay({ slots, klass }).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(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: {\n value: this.value\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 });\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 //@ts-ignore\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 }","import { ParsedElement } from \"@optionfactory/ftl\"\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 };","import { Attributes, Fragments, Nodes, ParsedElement, registry, Rendering } from \"@optionfactory/ftl\"\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(new CustomEvent('sort-requested', {\n bubbles: true,\n cancelable: true,\n detail: {\n value: { sorter, order: nextOrder }\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 }\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(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 index: current,\n label: current + 1\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 = columns.filter(v => v.hasAttribute('order')).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 = (!sorter && !order) ? titleNode : (() => {\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.withOverlay({ inHeaders: true, inRows: false }).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\n\n\nclass InMemoryTableLoader {\n #data\n constructor(data) {\n this.#data = data;\n }\n async load(pageRequest, sortRequest, filterRequest) {\n return { \n page: this.#data, \n size: this.#data.length \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.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\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 }\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.default, 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 page: 0,\n size: this.#latestRequest.pageRequest.size\n }, this.#latestRequest.sortRequest, evt.detail.request);\n })\n this.addEventListener('page-requested', async (/** @type any */e) => {\n await this.load({\n page: e.detail.value,\n size: this.#latestRequest.pageRequest.size\n }, this.#latestRequest.sortRequest, this.#latestRequest.filterRequest);\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(this.#latestRequest.pageRequest, this.#latestRequest.sortRequest, this.#latestRequest.filterRequest);\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(p => `${p.reason}`);\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 page: 0,\n size: this.#latestRequest.pageRequest.size\n }, this.#latestRequest.sortRequest, filterRequest);\n }\n #update(pageRequest, sortRequest, filterRequest, pageResponse) {\n this.#loading.setAttribute(\"hidden\", \"\");\n this.#body.replaceChildren(this.template('row').withOverlay({\n schema: this.#schema,\n pageRequest,\n filterRequest,\n pageResponse\n }).render());\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 }","import { Attributes } from \"@optionfactory/ftl\";\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.setAttibute('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 }","\nclass 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(k, ...args);\n }\n\n}\n\n\nexport { LocalizationModule }","import { HttpClient } from \"../http-client.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\n\nclass Plugin {\n configure(registry) {\n const httpClient = HttpClient.builder()\n .withCsrfToken()\n .withRedirectOnUnauthorized(\"/\")\n .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\n\n\nexport { Plugin }"],"names":["Base64","encode","arrayBuffer","dialect","d","URL_SAFE","len","byteLength","view","Uint8Array","res","i","substring","length","decode","str","nbytes","Math","floor","vi","si","v1","indexOf","charAt","v2","v3","v4","buffer","STANDARD","Failure","Error","constructor","message","problems","cause","super","this","name","dropping","prefix","dropProblemsContext","map","type","context","reason","details","startsWith","MediaType","subtype","normalized","parse","v","_","split","ptype","psubtype","trim","toLowerCase","HttpClientError","status","of","fromResponse","response","headers","get","data","json","statusText","title","detail","text","CsrfTokenInterceptor","k","document","querySelector","getAttribute","intercept","url","request","chain","set","proceed","RedirectOnUnauthorizedInterceptor","redirectUri","window","location","href","HttpClientBuilder","interceptors","withCsrfToken","push","withRedirectOnUnauthorized","withInterceptors","build","HttpClient","HttpCall","fetch","Request","HttpInterceptorChain","current","interceptor","builder","exchange","uri","options","is","URL","method","HttpRequestBuilder","create","head","post","put","patch","unmarshal","async","ex","client","params","body","baseUri","queryString","URLSearchParams","Headers","undefined","hs","entries","delete","header","ps","param","vs","append","JSON","stringify","multipart","callback","formData","FormData","HttpMultipartRequestCustomizer","kvs","Object","option","size","opts","ok","fetchText","fetchJson","fetchBlob","fetchArrayBuffer","field","value","blob","filename","blobs","values","Blob","LocalStorage","Storage","save","localStorage","setItem","load","got","getItem","remove","removeItem","pop","decoded","SessionStorage","sessionStorage","VersionedLocalStorage","key","revision","stored","AuthorizationCodeFlow","forKeycloak","clientId","realmBaseUrl","maybeScope","auth","token","logout","registration","redirect","scope","action","additionalParams","pkceVerifier","crypto","getRandomValues","pkceChallenge","subtle","digest","TextEncoder","state","PKCE_AND_STATE_KEY","verifier","searchParams","forEach","kv","toString","applicationInitiatedAction","kcAction","kc_action","tokenExchange","code","history","replaceState","stateAndVerifier","AuthorizationCodeFlowSession","ensureLoggedIn","parseToken","rawHeader","rawPayload","signature","utf8decoder","TextDecoder","payload","t","idToken","id_token","accessToken","access_token","refreshToken","refresh_token","refreshCallback","onRefresh","refresh","shouldBeRefreshed","gracePeriod","now","Date","getTime","refreshTokenExpiresAt","exp","refreshIf","bearerToken","gracePeriodBefore","gracePeriodAfter","AuthorizationCodeFlowInterceptor","session","AsyncEvents","fireAsync","el","evt","dispatchEvent","promise","asyncOn","fn","listener","event","resolve","reject","Promise","rej","e","addEventListener","asyncOff","removeEventListener","mixInto","classes","assign","prototype","Timing","sleep","ms","setTimeout","static","debounce","timeoutMs","func","DEBOUNCE_DEFAULT","tid","args","previousTimestamp","later","elapsed","DEBOUNCE_IMMEDIATE","arguments","clearTimeout","throttle","THROTTLE_DEFAULT","THROTTLE_NO_LEADING","remaining","THROTTLE_NO_TRAILING","Bindings","flatten","obj","stops","keys","reduce","acc","pre","has","providePath","result","path","test","previous","ckey","pkey","Number","isInteger","Array","isArray","extract","checked","dataset","tagName","extractFrom","form","elements","hasAttribute","matches","mutate","raw","mutateIn","names","from","filter","n","flattenedKey","Set","querySelectorAll","CSS","escape","errors","es","scrollOnError","fieldErrors","globalErrors","setCustomValidity","replaceChildren","setAttribute","parts","replace","slice","join","suffix","input","innerText","removeAttribute","sort","a","b","getBoundingClientRect","y","focus","RemoteJsonFormLoader","http","requestMapper","responseMapper","prepare","submit","transform","LocalFormLoader","FormLoader","conf","registry","component","Form","ParsedElement","render","createElement","Attributes","forward","childNodes","preventDefault","stopPropagation","target","spinner","loader","se","CustomEvent","bubbles","cancelable","sre","mapped","exception","console","warn","reset","spin","hidden","disabled","Input","_input","_fieldError","internals","attachInternals","role","_type","_fragment","slots","template","withOverlay","observed","skipObservedSetup","fragment","readonly","required","label","ariaDescribedByElements","ariaLabelledByElements","readOnly","reflect","toggle","error","setValidity","customError","formResetCallback","LocalDate","content","innerHTML","locale","Intl","DateTimeFormat","resolvedOptions","formatter","year","month","day","m","format","Instant","hour","minute","second","hour12","isoToLocal","iso","pad","String","padStart","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","InputLocalDate","min","max","step","fromIsoOrOffset","toISOString","match","exec","sign","offset","r","setDate","setMonth","setFullYear","InputLocalTime","InputInstant","InputFile","en","dropzonelabel","unaccepptablefiletype","maxfilesizeexceeded","maxtotalsizeexceeded","maxfilesexceeded","it","accept","items","dropzone","warnings","warning","multiple","itemlist","maxfiles","maxfilesize","maxtotalsize","closest","fileName","dt","DataTransfer","files","f","add","update","click","dataTransfer","kind","getAsFile","formatByteSize","round","ensureAcceptable","ensureFileSizes","ensureTotalSize","ensureFilesCount","withModule","renderTo","unacceptable","file","some","endsWith","includes","oversized","totalsize","useItemlist","useDropzone","RemoteLoader","prefetch","ensureFetched","exact","needle","reconfigureUrl","storageKey","PartialRemoteLoader","InMemoryLoader","SelectLoader","responseMapperFrom","evaluator","evaluateExpression","row","Dropdown","menu","Map","change","hide","acceptSelection","selected","firstElementChild","classList","index","shown","show","moveOrShow","candidate","scrollIntoView","block","behavior","Select","badges","ddmenu","fieldError","self","dload","abortdload","idx","children","changed","syncBadges","relatedTarget","contains","selectionStart","selectionEnd","clear","withLoader","selection","metadata","entry","RadioGroup","fieldset","firstRadio","booleanType","uid","radioEls","default","inputsAndLabels","Fragments","fromChildNodes","inert","Checkbox","container","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","RemoteTableLoader","filters","fromEntries","TableLoader","Table","initial","nodata","searchIcon","loading","noAutoload","feedback","paginator","sorters","latestRequest","table","Rendering","waitForChildren","maybeForm","s","reload","pageResponse","textContent","resetWithFilter","ceil","InstantFilter","operator","value1","value2","btn","previousElementSibling","LocalDateFilter","setAttibute","TextFilter","sensitivity","LocalizationModule","l10n","language","tl","hex","lenInBytes","octet","parseInt","bytes","upper","toUpperCase","o","configure","httpClient","defineModule","defineComponent","defineElement","defineOverlay","navigator"],"mappings":"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"}
1
+ {"version":3,"file":"ful.iife.min.js","sources":["../src/encodings.mjs","../src/failure.mjs","../src/http-client.mjs","../src/storage.mjs","../src/oauth-authorization-code.mjs","../src/events/async.mjs","../src/timing.mjs","../src/elements/bindings.mjs","../src/elements/form.mjs","../src/elements/input.mjs","../src/elements/temporals.mjs","../src/elements/files.mjs","../src/elements/select.mjs","../src/elements/radio.mjs","../src/elements/checkbox.mjs","../src/elements/spinner.mjs","../src/elements/table.mjs","../src/elements/filters.mjs","../src/elements/l10n.mjs","../src/elements/plugin.mjs"],"sourcesContent":["\n\nclass Base64 {\n static encode(arrayBuffer, dialect) {\n const d = dialect || Base64.URL_SAFE;\n const len = arrayBuffer.byteLength;\n const view = new Uint8Array(arrayBuffer);\n let res = '';\n for (let i = 0; i < len; i += 3) {\n const v1 = d[view[i] >> 2];\n const v2 = d[((view[i] & 3) << 4) | (view[i + 1] >> 4)];\n const v3 = d[((view[i + 1] & 15) << 2) | (view[i + 2] >> 6)];\n const v4 = d[view[i + 2] & 63];\n res += v1 + v2 + v3 + v4;\n }\n if (len % 3 === 2) {\n res = res.substring(0, res.length - 1);\n } else if (len % 3 === 1) {\n res = res.substring(0, res.length - 2);\n }\n return res;\n }\n static decode(str, dialect) {\n const d = dialect || Base64.URL_SAFE;\n let nbytes = Math.floor(str.length * 0.75);\n for (let i = 0; i !== str.length; ++i) {\n if (str[str.length - i - 1] !== '=') {\n break;\n }\n --nbytes;\n }\n const view = new Uint8Array(nbytes);\n\n let vi = 0;\n let si = 0;\n while (vi < str.length * 0.75) {\n const v1 = d.indexOf(str.charAt(si++));\n const v2 = d.indexOf(str.charAt(si++));\n const v3 = d.indexOf(str.charAt(si++));\n const v4 = d.indexOf(str.charAt(si++));\n view[vi++] = (v1 << 2) | (v2 >> 4);\n view[vi++] = ((v2 & 15) << 4) | (v3 >> 2);\n view[vi++] = ((v3 & 3) << 6) | v4;\n }\n\n return view.buffer;\n }\n}\n\nBase64.STANDARD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nBase64.URL_SAFE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n\nclass Hex {\n static decode(hex) {\n if (hex.length % 2 !== 0) {\n throw new Error(\"invalid length\");\n }\n const lenInBytes = hex.length / 2;\n return new Uint8Array(lenInBytes).map((e, i) => {\n const offset = i * 2;\n const octet = hex.substring(offset, offset + 2);\n return parseInt(octet, 16);\n });\n }\n static encode(bytes, upper) {\n return Array.from(bytes)\n .map(b => b.toString(16))\n .map(b => upper ? b.toUpperCase() : b)\n .map(o => o.padStart(2, 0))\n .join('');\n }\n}\n\nexport { Base64, Hex };","\n\n/**\n * @typedef {{ type: string; context: string?; reason: string; details: any?; }} Problem\n */\nclass Failure extends Error {\n /**\n * \n * @param {string} message \n * @param {Problem[]} problems \n * @param {*} cause\n */\n constructor(message, problems, cause) {\n super(message, { cause });\n this.name = 'Failure';\n this.problems = problems;\n }\n dropping(prefix){\n return new Failure(this.message, Failure.dropProblemsContext(this.problems, prefix), this);\n }\n static dropProblemsContext(problems, prefix){\n return problems.map(({type, context, reason, details}) => {\n const nctx = context?.startsWith(prefix) ? context.substring(prefix.length) : context;\n return {type, context: nctx, reason, details};\n })\n }\n\n}\n\nexport { Failure };","import { Failure } from \"./failure.mjs\";\n\nclass MediaType {\n #type;\n #subtype;\n constructor(type, subtype) {\n this.#type = type;\n this.#subtype = subtype;\n }\n get normalized() {\n return `${this.#type}/${this.#subtype}`;\n }\n get type() {\n return this.#type;\n }\n get subtype() {\n return this.#subtype;\n }\n /**\n * \n * @param {string|null|undefined} v \n * @returns \n */\n static parse(v) {\n if (!v) {\n return new MediaType(\"unknown\", \"unknown\");\n }\n const [prefix, _] = v.split(\";\");\n const [ptype, psubtype] = prefix.trim().split(\"/\");\n return new MediaType(ptype.toLowerCase(), psubtype?.toLowerCase());\n }\n}\n\n/**\n * @typedef {Int8Array| Uint8Array| Uint8ClampedArray| Int16Array| Uint16Array| Int32Array| Uint32Array| Float32Array| Float64Array| BigInt64Array| BigUint64Array} TypedArray\n */\n/**\n * @typedef HttpInterceptor\n * @property {function(URL,RequestInit|undefined,HttpInterceptorChain):Promise<Response>} intercept \n */\n\nclass HttpClientError extends Failure {\n /**\n * @param {string} message\n * @param {number} status\n * @param {{ type: string; context: string?; reason: string; details: any?; }[]} problems\n * @param {Error|undefined} [cause]\n */\n constructor(message, status, problems, cause) {\n super(message, problems, cause);\n this.name = 'HttpClientError';\n this.status = status;\n }\n dropping(prefix){\n return new HttpClientError(this.message, this.status, Failure.dropProblemsContext(this.problems, prefix), this);\n }\n /**\n * \n * @param {string} type \n * @param {any} cause \n * @returns \n */\n static of(type, cause) {\n return new HttpClientError(cause.message, 0, [{\n type,\n context: null,\n reason: cause.message,\n details: null\n }], cause);\n }\n /**\n * Creates an HttpClientError from a Response.\n * @param {Response} response \n * @returns an HttpClientError\n */\n static async fromResponse(response) {\n switch (MediaType.parse(response.headers.get(\"Content-Type\")).normalized) {\n case 'application/failures+json': {\n const data = await response.json();\n const message = `${response.status} ${response.statusText}: ${data.length} failures`;\n return new HttpClientError(message, response.status, data);\n }\n case 'application/problem+json': {\n const data = await response.json();\n const message = `${response.status} ${response.statusText}: ${data.title} ${data.detail}`;\n return new HttpClientError(message, response.status, data.problems || [{\n type: \"GENERIC_PROBLEM\",\n context: null,\n reason: message,\n details: null\n }]);\n }\n default: {\n const text = await response.text();\n const message = `${response.status} ${response.statusText}: ${text}`;\n return new HttpClientError(message, response.status, [{\n type: \"GENERIC_PROBLEM\",\n context: null,\n reason: message,\n details: null\n }]);\n }\n }\n }\n}\n\n/**\n * @implements {HttpInterceptor}\n */\nclass CsrfTokenInterceptor {\n #k; #v;\n constructor() {\n this.#k = document.querySelector(\"meta[name='_csrf_header']\")?.getAttribute(\"content\");\n this.#v = document.querySelector(\"meta[name='_csrf']\")?.getAttribute(\"content\");\n }\n async intercept(url, request, chain) {\n if (this.#k && this.#v) {\n request.headers.set(this.#k, this.#v);\n }\n return await chain.proceed(url, request);\n }\n}\n/**\n * @implements {HttpInterceptor}\n */\nclass RedirectOnUnauthorizedInterceptor {\n #redirectUri;\n /**\n * @param {string} redirectUri\n */\n constructor(redirectUri) {\n this.#redirectUri = redirectUri;\n }\n async intercept(url, request, chain) {\n const response = await chain.proceed(url, request);\n if (response.status === 401) {\n window.location.href = this.#redirectUri;\n }\n return response;\n }\n}\n\nclass HttpClientBuilder {\n /**\n * @type {HttpInterceptor[]}\n */\n #interceptors;\n constructor() {\n this.#interceptors = [];\n }\n withCsrfToken() {\n this.#interceptors.push(new CsrfTokenInterceptor());\n return this;\n }\n withRedirectOnUnauthorized(redirectUri) {\n this.#interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));\n return this;\n }\n /**\n * @param {...HttpInterceptor} interceptors\n */\n withInterceptors(...interceptors) {\n this.#interceptors.push(...interceptors);\n return this;\n }\n build() {\n return new HttpClient(this.#interceptors);\n }\n}\n\n/**\n * @implements {HttpInterceptor}\n */\nclass HttpCall {\n async intercept(url, request, chain) {\n return await fetch(new Request(url, request));\n }\n}\n\nclass HttpInterceptorChain {\n #interceptors;\n #current;\n /**\n * \n * @param {HttpInterceptor[]} interceptors \n * @param {number} current \n */\n constructor(interceptors, current) {\n this.#interceptors = interceptors;\n this.#current = current;\n }\n /**\n * \n * @param {URL} url\n * @param {RequestInit} request \n * @returns {Promise<Response>} the response\n */\n async proceed(url, request) {\n const interceptor = this.#interceptors[this.#current];\n return await interceptor.intercept(url, request, new HttpInterceptorChain(this.#interceptors, this.#current + 1));\n }\n}\n\nclass HttpClient {\n #interceptors;\n /**\n * Creates a builder for an HttpClient.\n * @returns {HttpClientBuilder} the client builder\n */\n static builder() {\n return new HttpClientBuilder();\n }\n /**\n * Creates an HttpClient.\n * @param {HttpInterceptor[]|undefined} interceptors - a list of interceptors to be registered for every request performed by the created client. \n */\n constructor(interceptors) {\n this.#interceptors = interceptors || [];\n }\n /**\n * Performs an HTTP exchange.\n * @async\n * @param {string} uri - the (possibly relative) request url\n * @param {RequestInit|undefined} options - fetch options\n * @param {HttpInterceptor[]|undefined} interceptors - the HttpInterceptors to be registered for this exchange.\n * @returns {Promise<Response>} the response\n */\n async exchange(uri, options, interceptors) {\n const is = [...this.#interceptors, ...interceptors || [], new HttpCall()];\n const chain = new HttpInterceptorChain(is, 0);\n const url = new URL(new Request(uri).url);\n return await chain.proceed(url, options ?? {});\n }\n /**\n * Creates a request builder.\n * @param {string} method - the HTTP method to be used\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n request(method, uri) {\n return HttpRequestBuilder.create(this, method, uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url \n * @returns {HttpRequestBuilder} the request builder\n */\n get(uri) {\n return HttpRequestBuilder.create(this, 'GET', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n head(uri) {\n return HttpRequestBuilder.create(this, 'HEAD', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n post(uri) {\n return HttpRequestBuilder.create(this, 'POST', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n put(uri) {\n return HttpRequestBuilder.create(this, 'PUT', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n patch(uri) {\n return HttpRequestBuilder.create(this, 'PATCH', uri);\n }\n /**\n * Creates a request builder.\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the request builder\n */\n delete(uri) {\n return HttpRequestBuilder.create(this, 'DELETE', uri);\n }\n}\n\n/**\n * \n * @param {Response} response \n * @param {'text'|'json'|'blob'|'arrayBuffer'} type \n * @returns \n */\nconst unmarshal = async (response, type) => {\n try {\n return await response[type]();\n } catch (ex) {\n throw HttpClientError.of(\"UNMARSHALING_PROBLEM\", ex);\n }\n}\n\nclass HttpRequestBuilder {\n #client;\n #method;\n #uri;\n #params;\n #headers;\n #body;\n #options;\n #interceptors;\n /**\n * Creates an HttpRequestBuilder.\n * @param {HttpClient} client \n * @param {string} method - the HTTP method to be used\n * @param {string} uri - the (possibly relative) request url\n * @returns {HttpRequestBuilder} the builder\n */\n static create(client, method, uri) {\n const [baseUri, queryString = ''] = uri.split('?');\n return new HttpRequestBuilder(\n client,\n method,\n baseUri,\n new URLSearchParams(queryString),\n new Headers(),\n undefined,\n {},\n []\n );\n }\n /**\n * Creates an HttpRequestBuilder.\n * @param {HttpClient} client \n * @param {string} method - the HTTP method to be used\n * @param {string} uri - the (possibly relative) request url\n * @param {URLSearchParams} params \n * @param {Headers} headers \n * @param {any} body \n * @param {Omit<RequestInit,\"headers\"|\"method\"|\"body\">} options \n * @param {HttpInterceptor[]} interceptors \n */\n constructor(client, method, uri, params, headers, body, options, interceptors) {\n this.#client = client;\n this.#method = method;\n this.#uri = uri;\n this.#params = params;\n this.#body = body;\n this.#headers = headers;\n this.#options = options;\n this.#interceptors = interceptors;\n }\n /**\n * Add all passed headers to the request, overriding existing ones if that key already exists. Null and undefined values cause the key to be removed.\n * @param {HeadersInit} hs \n * @returns {HttpRequestBuilder} this builder\n */\n headers(hs) {\n for (const [k, v] of new Headers(hs).entries()) {\n if (v == null) {\n this.#headers.delete(k);\n } else {\n this.#headers.set(k, v);\n }\n }\n return this;\n }\n /**\n * Adds an header to the request, overriding it if it already exists. Null and undefined values cause the key to be removed\n * @param {string} k \n * @param {string} v \n * @returns {HttpRequestBuilder} this builder\n */\n header(k, v) {\n if (v == null) {\n this.#headers.delete(k);\n } else {\n this.#headers.set(k, v);\n }\n return this;\n }\n /**\n * Add all query parameters to the request, overriding existing ones if that key already exists. Null and undefined values cause the key to be removed\n * @param {URLSearchParams|Record<string,string>|string[][]|string} ps \n * @returns {HttpRequestBuilder} this builder\n */\n params(ps) {\n for (const [k, v] of new URLSearchParams(ps).entries()) {\n if (v == null) {\n this.#params.delete(k);\n } else {\n this.#params.set(k, v);\n }\n }\n return this;\n }\n /**\n * Adds a query parameter to the request, overriding it if it already exists. Empty vs, or a single null or undefined value cause the key to be removed.\n * @param {string} k \n * @param {...string} vs\n * @returns {HttpRequestBuilder} this builder\n */\n param(k, ...vs) {\n if (vs.length === 0 || vs[0] == null) {\n this.#params.delete(k);\n return this;\n }\n for (const v of vs) {\n this.#params.append(k, v);\n }\n return this;\n }\n /**\n * Sets the request body. \n * `Content-Type: multipart/form-data` header is automatically added by fetch when data is a FormData instance if not explicitly set.\n * `Content-Type: application/x-www-form-urlencoded` header is automatically added by fetch when data is an URLSearchParams instance if not explicitly set.\n * `Content-Type: text/plain` header is automatically added by fetch when data is a string instance if not explicitly set.\n * @param {string|ArrayBuffer|Blob|DataView|File|FormData|TypedArray|URLSearchParams|ReadableStream} data \n * @returns {HttpRequestBuilder} this builder\n */\n body(data) {\n this.#body = data;\n return this;\n }\n /**\n * Sets the request body that will be serialized as json. Calling this method adds the `Content-Type application/json` header for the request.\n * @param {any} body - the body to be serialized as json\n * @returns {HttpRequestBuilder} this builder\n */\n json(body) {\n this.#headers.set(\"Content-Type\", \"application/json\");\n this.#body = JSON.stringify(body);\n return this;\n }\n /**\n * Sets the request body as a FormData configured using the callback.\n * `Content-Type: multipart/form-data` header is automatically added by fetch if not explicitly set.\n * @param {function(HttpMultipartRequestCustomizer):void} callback\n */\n multipart(callback) {\n const formData = new FormData();\n const builder = new HttpMultipartRequestCustomizer(formData);\n callback(builder);\n this.#body = formData;\n return this;\n }\n /**\n * Sets a fetch options for the request.\n * @param {Omit<RequestInit,\"headers\"|\"method\"|\"body\">} kvs\n * @returns {HttpRequestBuilder} this builder\n */\n options(kvs) {\n for (const [k, v] of Object.entries(kvs)) {\n this.#options[k] = v;\n }\n return this;\n }\n /**\n * Sets a fetch option for the request.\n * @param {keyof Omit<RequestInit,\"headers\"|\"method\"|\"body\">} k \n * @param {*} v \n * @returns {HttpRequestBuilder} this builder\n */\n option(k, v) {\n this.#options[k] = v;\n return this;\n }\n /**\n * Adds interceptors to the request.\n * @param {[HttpInterceptor]} is - the interceptor to be regisered\n * @returns {HttpRequestBuilder} this builder\n */\n interceptors(is) {\n for (const i of is) {\n this.#interceptors.push(i);\n }\n return this;\n }\n /**\n * Adds an interceptor to the request.\n * @param {HttpInterceptor} i - the interceptor to be regisered\n * @returns {HttpRequestBuilder} this builder\n */\n interceptor(i) {\n this.#interceptors.push(i);\n return this;\n }\n /**\n * Performs an HTTP exchange using the configured client, request and interceptors.\n * @returns {Promise<Response>} the response\n */\n async exchange() {\n const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;\n const opts = {\n ...this.#options,\n headers: this.#headers,\n method: this.#method,\n body: this.#body,\n };\n return await this.#client.exchange(uri, opts, this.#interceptors);\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<Response>} the response\n */\n async fetch() {\n const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;\n const opts = {\n ...this.#options,\n headers: this.#headers,\n method: this.#method,\n body: this.#body,\n };\n try {\n const response = await this.#client.exchange(uri, opts, this.#interceptors);\n if (!response.ok) {\n throw await HttpClientError.fromResponse(response);\n }\n return response;\n } catch (ex) {\n if (ex instanceof Failure) {\n throw ex;\n }\n throw HttpClientError.of(\"CONNECTION_PROBLEM\", ex);\n }\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<string>} the response body, as text\n */\n async fetchText() {\n const response = await this.fetch();\n return await unmarshal(response, 'text');\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<any>} the response body, deserialized as JSON\n */\n async fetchJson() {\n const response = await this.fetch();\n return await unmarshal(response, 'json');\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<Blob>} the response body, as a Blob\n */\n async fetchBlob() {\n const response = await this.fetch();\n return await unmarshal(response, 'blob');\n }\n /**\n * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.\n * @returns {Promise<ArrayBuffer>} the response body, as an ArrayBuffer\n */\n async fetchArrayBuffer() {\n const response = await this.fetch();\n return await unmarshal(response, 'arrayBuffer');\n }\n}\n\nclass HttpMultipartRequestCustomizer {\n #formData;\n /**\n * \n * @param {FormData} formData \n */\n constructor(formData) {\n this.#formData = formData;\n }\n /**\n * Appends a value to the FormData.\n * @param {string} name \n * @param {*} value \n * @returns this builder\n */\n field(name, value) {\n this.#formData.append(name, value);\n return this;\n }\n /**\n * Appends a Blob to the FormData. \n * If `filename` is omitted, FormData defaults are applied:\n * The default filename for Blob objects is \"blob\"; \n * The default filename for File objects is the file's filename.\n * @param {string} name \n * @param {Blob} value \n * @param {string|undefined} filename \n * @returns this builder\n */\n blob(name, value, filename) {\n this.#formData.append(name, value, filename);\n return this;\n }\n /**\n * Appends multiple Blobs to the FormData with the same name. \n * The default filename for Blob objects is \"blob\"; \n * The default filename for File objects is the file's filename.\n * @param {string} name \n * @param {Blob[]} values\n * @returns this builder\n */\n blobs(name, values) {\n for (let v of values) {\n this.#formData.append(name, v);\n }\n return this;\n }\n /**\n * Appends a JSON serialized blob to the FormData.\n * @param {string} name \n * @param {any} value \n * @param {string|undefined} filename \n * @returns this builder\n */\n json(name, value, filename) {\n const blob = new Blob([JSON.stringify(value)], { type: 'application/json' });\n this.#formData.append(name, blob, filename);\n return this;\n }\n}\n\nexport { MediaType, HttpClient, HttpClientError };\n","\nclass 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}\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\n\nexport { LocalStorage, VersionedLocalStorage, SessionStorage, VersionedSessionStorage };","import { Base64 } from \"./encodings.mjs\";\nimport { SessionStorage } from \"./storage.mjs\";\n\n\nclass AuthorizationCodeFlow {\n static forKeycloak(clientId, realmBaseUrl, redirectUri, maybeScope) {\n const scope = maybeScope ?? \"openid profile\";\n return new AuthorizationCodeFlow(clientId, scope, {\n auth: new URL(\"protocol/openid-connect/auth\", realmBaseUrl),\n token: new URL(\"protocol/openid-connect/token\", realmBaseUrl),\n logout: new URL(\"protocol/openid-connect/logout\", realmBaseUrl),\n registration: new URL(\"protocol/openid-connect/registrations\", realmBaseUrl),\n redirect: redirectUri\n });\n }\n constructor(clientId, scope, { auth, token, registration, logout, redirect }) {\n this.clientId = clientId;\n this.scope = scope;\n this.uri = { auth, token, registration, logout, redirect };\n }\n async action(uri, additionalParams) {\n const pkceVerifier = Base64.encode(crypto.getRandomValues(new Uint8Array(32)).buffer);\n const pkceChallenge = Base64.encode(await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(pkceVerifier)));\n const state = this.clientId + Base64.encode(crypto.getRandomValues(new Uint8Array(16)).buffer);\n SessionStorage.save(`${AuthorizationCodeFlow.PKCE_AND_STATE_KEY}-${this.clientId}`, {\n state: state,\n verifier: pkceVerifier\n });\n const url = new URL(uri);\n url.searchParams.set(\"client_id\", this.clientId);\n url.searchParams.set(\"redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"response_type\", 'code');\n url.searchParams.set(\"scope\", this.scope);\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", pkceChallenge);\n url.searchParams.set(\"code_challenge_method\", 'S256');\n Object.entries(additionalParams || {}).forEach(kv => {\n url.searchParams.set(kv[0], kv[1]);\n });\n window.location.href = url.toString();\n }\n async registration(additionalParams) {\n await this.action(this.uri.registration, additionalParams);\n }\n async applicationInitiatedAction(kcAction, additionalParams) {\n await this.action(this.uri.auth, {\n ...additionalParams,\n kc_action: kcAction,\n });\n }\n async #tokenExchange(code, state) {\n window.history.replaceState('', \"\", this.uri.redirect);\n const stateAndVerifier = SessionStorage.pop(`${AuthorizationCodeFlow.PKCE_AND_STATE_KEY}-${this.clientId}`);\n if (stateAndVerifier.state !== state) {\n throw new Error(\"State mismatch\");\n }\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"code\", code],\n [\"grant_type\", \"authorization_code\"],\n [\"code_verifier\", stateAndVerifier.verifier],\n [\"state\", stateAndVerifier.state],\n [\"redirect_uri\", this.uri.redirect]\n ])\n });\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\"Error:\" + response.status + \": \" + text);\n }\n const token = await response.json();\n return new AuthorizationCodeFlowSession(this.clientId, token, this.uri);\n }\n async ensureLoggedIn() {\n const url = new URL(window.location.href);\n const code = url.searchParams.get(\"code\");\n if (code && SessionStorage.load(`${AuthorizationCodeFlow.PKCE_AND_STATE_KEY}-${this.clientId}`)) {\n //if callback from keycloak and we have our state still stored\n const state = url.searchParams.get(\"state\");\n return await this.#tokenExchange(code, state);\n }\n //if not authorized\n await this.action(this.uri.auth, {});\n return null;\n }\n}\nAuthorizationCodeFlow.PKCE_AND_STATE_KEY = \"state-and-verifier\";\n\nclass AuthorizationCodeFlowSession {\n static parseToken(token) {\n const [rawHeader, rawPayload, signature] = token.split(\".\");\n const utf8decoder = new TextDecoder(\"utf-8\");\n return {\n header: JSON.parse(utf8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),\n payload: JSON.parse(utf8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),\n signature: signature\n };\n }\n constructor(clientId, t, { token, logout, redirect }) {\n this.clientId = clientId;\n this.token = t;\n this.idToken = AuthorizationCodeFlowSession.parseToken(t.id_token);\n this.accessToken = AuthorizationCodeFlowSession.parseToken(t.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(t.refresh_token);\n this.uri = { token, logout, redirect }\n this.refreshCallback = null;\n }\n onRefresh(callback) {\n this.refreshCallback = callback;\n }\n async refresh() {\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"grant_type\", \"refresh_token\"],\n [\"refresh_token\", this.token.refresh_token]\n ])\n });\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\"Error:\" + response.status + \": \" + text);\n }\n const token = await response.json();\n this.token = token;\n this.idToken = AuthorizationCodeFlowSession.parseToken(token.id_token);\n this.accessToken = AuthorizationCodeFlowSession.parseToken(token.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(token.refresh_token);\n if (this.refreshCallback) {\n this.refreshCallback(this.token, this.accessToken, this.refreshToken);\n }\n }\n shouldBeRefreshed(gracePeriod) {\n const now = new Date().getTime();\n const refreshTokenExpiresAt = this.refreshToken.payload.exp * 1000;\n const expired = now > refreshTokenExpiresAt;\n const shouldRefresh = now - gracePeriod > refreshTokenExpiresAt;\n return !expired && shouldRefresh;\n }\n async refreshIf(gracePeriod) {\n if (!this.shouldBeRefreshed(gracePeriod)) {\n return;\n }\n await this.refresh();\n }\n logout() {\n const url = new URL(this.uri.logout);\n url.searchParams.set(\"post_logout_redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"id_token_hint\", this.token.id_token);\n window.location.href = url.toString();\n }\n\n bearerToken() {\n return `Bearer ${this.token.access_token}`;\n }\n\n interceptor(gracePeriodBefore, gracePeriodAfter) {\n return new AuthorizationCodeFlowInterceptor(this, gracePeriodBefore, gracePeriodAfter);\n }\n}\n\nclass AuthorizationCodeFlowInterceptor {\n #session;\n #gracePeriodBefore;\n #gracePeriodAfter;\n constructor(session, gracePeriodBefore, gracePeriodAfter) {\n this.#session = session;\n this.#gracePeriodBefore = gracePeriodBefore || 2000;\n this.#gracePeriodAfter = gracePeriodAfter || 30000;\n }\n async intercept(url, request, chain) {\n await this.#session.refreshIf(this.#gracePeriodBefore);\n request.headers.set(\"Authorization\", this.#session.bearerToken());\n const response = await chain.proceed(url, request);\n await this.#session.refreshIf(this.#gracePeriodAfter);\n return response;\n }\n}\n\nexport { AuthorizationCodeFlow, AuthorizationCodeFlowSession, AuthorizationCodeFlowInterceptor };","class AsyncEvents {\n static async fireAsync(el, evt) {\n el.dispatchEvent(evt);\n return await evt.async?.promise;\n }\n /**\n * \n * @param {*} el \n * @param {*} type \n * @param {*} fn returning the result\n * @param {*} options \n * @returns \n */\n static asyncOn(el, type, fn, options) {\n const listener = async (event) => {\n let resolve, reject;\n const promise = new Promise((res, rej) => {\n resolve = res;\n reject = rej;\n });\n event.async = { promise };\n try {\n //@ts-ignore\n resolve(await fn(event));\n } catch (e) {\n //@ts-ignore\n reject(e);\n }\n };\n el.addEventListener(type, listener, options);\n return listener;\n }\n /**\n * \n * @param {*} el \n * @param {*} type \n * @param {*} listener the listener returned by asyncOn\n * @param {*} options \n */ \n static asyncOff(el, type, listener, options) {\n el.removeEventListener(type, listener, options);\n }\n static mixInto(...classes) {\n for (const k of classes) {\n Object.assign(k.prototype, {\n async fireAsync(evt) {\n return await AsyncEvents.fireAsync(this, evt);\n },\n asyncOn(type, fn, options) {\n return AsyncEvents.asyncOn(this, type, fn, options);\n },\n asyncOff(type, listener, options) {\n return AsyncEvents.asyncOff(this, type, listener, options);\n }\n });\n }\n }\n}\n\nexport { AsyncEvents }","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 = new Date().getTime() - 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 = new Date().getTime();\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 : new Date().getTime();\n tid = null;\n func(...args);\n if (tid === null) {\n args = [];\n }\n };\n const throttled = function () {\n const now = new Date().getTime();\n if (!previousTimestamp && (opts & Timing.THROTTLE_NO_LEADING)) {\n previousTimestamp = now;\n }\n const remaining = 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 };","\nclass Bindings {\n\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') {\n return el.value === '' || el.value === undefined ? null : el.value;\n }\n return el.value;\n }\n\n /**\n * \n * @param {HTMLFormElement} form \n * @returns \n */\n static extractFrom(form){\n let result = {};\n for(const el of form.elements){\n if(!el.hasAttribute(\"name\") || el.matches(\":disabled\")){\n continue;\n }\n result = Bindings.providePath(result, /** @type {string} */(el.getAttribute('name')), Bindings.extract(el))\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\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(\"[\", \".\").replace(\"].\", \".\").replace(\"]\", \"\");\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 => input.setCustomValidity?.(e.reason, suffix));\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`)).sort((a,b) => a.getBoundingClientRect().y - b.getBoundingClientRect().y)[0]?.focus();\n }\n}\n\n\nexport { Bindings }\n","import { Attributes, ParsedElement, registry } from \"@optionfactory/ftl\"\nimport { Failure } from \"../failure.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)\n .json(values)\n .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\") ? registry.component(el.getAttribute(\"request-mapper\")) : v => v;\n const responseMapper = el.hasAttribute(\"response-mapper\") ? registry.component(el.getAttribute(\"response-mapper\")) : 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();\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 async submit() {\n this.spinner(true)\n try {\n const loader = registry.component(this.getAttribute(\"loader\") ?? 'loaders:form').create(this);\n const values = this.values;\n let request = await loader.prepare(values, this)\n try {\n const se = new CustomEvent('submit', { bubbles: true, cancelable: true, detail: { values, request } });\n if (!this.dispatchEvent(se)) {\n return;\n }\n const sre = new CustomEvent('submit:requested', { bubbles: true, cancelable: false, detail: { values: se.detail.values, request: se.detail.request} })\n let response = await AsyncEvents.fireAsync(this, sre);\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(new CustomEvent('submit:success', { bubbles: true, cancelable: false, detail: { values, request, response: mapped } }))\n } catch (e) {\n this.dispatchEvent(new CustomEvent('submit:failure', { bubbles: true, cancelable: false, detail: { values, request, exception: e } }));\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 hel.disabled = spin\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 \"@optionfactory/ftl\"\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\n this._input.addEventListener('change', (evt) => {\n evt.stopPropagation();\n this.dispatchEvent(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: {\n value: this.value\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 return this._input.value === '' ? null : this._input.value;\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 //@ts-ignore\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 \"@optionfactory/ftl\";\nimport { Input } from \"./input.mjs\";\n\n\n\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\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 if (v === 'now') {\n return new Date().toISOString().split(\"T\")[0];\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 switch (match[3]) {\n case 'd':\n r.setDate(r.getDate() + offset * sign);\n break;\n case 'm':\n r.setMonth(r.getMonth() + offset * sign);\n break;\n case 'y':\n r.setFullYear(r.getFullYear() + offset * sign);\n break;\n }\n return r.toISOString().split(\"T\")[0];\n }\n}\n\nclass InputLocalTime extends InputLocalDate {\n _type() {\n return 'time';\n }\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.min;\n this.step = observed.min;\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\n\n\n\nexport { Instant, LocalDate, InputLocalDate, InputLocalTime, InputInstant }","import { Attributes } from \"@optionfactory/ftl\";\nimport { Input } from \"./input.mjs\";\n\n\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 }\n static observed = ['value', 'readonly:presence', 'required:presence', \"accept:csv\", 'multiple:presence', \"itemlist:presence\", \"dropzone:presence\", \"maxfiles:number\", \"maxfilesize:number\", \"maxtotalsize:number\"];\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\"></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) ? `${Math.round(v / 1024 / 1024 * 100) / 100}MiB` : (v > 1024 ? `${Math.round(v / 1024 * 100) / 100}KiB` : `${v}B`);\n }\n #update() {\n this.setCustomValidity();\n this.#ensureAcceptable();\n this.#ensureFileSizes();\n this.#ensureTotalSize();\n this.#ensureFilesCount();\n this.template('items').withOverlay({ files: this.files }).withModule('bytes', { format: this.#formatByteSize }).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]\n .filter(file => !this.#accept.some(type => file.name.toLowerCase().endsWith(type.toLowerCase())));\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]\n .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 dt.items.add(v);\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 //TODO:\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 }","import { Attributes, ParsedElement, registry } from \"@optionfactory/ftl\"\nimport { Timing } from \"../timing.mjs\";\nimport { VersionedLocalStorage } from \"../storage.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 storageKey = `${this.#method}@${this.#url}`;\n if (this.#revision !== null) {\n const data = VersionedLocalStorage.load(storageKey, this.#revision);\n if (data !== undefined) {\n this.#data = data;\n return;\n }\n }\n const data = await this.#http.request(this.#method, this.#url)\n .fetchJson()\n this.#data = this.#responseMapper(data);\n if (this.#revision !== null) {\n VersionedLocalStorage.save(storageKey, this.#revision, this.#data);\n }\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.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)\n .param(\"s\", needle)\n .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\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.evaluator().withOverlay(response).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\" hidden></menu>\n `;\n #spinner;\n #menu;\n #options = new Map();\n render({ slots }) {\n const fragment = this.template().render();\n this.#spinner = fragment.querySelector(\"ful-spinner\");\n this.#menu = fragment.querySelector(\"menu\");\n this.#menu.addEventListener('click', evt => {\n evt.stopPropagation();\n if (!evt.target.matches('li')) {\n this.hide();\n return;\n }\n this.#change(evt.target);\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 if (values.length === 0) {\n const el = document.createElement('div');\n el.classList.add('text-center', 'py-2', 'bi', 'bi-database-slash');\n this.#menu.replaceChildren(el);\n return;\n }\n this.#menu.replaceChildren(...values.map(([k, v, m], i) => {\n const el = document.createElement('li');\n if (i === 0) {\n el.setAttribute(\"selected\", '');\n }\n el.setAttribute(\"value\", i);\n el.innerText = v;\n return el;\n }));\n }\n #change(target) {\n const index = target.getAttribute('value');\n const data = this.#options.get(index)\n this.hide();\n this.dispatchEvent(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: { index, data }\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=\"\">\n </div>\n <ful-dropdown hidden popover=\"manual\"></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.component(this.getAttribute(\"loader\") ?? 'loaders:select').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, () => self.#ddmenu.show(() => self.#loader.load(self.#input.value)));\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.#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.#ddmenu.hide();\n this.#input.value = '';\n });\n this.#input.addEventListener('keydown', e => {\n e.stopPropagation();\n if (this.disabled || this.readonly) {\n return;\n }\n switch (e.code) {\n case 'ArrowUp': {\n this.#ddmenu.moveOrShow(false, () => self.#loader.load(self.#input.value));\n break;\n }\n case 'ArrowDown': {\n this.#ddmenu.moveOrShow(true, () => self.#loader.load(self.#input.value));\n break;\n }\n case 'Escape': {\n this.#ddmenu.hide();\n break;\n }\n case 'Enter': {\n this.#ddmenu.acceptSelection();\n this.#input.value = '';\n break;\n }\n case 'Backspace': {\n //remove last if caret a 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.#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.#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 => ({ key: e[0], label: e[1][0], metadata: e[1].slice(1) }))\n const value = this.#multiple ? selection : (selection[0] ?? null);\n this.dispatchEvent(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: { value }\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 //@ts-ignore\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 { SelectLoader, Select, Dropdown };","import { Attributes, Fragments, ParsedElement } from \"@optionfactory/ftl\"\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(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: {\n value: this.value\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 //@ts-ignore\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 };","import { Attributes, ParsedElement } from \"@optionfactory/ftl\";\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\" role=\"switch\" 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 klass = this.getAttribute('type') == 'switch' ? \"form-check form-switch\" : \"form-check\";\n const fragment = this.template().withOverlay({ slots, klass }).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(new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: {\n value: this.value\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 });\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 //@ts-ignore\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 }","import { ParsedElement } from \"@optionfactory/ftl\"\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 };","import { Attributes, Fragments, Nodes, ParsedElement, registry, Rendering } from \"@optionfactory/ftl\"\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(new CustomEvent('sort-requested', {\n bubbles: true,\n cancelable: true,\n detail: {\n value: { sorter, order: nextOrder }\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 }\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(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 index: current,\n label: current + 1\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 = columns.filter(v => v.hasAttribute('order')).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 = (!sorter && !order) ? titleNode : (() => {\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.withOverlay({ inHeaders: true, inRows: false }).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\n\n\nclass InMemoryTableLoader {\n #data\n constructor(data) {\n this.#data = data;\n }\n async load(pageRequest, sortRequest, filterRequest) {\n return { \n page: this.#data, \n size: this.#data.length \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.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\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 }\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 page: 0,\n size: this.#latestRequest.pageRequest.size\n }, this.#latestRequest.sortRequest, evt.detail.request);\n })\n this.addEventListener('page-requested', async (/** @type any */e) => {\n await this.load({\n page: e.detail.value,\n size: this.#latestRequest.pageRequest.size\n }, this.#latestRequest.sortRequest, this.#latestRequest.filterRequest);\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(this.#latestRequest.pageRequest, this.#latestRequest.sortRequest, this.#latestRequest.filterRequest);\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(p => `${p.reason}`);\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 page: 0,\n size: this.#latestRequest.pageRequest.size\n }, this.#latestRequest.sortRequest, filterRequest);\n }\n #update(pageRequest, sortRequest, filterRequest, pageResponse) {\n this.#loading.setAttribute(\"hidden\", \"\");\n this.#body.replaceChildren(this.template('row').withOverlay({\n schema: this.#schema,\n pageRequest,\n filterRequest,\n pageResponse\n }).render());\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 }","import { Attributes } from \"@optionfactory/ftl\";\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.setAttibute('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 }","\nclass 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(k, ...args);\n }\n\n}\n\n\nexport { LocalizationModule }","import { HttpClient } from \"../http-client.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\n\nclass Plugin {\n configure(registry) {\n const httpClient = HttpClient.builder()\n .withCsrfToken()\n .withRedirectOnUnauthorized(\"/\")\n .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\n\n\nexport { Plugin }"],"names":["Base64","encode","arrayBuffer","dialect","d","URL_SAFE","len","byteLength","view","Uint8Array","res","i","substring","length","decode","str","nbytes","Math","floor","vi","si","v1","indexOf","charAt","v2","v3","v4","buffer","STANDARD","Failure","Error","constructor","message","problems","cause","super","this","name","dropping","prefix","dropProblemsContext","map","type","context","reason","details","startsWith","MediaType","subtype","normalized","parse","v","_","split","ptype","psubtype","trim","toLowerCase","HttpClientError","status","of","fromResponse","response","headers","get","data","json","statusText","title","detail","text","CsrfTokenInterceptor","k","document","querySelector","getAttribute","intercept","url","request","chain","set","proceed","RedirectOnUnauthorizedInterceptor","redirectUri","window","location","href","HttpClientBuilder","interceptors","withCsrfToken","push","withRedirectOnUnauthorized","withInterceptors","build","HttpClient","HttpCall","fetch","Request","HttpInterceptorChain","current","interceptor","builder","exchange","uri","options","is","URL","method","HttpRequestBuilder","create","head","post","put","patch","unmarshal","async","ex","client","params","body","baseUri","queryString","URLSearchParams","Headers","undefined","hs","entries","delete","header","ps","param","vs","append","JSON","stringify","multipart","callback","formData","FormData","HttpMultipartRequestCustomizer","kvs","Object","option","size","opts","ok","fetchText","fetchJson","fetchBlob","fetchArrayBuffer","field","value","blob","filename","blobs","values","Blob","LocalStorage","Storage","save","localStorage","setItem","load","got","getItem","remove","removeItem","pop","decoded","SessionStorage","sessionStorage","VersionedLocalStorage","key","revision","stored","AuthorizationCodeFlow","forKeycloak","clientId","realmBaseUrl","maybeScope","auth","token","logout","registration","redirect","scope","action","additionalParams","pkceVerifier","crypto","getRandomValues","pkceChallenge","subtle","digest","TextEncoder","state","PKCE_AND_STATE_KEY","verifier","searchParams","forEach","kv","toString","applicationInitiatedAction","kcAction","kc_action","tokenExchange","code","history","replaceState","stateAndVerifier","AuthorizationCodeFlowSession","ensureLoggedIn","parseToken","rawHeader","rawPayload","signature","utf8decoder","TextDecoder","payload","t","idToken","id_token","accessToken","access_token","refreshToken","refresh_token","refreshCallback","onRefresh","refresh","shouldBeRefreshed","gracePeriod","now","Date","getTime","refreshTokenExpiresAt","exp","refreshIf","bearerToken","gracePeriodBefore","gracePeriodAfter","AuthorizationCodeFlowInterceptor","session","AsyncEvents","fireAsync","el","evt","dispatchEvent","promise","asyncOn","fn","listener","event","resolve","reject","Promise","rej","e","addEventListener","asyncOff","removeEventListener","mixInto","classes","assign","prototype","Timing","sleep","ms","setTimeout","static","debounce","timeoutMs","func","DEBOUNCE_DEFAULT","tid","args","previousTimestamp","later","elapsed","DEBOUNCE_IMMEDIATE","arguments","clearTimeout","throttle","THROTTLE_DEFAULT","THROTTLE_NO_LEADING","remaining","THROTTLE_NO_TRAILING","Bindings","flatten","obj","stops","keys","reduce","acc","pre","has","providePath","result","path","test","previous","ckey","pkey","Number","isInteger","Array","isArray","extract","checked","dataset","tagName","extractFrom","form","elements","hasAttribute","matches","mutate","raw","mutateIn","names","from","filter","n","flattenedKey","Set","querySelectorAll","CSS","escape","errors","es","scrollOnError","fieldErrors","globalErrors","setCustomValidity","replaceChildren","setAttribute","parts","replace","slice","join","suffix","input","innerText","removeAttribute","sort","a","b","getBoundingClientRect","y","focus","RemoteJsonFormLoader","http","requestMapper","responseMapper","prepare","submit","transform","LocalFormLoader","FormLoader","conf","registry","component","Form","ParsedElement","render","createElement","Attributes","forward","childNodes","preventDefault","stopPropagation","target","spinner","loader","se","CustomEvent","bubbles","cancelable","sre","mapped","exception","console","warn","reset","spin","hidden","hel","disabled","Input","_input","_fieldError","internals","attachInternals","role","_type","_fragment","slots","template","withOverlay","observed","skipObservedSetup","fragment","readonly","required","label","ariaDescribedByElements","ariaLabelledByElements","readOnly","reflect","toggle","error","setValidity","customError","formResetCallback","LocalDate","content","innerHTML","locale","Intl","DateTimeFormat","resolvedOptions","formatter","year","month","day","m","format","Instant","hour","minute","second","hour12","isoToLocal","iso","pad","String","padStart","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","InputLocalDate","min","max","step","fromIsoOrOffset","toISOString","match","exec","sign","offset","r","setDate","setMonth","setFullYear","InputLocalTime","InputInstant","InputFile","en","dropzonelabel","unaccepptablefiletype","maxfilesizeexceeded","maxtotalsizeexceeded","maxfilesexceeded","it","accept","items","dropzone","warnings","warning","multiple","itemlist","maxfiles","maxfilesize","maxtotalsize","closest","fileName","dt","DataTransfer","files","f","add","update","click","dataTransfer","kind","getAsFile","formatByteSize","round","ensureAcceptable","ensureFileSizes","ensureTotalSize","ensureFilesCount","withModule","renderTo","unacceptable","file","some","endsWith","includes","oversized","totalsize","useItemlist","useDropzone","RemoteLoader","prefetch","ensureFetched","exact","needle","reconfigureUrl","storageKey","PartialRemoteLoader","InMemoryLoader","SelectLoader","responseMapperFrom","evaluator","evaluateExpression","row","Dropdown","menu","Map","change","hide","acceptSelection","selected","firstElementChild","classList","index","shown","show","moveOrShow","candidate","scrollIntoView","block","behavior","Select","badges","ddmenu","fieldError","self","dload","abortdload","idx","children","changed","syncBadges","relatedTarget","contains","selectionStart","selectionEnd","clear","withLoader","selection","metadata","entry","RadioGroup","fieldset","firstRadio","booleanType","uid","radioEls","default","inputsAndLabels","Fragments","fromChildNodes","inert","Checkbox","container","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","RemoteTableLoader","filters","fromEntries","TableLoader","Table","initial","nodata","searchIcon","loading","noAutoload","feedback","paginator","sorters","latestRequest","table","Rendering","waitForChildren","maybeForm","s","reload","pageResponse","textContent","resetWithFilter","ceil","InstantFilter","operator","value1","value2","btn","previousElementSibling","LocalDateFilter","setAttibute","TextFilter","sensitivity","LocalizationModule","l10n","language","tl","hex","lenInBytes","octet","parseInt","bytes","upper","toUpperCase","o","configure","httpClient","defineModule","defineComponent","defineElement","defineOverlay","navigator"],"mappings":"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"}