{"version":3,"file":"httpc.min.mjs","sources":["../src/httpc/failure.mjs","../src/httpc/encodings.mjs","../src/httpc/http-client.mjs"],"sourcesContent":["/**\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\nexport { Failure };\n","class 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\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","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 {object} HttpInterceptor\n * @property {(url: URL, init: RequestInit|undefined, chain: 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(\n            cause.message,\n            0,\n            [\n                {\n                    type,\n                    context: null,\n                    reason: cause.message,\n                    details: null,\n                },\n            ],\n            cause,\n        );\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(\n                    message,\n                    response.status,\n                    data.problems || [\n                        {\n                            type: 'GENERIC_PROBLEM',\n                            context: null,\n                            reason: message,\n                            details: null,\n                        },\n                    ],\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                    {\n                        type: 'GENERIC_PROBLEM',\n                        context: null,\n                        reason: message,\n                        details: null,\n                    },\n                ]);\n            }\n        }\n    }\n}\n\n/**\n * @implements {HttpInterceptor}\n */\nclass CsrfTokenInterceptor {\n    #k;\n    #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            return new Promise(() => {});\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(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(\n            url,\n            request,\n            new HttpInterceptorChain(this.#interceptors, this.#current + 1),\n        );\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"],"names":["Failure","Error","constructor","message","problems","cause","super","this","name","dropping","prefix","dropProblemsContext","map","type","context","reason","details","startsWith","substring","length","Base64","encode","arrayBuffer","dialect","d","URL_SAFE","len","byteLength","view","Uint8Array","res","i","decode","str","nbytes","Math","floor","vi","si","v1","indexOf","charAt","v2","v3","v4","buffer","STANDARD","Hex","hex","lenInBytes","e","offset","octet","parseInt","bytes","upper","Array","from","b","toString","toUpperCase","o","padStart","join","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","Promise","HttpClientBuilder","interceptors","withCsrfToken","push","withRedirectOnUnauthorized","withInterceptors","build","HttpClient","HttpCall","fetch","HttpInterceptorChain","current","interceptor","builder","exchange","uri","options","is","URL","Request","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"],"mappings":"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"}