UNPKG

wretch

Version:

A tiny wrapper built around fetch with an intuitive syntax.

1 lines 18.5 kB
{"version":3,"file":"wretch.min.cjs","names":[],"sources":["../../src/utils.ts","../../src/constants.ts","../../src/middleware.ts","../../src/resolver.ts","../../src/core.ts","../../src/index.ts"],"sourcesContent":["export function extractContentType(headers: HeadersInit = {}): string | undefined {\n const normalizedHeaders = headers instanceof Array ? Object.fromEntries(headers) : headers\n for (const k in normalizedHeaders) {\n if (k.toLowerCase() === \"content-type\") return normalizedHeaders[k]\n }\n}\n\nexport function isLikelyJsonMime(value: string): boolean {\n return /^application\\/.*json/.test(value)\n}\n\nexport const mix = (one: object, two: object, mergeArrays = false) => {\n const acc = { ...one }\n for (const key in two) {\n if (!Object.prototype.hasOwnProperty.call(two, key)) continue\n const value = one[key]\n const newValue = two[key]\n acc[key] = Array.isArray(value) && Array.isArray(newValue) ?\n mergeArrays ? [...value, ...newValue] : newValue :\n typeof value === \"object\" && typeof newValue === \"object\" ?\n mix(value, newValue, mergeArrays) :\n newValue\n }\n return acc\n}\n","export const JSON_MIME = \"application/json\"\nexport const FETCH_ERROR = Symbol()\nexport const CATCHER_FALLBACK = Symbol()\n","import type { ConfiguredMiddleware, FetchLike } from \"./types.js\"\n\n/**\n * @private @internal\n */\nexport const middlewareHelper = (middlewares: ConfiguredMiddleware[]) => (fetchFunction: FetchLike): FetchLike =>\n middlewares.reduceRight((acc, curr) => curr(acc), fetchFunction)\n","import { middlewareHelper } from \"./middleware.js\"\nimport type { Wretch, WretchResponse, WretchResponseChain, WretchError as WretchErrorType } from \"./types.js\"\nimport { CATCHER_FALLBACK, FETCH_ERROR } from \"./constants.js\"\n\n/**\n * This class inheriting from Error is thrown when the fetch response is not \"ok\".\n * It extends Error and adds status, text and body fields.\n */\nexport class WretchError extends Error implements WretchErrorType {\n status: number\n response: WretchResponse\n url: string\n}\n\nexport const resolver = <T, Chain, R, E, CatcherResult>(wretch: T & Wretch<T, Chain, R, E, CatcherResult>) => {\n const sharedState = Object.create(null)\n\n wretch = wretch._addons.reduce((w, addon) =>\n addon.beforeRequest &&\n addon.beforeRequest(w, wretch._options, sharedState)\n || w,\n wretch)\n\n const {\n _url: url,\n _options: opts,\n _fetch,\n _errorTransformer: errorTransformer,\n _catchers: _catchers,\n _resolvers: resolvers,\n _middlewares: middlewares,\n _addons: addons\n } = wretch\n\n const catchers = new Map(_catchers)\n const finalOptions = opts\n\n // The generated fetch request\n let finalUrl = url\n const _fetchReq = middlewareHelper(middlewares)((url, options) => {\n finalUrl = url\n const fetchImpl = _fetch || fetch\n return fetchImpl(url, options)\n })(url, finalOptions)\n // Throws on an http error\n const referenceError = new Error()\n const throwingPromise: Promise<void | WretchResponse> = _fetchReq\n .catch(error => {\n // Interect fetch errors and mark them with a special symbol so that they can be caught by a matching catcher\n error[FETCH_ERROR] = true\n throw error\n })\n .then(async response => {\n if (!response.ok) {\n const err = new WretchError()\n err[\"cause\"] = referenceError\n err.stack += \"\\nCAUSE: \" + referenceError.stack\n err.response = response\n err.status = response.status\n err.url = finalUrl\n\n if (response.type === \"opaque\" || errorTransformer) {\n err.message = response.statusText\n } else {\n try {\n err.message = await response.clone().text()\n } catch {\n err.message = response.statusText\n }\n }\n\n throw err\n }\n return response\n })\n // Wraps the Promise in order to dispatch the error to a matching catcher, if any.\n // If a catcher returns a value, the promise resolves with that value instead of rejecting.\n const catchersWrapper = <T>(promise: Promise<T>): Promise<T | CatcherResult> =>\n promise.catch(async error => {\n const catcher =\n catchers.get(error?.status) ||\n catchers.get(error?.name) ||\n (error?.[FETCH_ERROR] && catchers.get(FETCH_ERROR)) ||\n catchers.get(CATCHER_FALLBACK)\n\n if (error.response && errorTransformer) {\n error = await errorTransformer(error, error.response, wretch)\n }\n\n if (catcher)\n return catcher(error, wretch) as CatcherResult\n\n throw error\n })\n // Each body parser returns the normal parsed value, plus any value that a\n // registered catcher may have produced instead.\n type BodyParser =\n <Type>(funName: \"json\" | \"blob\" | \"formData\" | \"arrayBuffer\" | \"text\" | null)\n => <Result = void>(cb?: (type: Type) => Result)\n => Promise<Awaited<Result> | CatcherResult>\n const bodyParser: BodyParser = funName => cb => {\n const promise = funName ?\n // If a callback is provided, then callback with the body result otherwise return the parsed body itself.\n throwingPromise.then(_ => _?.[funName]()) :\n // No body parsing method - return the response\n throwingPromise\n return catchersWrapper(cb ? promise.then(cb) : promise)\n }\n\n // Registering a response-chain catcher mutates only this local chain state at\n // runtime, but its interface widens `CatcherResult` at the type level.\n const responseChain: WretchResponseChain<T, Chain, R, E, CatcherResult> = {\n _wretchReq: wretch,\n _fetchReq,\n _sharedState: sharedState,\n res: bodyParser<WretchResponse>(null),\n json: bodyParser<any>(\"json\"),\n blob: bodyParser<Blob>(\"blob\"),\n formData: bodyParser<FormData>(\"formData\"),\n arrayBuffer: bodyParser<ArrayBuffer>(\"arrayBuffer\"),\n text: bodyParser<string>(\"text\"),\n error(errorId, cb) {\n catchers.set(errorId, cb)\n return this\n },\n badRequest(cb) { return this.error(400, cb) },\n unauthorized(cb) { return this.error(401, cb) },\n forbidden(cb) { return this.error(403, cb) },\n notFound(cb) { return this.error(404, cb) },\n timeout(cb) { return this.error(408, cb) },\n internalError(cb) { return this.error(500, cb) },\n fetchError(cb) { return this.error(FETCH_ERROR, cb) },\n }\n\n // Addon resolvers and user-defined `.resolve(...)` callbacks both receive the\n // chain with the same CatcherResult information threaded through it.\n const enhancedResponseChain: R extends undefined ? Chain & WretchResponseChain<T, Chain, undefined, E, CatcherResult> : R = addons.reduce((chain, addon) => ({\n ...chain,\n ...(typeof addon.resolver === \"function\" ? (addon.resolver as (_: WretchResponseChain<T, Chain, R, E, CatcherResult>) => any)(chain) : addon.resolver)\n }), responseChain)\n\n return resolvers.reduce((chain, r) => r(chain, wretch), enhancedResponseChain)\n}\n","import { mix, extractContentType, isLikelyJsonMime } from \"./utils.js\"\nimport { JSON_MIME, CATCHER_FALLBACK } from \"./constants.js\"\nimport { resolver, WretchError } from \"./resolver.js\"\nimport type { Wretch, WretchOptions } from \"./types.js\"\n\nexport const core: Wretch = {\n _url: \"\",\n _options: {},\n _catchers: new Map(),\n _resolvers: [],\n _deferred: [],\n _middlewares: [],\n _addons: [],\n addon(addon) {\n const addons = Array.isArray(addon) ? addon : [addon]\n const wretchProps = addons.reduce((acc, a) => ({ ...acc, ...a.wretch }), {})\n return { ...this, _addons: [...this._addons, ...addons], ...wretchProps }\n },\n fetchPolyfill(fetchImpl) {\n return { ...this, _fetch: fetchImpl }\n },\n url(_url, replace = false) {\n if (replace)\n return { ...this, _url }\n const idx = this._url.indexOf(\"?\")\n return {\n ...this,\n _url: idx > -1 ?\n this._url.slice(0, idx) + _url + this._url.slice(idx) :\n this._url + _url\n }\n },\n options(options, replace = false) {\n return { ...this, _options: replace ? options : mix(this._options, options) }\n },\n headers(headerValues) {\n const headers =\n !headerValues ? {} :\n Array.isArray(headerValues) ? Object.fromEntries(headerValues) :\n \"entries\" in headerValues ? Object.fromEntries((headerValues as Headers).entries()) :\n headerValues\n return { ...this, _options: mix(this._options, { headers }) }\n },\n accept(headerValue) {\n return this.headers({ Accept: headerValue })\n },\n content(headerValue) {\n return this.headers({ \"Content-Type\": headerValue })\n },\n auth(headerValue) {\n return this.headers({ Authorization: headerValue })\n },\n catcher(ids, catcher) {\n const newMap = new Map(this._catchers)\n const errorIds = Array.isArray(ids) ? ids : [ids]\n for (const errorId of errorIds) {\n newMap.set(errorId, catcher)\n }\n return { ...this, _catchers: newMap }\n },\n catcherFallback(catcher) {\n return this.catcher(CATCHER_FALLBACK, catcher)\n },\n customError(transformer) {\n return { ...this, _errorTransformer: transformer } as any\n },\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n resolve<R = unknown>(resolver, clear: boolean = false) {\n return { ...this, _resolvers: clear ? [resolver] : [...this._resolvers, resolver] }\n },\n defer(callback, clear: boolean = false) {\n return {\n ...this,\n _deferred: clear ? [callback] : [...this._deferred, callback]\n }\n },\n middlewares(middlewares, clear = false) {\n return {\n ...this,\n _middlewares: clear ? middlewares : [...this._middlewares, ...middlewares]\n }\n },\n fetch(method: string = this._options.method, url = \"\", body = null) {\n let base = this.url(url).options({ method })\n // \"Jsonify\" the body if it is an object and if it is likely that the content type targets json.\n const contentType = extractContentType(base._options.headers)\n const jsonify =\n typeof body === \"object\" &&\n !(body instanceof FormData) &&\n (!base._options.headers || !contentType || isLikelyJsonMime(contentType))\n base =\n !body ? base :\n jsonify ? base.json(body, contentType) :\n base.body(body)\n return resolver(\n base\n ._deferred\n .reduce((acc: Wretch, curr) => curr(acc, acc._url, acc._options), base)\n )\n },\n get(url = \"\") {\n return this.fetch(\"GET\", url)\n },\n delete(url = \"\") {\n return this.fetch(\"DELETE\", url)\n },\n put(body, url = \"\") {\n return this.fetch(\"PUT\", url, body)\n },\n post(body, url = \"\") {\n return this.fetch(\"POST\", url, body)\n },\n patch(body, url = \"\") {\n return this.fetch(\"PATCH\", url, body)\n },\n head(url = \"\") {\n return this.fetch(\"HEAD\", url)\n },\n opts(url = \"\") {\n return this.fetch(\"OPTIONS\", url)\n },\n body(contents) {\n return { ...this, _options: { ...this._options, body: contents } }\n },\n json(jsObject, contentType) {\n const currentContentType = extractContentType(this._options.headers)\n return this.content(\n contentType ||\n isLikelyJsonMime(currentContentType) && currentContentType ||\n JSON_MIME\n ).body(JSON.stringify(jsObject))\n },\n toFetch() {\n return (fetchUrl, fetchOptions: WretchOptions = {}) => {\n return this\n .url(fetchUrl)\n .options(fetchOptions)\n .catcherFallback(error => {\n if(error instanceof WretchError) { return error.response }\n else { throw error }\n })\n .fetch()\n .res()\n }\n }\n}\n","import { core } from \"./core.js\"\nimport { WretchError } from \"./resolver.js\"\nimport type { Wretch, WretchOptions } from \"./types.js\"\n\nexport type {\n Wretch,\n ConfiguredMiddleware,\n FetchLike,\n Middleware,\n WretchResponseChain,\n WretchOptions,\n WretchError,\n WretchErrorCallback,\n WretchResponse,\n WretchDeferredCallback,\n WretchAddon\n} from \"./types.js\"\n\n/**\n * Creates a new wretch instance with a base url and base\n * [fetch options](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch).\n *\n * ```ts\n * import wretch from \"wretch\"\n *\n * // Reusable instance\n * const w = wretch(\"https://domain.com\", { mode: \"cors\" })\n * ```\n *\n * @param _url The base url\n * @param _options The base fetch options\n * @returns A fresh wretch instance\n */\nconst factory = (_url = \"\", _options: WretchOptions = {}): Wretch =>\n ({ ...core, _url, _options })\n\nfactory[\"default\"] = factory\nfactory.WretchError = WretchError\n\nexport default factory\n"],"mappings":"AAAA,SAAgB,EAAmB,EAAuB,CAAC,EAAuB,CAChF,IAAM,EAAoB,aAAmB,MAAQ,OAAO,YAAY,CAAO,EAAI,EACnF,IAAK,IAAM,KAAK,EACd,GAAI,EAAE,YAAY,IAAM,eAAgB,OAAO,EAAkB,EAErE,CAEA,SAAgB,EAAiB,EAAwB,CACvD,MAAO,uBAAuB,KAAK,CAAK,CAC1C,CAEA,MAAa,GAAO,EAAa,EAAa,EAAc,KAAU,CACpE,IAAM,EAAM,CAAE,GAAG,CAAI,EACrB,IAAK,IAAM,KAAO,EAAK,CACrB,GAAI,CAAC,OAAO,UAAU,eAAe,KAAK,EAAK,CAAG,EAAG,SACrD,IAAM,EAAQ,EAAI,GACZ,EAAW,EAAI,GACrB,EAAI,GAAO,MAAM,QAAQ,CAAK,GAAK,MAAM,QAAQ,CAAQ,EACvD,EAAc,CAAC,GAAG,EAAO,GAAG,CAAQ,EAAI,EACxC,OAAO,GAAU,UAAY,OAAO,GAAa,SAC/C,EAAI,EAAO,EAAU,CAAW,EAChC,CACN,CACA,OAAO,CACT,ECvBa,EAAc,OAAO,EACrB,EAAmB,OAAO,ECG1B,EAAoB,GAAyC,GACxE,EAAY,aAAa,EAAK,IAAS,EAAK,CAAG,EAAG,CAAa,ECEjE,IAAa,EAAb,cAAiC,KAAiC,CAIlE,EAEA,MAAa,EAA2C,GAAsD,CAC5G,IAAM,EAAc,OAAO,OAAO,IAAI,EAEtC,EAAS,EAAO,QAAQ,QAAQ,EAAG,IACjC,EAAM,eACN,EAAM,cAAc,EAAG,EAAO,SAAU,CAAW,GAChD,EACL,CAAM,EAEN,GAAM,CACJ,KAAM,EACN,SAAU,EACV,SACA,kBAAmB,EACR,YACX,WAAY,EACZ,aAAc,EACd,QAAS,GACP,EAEE,EAAW,IAAI,IAAI,CAAS,EAC5B,EAAe,EAGjB,EAAW,EACT,EAAY,EAAiB,CAAW,GAAG,EAAK,KACpD,EAAW,GACO,GAAU,OACX,EAAK,CAAO,EAC9B,EAAE,EAAK,CAAY,EAEd,EAAqB,MAAM,EAC3B,EAAkD,EACrD,MAAM,GAAS,CAGd,KADA,GAAM,GAAe,GACf,CACR,CAAC,EACA,KAAK,KAAM,IAAY,CACtB,GAAI,CAAC,EAAS,GAAI,CAChB,IAAM,EAAM,IAAI,EAOhB,GANA,EAAI,MAAW,EACf,EAAI,OAAS;SAAc,EAAe,MAC1C,EAAI,SAAW,EACf,EAAI,OAAS,EAAS,OACtB,EAAI,IAAM,EAEN,EAAS,OAAS,UAAY,EAChC,EAAI,QAAU,EAAS,gBAEvB,GAAI,CACF,EAAI,QAAU,MAAM,EAAS,MAAM,EAAE,KAAK,CAC5C,MAAQ,CACN,EAAI,QAAU,EAAS,UACzB,CAGF,MAAM,CACR,CACA,OAAO,CACT,CAAC,EAGG,EAAsB,GAC1B,EAAQ,MAAM,KAAM,IAAS,CAC3B,IAAM,EACJ,EAAS,IAAI,GAAO,MAAM,GAC1B,EAAS,IAAI,GAAO,IAAI,GACvB,IAAQ,IAAgB,EAAS,IAAI,CAAW,GACjD,EAAS,IAAI,CAAgB,EAM/B,GAJI,EAAM,UAAY,IACpB,EAAQ,MAAM,EAAiB,EAAO,EAAM,SAAU,CAAM,GAG1D,EACF,OAAO,EAAQ,EAAO,CAAM,EAE9B,MAAM,CACR,CAAC,EAOG,EAAyB,GAAW,GAAM,CAC9C,IAAM,EAAU,EAEd,EAAgB,KAAK,GAAK,IAAI,GAAS,CAAC,EAExC,EACF,OAAO,EAAgB,EAAK,EAAQ,KAAK,CAAE,EAAI,CAAO,CACxD,EAIM,EAAoE,CACxE,WAAY,EACZ,YACA,aAAc,EACd,IAAK,EAA2B,IAAI,EACpC,KAAM,EAAgB,MAAM,EAC5B,KAAM,EAAiB,MAAM,EAC7B,SAAU,EAAqB,UAAU,EACzC,YAAa,EAAwB,aAAa,EAClD,KAAM,EAAmB,MAAM,EAC/B,MAAM,EAAS,EAAI,CAEjB,OADA,EAAS,IAAI,EAAS,CAAE,EACjB,IACT,EACA,WAAW,EAAI,CAAE,OAAO,KAAK,MAAM,IAAK,CAAE,CAAE,EAC5C,aAAa,EAAI,CAAE,OAAO,KAAK,MAAM,IAAK,CAAE,CAAE,EAC9C,UAAU,EAAI,CAAE,OAAO,KAAK,MAAM,IAAK,CAAE,CAAE,EAC3C,SAAS,EAAI,CAAE,OAAO,KAAK,MAAM,IAAK,CAAE,CAAE,EAC1C,QAAQ,EAAI,CAAE,OAAO,KAAK,MAAM,IAAK,CAAE,CAAE,EACzC,cAAc,EAAI,CAAE,OAAO,KAAK,MAAM,IAAK,CAAE,CAAE,EAC/C,WAAW,EAAI,CAAE,OAAO,KAAK,MAAM,EAAa,CAAE,CAAE,CACtD,EAIM,EAAsH,EAAO,QAAQ,EAAO,KAAW,CAC3J,GAAG,EACH,GAAI,OAAO,EAAM,UAAa,WAAc,EAAM,SAA4E,CAAK,EAAI,EAAM,QAC/I,GAAI,CAAa,EAEjB,OAAO,EAAU,QAAQ,EAAO,IAAM,EAAE,EAAO,CAAM,EAAG,CAAqB,CAC/E,ECzIa,EAAe,CAC1B,KAAM,GACN,SAAU,CAAC,EACX,UAAW,IAAI,IACf,WAAY,CAAC,EACb,UAAW,CAAC,EACZ,aAAc,CAAC,EACf,QAAS,CAAC,EACV,MAAM,EAAO,CACX,IAAM,EAAS,MAAM,QAAQ,CAAK,EAAI,EAAQ,CAAC,CAAK,EAC9C,EAAc,EAAO,QAAQ,EAAK,KAAO,CAAE,GAAG,EAAK,GAAG,EAAE,MAAO,GAAI,CAAC,CAAC,EAC3E,MAAO,CAAE,GAAG,KAAM,QAAS,CAAC,GAAG,KAAK,QAAS,GAAG,CAAM,EAAG,GAAG,CAAY,CAC1E,EACA,cAAc,EAAW,CACvB,MAAO,CAAE,GAAG,KAAM,OAAQ,CAAU,CACtC,EACA,IAAI,EAAM,EAAU,GAAO,CACzB,GAAI,EACF,MAAO,CAAE,GAAG,KAAM,MAAK,EACzB,IAAM,EAAM,KAAK,KAAK,QAAQ,GAAG,EACjC,MAAO,CACL,GAAG,KACH,KAAM,EAAM,GACV,KAAK,KAAK,MAAM,EAAG,CAAG,EAAI,EAAO,KAAK,KAAK,MAAM,CAAG,EACpD,KAAK,KAAO,CAChB,CACF,EACA,QAAQ,EAAS,EAAU,GAAO,CAChC,MAAO,CAAE,GAAG,KAAM,SAAU,EAAU,EAAU,EAAI,KAAK,SAAU,CAAO,CAAE,CAC9E,EACA,QAAQ,EAAc,CACpB,IAAM,EACH,EACC,MAAM,QAAQ,CAAY,EAAI,OAAO,YAAY,CAAY,EAC3D,YAAa,EAAe,OAAO,YAAa,EAAyB,QAAQ,CAAC,EAChF,EAHU,CAAC,EAInB,MAAO,CAAE,GAAG,KAAM,SAAU,EAAI,KAAK,SAAU,CAAE,SAAQ,CAAC,CAAE,CAC9D,EACA,OAAO,EAAa,CAClB,OAAO,KAAK,QAAQ,CAAE,OAAQ,CAAY,CAAC,CAC7C,EACA,QAAQ,EAAa,CACnB,OAAO,KAAK,QAAQ,CAAE,eAAgB,CAAY,CAAC,CACrD,EACA,KAAK,EAAa,CAChB,OAAO,KAAK,QAAQ,CAAE,cAAe,CAAY,CAAC,CACpD,EACA,QAAQ,EAAK,EAAS,CACpB,IAAM,EAAS,IAAI,IAAI,KAAK,SAAS,EAC/B,EAAW,MAAM,QAAQ,CAAG,EAAI,EAAM,CAAC,CAAG,EAChD,IAAK,IAAM,KAAW,EACpB,EAAO,IAAI,EAAS,CAAO,EAE7B,MAAO,CAAE,GAAG,KAAM,UAAW,CAAO,CACtC,EACA,gBAAgB,EAAS,CACvB,OAAO,KAAK,QAAQ,EAAkB,CAAO,CAC/C,EACA,YAAY,EAAa,CACvB,MAAO,CAAE,GAAG,KAAM,kBAAmB,CAAY,CACnD,EAEA,QAAqB,EAAU,EAAiB,GAAO,CACrD,MAAO,CAAE,GAAG,KAAM,WAAY,EAAQ,CAAC,CAAQ,EAAI,CAAC,GAAG,KAAK,WAAY,CAAQ,CAAE,CACpF,EACA,MAAM,EAAU,EAAiB,GAAO,CACtC,MAAO,CACL,GAAG,KACH,UAAW,EAAQ,CAAC,CAAQ,EAAI,CAAC,GAAG,KAAK,UAAW,CAAQ,CAC9D,CACF,EACA,YAAY,EAAa,EAAQ,GAAO,CACtC,MAAO,CACL,GAAG,KACH,aAAc,EAAQ,EAAc,CAAC,GAAG,KAAK,aAAc,GAAG,CAAW,CAC3E,CACF,EACA,MAAM,EAAiB,KAAK,SAAS,OAAQ,EAAM,GAAI,EAAO,KAAM,CAClE,IAAI,EAAO,KAAK,IAAI,CAAG,EAAE,QAAQ,CAAE,QAAO,CAAC,EAErC,EAAc,EAAmB,EAAK,SAAS,OAAO,EACtD,EACJ,OAAO,GAAS,UAChB,EAAE,aAAgB,YACjB,CAAC,EAAK,SAAS,SAAW,CAAC,GAAe,EAAiB,CAAW,GAKzE,MAJA,GACG,EACC,EAAU,EAAK,KAAK,EAAM,CAAW,EACnC,EAAK,KAAK,CAAI,EAFV,EAGH,EACL,EACG,UACA,QAAQ,EAAa,IAAS,EAAK,EAAK,EAAI,KAAM,EAAI,QAAQ,EAAG,CAAI,CAC1E,CACF,EACA,IAAI,EAAM,GAAI,CACZ,OAAO,KAAK,MAAM,MAAO,CAAG,CAC9B,EACA,OAAO,EAAM,GAAI,CACf,OAAO,KAAK,MAAM,SAAU,CAAG,CACjC,EACA,IAAI,EAAM,EAAM,GAAI,CAClB,OAAO,KAAK,MAAM,MAAO,EAAK,CAAI,CACpC,EACA,KAAK,EAAM,EAAM,GAAI,CACnB,OAAO,KAAK,MAAM,OAAQ,EAAK,CAAI,CACrC,EACA,MAAM,EAAM,EAAM,GAAI,CACpB,OAAO,KAAK,MAAM,QAAS,EAAK,CAAI,CACtC,EACA,KAAK,EAAM,GAAI,CACb,OAAO,KAAK,MAAM,OAAQ,CAAG,CAC/B,EACA,KAAK,EAAM,GAAI,CACb,OAAO,KAAK,MAAM,UAAW,CAAG,CAClC,EACA,KAAK,EAAU,CACb,MAAO,CAAE,GAAG,KAAM,SAAU,CAAE,GAAG,KAAK,SAAU,KAAM,CAAS,CAAE,CACnE,EACA,KAAK,EAAU,EAAa,CAC1B,IAAM,EAAqB,EAAmB,KAAK,SAAS,OAAO,EACnE,OAAO,KAAK,QACV,GACA,EAAiB,CAAkB,GAAK,GAAA,kBAE1C,EAAE,KAAK,KAAK,UAAU,CAAQ,CAAC,CACjC,EACA,SAAU,CACR,OAAQ,EAAU,EAA8B,CAAC,IACxC,KACJ,IAAI,CAAQ,EACZ,QAAQ,CAAY,EACpB,gBAAgB,GAAS,CACxB,GAAG,aAAiB,EAAe,OAAO,EAAM,SACzC,MAAM,CACf,CAAC,EACA,MAAM,EACN,IAAI,CAEX,CACF,EChHM,GAAW,EAAO,GAAI,EAA0B,CAAC,KACpD,CAAE,GAAG,EAAM,OAAM,UAAS,GAE7B,EAAQ,QAAa,EACrB,EAAQ,YAAc"}