@hadoku/watchparty-ui 0.45.17 → 0.45.19

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 +0,0 @@
1
- {"version":3,"file":"index-Ip1nTIQR.js","sources":["../../../../node_modules/.pnpm/react-router@7.12.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/react-router/dist/development/chunk-EPOLDU6W.mjs","../../../../node_modules/.pnpm/react-router@7.12.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/react-router/dist/development/dom-export.mjs","../../../../node_modules/.pnpm/zustand@5.0.10_@types+react@19.2.8_react@19.2.3/node_modules/zustand/esm/vanilla.mjs","../../../../node_modules/.pnpm/zustand@5.0.10_@types+react@19.2.8_react@19.2.3/node_modules/zustand/esm/react.mjs","../../../../packages/shared/dist/chatImages.js","../../../../packages/shared/dist/defaults.js","../../../../packages/shared/dist/tierlist.js","../../../../packages/shared/dist/protocol.js","../../../../packages/shared/dist/characters.js","../../../../packages/shared/dist/playback.js","../../../../packages/shared/dist/auth.js","../../../../packages/shared/dist/fragmentDeliveryFlag.js","../../../../packages/shared/dist/submissions.js","../../../../packages/shared/dist/gameCatalog.js","../../../../packages/shared/dist/mediaSearch.js","../../../../node_modules/.pnpm/@wolffm+cdn-client@2.0.3_react@19.2.3/node_modules/@wolffm/cdn-client/dist/chunk-KAVZB4QP.js","../../src/lib/chatMedia/config.ts","../../src/lib/config.ts","../../src/lib/storageKeys.ts","../../src/lib/browserStorage.ts","../../src/lib/debugGlobals.ts","../../src/lib/debug.ts","../../src/lib/characters.ts","../../src/lib/auth.ts","../../src/prefs/watchpartyPrefs.ts","../../src/lib/preferences.ts","../../src/roomChrome/chatLayout.ts","../../src/lib/store.ts","../../src/components/Toasts.tsx","../../src/components/StarfieldCanvas.tsx","../../src/lib/pictureColor.ts","../../src/components/AvatarImage.tsx","../../src/lib/hadokuApp.ts","../../src/routes/Home.tsx","../../src/components/APIDownFallback.tsx","../../src/lib/fragmentDelivery.ts","../../src/lib/gameCatalog.ts","../../src/lib/lazyWithRetry.ts","../../src/lib/authGate.ts","../../src/App.tsx","../../src/router.tsx","../../src/lib/deviceId.ts","../../../../node_modules/.pnpm/engine.io-parser@5.2.3/node_modules/engine.io-parser/build/esm/commons.js","../../../../node_modules/.pnpm/engine.io-parser@5.2.3/node_modules/engine.io-parser/build/esm/encodePacket.browser.js","../../../../node_modules/.pnpm/engine.io-parser@5.2.3/node_modules/engine.io-parser/build/esm/contrib/base64-arraybuffer.js","../../../../node_modules/.pnpm/engine.io-parser@5.2.3/node_modules/engine.io-parser/build/esm/decodePacket.browser.js","../../../../node_modules/.pnpm/engine.io-parser@5.2.3/node_modules/engine.io-parser/build/esm/index.js","../../../../node_modules/.pnpm/@socket.io+component-emitter@3.1.2/node_modules/@socket.io/component-emitter/lib/esm/index.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/globals.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/util.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/contrib/parseqs.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/transport.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/transports/polling.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/contrib/has-cors.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/transports/polling-xhr.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/transports/websocket.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/transports/webtransport.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/transports/index.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/contrib/parseuri.js","../../../../node_modules/.pnpm/engine.io-client@6.6.3/node_modules/engine.io-client/build/esm/socket.js","../../../../node_modules/.pnpm/socket.io-client@4.8.3/node_modules/socket.io-client/build/esm/url.js","../../../../node_modules/.pnpm/socket.io-parser@4.2.4/node_modules/socket.io-parser/build/esm/is-binary.js","../../../../node_modules/.pnpm/socket.io-parser@4.2.4/node_modules/socket.io-parser/build/esm/binary.js","../../../../node_modules/.pnpm/socket.io-parser@4.2.4/node_modules/socket.io-parser/build/esm/index.js","../../../../node_modules/.pnpm/socket.io-client@4.8.3/node_modules/socket.io-client/build/esm/on.js","../../../../node_modules/.pnpm/socket.io-client@4.8.3/node_modules/socket.io-client/build/esm/socket.js","../../../../node_modules/.pnpm/socket.io-client@4.8.3/node_modules/socket.io-client/build/esm/contrib/backo2.js","../../../../node_modules/.pnpm/socket.io-client@4.8.3/node_modules/socket.io-client/build/esm/manager.js","../../../../node_modules/.pnpm/socket.io-client@4.8.3/node_modules/socket.io-client/build/esm/index.js","../../src/lib/mediaUrls.ts","../../src/lib/tierlistApi.ts","../../src/lib/spriteRetry.ts","../../../../node_modules/.pnpm/@wolffm+prefs-client@1.1.11_react@19.2.3_zod@4.3.5/node_modules/@wolffm/prefs-client/dist/avatar.js","../../src/lib/avatar.ts","../../src/lib/embedContext.ts","../../../../packages/rooms-protocol/dist/resync.js","../../src/lib/playlistVotes.ts","../../src/lib/connectionLiveness.ts","../../src/lib/socket.ts","../../src/entry.tsx"],"sourcesContent":["/**\n * react-router v7.12.0\n *\n * Copyright (c) Remix Software Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.md file in the root directory of this source tree.\n *\n * @license MIT\n */\nvar __typeError = (msg) => {\n throw TypeError(msg);\n};\nvar __accessCheck = (obj, member, msg) => member.has(obj) || __typeError(\"Cannot \" + msg);\nvar __privateGet = (obj, member, getter) => (__accessCheck(obj, member, \"read from private field\"), getter ? getter.call(obj) : member.get(obj));\nvar __privateAdd = (obj, member, value) => member.has(obj) ? __typeError(\"Cannot add the same private member more than once\") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\n\n// lib/router/history.ts\nvar Action = /* @__PURE__ */ ((Action2) => {\n Action2[\"Pop\"] = \"POP\";\n Action2[\"Push\"] = \"PUSH\";\n Action2[\"Replace\"] = \"REPLACE\";\n return Action2;\n})(Action || {});\nvar PopStateEventType = \"popstate\";\nfunction createMemoryHistory(options = {}) {\n let { initialEntries = [\"/\"], initialIndex, v5Compat = false } = options;\n let entries;\n entries = initialEntries.map(\n (entry, index2) => createMemoryLocation(\n entry,\n typeof entry === \"string\" ? null : entry.state,\n index2 === 0 ? \"default\" : void 0\n )\n );\n let index = clampIndex(\n initialIndex == null ? entries.length - 1 : initialIndex\n );\n let action = \"POP\" /* Pop */;\n let listener = null;\n function clampIndex(n) {\n return Math.min(Math.max(n, 0), entries.length - 1);\n }\n function getCurrentLocation() {\n return entries[index];\n }\n function createMemoryLocation(to, state = null, key) {\n let location = createLocation(\n entries ? getCurrentLocation().pathname : \"/\",\n to,\n state,\n key\n );\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in memory history: ${JSON.stringify(\n to\n )}`\n );\n return location;\n }\n function createHref2(to) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n let history = {\n get index() {\n return index;\n },\n get action() {\n return action;\n },\n get location() {\n return getCurrentLocation();\n },\n createHref: createHref2,\n createURL(to) {\n return new URL(createHref2(to), \"http://localhost\");\n },\n encodeLocation(to) {\n let path = typeof to === \"string\" ? parsePath(to) : to;\n return {\n pathname: path.pathname || \"\",\n search: path.search || \"\",\n hash: path.hash || \"\"\n };\n },\n push(to, state) {\n action = \"PUSH\" /* Push */;\n let nextLocation = createMemoryLocation(to, state);\n index += 1;\n entries.splice(index, entries.length, nextLocation);\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 1 });\n }\n },\n replace(to, state) {\n action = \"REPLACE\" /* Replace */;\n let nextLocation = createMemoryLocation(to, state);\n entries[index] = nextLocation;\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 0 });\n }\n },\n go(delta) {\n action = \"POP\" /* Pop */;\n let nextIndex = clampIndex(index + delta);\n let nextLocation = entries[nextIndex];\n index = nextIndex;\n if (listener) {\n listener({ action, location: nextLocation, delta });\n }\n },\n listen(fn) {\n listener = fn;\n return () => {\n listener = null;\n };\n }\n };\n return history;\n}\nfunction createBrowserHistory(options = {}) {\n function createBrowserLocation(window2, globalHistory) {\n let { pathname, search, hash } = window2.location;\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n globalHistory.state && globalHistory.state.usr || null,\n globalHistory.state && globalHistory.state.key || \"default\"\n );\n }\n function createBrowserHref(window2, to) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n return getUrlBasedHistory(\n createBrowserLocation,\n createBrowserHref,\n null,\n options\n );\n}\nfunction createHashHistory(options = {}) {\n function createHashLocation(window2, globalHistory) {\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\"\n } = parsePath(window2.location.hash.substring(1));\n if (!pathname.startsWith(\"/\") && !pathname.startsWith(\".\")) {\n pathname = \"/\" + pathname;\n }\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n globalHistory.state && globalHistory.state.usr || null,\n globalHistory.state && globalHistory.state.key || \"default\"\n );\n }\n function createHashHref(window2, to) {\n let base = window2.document.querySelector(\"base\");\n let href = \"\";\n if (base && base.getAttribute(\"href\")) {\n let url = window2.location.href;\n let hashIndex = url.indexOf(\"#\");\n href = hashIndex === -1 ? url : url.slice(0, hashIndex);\n }\n return href + \"#\" + (typeof to === \"string\" ? to : createPath(to));\n }\n function validateHashLocation(location, to) {\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in hash history.push(${JSON.stringify(\n to\n )})`\n );\n }\n return getUrlBasedHistory(\n createHashLocation,\n createHashHref,\n validateHashLocation,\n options\n );\n}\nfunction invariant(value, message) {\n if (value === false || value === null || typeof value === \"undefined\") {\n throw new Error(message);\n }\n}\nfunction warning(cond, message) {\n if (!cond) {\n if (typeof console !== \"undefined\") console.warn(message);\n try {\n throw new Error(message);\n } catch (e) {\n }\n }\n}\nfunction createKey() {\n return Math.random().toString(36).substring(2, 10);\n}\nfunction getHistoryState(location, index) {\n return {\n usr: location.state,\n key: location.key,\n idx: index\n };\n}\nfunction createLocation(current, to, state = null, key) {\n let location = {\n pathname: typeof current === \"string\" ? current : current.pathname,\n search: \"\",\n hash: \"\",\n ...typeof to === \"string\" ? parsePath(to) : to,\n state,\n // TODO: This could be cleaned up. push/replace should probably just take\n // full Locations now and avoid the need to run through this flow at all\n // But that's a pretty big refactor to the current test suite so going to\n // keep as is for the time being and just let any incoming keys take precedence\n key: to && to.key || key || createKey()\n };\n return location;\n}\nfunction createPath({\n pathname = \"/\",\n search = \"\",\n hash = \"\"\n}) {\n if (search && search !== \"?\")\n pathname += search.charAt(0) === \"?\" ? search : \"?\" + search;\n if (hash && hash !== \"#\")\n pathname += hash.charAt(0) === \"#\" ? hash : \"#\" + hash;\n return pathname;\n}\nfunction parsePath(path) {\n let parsedPath = {};\n if (path) {\n let hashIndex = path.indexOf(\"#\");\n if (hashIndex >= 0) {\n parsedPath.hash = path.substring(hashIndex);\n path = path.substring(0, hashIndex);\n }\n let searchIndex = path.indexOf(\"?\");\n if (searchIndex >= 0) {\n parsedPath.search = path.substring(searchIndex);\n path = path.substring(0, searchIndex);\n }\n if (path) {\n parsedPath.pathname = path;\n }\n }\n return parsedPath;\n}\nfunction getUrlBasedHistory(getLocation, createHref2, validateLocation, options = {}) {\n let { window: window2 = document.defaultView, v5Compat = false } = options;\n let globalHistory = window2.history;\n let action = \"POP\" /* Pop */;\n let listener = null;\n let index = getIndex();\n if (index == null) {\n index = 0;\n globalHistory.replaceState({ ...globalHistory.state, idx: index }, \"\");\n }\n function getIndex() {\n let state = globalHistory.state || { idx: null };\n return state.idx;\n }\n function handlePop() {\n action = \"POP\" /* Pop */;\n let nextIndex = getIndex();\n let delta = nextIndex == null ? null : nextIndex - index;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n }\n function push(to, state) {\n action = \"PUSH\" /* Push */;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n index = getIndex() + 1;\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n try {\n globalHistory.pushState(historyState, \"\", url);\n } catch (error) {\n if (error instanceof DOMException && error.name === \"DataCloneError\") {\n throw error;\n }\n window2.location.assign(url);\n }\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 1 });\n }\n }\n function replace2(to, state) {\n action = \"REPLACE\" /* Replace */;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n index = getIndex();\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n globalHistory.replaceState(historyState, \"\", url);\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 0 });\n }\n }\n function createURL(to) {\n return createBrowserURLImpl(to);\n }\n let history = {\n get action() {\n return action;\n },\n get location() {\n return getLocation(window2, globalHistory);\n },\n listen(fn) {\n if (listener) {\n throw new Error(\"A history only accepts one active listener\");\n }\n window2.addEventListener(PopStateEventType, handlePop);\n listener = fn;\n return () => {\n window2.removeEventListener(PopStateEventType, handlePop);\n listener = null;\n };\n },\n createHref(to) {\n return createHref2(window2, to);\n },\n createURL,\n encodeLocation(to) {\n let url = createURL(to);\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash\n };\n },\n push,\n replace: replace2,\n go(n) {\n return globalHistory.go(n);\n }\n };\n return history;\n}\nfunction createBrowserURLImpl(to, isAbsolute = false) {\n let base = \"http://localhost\";\n if (typeof window !== \"undefined\") {\n base = window.location.origin !== \"null\" ? window.location.origin : window.location.href;\n }\n invariant(base, \"No window.location.(origin|href) available to create URL\");\n let href = typeof to === \"string\" ? to : createPath(to);\n href = href.replace(/ $/, \"%20\");\n if (!isAbsolute && href.startsWith(\"//\")) {\n href = base + href;\n }\n return new URL(href, base);\n}\n\n// lib/router/utils.ts\nfunction createContext(defaultValue) {\n return { defaultValue };\n}\nvar _map;\nvar RouterContextProvider = class {\n /**\n * Create a new `RouterContextProvider` instance\n * @param init An optional initial context map to populate the provider with\n */\n constructor(init) {\n __privateAdd(this, _map, /* @__PURE__ */ new Map());\n if (init) {\n for (let [context, value] of init) {\n this.set(context, value);\n }\n }\n }\n /**\n * Access a value from the context. If no value has been set for the context,\n * it will return the context's `defaultValue` if provided, or throw an error\n * if no `defaultValue` was set.\n * @param context The context to get the value for\n * @returns The value for the context, or the context's `defaultValue` if no\n * value was set\n */\n get(context) {\n if (__privateGet(this, _map).has(context)) {\n return __privateGet(this, _map).get(context);\n }\n if (context.defaultValue !== void 0) {\n return context.defaultValue;\n }\n throw new Error(\"No value found for context\");\n }\n /**\n * Set a value for the context. If the context already has a value set, this\n * will overwrite it.\n *\n * @param context The context to set the value for\n * @param value The value to set for the context\n * @returns {void}\n */\n set(context, value) {\n __privateGet(this, _map).set(context, value);\n }\n};\n_map = new WeakMap();\nvar unsupportedLazyRouteObjectKeys = /* @__PURE__ */ new Set([\n \"lazy\",\n \"caseSensitive\",\n \"path\",\n \"id\",\n \"index\",\n \"children\"\n]);\nfunction isUnsupportedLazyRouteObjectKey(key) {\n return unsupportedLazyRouteObjectKeys.has(\n key\n );\n}\nvar unsupportedLazyRouteFunctionKeys = /* @__PURE__ */ new Set([\n \"lazy\",\n \"caseSensitive\",\n \"path\",\n \"id\",\n \"index\",\n \"middleware\",\n \"children\"\n]);\nfunction isUnsupportedLazyRouteFunctionKey(key) {\n return unsupportedLazyRouteFunctionKeys.has(\n key\n );\n}\nfunction isIndexRoute(route) {\n return route.index === true;\n}\nfunction convertRoutesToDataRoutes(routes, mapRouteProperties2, parentPath = [], manifest = {}, allowInPlaceMutations = false) {\n return routes.map((route, index) => {\n let treePath = [...parentPath, String(index)];\n let id = typeof route.id === \"string\" ? route.id : treePath.join(\"-\");\n invariant(\n route.index !== true || !route.children,\n `Cannot specify children on an index route`\n );\n invariant(\n allowInPlaceMutations || !manifest[id],\n `Found a route id collision on id \"${id}\". Route id's must be globally unique within Data Router usages`\n );\n if (isIndexRoute(route)) {\n let indexRoute = {\n ...route,\n id\n };\n manifest[id] = mergeRouteUpdates(\n indexRoute,\n mapRouteProperties2(indexRoute)\n );\n return indexRoute;\n } else {\n let pathOrLayoutRoute = {\n ...route,\n id,\n children: void 0\n };\n manifest[id] = mergeRouteUpdates(\n pathOrLayoutRoute,\n mapRouteProperties2(pathOrLayoutRoute)\n );\n if (route.children) {\n pathOrLayoutRoute.children = convertRoutesToDataRoutes(\n route.children,\n mapRouteProperties2,\n treePath,\n manifest,\n allowInPlaceMutations\n );\n }\n return pathOrLayoutRoute;\n }\n });\n}\nfunction mergeRouteUpdates(route, updates) {\n return Object.assign(route, {\n ...updates,\n ...typeof updates.lazy === \"object\" && updates.lazy != null ? {\n lazy: {\n ...route.lazy,\n ...updates.lazy\n }\n } : {}\n });\n}\nfunction matchRoutes(routes, locationArg, basename = \"/\") {\n return matchRoutesImpl(routes, locationArg, basename, false);\n}\nfunction matchRoutesImpl(routes, locationArg, basename, allowPartial) {\n let location = typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n let pathname = stripBasename(location.pathname || \"/\", basename);\n if (pathname == null) {\n return null;\n }\n let branches = flattenRoutes(routes);\n rankRouteBranches(branches);\n let matches = null;\n for (let i = 0; matches == null && i < branches.length; ++i) {\n let decoded = decodePath(pathname);\n matches = matchRouteBranch(\n branches[i],\n decoded,\n allowPartial\n );\n }\n return matches;\n}\nfunction convertRouteMatchToUiMatch(match, loaderData) {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id],\n loaderData: loaderData[route.id],\n handle: route.handle\n };\n}\nfunction flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = \"\", _hasParentOptionalSegments = false) {\n let flattenRoute = (route, index, hasParentOptionalSegments = _hasParentOptionalSegments, relativePath) => {\n let meta = {\n relativePath: relativePath === void 0 ? route.path || \"\" : relativePath,\n caseSensitive: route.caseSensitive === true,\n childrenIndex: index,\n route\n };\n if (meta.relativePath.startsWith(\"/\")) {\n if (!meta.relativePath.startsWith(parentPath) && hasParentOptionalSegments) {\n return;\n }\n invariant(\n meta.relativePath.startsWith(parentPath),\n `Absolute route path \"${meta.relativePath}\" nested under path \"${parentPath}\" is not valid. An absolute child route path must start with the combined path of all its parent routes.`\n );\n meta.relativePath = meta.relativePath.slice(parentPath.length);\n }\n let path = joinPaths([parentPath, meta.relativePath]);\n let routesMeta = parentsMeta.concat(meta);\n if (route.children && route.children.length > 0) {\n invariant(\n // Our types know better, but runtime JS may not!\n // @ts-expect-error\n route.index !== true,\n `Index routes must not have child routes. Please remove all child routes from route path \"${path}\".`\n );\n flattenRoutes(\n route.children,\n branches,\n routesMeta,\n path,\n hasParentOptionalSegments\n );\n }\n if (route.path == null && !route.index) {\n return;\n }\n branches.push({\n path,\n score: computeScore(path, route.index),\n routesMeta\n });\n };\n routes.forEach((route, index) => {\n if (route.path === \"\" || !route.path?.includes(\"?\")) {\n flattenRoute(route, index);\n } else {\n for (let exploded of explodeOptionalSegments(route.path)) {\n flattenRoute(route, index, true, exploded);\n }\n }\n });\n return branches;\n}\nfunction explodeOptionalSegments(path) {\n let segments = path.split(\"/\");\n if (segments.length === 0) return [];\n let [first, ...rest] = segments;\n let isOptional = first.endsWith(\"?\");\n let required = first.replace(/\\?$/, \"\");\n if (rest.length === 0) {\n return isOptional ? [required, \"\"] : [required];\n }\n let restExploded = explodeOptionalSegments(rest.join(\"/\"));\n let result = [];\n result.push(\n ...restExploded.map(\n (subpath) => subpath === \"\" ? required : [required, subpath].join(\"/\")\n )\n );\n if (isOptional) {\n result.push(...restExploded);\n }\n return result.map(\n (exploded) => path.startsWith(\"/\") && exploded === \"\" ? \"/\" : exploded\n );\n}\nfunction rankRouteBranches(branches) {\n branches.sort(\n (a, b) => a.score !== b.score ? b.score - a.score : compareIndexes(\n a.routesMeta.map((meta) => meta.childrenIndex),\n b.routesMeta.map((meta) => meta.childrenIndex)\n )\n );\n}\nvar paramRe = /^:[\\w-]+$/;\nvar dynamicSegmentValue = 3;\nvar indexRouteValue = 2;\nvar emptySegmentValue = 1;\nvar staticSegmentValue = 10;\nvar splatPenalty = -2;\nvar isSplat = (s) => s === \"*\";\nfunction computeScore(path, index) {\n let segments = path.split(\"/\");\n let initialScore = segments.length;\n if (segments.some(isSplat)) {\n initialScore += splatPenalty;\n }\n if (index) {\n initialScore += indexRouteValue;\n }\n return segments.filter((s) => !isSplat(s)).reduce(\n (score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === \"\" ? emptySegmentValue : staticSegmentValue),\n initialScore\n );\n}\nfunction compareIndexes(a, b) {\n let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);\n return siblings ? (\n // If two routes are siblings, we should try to match the earlier sibling\n // first. This allows people to have fine-grained control over the matching\n // behavior by simply putting routes with identical paths in the order they\n // want them tried.\n a[a.length - 1] - b[b.length - 1]\n ) : (\n // Otherwise, it doesn't really make sense to rank non-siblings by index,\n // so they sort equally.\n 0\n );\n}\nfunction matchRouteBranch(branch, pathname, allowPartial = false) {\n let { routesMeta } = branch;\n let matchedParams = {};\n let matchedPathname = \"/\";\n let matches = [];\n for (let i = 0; i < routesMeta.length; ++i) {\n let meta = routesMeta[i];\n let end = i === routesMeta.length - 1;\n let remainingPathname = matchedPathname === \"/\" ? pathname : pathname.slice(matchedPathname.length) || \"/\";\n let match = matchPath(\n { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },\n remainingPathname\n );\n let route = meta.route;\n if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) {\n match = matchPath(\n {\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end: false\n },\n remainingPathname\n );\n }\n if (!match) {\n return null;\n }\n Object.assign(matchedParams, match.params);\n matches.push({\n // TODO: Can this as be avoided?\n params: matchedParams,\n pathname: joinPaths([matchedPathname, match.pathname]),\n pathnameBase: normalizePathname(\n joinPaths([matchedPathname, match.pathnameBase])\n ),\n route\n });\n if (match.pathnameBase !== \"/\") {\n matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);\n }\n }\n return matches;\n}\nfunction generatePath(originalPath, params = {}) {\n let path = originalPath;\n if (path.endsWith(\"*\") && path !== \"*\" && !path.endsWith(\"/*\")) {\n warning(\n false,\n `Route path \"${path}\" will be treated as if it were \"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must always follow a \\`/\\` in the pattern. To get rid of this warning, please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n path = path.replace(/\\*$/, \"/*\");\n }\n const prefix = path.startsWith(\"/\") ? \"/\" : \"\";\n const stringify2 = (p) => p == null ? \"\" : typeof p === \"string\" ? p : String(p);\n const segments = path.split(/\\/+/).map((segment, index, array) => {\n const isLastSegment = index === array.length - 1;\n if (isLastSegment && segment === \"*\") {\n const star = \"*\";\n return stringify2(params[star]);\n }\n const keyMatch = segment.match(/^:([\\w-]+)(\\??)(.*)/);\n if (keyMatch) {\n const [, key, optional, suffix] = keyMatch;\n let param = params[key];\n invariant(optional === \"?\" || param != null, `Missing \":${key}\" param`);\n return encodeURIComponent(stringify2(param)) + suffix;\n }\n return segment.replace(/\\?$/g, \"\");\n }).filter((segment) => !!segment);\n return prefix + segments.join(\"/\");\n}\nfunction matchPath(pattern, pathname) {\n if (typeof pattern === \"string\") {\n pattern = { path: pattern, caseSensitive: false, end: true };\n }\n let [matcher, compiledParams] = compilePath(\n pattern.path,\n pattern.caseSensitive,\n pattern.end\n );\n let match = pathname.match(matcher);\n if (!match) return null;\n let matchedPathname = match[0];\n let pathnameBase = matchedPathname.replace(/(.)\\/+$/, \"$1\");\n let captureGroups = match.slice(1);\n let params = compiledParams.reduce(\n (memo2, { paramName, isOptional }, index) => {\n if (paramName === \"*\") {\n let splatValue = captureGroups[index] || \"\";\n pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\\/+$/, \"$1\");\n }\n const value = captureGroups[index];\n if (isOptional && !value) {\n memo2[paramName] = void 0;\n } else {\n memo2[paramName] = (value || \"\").replace(/%2F/g, \"/\");\n }\n return memo2;\n },\n {}\n );\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern\n };\n}\nfunction compilePath(path, caseSensitive = false, end = true) {\n warning(\n path === \"*\" || !path.endsWith(\"*\") || path.endsWith(\"/*\"),\n `Route path \"${path}\" will be treated as if it were \"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must always follow a \\`/\\` in the pattern. To get rid of this warning, please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n let params = [];\n let regexpSource = \"^\" + path.replace(/\\/*\\*?$/, \"\").replace(/^\\/*/, \"/\").replace(/[\\\\.*+^${}|()[\\]]/g, \"\\\\$&\").replace(\n /\\/:([\\w-]+)(\\?)?/g,\n (_, paramName, isOptional) => {\n params.push({ paramName, isOptional: isOptional != null });\n return isOptional ? \"/?([^\\\\/]+)?\" : \"/([^\\\\/]+)\";\n }\n ).replace(/\\/([\\w-]+)\\?(\\/|$)/g, \"(/$1)?$2\");\n if (path.endsWith(\"*\")) {\n params.push({ paramName: \"*\" });\n regexpSource += path === \"*\" || path === \"/*\" ? \"(.*)$\" : \"(?:\\\\/(.+)|\\\\/*)$\";\n } else if (end) {\n regexpSource += \"\\\\/*$\";\n } else if (path !== \"\" && path !== \"/\") {\n regexpSource += \"(?:(?=\\\\/|$))\";\n } else {\n }\n let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : \"i\");\n return [matcher, params];\n}\nfunction decodePath(value) {\n try {\n return value.split(\"/\").map((v) => decodeURIComponent(v).replace(/\\//g, \"%2F\")).join(\"/\");\n } catch (error) {\n warning(\n false,\n `The URL path \"${value}\" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${error}).`\n );\n return value;\n }\n}\nfunction stripBasename(pathname, basename) {\n if (basename === \"/\") return pathname;\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return null;\n }\n let startIndex = basename.endsWith(\"/\") ? basename.length - 1 : basename.length;\n let nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== \"/\") {\n return null;\n }\n return pathname.slice(startIndex) || \"/\";\n}\nfunction prependBasename({\n basename,\n pathname\n}) {\n return pathname === \"/\" ? basename : joinPaths([basename, pathname]);\n}\nvar ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\nvar isAbsoluteUrl = (url) => ABSOLUTE_URL_REGEX.test(url);\nfunction resolvePath(to, fromPathname = \"/\") {\n let {\n pathname: toPathname,\n search = \"\",\n hash = \"\"\n } = typeof to === \"string\" ? parsePath(to) : to;\n let pathname;\n if (toPathname) {\n if (isAbsoluteUrl(toPathname)) {\n pathname = toPathname;\n } else {\n if (toPathname.includes(\"//\")) {\n let oldPathname = toPathname;\n toPathname = toPathname.replace(/\\/\\/+/g, \"/\");\n warning(\n false,\n `Pathnames cannot have embedded double slashes - normalizing ${oldPathname} -> ${toPathname}`\n );\n }\n if (toPathname.startsWith(\"/\")) {\n pathname = resolvePathname(toPathname.substring(1), \"/\");\n } else {\n pathname = resolvePathname(toPathname, fromPathname);\n }\n }\n } else {\n pathname = fromPathname;\n }\n return {\n pathname,\n search: normalizeSearch(search),\n hash: normalizeHash(hash)\n };\n}\nfunction resolvePathname(relativePath, fromPathname) {\n let segments = fromPathname.replace(/\\/+$/, \"\").split(\"/\");\n let relativeSegments = relativePath.split(\"/\");\n relativeSegments.forEach((segment) => {\n if (segment === \"..\") {\n if (segments.length > 1) segments.pop();\n } else if (segment !== \".\") {\n segments.push(segment);\n }\n });\n return segments.length > 1 ? segments.join(\"/\") : \"/\";\n}\nfunction getInvalidPathError(char, field, dest, path) {\n return `Cannot include a '${char}' character in a manually specified \\`to.${field}\\` field [${JSON.stringify(\n path\n )}]. Please separate it out to the \\`to.${dest}\\` field. Alternatively you may provide the full path as a string in <Link to=\"...\"> and the router will parse it for you.`;\n}\nfunction getPathContributingMatches(matches) {\n return matches.filter(\n (match, index) => index === 0 || match.route.path && match.route.path.length > 0\n );\n}\nfunction getResolveToMatches(matches) {\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches.map(\n (match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase\n );\n}\nfunction resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) {\n let to;\n if (typeof toArg === \"string\") {\n to = parsePath(toArg);\n } else {\n to = { ...toArg };\n invariant(\n !to.pathname || !to.pathname.includes(\"?\"),\n getInvalidPathError(\"?\", \"pathname\", \"search\", to)\n );\n invariant(\n !to.pathname || !to.pathname.includes(\"#\"),\n getInvalidPathError(\"#\", \"pathname\", \"hash\", to)\n );\n invariant(\n !to.search || !to.search.includes(\"#\"),\n getInvalidPathError(\"#\", \"search\", \"hash\", to)\n );\n }\n let isEmptyPath = toArg === \"\" || to.pathname === \"\";\n let toPathname = isEmptyPath ? \"/\" : to.pathname;\n let from;\n if (toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n if (!isPathRelative && toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n to.pathname = toSegments.join(\"/\");\n }\n from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : \"/\";\n }\n let path = resolvePath(to, from);\n let hasExplicitTrailingSlash = toPathname && toPathname !== \"/\" && toPathname.endsWith(\"/\");\n let hasCurrentTrailingSlash = (isEmptyPath || toPathname === \".\") && locationPathname.endsWith(\"/\");\n if (!path.pathname.endsWith(\"/\") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {\n path.pathname += \"/\";\n }\n return path;\n}\nvar joinPaths = (paths) => paths.join(\"/\").replace(/\\/\\/+/g, \"/\");\nvar normalizePathname = (pathname) => pathname.replace(/\\/+$/, \"\").replace(/^\\/*/, \"/\");\nvar normalizeSearch = (search) => !search || search === \"?\" ? \"\" : search.startsWith(\"?\") ? search : \"?\" + search;\nvar normalizeHash = (hash) => !hash || hash === \"#\" ? \"\" : hash.startsWith(\"#\") ? hash : \"#\" + hash;\nvar DataWithResponseInit = class {\n constructor(data2, init) {\n this.type = \"DataWithResponseInit\";\n this.data = data2;\n this.init = init || null;\n }\n};\nfunction data(data2, init) {\n return new DataWithResponseInit(\n data2,\n typeof init === \"number\" ? { status: init } : init\n );\n}\nvar redirect = (url, init = 302) => {\n let responseInit = init;\n if (typeof responseInit === \"number\") {\n responseInit = { status: responseInit };\n } else if (typeof responseInit.status === \"undefined\") {\n responseInit.status = 302;\n }\n let headers = new Headers(responseInit.headers);\n headers.set(\"Location\", url);\n return new Response(null, { ...responseInit, headers });\n};\nvar redirectDocument = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Reload-Document\", \"true\");\n return response;\n};\nvar replace = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Replace\", \"true\");\n return response;\n};\nvar ErrorResponseImpl = class {\n constructor(status, statusText, data2, internal = false) {\n this.status = status;\n this.statusText = statusText || \"\";\n this.internal = internal;\n if (data2 instanceof Error) {\n this.data = data2.toString();\n this.error = data2;\n } else {\n this.data = data2;\n }\n }\n};\nfunction isRouteErrorResponse(error) {\n return error != null && typeof error.status === \"number\" && typeof error.statusText === \"string\" && typeof error.internal === \"boolean\" && \"data\" in error;\n}\nfunction getRoutePattern(matches) {\n return matches.map((m) => m.route.path).filter(Boolean).join(\"/\").replace(/\\/\\/*/g, \"/\") || \"/\";\n}\nvar isBrowser = typeof window !== \"undefined\" && typeof window.document !== \"undefined\" && typeof window.document.createElement !== \"undefined\";\nfunction parseToInfo(_to, basename) {\n let to = _to;\n if (typeof to !== \"string\" || !ABSOLUTE_URL_REGEX.test(to)) {\n return {\n absoluteURL: void 0,\n isExternal: false,\n to\n };\n }\n let absoluteURL = to;\n let isExternal = false;\n if (isBrowser) {\n try {\n let currentUrl = new URL(window.location.href);\n let targetUrl = to.startsWith(\"//\") ? new URL(currentUrl.protocol + to) : new URL(to);\n let path = stripBasename(targetUrl.pathname, basename);\n if (targetUrl.origin === currentUrl.origin && path != null) {\n to = path + targetUrl.search + targetUrl.hash;\n } else {\n isExternal = true;\n }\n } catch (e) {\n warning(\n false,\n `<Link to=\"${to}\"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`\n );\n }\n }\n return {\n absoluteURL,\n isExternal,\n to\n };\n}\n\n// lib/router/instrumentation.ts\nvar UninstrumentedSymbol = Symbol(\"Uninstrumented\");\nfunction getRouteInstrumentationUpdates(fns, route) {\n let aggregated = {\n lazy: [],\n \"lazy.loader\": [],\n \"lazy.action\": [],\n \"lazy.middleware\": [],\n middleware: [],\n loader: [],\n action: []\n };\n fns.forEach(\n (fn) => fn({\n id: route.id,\n index: route.index,\n path: route.path,\n instrument(i) {\n let keys = Object.keys(aggregated);\n for (let key of keys) {\n if (i[key]) {\n aggregated[key].push(i[key]);\n }\n }\n }\n })\n );\n let updates = {};\n if (typeof route.lazy === \"function\" && aggregated.lazy.length > 0) {\n let instrumented = wrapImpl(aggregated.lazy, route.lazy, () => void 0);\n if (instrumented) {\n updates.lazy = instrumented;\n }\n }\n if (typeof route.lazy === \"object\") {\n let lazyObject = route.lazy;\n [\"middleware\", \"loader\", \"action\"].forEach((key) => {\n let lazyFn = lazyObject[key];\n let instrumentations = aggregated[`lazy.${key}`];\n if (typeof lazyFn === \"function\" && instrumentations.length > 0) {\n let instrumented = wrapImpl(instrumentations, lazyFn, () => void 0);\n if (instrumented) {\n updates.lazy = Object.assign(updates.lazy || {}, {\n [key]: instrumented\n });\n }\n }\n });\n }\n [\"loader\", \"action\"].forEach((key) => {\n let handler = route[key];\n if (typeof handler === \"function\" && aggregated[key].length > 0) {\n let original = handler[UninstrumentedSymbol] ?? handler;\n let instrumented = wrapImpl(\n aggregated[key],\n original,\n (...args) => getHandlerInfo(args[0])\n );\n if (instrumented) {\n if (key === \"loader\" && original.hydrate === true) {\n instrumented.hydrate = true;\n }\n instrumented[UninstrumentedSymbol] = original;\n updates[key] = instrumented;\n }\n }\n });\n if (route.middleware && route.middleware.length > 0 && aggregated.middleware.length > 0) {\n updates.middleware = route.middleware.map((middleware) => {\n let original = middleware[UninstrumentedSymbol] ?? middleware;\n let instrumented = wrapImpl(\n aggregated.middleware,\n original,\n (...args) => getHandlerInfo(args[0])\n );\n if (instrumented) {\n instrumented[UninstrumentedSymbol] = original;\n return instrumented;\n }\n return middleware;\n });\n }\n return updates;\n}\nfunction instrumentClientSideRouter(router, fns) {\n let aggregated = {\n navigate: [],\n fetch: []\n };\n fns.forEach(\n (fn) => fn({\n instrument(i) {\n let keys = Object.keys(i);\n for (let key of keys) {\n if (i[key]) {\n aggregated[key].push(i[key]);\n }\n }\n }\n })\n );\n if (aggregated.navigate.length > 0) {\n let navigate = router.navigate[UninstrumentedSymbol] ?? router.navigate;\n let instrumentedNavigate = wrapImpl(\n aggregated.navigate,\n navigate,\n (...args) => {\n let [to, opts] = args;\n return {\n to: typeof to === \"number\" || typeof to === \"string\" ? to : to ? createPath(to) : \".\",\n ...getRouterInfo(router, opts ?? {})\n };\n }\n );\n if (instrumentedNavigate) {\n instrumentedNavigate[UninstrumentedSymbol] = navigate;\n router.navigate = instrumentedNavigate;\n }\n }\n if (aggregated.fetch.length > 0) {\n let fetch2 = router.fetch[UninstrumentedSymbol] ?? router.fetch;\n let instrumentedFetch = wrapImpl(aggregated.fetch, fetch2, (...args) => {\n let [key, , href, opts] = args;\n return {\n href: href ?? \".\",\n fetcherKey: key,\n ...getRouterInfo(router, opts ?? {})\n };\n });\n if (instrumentedFetch) {\n instrumentedFetch[UninstrumentedSymbol] = fetch2;\n router.fetch = instrumentedFetch;\n }\n }\n return router;\n}\nfunction instrumentHandler(handler, fns) {\n let aggregated = {\n request: []\n };\n fns.forEach(\n (fn) => fn({\n instrument(i) {\n let keys = Object.keys(i);\n for (let key of keys) {\n if (i[key]) {\n aggregated[key].push(i[key]);\n }\n }\n }\n })\n );\n let instrumentedHandler = handler;\n if (aggregated.request.length > 0) {\n instrumentedHandler = wrapImpl(aggregated.request, handler, (...args) => {\n let [request, context] = args;\n return {\n request: getReadonlyRequest(request),\n context: context != null ? getReadonlyContext(context) : context\n };\n });\n }\n return instrumentedHandler;\n}\nfunction wrapImpl(impls, handler, getInfo) {\n if (impls.length === 0) {\n return null;\n }\n return async (...args) => {\n let result = await recurseRight(\n impls,\n getInfo(...args),\n () => handler(...args),\n impls.length - 1\n );\n if (result.type === \"error\") {\n throw result.value;\n }\n return result.value;\n };\n}\nasync function recurseRight(impls, info, handler, index) {\n let impl = impls[index];\n let result;\n if (!impl) {\n try {\n let value = await handler();\n result = { type: \"success\", value };\n } catch (e) {\n result = { type: \"error\", value: e };\n }\n } else {\n let handlerPromise = void 0;\n let callHandler = async () => {\n if (handlerPromise) {\n console.error(\"You cannot call instrumented handlers more than once\");\n } else {\n handlerPromise = recurseRight(impls, info, handler, index - 1);\n }\n result = await handlerPromise;\n invariant(result, \"Expected a result\");\n if (result.type === \"error\" && result.value instanceof Error) {\n return { status: \"error\", error: result.value };\n }\n return { status: \"success\", error: void 0 };\n };\n try {\n await impl(callHandler, info);\n } catch (e) {\n console.error(\"An instrumentation function threw an error:\", e);\n }\n if (!handlerPromise) {\n await callHandler();\n }\n await handlerPromise;\n }\n if (result) {\n return result;\n }\n return {\n type: \"error\",\n value: new Error(\"No result assigned in instrumentation chain.\")\n };\n}\nfunction getHandlerInfo(args) {\n let { request, context, params, unstable_pattern } = args;\n return {\n request: getReadonlyRequest(request),\n params: { ...params },\n unstable_pattern,\n context: getReadonlyContext(context)\n };\n}\nfunction getRouterInfo(router, opts) {\n return {\n currentUrl: createPath(router.state.location),\n ...\"formMethod\" in opts ? { formMethod: opts.formMethod } : {},\n ...\"formEncType\" in opts ? { formEncType: opts.formEncType } : {},\n ...\"formData\" in opts ? { formData: opts.formData } : {},\n ...\"body\" in opts ? { body: opts.body } : {}\n };\n}\nfunction getReadonlyRequest(request) {\n return {\n method: request.method,\n url: request.url,\n headers: {\n get: (...args) => request.headers.get(...args)\n }\n };\n}\nfunction getReadonlyContext(context) {\n if (isPlainObject(context)) {\n let frozen = { ...context };\n Object.freeze(frozen);\n return frozen;\n } else {\n return {\n get: (ctx) => context.get(ctx)\n };\n }\n}\nvar objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join(\"\\0\");\nfunction isPlainObject(thing) {\n if (thing === null || typeof thing !== \"object\") {\n return false;\n }\n const proto = Object.getPrototypeOf(thing);\n return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join(\"\\0\") === objectProtoNames;\n}\n\n// lib/router/router.ts\nvar validMutationMethodsArr = [\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\"\n];\nvar validMutationMethods = new Set(\n validMutationMethodsArr\n);\nvar validRequestMethodsArr = [\n \"GET\",\n ...validMutationMethodsArr\n];\nvar validRequestMethods = new Set(validRequestMethodsArr);\nvar redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);\nvar redirectPreserveMethodStatusCodes = /* @__PURE__ */ new Set([307, 308]);\nvar IDLE_NAVIGATION = {\n state: \"idle\",\n location: void 0,\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0\n};\nvar IDLE_FETCHER = {\n state: \"idle\",\n data: void 0,\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0\n};\nvar IDLE_BLOCKER = {\n state: \"unblocked\",\n proceed: void 0,\n reset: void 0,\n location: void 0\n};\nvar defaultMapRouteProperties = (route) => ({\n hasErrorBoundary: Boolean(route.hasErrorBoundary)\n});\nvar TRANSITIONS_STORAGE_KEY = \"remix-router-transitions\";\nvar ResetLoaderDataSymbol = Symbol(\"ResetLoaderData\");\nfunction createRouter(init) {\n const routerWindow = init.window ? init.window : typeof window !== \"undefined\" ? window : void 0;\n const isBrowser3 = typeof routerWindow !== \"undefined\" && typeof routerWindow.document !== \"undefined\" && typeof routerWindow.document.createElement !== \"undefined\";\n invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n let hydrationRouteProperties2 = init.hydrationRouteProperties || [];\n let _mapRouteProperties = init.mapRouteProperties || defaultMapRouteProperties;\n let mapRouteProperties2 = _mapRouteProperties;\n if (init.unstable_instrumentations) {\n let instrumentations = init.unstable_instrumentations;\n mapRouteProperties2 = (route) => {\n return {\n ..._mapRouteProperties(route),\n ...getRouteInstrumentationUpdates(\n instrumentations.map((i) => i.route).filter(Boolean),\n route\n )\n };\n };\n }\n let manifest = {};\n let dataRoutes = convertRoutesToDataRoutes(\n init.routes,\n mapRouteProperties2,\n void 0,\n manifest\n );\n let inFlightDataRoutes;\n let basename = init.basename || \"/\";\n if (!basename.startsWith(\"/\")) {\n basename = `/${basename}`;\n }\n let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware;\n let future = {\n ...init.future\n };\n let unlistenHistory = null;\n let subscribers = /* @__PURE__ */ new Set();\n let savedScrollPositions2 = null;\n let getScrollRestorationKey2 = null;\n let getScrollPosition = null;\n let initialScrollRestored = init.hydrationData != null;\n let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);\n let initialMatchesIsFOW = false;\n let initialErrors = null;\n let initialized;\n if (initialMatches == null && !init.patchRoutesOnNavigation) {\n let error = getInternalRouterError(404, {\n pathname: init.history.location.pathname\n });\n let { matches, route } = getShortCircuitMatches(dataRoutes);\n initialized = true;\n initialMatches = matches;\n initialErrors = { [route.id]: error };\n } else {\n if (initialMatches && !init.hydrationData) {\n let fogOfWar = checkFogOfWar(\n initialMatches,\n dataRoutes,\n init.history.location.pathname\n );\n if (fogOfWar.active) {\n initialMatches = null;\n }\n }\n if (!initialMatches) {\n initialized = false;\n initialMatches = [];\n let fogOfWar = checkFogOfWar(\n null,\n dataRoutes,\n init.history.location.pathname\n );\n if (fogOfWar.active && fogOfWar.matches) {\n initialMatchesIsFOW = true;\n initialMatches = fogOfWar.matches;\n }\n } else if (initialMatches.some((m) => m.route.lazy)) {\n initialized = false;\n } else if (!initialMatches.some((m) => routeHasLoaderOrMiddleware(m.route))) {\n initialized = true;\n } else {\n let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;\n let errors = init.hydrationData ? init.hydrationData.errors : null;\n if (errors) {\n let idx = initialMatches.findIndex(\n (m) => errors[m.route.id] !== void 0\n );\n initialized = initialMatches.slice(0, idx + 1).every(\n (m) => !shouldLoadRouteOnHydration(m.route, loaderData, errors)\n );\n } else {\n initialized = initialMatches.every(\n (m) => !shouldLoadRouteOnHydration(m.route, loaderData, errors)\n );\n }\n }\n }\n let router;\n let state = {\n historyAction: init.history.action,\n location: init.history.location,\n matches: initialMatches,\n initialized,\n navigation: IDLE_NAVIGATION,\n // Don't restore on initial updateState() if we were SSR'd\n restoreScrollPosition: init.hydrationData != null ? false : null,\n preventScrollReset: false,\n revalidation: \"idle\",\n loaderData: init.hydrationData && init.hydrationData.loaderData || {},\n actionData: init.hydrationData && init.hydrationData.actionData || null,\n errors: init.hydrationData && init.hydrationData.errors || initialErrors,\n fetchers: /* @__PURE__ */ new Map(),\n blockers: /* @__PURE__ */ new Map()\n };\n let pendingAction = \"POP\" /* Pop */;\n let pendingPopstateNavigationDfd = null;\n let pendingPreventScrollReset = false;\n let pendingNavigationController;\n let pendingViewTransitionEnabled = false;\n let appliedViewTransitions = /* @__PURE__ */ new Map();\n let removePageHideEventListener = null;\n let isUninterruptedRevalidation = false;\n let isRevalidationRequired = false;\n let cancelledFetcherLoads = /* @__PURE__ */ new Set();\n let fetchControllers = /* @__PURE__ */ new Map();\n let incrementingLoadId = 0;\n let pendingNavigationLoadId = -1;\n let fetchReloadIds = /* @__PURE__ */ new Map();\n let fetchRedirectIds = /* @__PURE__ */ new Set();\n let fetchLoadMatches = /* @__PURE__ */ new Map();\n let activeFetchers = /* @__PURE__ */ new Map();\n let fetchersQueuedForDeletion = /* @__PURE__ */ new Set();\n let blockerFunctions = /* @__PURE__ */ new Map();\n let unblockBlockerHistoryUpdate = void 0;\n let pendingRevalidationDfd = null;\n function initialize() {\n unlistenHistory = init.history.listen(\n ({ action: historyAction, location, delta }) => {\n if (unblockBlockerHistoryUpdate) {\n unblockBlockerHistoryUpdate();\n unblockBlockerHistoryUpdate = void 0;\n return;\n }\n warning(\n blockerFunctions.size === 0 || delta != null,\n \"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL.\"\n );\n let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction\n });\n if (blockerKey && delta != null) {\n let nextHistoryUpdatePromise = new Promise((resolve) => {\n unblockBlockerHistoryUpdate = resolve;\n });\n init.history.go(delta * -1);\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location,\n proceed() {\n updateBlocker(blockerKey, {\n state: \"proceeding\",\n proceed: void 0,\n reset: void 0,\n location\n });\n nextHistoryUpdatePromise.then(() => init.history.go(delta));\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey, IDLE_BLOCKER);\n updateState({ blockers });\n }\n });\n pendingPopstateNavigationDfd?.resolve();\n pendingPopstateNavigationDfd = null;\n return;\n }\n return startNavigation(historyAction, location);\n }\n );\n if (isBrowser3) {\n restoreAppliedTransitions(routerWindow, appliedViewTransitions);\n let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions);\n routerWindow.addEventListener(\"pagehide\", _saveAppliedTransitions);\n removePageHideEventListener = () => routerWindow.removeEventListener(\"pagehide\", _saveAppliedTransitions);\n }\n if (!state.initialized) {\n startNavigation(\"POP\" /* Pop */, state.location, {\n initialHydration: true\n });\n }\n return router;\n }\n function dispose() {\n if (unlistenHistory) {\n unlistenHistory();\n }\n if (removePageHideEventListener) {\n removePageHideEventListener();\n }\n subscribers.clear();\n pendingNavigationController && pendingNavigationController.abort();\n state.fetchers.forEach((_, key) => deleteFetcher(key));\n state.blockers.forEach((_, key) => deleteBlocker(key));\n }\n function subscribe(fn) {\n subscribers.add(fn);\n return () => subscribers.delete(fn);\n }\n function updateState(newState, opts = {}) {\n if (newState.matches) {\n newState.matches = newState.matches.map((m) => {\n let route = manifest[m.route.id];\n let matchRoute = m.route;\n if (matchRoute.element !== route.element || matchRoute.errorElement !== route.errorElement || matchRoute.hydrateFallbackElement !== route.hydrateFallbackElement) {\n return {\n ...m,\n route\n };\n }\n return m;\n });\n }\n state = {\n ...state,\n ...newState\n };\n let unmountedFetchers = [];\n let mountedFetchers = [];\n state.fetchers.forEach((fetcher, key) => {\n if (fetcher.state === \"idle\") {\n if (fetchersQueuedForDeletion.has(key)) {\n unmountedFetchers.push(key);\n } else {\n mountedFetchers.push(key);\n }\n }\n });\n fetchersQueuedForDeletion.forEach((key) => {\n if (!state.fetchers.has(key) && !fetchControllers.has(key)) {\n unmountedFetchers.push(key);\n }\n });\n [...subscribers].forEach(\n (subscriber) => subscriber(state, {\n deletedFetchers: unmountedFetchers,\n newErrors: newState.errors ?? null,\n viewTransitionOpts: opts.viewTransitionOpts,\n flushSync: opts.flushSync === true\n })\n );\n unmountedFetchers.forEach((key) => deleteFetcher(key));\n mountedFetchers.forEach((key) => state.fetchers.delete(key));\n }\n function completeNavigation(location, newState, { flushSync } = {}) {\n let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === \"loading\" && location.state?._isRedirect !== true;\n let actionData;\n if (newState.actionData) {\n if (Object.keys(newState.actionData).length > 0) {\n actionData = newState.actionData;\n } else {\n actionData = null;\n }\n } else if (isActionReload) {\n actionData = state.actionData;\n } else {\n actionData = null;\n }\n let loaderData = newState.loaderData ? mergeLoaderData(\n state.loaderData,\n newState.loaderData,\n newState.matches || [],\n newState.errors\n ) : state.loaderData;\n let blockers = state.blockers;\n if (blockers.size > 0) {\n blockers = new Map(blockers);\n blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));\n }\n let restoreScrollPosition = isUninterruptedRevalidation ? false : getSavedScrollPosition(location, newState.matches || state.matches);\n let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && location.state?._isRedirect !== true;\n if (inFlightDataRoutes) {\n dataRoutes = inFlightDataRoutes;\n inFlightDataRoutes = void 0;\n }\n if (isUninterruptedRevalidation) {\n } else if (pendingAction === \"POP\" /* Pop */) {\n } else if (pendingAction === \"PUSH\" /* Push */) {\n init.history.push(location, location.state);\n } else if (pendingAction === \"REPLACE\" /* Replace */) {\n init.history.replace(location, location.state);\n }\n let viewTransitionOpts;\n if (pendingAction === \"POP\" /* Pop */) {\n let priorPaths = appliedViewTransitions.get(state.location.pathname);\n if (priorPaths && priorPaths.has(location.pathname)) {\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location\n };\n } else if (appliedViewTransitions.has(location.pathname)) {\n viewTransitionOpts = {\n currentLocation: location,\n nextLocation: state.location\n };\n }\n } else if (pendingViewTransitionEnabled) {\n let toPaths = appliedViewTransitions.get(state.location.pathname);\n if (toPaths) {\n toPaths.add(location.pathname);\n } else {\n toPaths = /* @__PURE__ */ new Set([location.pathname]);\n appliedViewTransitions.set(state.location.pathname, toPaths);\n }\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location\n };\n }\n updateState(\n {\n ...newState,\n // matches, errors, fetchers go through as-is\n actionData,\n loaderData,\n historyAction: pendingAction,\n location,\n initialized: true,\n navigation: IDLE_NAVIGATION,\n revalidation: \"idle\",\n restoreScrollPosition,\n preventScrollReset,\n blockers\n },\n {\n viewTransitionOpts,\n flushSync: flushSync === true\n }\n );\n pendingAction = \"POP\" /* Pop */;\n pendingPreventScrollReset = false;\n pendingViewTransitionEnabled = false;\n isUninterruptedRevalidation = false;\n isRevalidationRequired = false;\n pendingPopstateNavigationDfd?.resolve();\n pendingPopstateNavigationDfd = null;\n pendingRevalidationDfd?.resolve();\n pendingRevalidationDfd = null;\n }\n async function navigate(to, opts) {\n pendingPopstateNavigationDfd?.resolve();\n pendingPopstateNavigationDfd = null;\n if (typeof to === \"number\") {\n if (!pendingPopstateNavigationDfd) {\n pendingPopstateNavigationDfd = createDeferred();\n }\n let promise = pendingPopstateNavigationDfd.promise;\n init.history.go(to);\n return promise;\n }\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n to,\n opts?.fromRouteId,\n opts?.relative\n );\n let { path, submission, error } = normalizeNavigateOptions(\n false,\n normalizedPath,\n opts\n );\n let currentLocation = state.location;\n let nextLocation = createLocation(state.location, path, opts && opts.state);\n nextLocation = {\n ...nextLocation,\n ...init.history.encodeLocation(nextLocation)\n };\n let userReplace = opts && opts.replace != null ? opts.replace : void 0;\n let historyAction = \"PUSH\" /* Push */;\n if (userReplace === true) {\n historyAction = \"REPLACE\" /* Replace */;\n } else if (userReplace === false) {\n } else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) {\n historyAction = \"REPLACE\" /* Replace */;\n }\n let preventScrollReset = opts && \"preventScrollReset\" in opts ? opts.preventScrollReset === true : void 0;\n let flushSync = (opts && opts.flushSync) === true;\n let blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction\n });\n if (blockerKey) {\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location: nextLocation,\n proceed() {\n updateBlocker(blockerKey, {\n state: \"proceeding\",\n proceed: void 0,\n reset: void 0,\n location: nextLocation\n });\n navigate(to, opts);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey, IDLE_BLOCKER);\n updateState({ blockers });\n }\n });\n return;\n }\n await startNavigation(historyAction, nextLocation, {\n submission,\n // Send through the formData serialization error if we have one so we can\n // render at the right error boundary after we match routes\n pendingError: error,\n preventScrollReset,\n replace: opts && opts.replace,\n enableViewTransition: opts && opts.viewTransition,\n flushSync,\n callSiteDefaultShouldRevalidate: opts && opts.unstable_defaultShouldRevalidate\n });\n }\n function revalidate() {\n if (!pendingRevalidationDfd) {\n pendingRevalidationDfd = createDeferred();\n }\n interruptActiveLoads();\n updateState({ revalidation: \"loading\" });\n let promise = pendingRevalidationDfd.promise;\n if (state.navigation.state === \"submitting\") {\n return promise;\n }\n if (state.navigation.state === \"idle\") {\n startNavigation(state.historyAction, state.location, {\n startUninterruptedRevalidation: true\n });\n return promise;\n }\n startNavigation(\n pendingAction || state.historyAction,\n state.navigation.location,\n {\n overrideNavigation: state.navigation,\n // Proxy through any rending view transition\n enableViewTransition: pendingViewTransitionEnabled === true\n }\n );\n return promise;\n }\n async function startNavigation(historyAction, location, opts) {\n pendingNavigationController && pendingNavigationController.abort();\n pendingNavigationController = null;\n pendingAction = historyAction;\n isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true;\n saveScrollPosition(state.location, state.matches);\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let loadingNavigation = opts && opts.overrideNavigation;\n let matches = opts?.initialHydration && state.matches && state.matches.length > 0 && !initialMatchesIsFOW ? (\n // `matchRoutes()` has already been called if we're in here via `router.initialize()`\n state.matches\n ) : matchRoutes(routesToUse, location, basename);\n let flushSync = (opts && opts.flushSync) === true;\n if (matches && state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) {\n completeNavigation(location, { matches }, { flushSync });\n return;\n }\n let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n if (!matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n completeNavigation(\n location,\n {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error\n }\n },\n { flushSync }\n );\n return;\n }\n pendingNavigationController = new AbortController();\n let request = createClientSideRequest(\n init.history,\n location,\n pendingNavigationController.signal,\n opts && opts.submission\n );\n let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider();\n let pendingActionResult;\n if (opts && opts.pendingError) {\n pendingActionResult = [\n findNearestBoundary(matches).route.id,\n { type: \"error\" /* error */, error: opts.pendingError }\n ];\n } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) {\n let actionResult = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n scopedContext,\n fogOfWar.active,\n opts && opts.initialHydration === true,\n { replace: opts.replace, flushSync }\n );\n if (actionResult.shortCircuited) {\n return;\n }\n if (actionResult.pendingActionResult) {\n let [routeId, result] = actionResult.pendingActionResult;\n if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) {\n pendingNavigationController = null;\n completeNavigation(location, {\n matches: actionResult.matches,\n loaderData: {},\n errors: {\n [routeId]: result.error\n }\n });\n return;\n }\n }\n matches = actionResult.matches || matches;\n pendingActionResult = actionResult.pendingActionResult;\n loadingNavigation = getLoadingNavigation(location, opts.submission);\n flushSync = false;\n fogOfWar.active = false;\n request = createClientSideRequest(\n init.history,\n request.url,\n request.signal\n );\n }\n let {\n shortCircuited,\n matches: updatedMatches,\n loaderData,\n errors\n } = await handleLoaders(\n request,\n location,\n matches,\n scopedContext,\n fogOfWar.active,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.fetcherSubmission,\n opts && opts.replace,\n opts && opts.initialHydration === true,\n flushSync,\n pendingActionResult,\n opts && opts.callSiteDefaultShouldRevalidate\n );\n if (shortCircuited) {\n return;\n }\n pendingNavigationController = null;\n completeNavigation(location, {\n matches: updatedMatches || matches,\n ...getActionDataForCommit(pendingActionResult),\n loaderData,\n errors\n });\n }\n async function handleAction(request, location, submission, matches, scopedContext, isFogOfWar, initialHydration, opts = {}) {\n interruptActiveLoads();\n let navigation = getSubmittingNavigation(location, submission);\n updateState({ navigation }, { flushSync: opts.flushSync === true });\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n if (discoverResult.partialMatches.length === 0) {\n let { matches: matches2, route } = getShortCircuitMatches(dataRoutes);\n return {\n matches: matches2,\n pendingActionResult: [\n route.id,\n {\n type: \"error\" /* error */,\n error: discoverResult.error\n }\n ]\n };\n }\n let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;\n return {\n matches: discoverResult.partialMatches,\n pendingActionResult: [\n boundaryId,\n {\n type: \"error\" /* error */,\n error: discoverResult.error\n }\n ]\n };\n } else if (!discoverResult.matches) {\n let { notFoundMatches, error, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n pendingActionResult: [\n route.id,\n {\n type: \"error\" /* error */,\n error\n }\n ]\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n let result;\n let actionMatch = getTargetMatch(matches, location);\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n result = {\n type: \"error\" /* error */,\n error: getInternalRouterError(405, {\n method: request.method,\n pathname: location.pathname,\n routeId: actionMatch.route.id\n })\n };\n } else {\n let dsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n request,\n matches,\n actionMatch,\n initialHydration ? [] : hydrationRouteProperties2,\n scopedContext\n );\n let results = await callDataStrategy(\n request,\n dsMatches,\n scopedContext,\n null\n );\n result = results[actionMatch.route.id];\n if (!result) {\n for (let match of matches) {\n if (results[match.route.id]) {\n result = results[match.route.id];\n break;\n }\n }\n }\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n }\n if (isRedirectResult(result)) {\n let replace2;\n if (opts && opts.replace != null) {\n replace2 = opts.replace;\n } else {\n let location2 = normalizeRedirectLocation(\n result.response.headers.get(\"Location\"),\n new URL(request.url),\n basename,\n init.history\n );\n replace2 = location2 === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(request, result, true, {\n submission,\n replace: replace2\n });\n return { shortCircuited: true };\n }\n if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);\n if ((opts && opts.replace) !== true) {\n pendingAction = \"PUSH\" /* Push */;\n }\n return {\n matches,\n pendingActionResult: [\n boundaryMatch.route.id,\n result,\n actionMatch.route.id\n ]\n };\n }\n return {\n matches,\n pendingActionResult: [actionMatch.route.id, result]\n };\n }\n async function handleLoaders(request, location, matches, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync, pendingActionResult, callSiteDefaultShouldRevalidate) {\n let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);\n let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);\n let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration;\n if (isFogOfWar) {\n if (shouldUpdateNavigationState) {\n let actionData = getUpdatedActionData(pendingActionResult);\n updateState(\n {\n navigation: loadingNavigation,\n ...actionData !== void 0 ? { actionData } : {}\n },\n {\n flushSync\n }\n );\n }\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n if (discoverResult.partialMatches.length === 0) {\n let { matches: matches2, route } = getShortCircuitMatches(dataRoutes);\n return {\n matches: matches2,\n loaderData: {},\n errors: {\n [route.id]: discoverResult.error\n }\n };\n }\n let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;\n return {\n matches: discoverResult.partialMatches,\n loaderData: {},\n errors: {\n [boundaryId]: discoverResult.error\n }\n };\n } else if (!discoverResult.matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error\n }\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let { dsMatches, revalidatingFetchers } = getMatchesToLoad(\n request,\n scopedContext,\n mapRouteProperties2,\n manifest,\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n initialHydration ? [] : hydrationRouteProperties2,\n initialHydration === true,\n isRevalidationRequired,\n cancelledFetcherLoads,\n fetchersQueuedForDeletion,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n init.patchRoutesOnNavigation != null,\n pendingActionResult,\n callSiteDefaultShouldRevalidate\n );\n pendingNavigationLoadId = ++incrementingLoadId;\n if (!init.dataStrategy && !dsMatches.some((m) => m.shouldLoad) && !dsMatches.some(\n (m) => m.route.middleware && m.route.middleware.length > 0\n ) && revalidatingFetchers.length === 0) {\n let updatedFetchers2 = markFetchRedirectsDone();\n completeNavigation(\n location,\n {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { [pendingActionResult[0]]: pendingActionResult[1].error } : null,\n ...getActionDataForCommit(pendingActionResult),\n ...updatedFetchers2 ? { fetchers: new Map(state.fetchers) } : {}\n },\n { flushSync }\n );\n return { shortCircuited: true };\n }\n if (shouldUpdateNavigationState) {\n let updates = {};\n if (!isFogOfWar) {\n updates.navigation = loadingNavigation;\n let actionData = getUpdatedActionData(pendingActionResult);\n if (actionData !== void 0) {\n updates.actionData = actionData;\n }\n }\n if (revalidatingFetchers.length > 0) {\n updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers);\n }\n updateState(updates, { flushSync });\n }\n revalidatingFetchers.forEach((rf) => {\n abortFetcher(rf.key);\n if (rf.controller) {\n fetchControllers.set(rf.key, rf.controller);\n }\n });\n let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((f) => abortFetcher(f.key));\n if (pendingNavigationController) {\n pendingNavigationController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(\n dsMatches,\n revalidatingFetchers,\n request,\n scopedContext\n );\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n if (pendingNavigationController) {\n pendingNavigationController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));\n let redirect2 = findRedirect(loaderResults);\n if (redirect2) {\n await startRedirectNavigation(request, redirect2.result, true, {\n replace: replace2\n });\n return { shortCircuited: true };\n }\n redirect2 = findRedirect(fetcherResults);\n if (redirect2) {\n fetchRedirectIds.add(redirect2.key);\n await startRedirectNavigation(request, redirect2.result, true, {\n replace: replace2\n });\n return { shortCircuited: true };\n }\n let { loaderData, errors } = processLoaderData(\n state,\n matches,\n loaderResults,\n pendingActionResult,\n revalidatingFetchers,\n fetcherResults\n );\n if (initialHydration && state.errors) {\n errors = { ...state.errors, ...errors };\n }\n let updatedFetchers = markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;\n return {\n matches,\n loaderData,\n errors,\n ...shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {}\n };\n }\n function getUpdatedActionData(pendingActionResult) {\n if (pendingActionResult && !isErrorResult(pendingActionResult[1])) {\n return {\n [pendingActionResult[0]]: pendingActionResult[1].data\n };\n } else if (state.actionData) {\n if (Object.keys(state.actionData).length === 0) {\n return null;\n } else {\n return state.actionData;\n }\n }\n }\n function getUpdatedRevalidatingFetchers(revalidatingFetchers) {\n revalidatingFetchers.forEach((rf) => {\n let fetcher = state.fetchers.get(rf.key);\n let revalidatingFetcher = getLoadingFetcher(\n void 0,\n fetcher ? fetcher.data : void 0\n );\n state.fetchers.set(rf.key, revalidatingFetcher);\n });\n return new Map(state.fetchers);\n }\n async function fetch2(key, routeId, href, opts) {\n abortFetcher(key);\n let flushSync = (opts && opts.flushSync) === true;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n href,\n routeId,\n opts?.relative\n );\n let matches = matchRoutes(routesToUse, normalizedPath, basename);\n let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: normalizedPath }),\n { flushSync }\n );\n return;\n }\n let { path, submission, error } = normalizeNavigateOptions(\n true,\n normalizedPath,\n opts\n );\n if (error) {\n setFetcherError(key, routeId, error, { flushSync });\n return;\n }\n let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider();\n let preventScrollReset = (opts && opts.preventScrollReset) === true;\n if (submission && isMutationMethod(submission.formMethod)) {\n await handleFetcherAction(\n key,\n routeId,\n path,\n matches,\n scopedContext,\n fogOfWar.active,\n flushSync,\n preventScrollReset,\n submission,\n opts && opts.unstable_defaultShouldRevalidate\n );\n return;\n }\n fetchLoadMatches.set(key, { routeId, path });\n await handleFetcherLoader(\n key,\n routeId,\n path,\n matches,\n scopedContext,\n fogOfWar.active,\n flushSync,\n preventScrollReset,\n submission\n );\n }\n async function handleFetcherAction(key, routeId, path, requestMatches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission, callSiteDefaultShouldRevalidate) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {\n flushSync\n });\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n requestMatches,\n new URL(fetchRequest.url).pathname,\n fetchRequest.signal,\n key\n );\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n setFetcherError(key, routeId, discoverResult.error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n requestMatches = discoverResult.matches;\n }\n }\n let match = getTargetMatch(requestMatches, path);\n if (!match.route.action && !match.route.lazy) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId\n });\n setFetcherError(key, routeId, error, { flushSync });\n return;\n }\n fetchControllers.set(key, abortController);\n let originatingLoadId = incrementingLoadId;\n let fetchMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n requestMatches,\n match,\n hydrationRouteProperties2,\n scopedContext\n );\n let actionResults = await callDataStrategy(\n fetchRequest,\n fetchMatches,\n scopedContext,\n key\n );\n let actionResult = actionResults[match.route.id];\n if (!actionResult) {\n for (let match2 of fetchMatches) {\n if (actionResults[match2.route.id]) {\n actionResult = actionResults[match2.route.id];\n break;\n }\n }\n }\n if (fetchRequest.signal.aborted) {\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n return;\n }\n if (fetchersQueuedForDeletion.has(key)) {\n if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {\n updateFetcherState(key, getDoneFetcher(void 0));\n return;\n }\n } else {\n if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n if (pendingNavigationLoadId > originatingLoadId) {\n updateFetcherState(key, getDoneFetcher(void 0));\n return;\n } else {\n fetchRedirectIds.add(key);\n updateFetcherState(key, getLoadingFetcher(submission));\n return startRedirectNavigation(fetchRequest, actionResult, false, {\n fetcherSubmission: submission,\n preventScrollReset\n });\n }\n }\n if (isErrorResult(actionResult)) {\n setFetcherError(key, routeId, actionResult.error);\n return;\n }\n }\n let nextLocation = state.navigation.location || state.location;\n let revalidationRequest = createClientSideRequest(\n init.history,\n nextLocation,\n abortController.signal\n );\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let matches = state.navigation.state !== \"idle\" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches;\n invariant(matches, \"Didn't find any matches after fetcher action\");\n let loadId = ++incrementingLoadId;\n fetchReloadIds.set(key, loadId);\n let loadFetcher = getLoadingFetcher(submission, actionResult.data);\n state.fetchers.set(key, loadFetcher);\n let { dsMatches, revalidatingFetchers } = getMatchesToLoad(\n revalidationRequest,\n scopedContext,\n mapRouteProperties2,\n manifest,\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n hydrationRouteProperties2,\n false,\n isRevalidationRequired,\n cancelledFetcherLoads,\n fetchersQueuedForDeletion,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n init.patchRoutesOnNavigation != null,\n [match.route.id, actionResult],\n callSiteDefaultShouldRevalidate\n );\n revalidatingFetchers.filter((rf) => rf.key !== key).forEach((rf) => {\n let staleKey = rf.key;\n let existingFetcher2 = state.fetchers.get(staleKey);\n let revalidatingFetcher = getLoadingFetcher(\n void 0,\n existingFetcher2 ? existingFetcher2.data : void 0\n );\n state.fetchers.set(staleKey, revalidatingFetcher);\n abortFetcher(staleKey);\n if (rf.controller) {\n fetchControllers.set(staleKey, rf.controller);\n }\n });\n updateState({ fetchers: new Map(state.fetchers) });\n let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));\n abortController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(\n dsMatches,\n revalidatingFetchers,\n revalidationRequest,\n scopedContext\n );\n if (abortController.signal.aborted) {\n return;\n }\n abortController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key));\n if (state.fetchers.has(key)) {\n let doneFetcher = getDoneFetcher(actionResult.data);\n state.fetchers.set(key, doneFetcher);\n }\n let redirect2 = findRedirect(loaderResults);\n if (redirect2) {\n return startRedirectNavigation(\n revalidationRequest,\n redirect2.result,\n false,\n { preventScrollReset }\n );\n }\n redirect2 = findRedirect(fetcherResults);\n if (redirect2) {\n fetchRedirectIds.add(redirect2.key);\n return startRedirectNavigation(\n revalidationRequest,\n redirect2.result,\n false,\n { preventScrollReset }\n );\n }\n let { loaderData, errors } = processLoaderData(\n state,\n matches,\n loaderResults,\n void 0,\n revalidatingFetchers,\n fetcherResults\n );\n abortStaleFetchLoads(loadId);\n if (state.navigation.state === \"loading\" && loadId > pendingNavigationLoadId) {\n invariant(pendingAction, \"Expected pending action\");\n pendingNavigationController && pendingNavigationController.abort();\n completeNavigation(state.navigation.location, {\n matches,\n loaderData,\n errors,\n fetchers: new Map(state.fetchers)\n });\n } else {\n updateState({\n errors,\n loaderData: mergeLoaderData(\n state.loaderData,\n loaderData,\n matches,\n errors\n ),\n fetchers: new Map(state.fetchers)\n });\n isRevalidationRequired = false;\n }\n }\n async function handleFetcherLoader(key, routeId, path, matches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) {\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(\n key,\n getLoadingFetcher(\n submission,\n existingFetcher ? existingFetcher.data : void 0\n ),\n { flushSync }\n );\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n new URL(fetchRequest.url).pathname,\n fetchRequest.signal,\n key\n );\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n setFetcherError(key, routeId, discoverResult.error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n matches = discoverResult.matches;\n }\n }\n let match = getTargetMatch(matches, path);\n fetchControllers.set(key, abortController);\n let originatingLoadId = incrementingLoadId;\n let dsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n matches,\n match,\n hydrationRouteProperties2,\n scopedContext\n );\n let results = await callDataStrategy(\n fetchRequest,\n dsMatches,\n scopedContext,\n key\n );\n let result = results[match.route.id];\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n if (fetchRequest.signal.aborted) {\n return;\n }\n if (fetchersQueuedForDeletion.has(key)) {\n updateFetcherState(key, getDoneFetcher(void 0));\n return;\n }\n if (isRedirectResult(result)) {\n if (pendingNavigationLoadId > originatingLoadId) {\n updateFetcherState(key, getDoneFetcher(void 0));\n return;\n } else {\n fetchRedirectIds.add(key);\n await startRedirectNavigation(fetchRequest, result, false, {\n preventScrollReset\n });\n return;\n }\n }\n if (isErrorResult(result)) {\n setFetcherError(key, routeId, result.error);\n return;\n }\n updateFetcherState(key, getDoneFetcher(result.data));\n }\n async function startRedirectNavigation(request, redirect2, isNavigation, {\n submission,\n fetcherSubmission,\n preventScrollReset,\n replace: replace2\n } = {}) {\n if (!isNavigation) {\n pendingPopstateNavigationDfd?.resolve();\n pendingPopstateNavigationDfd = null;\n }\n if (redirect2.response.headers.has(\"X-Remix-Revalidate\")) {\n isRevalidationRequired = true;\n }\n let location = redirect2.response.headers.get(\"Location\");\n invariant(location, \"Expected a Location header on the redirect Response\");\n location = normalizeRedirectLocation(\n location,\n new URL(request.url),\n basename,\n init.history\n );\n let redirectLocation = createLocation(state.location, location, {\n _isRedirect: true\n });\n if (isBrowser3) {\n let isDocumentReload = false;\n if (redirect2.response.headers.has(\"X-Remix-Reload-Document\")) {\n isDocumentReload = true;\n } else if (isAbsoluteUrl(location)) {\n const url = createBrowserURLImpl(location, true);\n isDocumentReload = // Hard reload if it's an absolute URL to a new origin\n url.origin !== routerWindow.location.origin || // Hard reload if it's an absolute URL that does not match our basename\n stripBasename(url.pathname, basename) == null;\n }\n if (isDocumentReload) {\n if (replace2) {\n routerWindow.location.replace(location);\n } else {\n routerWindow.location.assign(location);\n }\n return;\n }\n }\n pendingNavigationController = null;\n let redirectNavigationType = replace2 === true || redirect2.response.headers.has(\"X-Remix-Replace\") ? \"REPLACE\" /* Replace */ : \"PUSH\" /* Push */;\n let { formMethod, formAction, formEncType } = state.navigation;\n if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) {\n submission = getSubmissionFromNavigation(state.navigation);\n }\n let activeSubmission = submission || fetcherSubmission;\n if (redirectPreserveMethodStatusCodes.has(redirect2.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) {\n await startNavigation(redirectNavigationType, redirectLocation, {\n submission: {\n ...activeSubmission,\n formAction: location\n },\n // Preserve these flags across redirects\n preventScrollReset: preventScrollReset || pendingPreventScrollReset,\n enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0\n });\n } else {\n let overrideNavigation = getLoadingNavigation(\n redirectLocation,\n submission\n );\n await startNavigation(redirectNavigationType, redirectLocation, {\n overrideNavigation,\n // Send fetcher submissions through for shouldRevalidate\n fetcherSubmission,\n // Preserve these flags across redirects\n preventScrollReset: preventScrollReset || pendingPreventScrollReset,\n enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0\n });\n }\n }\n async function callDataStrategy(request, matches, scopedContext, fetcherKey) {\n let results;\n let dataResults = {};\n try {\n results = await callDataStrategyImpl(\n dataStrategyImpl,\n request,\n matches,\n fetcherKey,\n scopedContext,\n false\n );\n } catch (e) {\n matches.filter((m) => m.shouldLoad).forEach((m) => {\n dataResults[m.route.id] = {\n type: \"error\" /* error */,\n error: e\n };\n });\n return dataResults;\n }\n if (request.signal.aborted) {\n return dataResults;\n }\n if (!isMutationMethod(request.method)) {\n for (let match of matches) {\n if (results[match.route.id]?.type === \"error\" /* error */) {\n break;\n }\n if (!results.hasOwnProperty(match.route.id) && !state.loaderData.hasOwnProperty(match.route.id) && (!state.errors || !state.errors.hasOwnProperty(match.route.id)) && match.shouldCallHandler()) {\n results[match.route.id] = {\n type: \"error\" /* error */,\n result: new Error(\n `No result returned from dataStrategy for route ${match.route.id}`\n )\n };\n }\n }\n }\n for (let [routeId, result] of Object.entries(results)) {\n if (isRedirectDataStrategyResult(result)) {\n let response = result.result;\n dataResults[routeId] = {\n type: \"redirect\" /* redirect */,\n response: normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n routeId,\n matches,\n basename\n )\n };\n } else {\n dataResults[routeId] = await convertDataStrategyResultToDataResult(result);\n }\n }\n return dataResults;\n }\n async function callLoadersAndMaybeResolveData(matches, fetchersToLoad, request, scopedContext) {\n let loaderResultsPromise = callDataStrategy(\n request,\n matches,\n scopedContext,\n null\n );\n let fetcherResultsPromise = Promise.all(\n fetchersToLoad.map(async (f) => {\n if (f.matches && f.match && f.request && f.controller) {\n let results = await callDataStrategy(\n f.request,\n f.matches,\n scopedContext,\n f.key\n );\n let result = results[f.match.route.id];\n return { [f.key]: result };\n } else {\n return Promise.resolve({\n [f.key]: {\n type: \"error\" /* error */,\n error: getInternalRouterError(404, {\n pathname: f.path\n })\n }\n });\n }\n })\n );\n let loaderResults = await loaderResultsPromise;\n let fetcherResults = (await fetcherResultsPromise).reduce(\n (acc, r) => Object.assign(acc, r),\n {}\n );\n return {\n loaderResults,\n fetcherResults\n };\n }\n function interruptActiveLoads() {\n isRevalidationRequired = true;\n fetchLoadMatches.forEach((_, key) => {\n if (fetchControllers.has(key)) {\n cancelledFetcherLoads.add(key);\n }\n abortFetcher(key);\n });\n }\n function updateFetcherState(key, fetcher, opts = {}) {\n state.fetchers.set(key, fetcher);\n updateState(\n { fetchers: new Map(state.fetchers) },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n function setFetcherError(key, routeId, error, opts = {}) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState(\n {\n errors: {\n [boundaryMatch.route.id]: error\n },\n fetchers: new Map(state.fetchers)\n },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n function getFetcher(key) {\n activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);\n if (fetchersQueuedForDeletion.has(key)) {\n fetchersQueuedForDeletion.delete(key);\n }\n return state.fetchers.get(key) || IDLE_FETCHER;\n }\n function resetFetcher(key, opts) {\n abortFetcher(key, opts?.reason);\n updateFetcherState(key, getDoneFetcher(null));\n }\n function deleteFetcher(key) {\n let fetcher = state.fetchers.get(key);\n if (fetchControllers.has(key) && !(fetcher && fetcher.state === \"loading\" && fetchReloadIds.has(key))) {\n abortFetcher(key);\n }\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n fetchersQueuedForDeletion.delete(key);\n cancelledFetcherLoads.delete(key);\n state.fetchers.delete(key);\n }\n function queueFetcherForDeletion(key) {\n let count = (activeFetchers.get(key) || 0) - 1;\n if (count <= 0) {\n activeFetchers.delete(key);\n fetchersQueuedForDeletion.add(key);\n } else {\n activeFetchers.set(key, count);\n }\n updateState({ fetchers: new Map(state.fetchers) });\n }\n function abortFetcher(key, reason) {\n let controller = fetchControllers.get(key);\n if (controller) {\n controller.abort(reason);\n fetchControllers.delete(key);\n }\n }\n function markFetchersDone(keys) {\n for (let key of keys) {\n let fetcher = getFetcher(key);\n let doneFetcher = getDoneFetcher(fetcher.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n function markFetchRedirectsDone() {\n let doneKeys = [];\n let updatedFetchers = false;\n for (let key of fetchRedirectIds) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n fetchRedirectIds.delete(key);\n doneKeys.push(key);\n updatedFetchers = true;\n }\n }\n markFetchersDone(doneKeys);\n return updatedFetchers;\n }\n function abortStaleFetchLoads(landedId) {\n let yeetedKeys = [];\n for (let [key, id] of fetchReloadIds) {\n if (id < landedId) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n abortFetcher(key);\n fetchReloadIds.delete(key);\n yeetedKeys.push(key);\n }\n }\n }\n markFetchersDone(yeetedKeys);\n return yeetedKeys.length > 0;\n }\n function getBlocker(key, fn) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n if (blockerFunctions.get(key) !== fn) {\n blockerFunctions.set(key, fn);\n }\n return blocker;\n }\n function deleteBlocker(key) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n }\n function updateBlocker(key, newBlocker) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n invariant(\n blocker.state === \"unblocked\" && newBlocker.state === \"blocked\" || blocker.state === \"blocked\" && newBlocker.state === \"blocked\" || blocker.state === \"blocked\" && newBlocker.state === \"proceeding\" || blocker.state === \"blocked\" && newBlocker.state === \"unblocked\" || blocker.state === \"proceeding\" && newBlocker.state === \"unblocked\",\n `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}`\n );\n let blockers = new Map(state.blockers);\n blockers.set(key, newBlocker);\n updateState({ blockers });\n }\n function shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction\n }) {\n if (blockerFunctions.size === 0) {\n return;\n }\n if (blockerFunctions.size > 1) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n let entries = Array.from(blockerFunctions.entries());\n let [blockerKey, blockerFunction] = entries[entries.length - 1];\n let blocker = state.blockers.get(blockerKey);\n if (blocker && blocker.state === \"proceeding\") {\n return;\n }\n if (blockerFunction({ currentLocation, nextLocation, historyAction })) {\n return blockerKey;\n }\n }\n function handleNavigational404(pathname) {\n let error = getInternalRouterError(404, { pathname });\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let { matches, route } = getShortCircuitMatches(routesToUse);\n return { notFoundMatches: matches, route, error };\n }\n function enableScrollRestoration(positions, getPosition, getKey) {\n savedScrollPositions2 = positions;\n getScrollPosition = getPosition;\n getScrollRestorationKey2 = getKey || null;\n if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {\n initialScrollRestored = true;\n let y = getSavedScrollPosition(state.location, state.matches);\n if (y != null) {\n updateState({ restoreScrollPosition: y });\n }\n }\n return () => {\n savedScrollPositions2 = null;\n getScrollPosition = null;\n getScrollRestorationKey2 = null;\n };\n }\n function getScrollKey(location, matches) {\n if (getScrollRestorationKey2) {\n let key = getScrollRestorationKey2(\n location,\n matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData))\n );\n return key || location.key;\n }\n return location.key;\n }\n function saveScrollPosition(location, matches) {\n if (savedScrollPositions2 && getScrollPosition) {\n let key = getScrollKey(location, matches);\n savedScrollPositions2[key] = getScrollPosition();\n }\n }\n function getSavedScrollPosition(location, matches) {\n if (savedScrollPositions2) {\n let key = getScrollKey(location, matches);\n let y = savedScrollPositions2[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n function checkFogOfWar(matches, routesToUse, pathname) {\n if (init.patchRoutesOnNavigation) {\n if (!matches) {\n let fogMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n return { active: true, matches: fogMatches || [] };\n } else {\n if (Object.keys(matches[0].params).length > 0) {\n let partialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n return { active: true, matches: partialMatches };\n }\n }\n }\n return { active: false, matches: null };\n }\n async function discoverRoutes(matches, pathname, signal, fetcherKey) {\n if (!init.patchRoutesOnNavigation) {\n return { type: \"success\", matches };\n }\n let partialMatches = matches;\n while (true) {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let localManifest = manifest;\n try {\n await init.patchRoutesOnNavigation({\n signal,\n path: pathname,\n matches: partialMatches,\n fetcherKey,\n patch: (routeId, children) => {\n if (signal.aborted) return;\n patchRoutesImpl(\n routeId,\n children,\n routesToUse,\n localManifest,\n mapRouteProperties2,\n false\n );\n }\n });\n } catch (e) {\n return { type: \"error\", error: e, partialMatches };\n } finally {\n if (isNonHMR && !signal.aborted) {\n dataRoutes = [...dataRoutes];\n }\n }\n if (signal.aborted) {\n return { type: \"aborted\" };\n }\n let newMatches = matchRoutes(routesToUse, pathname, basename);\n let newPartialMatches = null;\n if (newMatches) {\n if (Object.keys(newMatches[0].params).length === 0) {\n return { type: \"success\", matches: newMatches };\n } else {\n newPartialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n let matchedDeeper = newPartialMatches && partialMatches.length < newPartialMatches.length && compareMatches(\n partialMatches,\n newPartialMatches.slice(0, partialMatches.length)\n );\n if (!matchedDeeper) {\n return { type: \"success\", matches: newMatches };\n }\n }\n }\n if (!newPartialMatches) {\n newPartialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true\n );\n }\n if (!newPartialMatches || compareMatches(partialMatches, newPartialMatches)) {\n return { type: \"success\", matches: null };\n }\n partialMatches = newPartialMatches;\n }\n }\n function compareMatches(a, b) {\n return a.length === b.length && a.every((m, i) => m.route.id === b[i].route.id);\n }\n function _internalSetRoutes(newRoutes) {\n manifest = {};\n inFlightDataRoutes = convertRoutesToDataRoutes(\n newRoutes,\n mapRouteProperties2,\n void 0,\n manifest\n );\n }\n function patchRoutes(routeId, children, unstable_allowElementMutations = false) {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n patchRoutesImpl(\n routeId,\n children,\n routesToUse,\n manifest,\n mapRouteProperties2,\n unstable_allowElementMutations\n );\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n updateState({});\n }\n }\n router = {\n get basename() {\n return basename;\n },\n get future() {\n return future;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\n },\n get window() {\n return routerWindow;\n },\n initialize,\n subscribe,\n enableScrollRestoration,\n navigate,\n fetch: fetch2,\n revalidate,\n // Passthrough to history-aware createHref used by useHref so we get proper\n // hash-aware URLs in DOM paths\n createHref: (to) => init.history.createHref(to),\n encodeLocation: (to) => init.history.encodeLocation(to),\n getFetcher,\n resetFetcher,\n deleteFetcher: queueFetcherForDeletion,\n dispose,\n getBlocker,\n deleteBlocker,\n patchRoutes,\n _internalFetchControllers: fetchControllers,\n // TODO: Remove setRoutes, it's temporary to avoid dealing with\n // updating the tree while validating the update algorithm.\n _internalSetRoutes,\n _internalSetStateDoNotUseOrYouWillBreakYourApp(newState) {\n updateState(newState);\n }\n };\n if (init.unstable_instrumentations) {\n router = instrumentClientSideRouter(\n router,\n init.unstable_instrumentations.map((i) => i.router).filter(Boolean)\n );\n }\n return router;\n}\nfunction createStaticHandler(routes, opts) {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n let manifest = {};\n let basename = (opts ? opts.basename : null) || \"/\";\n let _mapRouteProperties = opts?.mapRouteProperties || defaultMapRouteProperties;\n let mapRouteProperties2 = _mapRouteProperties;\n if (opts?.unstable_instrumentations) {\n let instrumentations = opts.unstable_instrumentations;\n mapRouteProperties2 = (route) => {\n return {\n ..._mapRouteProperties(route),\n ...getRouteInstrumentationUpdates(\n instrumentations.map((i) => i.route).filter(Boolean),\n route\n )\n };\n };\n }\n let dataRoutes = convertRoutesToDataRoutes(\n routes,\n mapRouteProperties2,\n void 0,\n manifest\n );\n async function query(request, {\n requestContext,\n filterMatchesToLoad,\n skipLoaderErrorBubbling,\n skipRevalidation,\n dataStrategy,\n generateMiddlewareResponse\n } = {}) {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n requestContext = requestContext != null ? requestContext : new RouterContextProvider();\n if (!isValidMethod(method) && method !== \"HEAD\") {\n let error = getInternalRouterError(405, { method });\n let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes);\n let staticContext = {\n basename,\n location,\n matches: methodNotAllowedMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {}\n };\n return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;\n } else if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes);\n let staticContext = {\n basename,\n location,\n matches: notFoundMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {}\n };\n return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;\n }\n if (generateMiddlewareResponse) {\n invariant(\n requestContext instanceof RouterContextProvider,\n \"When using middleware in `staticHandler.query()`, any provided `requestContext` must be an instance of `RouterContextProvider`\"\n );\n try {\n await loadLazyMiddlewareForMatches(\n matches,\n manifest,\n mapRouteProperties2\n );\n let renderedStaticContext;\n let response = await runServerMiddlewarePipeline(\n {\n request,\n unstable_pattern: getRoutePattern(matches),\n matches,\n params: matches[0].params,\n // If we're calling middleware then it must be enabled so we can cast\n // this to the proper type knowing it's not an `AppLoadContext`\n context: requestContext\n },\n async () => {\n let res = await generateMiddlewareResponse(\n async (revalidationRequest, opts2 = {}) => {\n let result2 = await queryImpl(\n revalidationRequest,\n location,\n matches,\n requestContext,\n dataStrategy || null,\n skipLoaderErrorBubbling === true,\n null,\n \"filterMatchesToLoad\" in opts2 ? opts2.filterMatchesToLoad ?? null : filterMatchesToLoad ?? null,\n skipRevalidation === true\n );\n if (isResponse(result2)) {\n return result2;\n }\n renderedStaticContext = { location, basename, ...result2 };\n return renderedStaticContext;\n }\n );\n return res;\n },\n async (error, routeId) => {\n if (isRedirectResponse(error)) {\n return error;\n }\n if (isResponse(error)) {\n try {\n error = new ErrorResponseImpl(\n error.status,\n error.statusText,\n await parseResponseBody(error)\n );\n } catch (e) {\n error = e;\n }\n }\n if (isDataWithResponseInit(error)) {\n error = dataWithResponseInitToErrorResponse(error);\n }\n if (renderedStaticContext) {\n if (routeId in renderedStaticContext.loaderData) {\n renderedStaticContext.loaderData[routeId] = void 0;\n }\n let staticContext = getStaticContextFromError(\n dataRoutes,\n renderedStaticContext,\n error,\n skipLoaderErrorBubbling ? routeId : findNearestBoundary(matches, routeId).route.id\n );\n return generateMiddlewareResponse(\n () => Promise.resolve(staticContext)\n );\n } else {\n let boundaryRouteId = skipLoaderErrorBubbling ? routeId : findNearestBoundary(\n matches,\n matches.find(\n (m) => m.route.id === routeId || m.route.loader\n )?.route.id || routeId\n ).route.id;\n let staticContext = {\n matches,\n location,\n basename,\n loaderData: {},\n actionData: null,\n errors: {\n [boundaryRouteId]: error\n },\n statusCode: isRouteErrorResponse(error) ? error.status : 500,\n actionHeaders: {},\n loaderHeaders: {}\n };\n return generateMiddlewareResponse(\n () => Promise.resolve(staticContext)\n );\n }\n }\n );\n invariant(isResponse(response), \"Expected a response in query()\");\n return response;\n } catch (e) {\n if (isResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n dataStrategy || null,\n skipLoaderErrorBubbling === true,\n null,\n filterMatchesToLoad || null,\n skipRevalidation === true\n );\n if (isResponse(result)) {\n return result;\n }\n return { location, basename, ...result };\n }\n async function queryRoute(request, {\n routeId,\n requestContext,\n dataStrategy,\n generateMiddlewareResponse\n } = {}) {\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n requestContext = requestContext != null ? requestContext : new RouterContextProvider();\n if (!isValidMethod(method) && method !== \"HEAD\" && method !== \"OPTIONS\") {\n throw getInternalRouterError(405, { method });\n } else if (!matches) {\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n let match = routeId ? matches.find((m) => m.route.id === routeId) : getTargetMatch(matches, location);\n if (routeId && !match) {\n throw getInternalRouterError(403, {\n pathname: location.pathname,\n routeId\n });\n } else if (!match) {\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n if (generateMiddlewareResponse) {\n invariant(\n requestContext instanceof RouterContextProvider,\n \"When using middleware in `staticHandler.queryRoute()`, any provided `requestContext` must be an instance of `RouterContextProvider`\"\n );\n await loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2);\n let response = await runServerMiddlewarePipeline(\n {\n request,\n unstable_pattern: getRoutePattern(matches),\n matches,\n params: matches[0].params,\n // If we're calling middleware then it must be enabled so we can cast\n // this to the proper type knowing it's not an `AppLoadContext`\n context: requestContext\n },\n async () => {\n let res = await generateMiddlewareResponse(\n async (innerRequest) => {\n let result2 = await queryImpl(\n innerRequest,\n location,\n matches,\n requestContext,\n dataStrategy || null,\n false,\n match,\n null,\n false\n );\n let processed = handleQueryResult(result2);\n return isResponse(processed) ? processed : typeof processed === \"string\" ? new Response(processed) : Response.json(processed);\n }\n );\n return res;\n },\n (error) => {\n if (isDataWithResponseInit(error)) {\n return Promise.resolve(dataWithResponseInitToResponse(error));\n }\n if (isResponse(error)) {\n return Promise.resolve(error);\n }\n throw error;\n }\n );\n return response;\n }\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n dataStrategy || null,\n false,\n match,\n null,\n false\n );\n return handleQueryResult(result);\n function handleQueryResult(result2) {\n if (isResponse(result2)) {\n return result2;\n }\n let error = result2.errors ? Object.values(result2.errors)[0] : void 0;\n if (error !== void 0) {\n throw error;\n }\n if (result2.actionData) {\n return Object.values(result2.actionData)[0];\n }\n if (result2.loaderData) {\n return Object.values(result2.loaderData)[0];\n }\n return void 0;\n }\n }\n async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, skipRevalidation) {\n invariant(\n request.signal,\n \"query()/queryRoute() requests must contain an AbortController signal\"\n );\n try {\n if (isMutationMethod(request.method)) {\n let result2 = await submit(\n request,\n matches,\n routeMatch || getTargetMatch(matches, location),\n requestContext,\n dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch != null,\n filterMatchesToLoad,\n skipRevalidation\n );\n return result2;\n }\n let result = await loadRouteData(\n request,\n matches,\n requestContext,\n dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch,\n filterMatchesToLoad\n );\n return isResponse(result) ? result : {\n ...result,\n actionData: null,\n actionHeaders: {}\n };\n } catch (e) {\n if (isDataStrategyResult(e) && isResponse(e.result)) {\n if (e.type === \"error\" /* error */) {\n throw e.result;\n }\n return e.result;\n }\n if (isRedirectResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest, filterMatchesToLoad, skipRevalidation) {\n let result;\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n let error = getInternalRouterError(405, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: actionMatch.route.id\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: \"error\" /* error */,\n error\n };\n } else {\n let dsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n request,\n matches,\n actionMatch,\n [],\n requestContext\n );\n let results = await callDataStrategy(\n request,\n dsMatches,\n isRouteRequest,\n requestContext,\n dataStrategy\n );\n result = results[actionMatch.route.id];\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest);\n }\n }\n if (isRedirectResult(result)) {\n throw new Response(null, {\n status: result.response.status,\n headers: {\n Location: result.response.headers.get(\"Location\")\n }\n });\n }\n if (isRouteRequest) {\n if (isErrorResult(result)) {\n throw result.error;\n }\n return {\n matches: [actionMatch],\n loaderData: {},\n actionData: { [actionMatch.route.id]: result.data },\n errors: null,\n // Note: statusCode + headers are unused here since queryRoute will\n // return the raw Response or value\n statusCode: 200,\n loaderHeaders: {},\n actionHeaders: {}\n };\n }\n if (skipRevalidation) {\n if (isErrorResult(result)) {\n let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);\n return {\n statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,\n actionData: null,\n actionHeaders: {\n ...result.headers ? { [actionMatch.route.id]: result.headers } : {}\n },\n matches,\n loaderData: {},\n errors: {\n [boundaryMatch.route.id]: result.error\n },\n loaderHeaders: {}\n };\n } else {\n return {\n actionData: {\n [actionMatch.route.id]: result.data\n },\n actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {},\n matches,\n loaderData: {},\n errors: null,\n statusCode: result.statusCode || 200,\n loaderHeaders: {}\n };\n }\n }\n let loaderRequest = new Request(request.url, {\n headers: request.headers,\n redirect: request.redirect,\n signal: request.signal\n });\n if (isErrorResult(result)) {\n let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);\n let handlerContext2 = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n dataStrategy,\n skipLoaderErrorBubbling,\n null,\n filterMatchesToLoad,\n [boundaryMatch.route.id, result]\n );\n return {\n ...handlerContext2,\n statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,\n actionData: null,\n actionHeaders: {\n ...result.headers ? { [actionMatch.route.id]: result.headers } : {}\n }\n };\n }\n let handlerContext = await loadRouteData(\n loaderRequest,\n matches,\n requestContext,\n dataStrategy,\n skipLoaderErrorBubbling,\n null,\n filterMatchesToLoad\n );\n return {\n ...handlerContext,\n actionData: {\n [actionMatch.route.id]: result.data\n },\n // action status codes take precedence over loader status codes\n ...result.statusCode ? { statusCode: result.statusCode } : {},\n actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {}\n };\n }\n async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, pendingActionResult) {\n let isRouteRequest = routeMatch != null;\n if (isRouteRequest && !routeMatch?.route.loader && !routeMatch?.route.lazy) {\n throw getInternalRouterError(400, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: routeMatch?.route.id\n });\n }\n let dsMatches;\n if (routeMatch) {\n dsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n request,\n matches,\n routeMatch,\n [],\n requestContext\n );\n } else {\n let maxIdx = pendingActionResult && isErrorResult(pendingActionResult[1]) ? (\n // Up to but not including the boundary\n matches.findIndex((m) => m.route.id === pendingActionResult[0]) - 1\n ) : void 0;\n let pattern = getRoutePattern(matches);\n dsMatches = matches.map((match, index) => {\n if (maxIdx != null && index > maxIdx) {\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n pattern,\n match,\n [],\n requestContext,\n false\n );\n }\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n pattern,\n match,\n [],\n requestContext,\n (match.route.loader || match.route.lazy) != null && (!filterMatchesToLoad || filterMatchesToLoad(match))\n );\n });\n }\n if (!dataStrategy && !dsMatches.some((m) => m.shouldLoad)) {\n return {\n matches,\n loaderData: {},\n errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? {\n [pendingActionResult[0]]: pendingActionResult[1].error\n } : null,\n statusCode: 200,\n loaderHeaders: {}\n };\n }\n let results = await callDataStrategy(\n request,\n dsMatches,\n isRouteRequest,\n requestContext,\n dataStrategy\n );\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest);\n }\n let handlerContext = processRouteLoaderData(\n matches,\n results,\n pendingActionResult,\n true,\n skipLoaderErrorBubbling\n );\n return {\n ...handlerContext,\n matches\n };\n }\n async function callDataStrategy(request, matches, isRouteRequest, requestContext, dataStrategy) {\n let results = await callDataStrategyImpl(\n dataStrategy || defaultDataStrategy,\n request,\n matches,\n null,\n requestContext,\n true\n );\n let dataResults = {};\n await Promise.all(\n matches.map(async (match) => {\n if (!(match.route.id in results)) {\n return;\n }\n let result = results[match.route.id];\n if (isRedirectDataStrategyResult(result)) {\n let response = result.result;\n throw normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n match.route.id,\n matches,\n basename\n );\n }\n if (isRouteRequest) {\n if (isResponse(result.result)) {\n throw result;\n } else if (isDataWithResponseInit(result.result)) {\n throw dataWithResponseInitToResponse(result.result);\n }\n }\n dataResults[match.route.id] = await convertDataStrategyResultToDataResult(result);\n })\n );\n return dataResults;\n }\n return {\n dataRoutes,\n query,\n queryRoute\n };\n}\nfunction getStaticContextFromError(routes, handlerContext, error, boundaryId) {\n let errorBoundaryId = boundaryId || handlerContext._deepestRenderedBoundaryId || routes[0].id;\n return {\n ...handlerContext,\n statusCode: isRouteErrorResponse(error) ? error.status : 500,\n errors: {\n [errorBoundaryId]: error\n }\n };\n}\nfunction throwStaticHandlerAbortedError(request, isRouteRequest) {\n if (request.signal.reason !== void 0) {\n throw request.signal.reason;\n }\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(\n `${method}() call aborted without an \\`AbortSignal.reason\\`: ${request.method} ${request.url}`\n );\n}\nfunction isSubmissionNavigation(opts) {\n return opts != null && (\"formData\" in opts && opts.formData != null || \"body\" in opts && opts.body !== void 0);\n}\nfunction normalizeTo(location, matches, basename, to, fromRouteId, relative) {\n let contextualMatches;\n let activeRouteMatch;\n if (fromRouteId) {\n contextualMatches = [];\n for (let match of matches) {\n contextualMatches.push(match);\n if (match.route.id === fromRouteId) {\n activeRouteMatch = match;\n break;\n }\n }\n } else {\n contextualMatches = matches;\n activeRouteMatch = matches[matches.length - 1];\n }\n let path = resolveTo(\n to ? to : \".\",\n getResolveToMatches(contextualMatches),\n stripBasename(location.pathname, basename) || location.pathname,\n relative === \"path\"\n );\n if (to == null) {\n path.search = location.search;\n path.hash = location.hash;\n }\n if ((to == null || to === \"\" || to === \".\") && activeRouteMatch) {\n let nakedIndex = hasNakedIndexQuery(path.search);\n if (activeRouteMatch.route.index && !nakedIndex) {\n path.search = path.search ? path.search.replace(/^\\?/, \"?index&\") : \"?index\";\n } else if (!activeRouteMatch.route.index && nakedIndex) {\n let params = new URLSearchParams(path.search);\n let indexValues = params.getAll(\"index\");\n params.delete(\"index\");\n indexValues.filter((v) => v).forEach((v) => params.append(\"index\", v));\n let qs = params.toString();\n path.search = qs ? `?${qs}` : \"\";\n }\n }\n if (basename !== \"/\") {\n path.pathname = prependBasename({ basename, pathname: path.pathname });\n }\n return createPath(path);\n}\nfunction normalizeNavigateOptions(isFetcher, path, opts) {\n if (!opts || !isSubmissionNavigation(opts)) {\n return { path };\n }\n if (opts.formMethod && !isValidMethod(opts.formMethod)) {\n return {\n path,\n error: getInternalRouterError(405, { method: opts.formMethod })\n };\n }\n let getInvalidBodyError = () => ({\n path,\n error: getInternalRouterError(400, { type: \"invalid-body\" })\n });\n let rawFormMethod = opts.formMethod || \"get\";\n let formMethod = rawFormMethod.toUpperCase();\n let formAction = stripHashFromPath(path);\n if (opts.body !== void 0) {\n if (opts.formEncType === \"text/plain\") {\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n let text = typeof opts.body === \"string\" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? (\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data\n Array.from(opts.body.entries()).reduce(\n (acc, [name, value]) => `${acc}${name}=${value}\n`,\n \"\"\n )\n ) : String(opts.body);\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: void 0,\n json: void 0,\n text\n }\n };\n } else if (opts.formEncType === \"application/json\") {\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n try {\n let json = typeof opts.body === \"string\" ? JSON.parse(opts.body) : opts.body;\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: void 0,\n json,\n text: void 0\n }\n };\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n }\n invariant(\n typeof FormData === \"function\",\n \"FormData is not available in this environment\"\n );\n let searchParams;\n let formData;\n if (opts.formData) {\n searchParams = convertFormDataToSearchParams(opts.formData);\n formData = opts.formData;\n } else if (opts.body instanceof FormData) {\n searchParams = convertFormDataToSearchParams(opts.body);\n formData = opts.body;\n } else if (opts.body instanceof URLSearchParams) {\n searchParams = opts.body;\n formData = convertSearchParamsToFormData(searchParams);\n } else if (opts.body == null) {\n searchParams = new URLSearchParams();\n formData = new FormData();\n } else {\n try {\n searchParams = new URLSearchParams(opts.body);\n formData = convertSearchParamsToFormData(searchParams);\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n let submission = {\n formMethod,\n formAction,\n formEncType: opts && opts.formEncType || \"application/x-www-form-urlencoded\",\n formData,\n json: void 0,\n text: void 0\n };\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n let parsedPath = parsePath(path);\n if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n return { path: createPath(parsedPath), submission };\n}\nfunction getMatchesToLoad(request, scopedContext, mapRouteProperties2, manifest, history, state, matches, submission, location, lazyRoutePropertiesToSkip, initialHydration, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, hasPatchRoutesOnNavigation, pendingActionResult, callSiteDefaultShouldRevalidate) {\n let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : void 0;\n let currentUrl = history.createURL(state.location);\n let nextUrl = history.createURL(location);\n let maxIdx;\n if (initialHydration && state.errors) {\n let boundaryId = Object.keys(state.errors)[0];\n maxIdx = matches.findIndex((m) => m.route.id === boundaryId);\n } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) {\n let boundaryId = pendingActionResult[0];\n maxIdx = matches.findIndex((m) => m.route.id === boundaryId) - 1;\n }\n let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : void 0;\n let shouldSkipRevalidation = actionStatus && actionStatus >= 400;\n let baseShouldRevalidateArgs = {\n currentUrl,\n currentParams: state.matches[0]?.params || {},\n nextUrl,\n nextParams: matches[0].params,\n ...submission,\n actionResult,\n actionStatus\n };\n let pattern = getRoutePattern(matches);\n let dsMatches = matches.map((match, index) => {\n let { route } = match;\n let forceShouldLoad = null;\n if (maxIdx != null && index > maxIdx) {\n forceShouldLoad = false;\n } else if (route.lazy) {\n forceShouldLoad = true;\n } else if (!routeHasLoaderOrMiddleware(route)) {\n forceShouldLoad = false;\n } else if (initialHydration) {\n forceShouldLoad = shouldLoadRouteOnHydration(\n route,\n state.loaderData,\n state.errors\n );\n } else if (isNewLoader(state.loaderData, state.matches[index], match)) {\n forceShouldLoad = true;\n }\n if (forceShouldLoad !== null) {\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n pattern,\n match,\n lazyRoutePropertiesToSkip,\n scopedContext,\n forceShouldLoad\n );\n }\n let defaultShouldRevalidate = false;\n if (typeof callSiteDefaultShouldRevalidate === \"boolean\") {\n defaultShouldRevalidate = callSiteDefaultShouldRevalidate;\n } else if (shouldSkipRevalidation) {\n defaultShouldRevalidate = false;\n } else if (isRevalidationRequired) {\n defaultShouldRevalidate = true;\n } else if (currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search) {\n defaultShouldRevalidate = true;\n } else if (currentUrl.search !== nextUrl.search) {\n defaultShouldRevalidate = true;\n } else if (isNewRouteInstance(state.matches[index], match)) {\n defaultShouldRevalidate = true;\n }\n let shouldRevalidateArgs = {\n ...baseShouldRevalidateArgs,\n defaultShouldRevalidate\n };\n let shouldLoad = shouldRevalidateLoader(match, shouldRevalidateArgs);\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n pattern,\n match,\n lazyRoutePropertiesToSkip,\n scopedContext,\n shouldLoad,\n shouldRevalidateArgs,\n callSiteDefaultShouldRevalidate\n );\n });\n let revalidatingFetchers = [];\n fetchLoadMatches.forEach((f, key) => {\n if (initialHydration || !matches.some((m) => m.route.id === f.routeId) || fetchersQueuedForDeletion.has(key)) {\n return;\n }\n let fetcher = state.fetchers.get(key);\n let isMidInitialLoad = fetcher && fetcher.state !== \"idle\" && fetcher.data === void 0;\n let fetcherMatches = matchRoutes(routesToUse, f.path, basename);\n if (!fetcherMatches) {\n if (hasPatchRoutesOnNavigation && isMidInitialLoad) {\n return;\n }\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: null,\n match: null,\n request: null,\n controller: null\n });\n return;\n }\n if (fetchRedirectIds.has(key)) {\n return;\n }\n let fetcherMatch = getTargetMatch(fetcherMatches, f.path);\n let fetchController = new AbortController();\n let fetchRequest = createClientSideRequest(\n history,\n f.path,\n fetchController.signal\n );\n let fetcherDsMatches = null;\n if (cancelledFetcherLoads.has(key)) {\n cancelledFetcherLoads.delete(key);\n fetcherDsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n fetcherMatches,\n fetcherMatch,\n lazyRoutePropertiesToSkip,\n scopedContext\n );\n } else if (isMidInitialLoad) {\n if (isRevalidationRequired) {\n fetcherDsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n fetcherMatches,\n fetcherMatch,\n lazyRoutePropertiesToSkip,\n scopedContext\n );\n }\n } else {\n let defaultShouldRevalidate;\n if (typeof callSiteDefaultShouldRevalidate === \"boolean\") {\n defaultShouldRevalidate = callSiteDefaultShouldRevalidate;\n } else if (shouldSkipRevalidation) {\n defaultShouldRevalidate = false;\n } else {\n defaultShouldRevalidate = isRevalidationRequired;\n }\n let shouldRevalidateArgs = {\n ...baseShouldRevalidateArgs,\n defaultShouldRevalidate\n };\n if (shouldRevalidateLoader(fetcherMatch, shouldRevalidateArgs)) {\n fetcherDsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n fetcherMatches,\n fetcherMatch,\n lazyRoutePropertiesToSkip,\n scopedContext,\n shouldRevalidateArgs\n );\n }\n }\n if (fetcherDsMatches) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: fetcherDsMatches,\n match: fetcherMatch,\n request: fetchRequest,\n controller: fetchController\n });\n }\n });\n return { dsMatches, revalidatingFetchers };\n}\nfunction routeHasLoaderOrMiddleware(route) {\n return route.loader != null || route.middleware != null && route.middleware.length > 0;\n}\nfunction shouldLoadRouteOnHydration(route, loaderData, errors) {\n if (route.lazy) {\n return true;\n }\n if (!routeHasLoaderOrMiddleware(route)) {\n return false;\n }\n let hasData = loaderData != null && route.id in loaderData;\n let hasError = errors != null && errors[route.id] !== void 0;\n if (!hasData && hasError) {\n return false;\n }\n if (typeof route.loader === \"function\" && route.loader.hydrate === true) {\n return true;\n }\n return !hasData && !hasError;\n}\nfunction isNewLoader(currentLoaderData, currentMatch, match) {\n let isNew = (\n // [a] -> [a, b]\n !currentMatch || // [a, b] -> [a, c]\n match.route.id !== currentMatch.route.id\n );\n let isMissingData = !currentLoaderData.hasOwnProperty(match.route.id);\n return isNew || isMissingData;\n}\nfunction isNewRouteInstance(currentMatch, match) {\n let currentPath = currentMatch.route.path;\n return (\n // param change for this match, /users/123 -> /users/456\n currentMatch.pathname !== match.pathname || // splat param changed, which is not present in match.path\n // e.g. /files/images/avatar.jpg -> files/finances.xls\n currentPath != null && currentPath.endsWith(\"*\") && currentMatch.params[\"*\"] !== match.params[\"*\"]\n );\n}\nfunction shouldRevalidateLoader(loaderMatch, arg) {\n if (loaderMatch.route.shouldRevalidate) {\n let routeChoice = loaderMatch.route.shouldRevalidate(arg);\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n return arg.defaultShouldRevalidate;\n}\nfunction patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties2, allowElementMutations) {\n let childrenToPatch;\n if (routeId) {\n let route = manifest[routeId];\n invariant(\n route,\n `No route found to patch children into: routeId = ${routeId}`\n );\n if (!route.children) {\n route.children = [];\n }\n childrenToPatch = route.children;\n } else {\n childrenToPatch = routesToUse;\n }\n let uniqueChildren = [];\n let existingChildren = [];\n children.forEach((newRoute) => {\n let existingRoute = childrenToPatch.find(\n (existingRoute2) => isSameRoute(newRoute, existingRoute2)\n );\n if (existingRoute) {\n existingChildren.push({ existingRoute, newRoute });\n } else {\n uniqueChildren.push(newRoute);\n }\n });\n if (uniqueChildren.length > 0) {\n let newRoutes = convertRoutesToDataRoutes(\n uniqueChildren,\n mapRouteProperties2,\n [routeId || \"_\", \"patch\", String(childrenToPatch?.length || \"0\")],\n manifest\n );\n childrenToPatch.push(...newRoutes);\n }\n if (allowElementMutations && existingChildren.length > 0) {\n for (let i = 0; i < existingChildren.length; i++) {\n let { existingRoute, newRoute } = existingChildren[i];\n let existingRouteTyped = existingRoute;\n let [newRouteTyped] = convertRoutesToDataRoutes(\n [newRoute],\n mapRouteProperties2,\n [],\n // Doesn't matter for mutated routes since they already have an id\n {},\n // Don't touch the manifest here since we're updating in place\n true\n );\n Object.assign(existingRouteTyped, {\n element: newRouteTyped.element ? newRouteTyped.element : existingRouteTyped.element,\n errorElement: newRouteTyped.errorElement ? newRouteTyped.errorElement : existingRouteTyped.errorElement,\n hydrateFallbackElement: newRouteTyped.hydrateFallbackElement ? newRouteTyped.hydrateFallbackElement : existingRouteTyped.hydrateFallbackElement\n });\n }\n }\n}\nfunction isSameRoute(newRoute, existingRoute) {\n if (\"id\" in newRoute && \"id\" in existingRoute && newRoute.id === existingRoute.id) {\n return true;\n }\n if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) {\n return false;\n }\n if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) {\n return true;\n }\n return newRoute.children.every(\n (aChild, i) => existingRoute.children?.some((bChild) => isSameRoute(aChild, bChild))\n );\n}\nvar lazyRoutePropertyCache = /* @__PURE__ */ new WeakMap();\nvar loadLazyRouteProperty = ({\n key,\n route,\n manifest,\n mapRouteProperties: mapRouteProperties2\n}) => {\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n if (!routeToUpdate.lazy || typeof routeToUpdate.lazy !== \"object\") {\n return;\n }\n let lazyFn = routeToUpdate.lazy[key];\n if (!lazyFn) {\n return;\n }\n let cache = lazyRoutePropertyCache.get(routeToUpdate);\n if (!cache) {\n cache = {};\n lazyRoutePropertyCache.set(routeToUpdate, cache);\n }\n let cachedPromise = cache[key];\n if (cachedPromise) {\n return cachedPromise;\n }\n let propertyPromise = (async () => {\n let isUnsupported = isUnsupportedLazyRouteObjectKey(key);\n let staticRouteValue = routeToUpdate[key];\n let isStaticallyDefined = staticRouteValue !== void 0 && key !== \"hasErrorBoundary\";\n if (isUnsupported) {\n warning(\n !isUnsupported,\n \"Route property \" + key + \" is not a supported lazy route property. This property will be ignored.\"\n );\n cache[key] = Promise.resolve();\n } else if (isStaticallyDefined) {\n warning(\n false,\n `Route \"${routeToUpdate.id}\" has a static property \"${key}\" defined. The lazy property will be ignored.`\n );\n } else {\n let value = await lazyFn();\n if (value != null) {\n Object.assign(routeToUpdate, { [key]: value });\n Object.assign(routeToUpdate, mapRouteProperties2(routeToUpdate));\n }\n }\n if (typeof routeToUpdate.lazy === \"object\") {\n routeToUpdate.lazy[key] = void 0;\n if (Object.values(routeToUpdate.lazy).every((value) => value === void 0)) {\n routeToUpdate.lazy = void 0;\n }\n }\n })();\n cache[key] = propertyPromise;\n return propertyPromise;\n};\nvar lazyRouteFunctionCache = /* @__PURE__ */ new WeakMap();\nfunction loadLazyRoute(route, type, manifest, mapRouteProperties2, lazyRoutePropertiesToSkip) {\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n if (!route.lazy) {\n return {\n lazyRoutePromise: void 0,\n lazyHandlerPromise: void 0\n };\n }\n if (typeof route.lazy === \"function\") {\n let cachedPromise = lazyRouteFunctionCache.get(routeToUpdate);\n if (cachedPromise) {\n return {\n lazyRoutePromise: cachedPromise,\n lazyHandlerPromise: cachedPromise\n };\n }\n let lazyRoutePromise2 = (async () => {\n invariant(\n typeof route.lazy === \"function\",\n \"No lazy route function found\"\n );\n let lazyRoute = await route.lazy();\n let routeUpdates = {};\n for (let lazyRouteProperty in lazyRoute) {\n let lazyValue = lazyRoute[lazyRouteProperty];\n if (lazyValue === void 0) {\n continue;\n }\n let isUnsupported = isUnsupportedLazyRouteFunctionKey(lazyRouteProperty);\n let staticRouteValue = routeToUpdate[lazyRouteProperty];\n let isStaticallyDefined = staticRouteValue !== void 0 && // This property isn't static since it should always be updated based\n // on the route updates\n lazyRouteProperty !== \"hasErrorBoundary\";\n if (isUnsupported) {\n warning(\n !isUnsupported,\n \"Route property \" + lazyRouteProperty + \" is not a supported property to be returned from a lazy route function. This property will be ignored.\"\n );\n } else if (isStaticallyDefined) {\n warning(\n !isStaticallyDefined,\n `Route \"${routeToUpdate.id}\" has a static property \"${lazyRouteProperty}\" defined but its lazy function is also returning a value for this property. The lazy route property \"${lazyRouteProperty}\" will be ignored.`\n );\n } else {\n routeUpdates[lazyRouteProperty] = lazyValue;\n }\n }\n Object.assign(routeToUpdate, routeUpdates);\n Object.assign(routeToUpdate, {\n // To keep things framework agnostic, we use the provided `mapRouteProperties`\n // function to set the framework-aware properties (`element`/`hasErrorBoundary`)\n // since the logic will differ between frameworks.\n ...mapRouteProperties2(routeToUpdate),\n lazy: void 0\n });\n })();\n lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise2);\n lazyRoutePromise2.catch(() => {\n });\n return {\n lazyRoutePromise: lazyRoutePromise2,\n lazyHandlerPromise: lazyRoutePromise2\n };\n }\n let lazyKeys = Object.keys(route.lazy);\n let lazyPropertyPromises = [];\n let lazyHandlerPromise = void 0;\n for (let key of lazyKeys) {\n if (lazyRoutePropertiesToSkip && lazyRoutePropertiesToSkip.includes(key)) {\n continue;\n }\n let promise = loadLazyRouteProperty({\n key,\n route,\n manifest,\n mapRouteProperties: mapRouteProperties2\n });\n if (promise) {\n lazyPropertyPromises.push(promise);\n if (key === type) {\n lazyHandlerPromise = promise;\n }\n }\n }\n let lazyRoutePromise = lazyPropertyPromises.length > 0 ? Promise.all(lazyPropertyPromises).then(() => {\n }) : void 0;\n lazyRoutePromise?.catch(() => {\n });\n lazyHandlerPromise?.catch(() => {\n });\n return {\n lazyRoutePromise,\n lazyHandlerPromise\n };\n}\nfunction isNonNullable(value) {\n return value !== void 0;\n}\nfunction loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2) {\n let promises = matches.map(({ route }) => {\n if (typeof route.lazy !== \"object\" || !route.lazy.middleware) {\n return void 0;\n }\n return loadLazyRouteProperty({\n key: \"middleware\",\n route,\n manifest,\n mapRouteProperties: mapRouteProperties2\n });\n }).filter(isNonNullable);\n return promises.length > 0 ? Promise.all(promises) : void 0;\n}\nasync function defaultDataStrategy(args) {\n let matchesToLoad = args.matches.filter((m) => m.shouldLoad);\n let keyedResults = {};\n let results = await Promise.all(matchesToLoad.map((m) => m.resolve()));\n results.forEach((result, i) => {\n keyedResults[matchesToLoad[i].route.id] = result;\n });\n return keyedResults;\n}\nasync function defaultDataStrategyWithMiddleware(args) {\n if (!args.matches.some((m) => m.route.middleware)) {\n return defaultDataStrategy(args);\n }\n return runClientMiddlewarePipeline(args, () => defaultDataStrategy(args));\n}\nfunction runServerMiddlewarePipeline(args, handler, errorHandler) {\n return runMiddlewarePipeline(\n args,\n handler,\n processResult,\n isResponse,\n errorHandler\n );\n function processResult(result) {\n return isDataWithResponseInit(result) ? dataWithResponseInitToResponse(result) : result;\n }\n}\nfunction runClientMiddlewarePipeline(args, handler) {\n return runMiddlewarePipeline(\n args,\n handler,\n (r) => {\n if (isRedirectResponse(r)) {\n throw r;\n }\n return r;\n },\n isDataStrategyResults,\n errorHandler\n );\n function errorHandler(error, routeId, nextResult) {\n if (nextResult) {\n return Promise.resolve(\n Object.assign(nextResult.value, {\n [routeId]: { type: \"error\", result: error }\n })\n );\n } else {\n let { matches } = args;\n let maxBoundaryIdx = Math.min(\n // Throwing route\n Math.max(\n matches.findIndex((m) => m.route.id === routeId),\n 0\n ),\n // or the shallowest route that needs to load data\n Math.max(\n matches.findIndex((m) => m.shouldCallHandler()),\n 0\n )\n );\n let boundaryRouteId = findNearestBoundary(\n matches,\n matches[maxBoundaryIdx].route.id\n ).route.id;\n return Promise.resolve({\n [boundaryRouteId]: { type: \"error\", result: error }\n });\n }\n }\n}\nasync function runMiddlewarePipeline(args, handler, processResult, isResult, errorHandler) {\n let { matches, request, params, context, unstable_pattern } = args;\n let tuples = matches.flatMap(\n (m) => m.route.middleware ? m.route.middleware.map((fn) => [m.route.id, fn]) : []\n );\n let result = await callRouteMiddleware(\n {\n request,\n params,\n context,\n unstable_pattern\n },\n tuples,\n handler,\n processResult,\n isResult,\n errorHandler\n );\n return result;\n}\nasync function callRouteMiddleware(args, middlewares, handler, processResult, isResult, errorHandler, idx = 0) {\n let { request } = args;\n if (request.signal.aborted) {\n throw request.signal.reason ?? new Error(`Request aborted: ${request.method} ${request.url}`);\n }\n let tuple = middlewares[idx];\n if (!tuple) {\n let result = await handler();\n return result;\n }\n let [routeId, middleware] = tuple;\n let nextResult;\n let next = async () => {\n if (nextResult) {\n throw new Error(\"You may only call `next()` once per middleware\");\n }\n try {\n let result = await callRouteMiddleware(\n args,\n middlewares,\n handler,\n processResult,\n isResult,\n errorHandler,\n idx + 1\n );\n nextResult = { value: result };\n return nextResult.value;\n } catch (error) {\n nextResult = { value: await errorHandler(error, routeId, nextResult) };\n return nextResult.value;\n }\n };\n try {\n let value = await middleware(args, next);\n let result = value != null ? processResult(value) : void 0;\n if (isResult(result)) {\n return result;\n } else if (nextResult) {\n return result ?? nextResult.value;\n } else {\n nextResult = { value: await next() };\n return nextResult.value;\n }\n } catch (error) {\n let response = await errorHandler(error, routeId, nextResult);\n return response;\n }\n}\nfunction getDataStrategyMatchLazyPromises(mapRouteProperties2, manifest, request, match, lazyRoutePropertiesToSkip) {\n let lazyMiddlewarePromise = loadLazyRouteProperty({\n key: \"middleware\",\n route: match.route,\n manifest,\n mapRouteProperties: mapRouteProperties2\n });\n let lazyRoutePromises = loadLazyRoute(\n match.route,\n isMutationMethod(request.method) ? \"action\" : \"loader\",\n manifest,\n mapRouteProperties2,\n lazyRoutePropertiesToSkip\n );\n return {\n middleware: lazyMiddlewarePromise,\n route: lazyRoutePromises.lazyRoutePromise,\n handler: lazyRoutePromises.lazyHandlerPromise\n };\n}\nfunction getDataStrategyMatch(mapRouteProperties2, manifest, request, unstable_pattern, match, lazyRoutePropertiesToSkip, scopedContext, shouldLoad, shouldRevalidateArgs = null, callSiteDefaultShouldRevalidate) {\n let isUsingNewApi = false;\n let _lazyPromises = getDataStrategyMatchLazyPromises(\n mapRouteProperties2,\n manifest,\n request,\n match,\n lazyRoutePropertiesToSkip\n );\n return {\n ...match,\n _lazyPromises,\n shouldLoad,\n shouldRevalidateArgs,\n shouldCallHandler(defaultShouldRevalidate) {\n isUsingNewApi = true;\n if (!shouldRevalidateArgs) {\n return shouldLoad;\n }\n if (typeof callSiteDefaultShouldRevalidate === \"boolean\") {\n return shouldRevalidateLoader(match, {\n ...shouldRevalidateArgs,\n defaultShouldRevalidate: callSiteDefaultShouldRevalidate\n });\n }\n if (typeof defaultShouldRevalidate === \"boolean\") {\n return shouldRevalidateLoader(match, {\n ...shouldRevalidateArgs,\n defaultShouldRevalidate\n });\n }\n return shouldRevalidateLoader(match, shouldRevalidateArgs);\n },\n resolve(handlerOverride) {\n let { lazy, loader, middleware } = match.route;\n let callHandler = isUsingNewApi || shouldLoad || handlerOverride && !isMutationMethod(request.method) && (lazy || loader);\n let isMiddlewareOnlyRoute = middleware && middleware.length > 0 && !loader && !lazy;\n if (callHandler && (isMutationMethod(request.method) || !isMiddlewareOnlyRoute)) {\n return callLoaderOrAction({\n request,\n unstable_pattern,\n match,\n lazyHandlerPromise: _lazyPromises?.handler,\n lazyRoutePromise: _lazyPromises?.route,\n handlerOverride,\n scopedContext\n });\n }\n return Promise.resolve({ type: \"data\" /* data */, result: void 0 });\n }\n };\n}\nfunction getTargetedDataStrategyMatches(mapRouteProperties2, manifest, request, matches, targetMatch, lazyRoutePropertiesToSkip, scopedContext, shouldRevalidateArgs = null) {\n return matches.map((match) => {\n if (match.route.id !== targetMatch.route.id) {\n return {\n ...match,\n shouldLoad: false,\n shouldRevalidateArgs,\n shouldCallHandler: () => false,\n _lazyPromises: getDataStrategyMatchLazyPromises(\n mapRouteProperties2,\n manifest,\n request,\n match,\n lazyRoutePropertiesToSkip\n ),\n resolve: () => Promise.resolve({ type: \"data\", result: void 0 })\n };\n }\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n getRoutePattern(matches),\n match,\n lazyRoutePropertiesToSkip,\n scopedContext,\n true,\n shouldRevalidateArgs\n );\n });\n}\nasync function callDataStrategyImpl(dataStrategyImpl, request, matches, fetcherKey, scopedContext, isStaticHandler) {\n if (matches.some((m) => m._lazyPromises?.middleware)) {\n await Promise.all(matches.map((m) => m._lazyPromises?.middleware));\n }\n let dataStrategyArgs = {\n request,\n unstable_pattern: getRoutePattern(matches),\n params: matches[0].params,\n context: scopedContext,\n matches\n };\n let runClientMiddleware = isStaticHandler ? () => {\n throw new Error(\n \"You cannot call `runClientMiddleware()` from a static handler `dataStrategy`. Middleware is run outside of `dataStrategy` during SSR in order to bubble up the Response. You can enable middleware via the `respond` API in `query`/`queryRoute`\"\n );\n } : (cb) => {\n let typedDataStrategyArgs = dataStrategyArgs;\n return runClientMiddlewarePipeline(typedDataStrategyArgs, () => {\n return cb({\n ...typedDataStrategyArgs,\n fetcherKey,\n runClientMiddleware: () => {\n throw new Error(\n \"Cannot call `runClientMiddleware()` from within an `runClientMiddleware` handler\"\n );\n }\n });\n });\n };\n let results = await dataStrategyImpl({\n ...dataStrategyArgs,\n fetcherKey,\n runClientMiddleware\n });\n try {\n await Promise.all(\n matches.flatMap((m) => [\n m._lazyPromises?.handler,\n m._lazyPromises?.route\n ])\n );\n } catch (e) {\n }\n return results;\n}\nasync function callLoaderOrAction({\n request,\n unstable_pattern,\n match,\n lazyHandlerPromise,\n lazyRoutePromise,\n handlerOverride,\n scopedContext\n}) {\n let result;\n let onReject;\n let isAction = isMutationMethod(request.method);\n let type = isAction ? \"action\" : \"loader\";\n let runHandler = (handler) => {\n let reject;\n let abortPromise = new Promise((_, r) => reject = r);\n onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n let actualHandler = (ctx) => {\n if (typeof handler !== \"function\") {\n return Promise.reject(\n new Error(\n `You cannot call the handler for a route which defines a boolean \"${type}\" [routeId: ${match.route.id}]`\n )\n );\n }\n return handler(\n {\n request,\n unstable_pattern,\n params: match.params,\n context: scopedContext\n },\n ...ctx !== void 0 ? [ctx] : []\n );\n };\n let handlerPromise = (async () => {\n try {\n let val = await (handlerOverride ? handlerOverride((ctx) => actualHandler(ctx)) : actualHandler());\n return { type: \"data\", result: val };\n } catch (e) {\n return { type: \"error\", result: e };\n }\n })();\n return Promise.race([handlerPromise, abortPromise]);\n };\n try {\n let handler = isAction ? match.route.action : match.route.loader;\n if (lazyHandlerPromise || lazyRoutePromise) {\n if (handler) {\n let handlerError;\n let [value] = await Promise.all([\n // If the handler throws, don't let it immediately bubble out,\n // since we need to let the lazy() execution finish so we know if this\n // route has a boundary that can handle the error\n runHandler(handler).catch((e) => {\n handlerError = e;\n }),\n // Ensure all lazy route promises are resolved before continuing\n lazyHandlerPromise,\n lazyRoutePromise\n ]);\n if (handlerError !== void 0) {\n throw handlerError;\n }\n result = value;\n } else {\n await lazyHandlerPromise;\n let handler2 = isAction ? match.route.action : match.route.loader;\n if (handler2) {\n [result] = await Promise.all([runHandler(handler2), lazyRoutePromise]);\n } else if (type === \"action\") {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(405, {\n method: request.method,\n pathname,\n routeId: match.route.id\n });\n } else {\n return { type: \"data\" /* data */, result: void 0 };\n }\n }\n } else if (!handler) {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(404, {\n pathname\n });\n } else {\n result = await runHandler(handler);\n }\n } catch (e) {\n return { type: \"error\" /* error */, result: e };\n } finally {\n if (onReject) {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n }\n return result;\n}\nasync function parseResponseBody(response) {\n let contentType = response.headers.get(\"Content-Type\");\n if (contentType && /\\bapplication\\/json\\b/.test(contentType)) {\n return response.body == null ? null : response.json();\n }\n return response.text();\n}\nasync function convertDataStrategyResultToDataResult(dataStrategyResult) {\n let { result, type } = dataStrategyResult;\n if (isResponse(result)) {\n let data2;\n try {\n data2 = await parseResponseBody(result);\n } catch (e) {\n return { type: \"error\" /* error */, error: e };\n }\n if (type === \"error\" /* error */) {\n return {\n type: \"error\" /* error */,\n error: new ErrorResponseImpl(result.status, result.statusText, data2),\n statusCode: result.status,\n headers: result.headers\n };\n }\n return {\n type: \"data\" /* data */,\n data: data2,\n statusCode: result.status,\n headers: result.headers\n };\n }\n if (type === \"error\" /* error */) {\n if (isDataWithResponseInit(result)) {\n if (result.data instanceof Error) {\n return {\n type: \"error\" /* error */,\n error: result.data,\n statusCode: result.init?.status,\n headers: result.init?.headers ? new Headers(result.init.headers) : void 0\n };\n }\n return {\n type: \"error\" /* error */,\n error: dataWithResponseInitToErrorResponse(result),\n statusCode: isRouteErrorResponse(result) ? result.status : void 0,\n headers: result.init?.headers ? new Headers(result.init.headers) : void 0\n };\n }\n return {\n type: \"error\" /* error */,\n error: result,\n statusCode: isRouteErrorResponse(result) ? result.status : void 0\n };\n }\n if (isDataWithResponseInit(result)) {\n return {\n type: \"data\" /* data */,\n data: result.data,\n statusCode: result.init?.status,\n headers: result.init?.headers ? new Headers(result.init.headers) : void 0\n };\n }\n return { type: \"data\" /* data */, data: result };\n}\nfunction normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename) {\n let location = response.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n if (!isAbsoluteUrl(location)) {\n let trimmedMatches = matches.slice(\n 0,\n matches.findIndex((m) => m.route.id === routeId) + 1\n );\n location = normalizeTo(\n new URL(request.url),\n trimmedMatches,\n basename,\n location\n );\n response.headers.set(\"Location\", location);\n }\n return response;\n}\nfunction normalizeRedirectLocation(location, currentUrl, basename, historyInstance) {\n let invalidProtocols = [\n \"about:\",\n \"blob:\",\n \"chrome:\",\n \"chrome-untrusted:\",\n \"content:\",\n \"data:\",\n \"devtools:\",\n \"file:\",\n \"filesystem:\",\n // eslint-disable-next-line no-script-url\n \"javascript:\"\n ];\n if (isAbsoluteUrl(location)) {\n let normalizedLocation = location;\n let url = normalizedLocation.startsWith(\"//\") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation);\n if (invalidProtocols.includes(url.protocol)) {\n throw new Error(\"Invalid redirect location\");\n }\n let isSameBasename = stripBasename(url.pathname, basename) != null;\n if (url.origin === currentUrl.origin && isSameBasename) {\n return url.pathname + url.search + url.hash;\n }\n }\n try {\n let url = historyInstance.createURL(location);\n if (invalidProtocols.includes(url.protocol)) {\n throw new Error(\"Invalid redirect location\");\n }\n } catch (e) {\n }\n return location;\n}\nfunction createClientSideRequest(history, location, signal, submission) {\n let url = history.createURL(stripHashFromPath(location)).toString();\n let init = { signal };\n if (submission && isMutationMethod(submission.formMethod)) {\n let { formMethod, formEncType } = submission;\n init.method = formMethod.toUpperCase();\n if (formEncType === \"application/json\") {\n init.headers = new Headers({ \"Content-Type\": formEncType });\n init.body = JSON.stringify(submission.json);\n } else if (formEncType === \"text/plain\") {\n init.body = submission.text;\n } else if (formEncType === \"application/x-www-form-urlencoded\" && submission.formData) {\n init.body = convertFormDataToSearchParams(submission.formData);\n } else {\n init.body = submission.formData;\n }\n }\n return new Request(url, init);\n}\nfunction convertFormDataToSearchParams(formData) {\n let searchParams = new URLSearchParams();\n for (let [key, value] of formData.entries()) {\n searchParams.append(key, typeof value === \"string\" ? value : value.name);\n }\n return searchParams;\n}\nfunction convertSearchParamsToFormData(searchParams) {\n let formData = new FormData();\n for (let [key, value] of searchParams.entries()) {\n formData.append(key, value);\n }\n return formData;\n}\nfunction processRouteLoaderData(matches, results, pendingActionResult, isStaticHandler = false, skipLoaderErrorBubbling = false) {\n let loaderData = {};\n let errors = null;\n let statusCode;\n let foundError = false;\n let loaderHeaders = {};\n let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : void 0;\n matches.forEach((match) => {\n if (!(match.route.id in results)) {\n return;\n }\n let id = match.route.id;\n let result = results[id];\n invariant(\n !isRedirectResult(result),\n \"Cannot handle redirect results in processLoaderData\"\n );\n if (isErrorResult(result)) {\n let error = result.error;\n if (pendingError !== void 0) {\n error = pendingError;\n pendingError = void 0;\n }\n errors = errors || {};\n if (skipLoaderErrorBubbling) {\n errors[id] = error;\n } else {\n let boundaryMatch = findNearestBoundary(matches, id);\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\n }\n }\n if (!isStaticHandler) {\n loaderData[id] = ResetLoaderDataSymbol;\n }\n if (!foundError) {\n foundError = true;\n statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n loaderData[id] = result.data;\n if (result.statusCode && result.statusCode !== 200 && !foundError) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n }\n });\n if (pendingError !== void 0 && pendingActionResult) {\n errors = { [pendingActionResult[0]]: pendingError };\n if (pendingActionResult[2]) {\n loaderData[pendingActionResult[2]] = void 0;\n }\n }\n return {\n loaderData,\n errors,\n statusCode: statusCode || 200,\n loaderHeaders\n };\n}\nfunction processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults) {\n let { loaderData, errors } = processRouteLoaderData(\n matches,\n results,\n pendingActionResult\n );\n revalidatingFetchers.filter((f) => !f.matches || f.matches.some((m) => m.shouldLoad)).forEach((rf) => {\n let { key, match, controller } = rf;\n if (controller && controller.signal.aborted) {\n return;\n }\n let result = fetcherResults[key];\n invariant(result, \"Did not find corresponding fetcher result\");\n if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, match?.route.id);\n if (!(errors && errors[boundaryMatch.route.id])) {\n errors = {\n ...errors,\n [boundaryMatch.route.id]: result.error\n };\n }\n state.fetchers.delete(key);\n } else if (isRedirectResult(result)) {\n invariant(false, \"Unhandled fetcher revalidation redirect\");\n } else {\n let doneFetcher = getDoneFetcher(result.data);\n state.fetchers.set(key, doneFetcher);\n }\n });\n return { loaderData, errors };\n}\nfunction mergeLoaderData(loaderData, newLoaderData, matches, errors) {\n let mergedLoaderData = Object.entries(newLoaderData).filter(([, v]) => v !== ResetLoaderDataSymbol).reduce((merged, [k, v]) => {\n merged[k] = v;\n return merged;\n }, {});\n for (let match of matches) {\n let id = match.route.id;\n if (!newLoaderData.hasOwnProperty(id) && loaderData.hasOwnProperty(id) && match.route.loader) {\n mergedLoaderData[id] = loaderData[id];\n }\n if (errors && errors.hasOwnProperty(id)) {\n break;\n }\n }\n return mergedLoaderData;\n}\nfunction getActionDataForCommit(pendingActionResult) {\n if (!pendingActionResult) {\n return {};\n }\n return isErrorResult(pendingActionResult[1]) ? {\n // Clear out prior actionData on errors\n actionData: {}\n } : {\n actionData: {\n [pendingActionResult[0]]: pendingActionResult[1].data\n }\n };\n}\nfunction findNearestBoundary(matches, routeId) {\n let eligibleMatches = routeId ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1) : [...matches];\n return eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) || matches[0];\n}\nfunction getShortCircuitMatches(routes) {\n let route = routes.length === 1 ? routes[0] : routes.find((r) => r.index || !r.path || r.path === \"/\") || {\n id: `__shim-error-route__`\n };\n return {\n matches: [\n {\n params: {},\n pathname: \"\",\n pathnameBase: \"\",\n route\n }\n ],\n route\n };\n}\nfunction getInternalRouterError(status, {\n pathname,\n routeId,\n method,\n type,\n message\n} = {}) {\n let statusText = \"Unknown Server Error\";\n let errorMessage = \"Unknown @remix-run/router error\";\n if (status === 400) {\n statusText = \"Bad Request\";\n if (method && pathname && routeId) {\n errorMessage = `You made a ${method} request to \"${pathname}\" but did not provide a \\`loader\\` for route \"${routeId}\", so there is no way to handle the request.`;\n } else if (type === \"invalid-body\") {\n errorMessage = \"Unable to encode submission body\";\n }\n } else if (status === 403) {\n statusText = \"Forbidden\";\n errorMessage = `Route \"${routeId}\" does not match URL \"${pathname}\"`;\n } else if (status === 404) {\n statusText = \"Not Found\";\n errorMessage = `No route matches URL \"${pathname}\"`;\n } else if (status === 405) {\n statusText = \"Method Not Allowed\";\n if (method && pathname && routeId) {\n errorMessage = `You made a ${method.toUpperCase()} request to \"${pathname}\" but did not provide an \\`action\\` for route \"${routeId}\", so there is no way to handle the request.`;\n } else if (method) {\n errorMessage = `Invalid request method \"${method.toUpperCase()}\"`;\n }\n }\n return new ErrorResponseImpl(\n status || 500,\n statusText,\n new Error(errorMessage),\n true\n );\n}\nfunction findRedirect(results) {\n let entries = Object.entries(results);\n for (let i = entries.length - 1; i >= 0; i--) {\n let [key, result] = entries[i];\n if (isRedirectResult(result)) {\n return { key, result };\n }\n }\n}\nfunction stripHashFromPath(path) {\n let parsedPath = typeof path === \"string\" ? parsePath(path) : path;\n return createPath({ ...parsedPath, hash: \"\" });\n}\nfunction isHashChangeOnly(a, b) {\n if (a.pathname !== b.pathname || a.search !== b.search) {\n return false;\n }\n if (a.hash === \"\") {\n return b.hash !== \"\";\n } else if (a.hash === b.hash) {\n return true;\n } else if (b.hash !== \"\") {\n return true;\n }\n return false;\n}\nfunction dataWithResponseInitToResponse(data2) {\n return Response.json(data2.data, data2.init ?? void 0);\n}\nfunction dataWithResponseInitToErrorResponse(data2) {\n return new ErrorResponseImpl(\n data2.init?.status ?? 500,\n data2.init?.statusText ?? \"Internal Server Error\",\n data2.data\n );\n}\nfunction isDataStrategyResults(result) {\n return result != null && typeof result === \"object\" && Object.entries(result).every(\n ([key, value]) => typeof key === \"string\" && isDataStrategyResult(value)\n );\n}\nfunction isDataStrategyResult(result) {\n return result != null && typeof result === \"object\" && \"type\" in result && \"result\" in result && (result.type === \"data\" /* data */ || result.type === \"error\" /* error */);\n}\nfunction isRedirectDataStrategyResult(result) {\n return isResponse(result.result) && redirectStatusCodes.has(result.result.status);\n}\nfunction isErrorResult(result) {\n return result.type === \"error\" /* error */;\n}\nfunction isRedirectResult(result) {\n return (result && result.type) === \"redirect\" /* redirect */;\n}\nfunction isDataWithResponseInit(value) {\n return typeof value === \"object\" && value != null && \"type\" in value && \"data\" in value && \"init\" in value && value.type === \"DataWithResponseInit\";\n}\nfunction isResponse(value) {\n return value != null && typeof value.status === \"number\" && typeof value.statusText === \"string\" && typeof value.headers === \"object\" && typeof value.body !== \"undefined\";\n}\nfunction isRedirectStatusCode(statusCode) {\n return redirectStatusCodes.has(statusCode);\n}\nfunction isRedirectResponse(result) {\n return isResponse(result) && isRedirectStatusCode(result.status) && result.headers.has(\"Location\");\n}\nfunction isValidMethod(method) {\n return validRequestMethods.has(method.toUpperCase());\n}\nfunction isMutationMethod(method) {\n return validMutationMethods.has(method.toUpperCase());\n}\nfunction hasNakedIndexQuery(search) {\n return new URLSearchParams(search).getAll(\"index\").some((v) => v === \"\");\n}\nfunction getTargetMatch(matches, location) {\n let search = typeof location === \"string\" ? parsePath(location).search : location.search;\n if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || \"\")) {\n return matches[matches.length - 1];\n }\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches[pathMatches.length - 1];\n}\nfunction getSubmissionFromNavigation(navigation) {\n let { formMethod, formAction, formEncType, text, formData, json } = navigation;\n if (!formMethod || !formAction || !formEncType) {\n return;\n }\n if (text != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: void 0,\n json: void 0,\n text\n };\n } else if (formData != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData,\n json: void 0,\n text: void 0\n };\n } else if (json !== void 0) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: void 0,\n json,\n text: void 0\n };\n }\n}\nfunction getLoadingNavigation(location, submission) {\n if (submission) {\n let navigation = {\n state: \"loading\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text\n };\n return navigation;\n } else {\n let navigation = {\n state: \"loading\",\n location,\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0\n };\n return navigation;\n }\n}\nfunction getSubmittingNavigation(location, submission) {\n let navigation = {\n state: \"submitting\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text\n };\n return navigation;\n}\nfunction getLoadingFetcher(submission, data2) {\n if (submission) {\n let fetcher = {\n state: \"loading\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: data2\n };\n return fetcher;\n } else {\n let fetcher = {\n state: \"loading\",\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0,\n data: data2\n };\n return fetcher;\n }\n}\nfunction getSubmittingFetcher(submission, existingFetcher) {\n let fetcher = {\n state: \"submitting\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: existingFetcher ? existingFetcher.data : void 0\n };\n return fetcher;\n}\nfunction getDoneFetcher(data2) {\n let fetcher = {\n state: \"idle\",\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0,\n data: data2\n };\n return fetcher;\n}\nfunction restoreAppliedTransitions(_window, transitions) {\n try {\n let sessionPositions = _window.sessionStorage.getItem(\n TRANSITIONS_STORAGE_KEY\n );\n if (sessionPositions) {\n let json = JSON.parse(sessionPositions);\n for (let [k, v] of Object.entries(json || {})) {\n if (v && Array.isArray(v)) {\n transitions.set(k, new Set(v || []));\n }\n }\n }\n } catch (e) {\n }\n}\nfunction persistAppliedTransitions(_window, transitions) {\n if (transitions.size > 0) {\n let json = {};\n for (let [k, v] of transitions) {\n json[k] = [...v];\n }\n try {\n _window.sessionStorage.setItem(\n TRANSITIONS_STORAGE_KEY,\n JSON.stringify(json)\n );\n } catch (error) {\n warning(\n false,\n `Failed to save applied view transitions in sessionStorage (${error}).`\n );\n }\n }\n}\nfunction createDeferred() {\n let resolve;\n let reject;\n let promise = new Promise((res, rej) => {\n resolve = async (val) => {\n res(val);\n try {\n await promise;\n } catch (e) {\n }\n };\n reject = async (error) => {\n rej(error);\n try {\n await promise;\n } catch (e) {\n }\n };\n });\n return {\n promise,\n //@ts-ignore\n resolve,\n //@ts-ignore\n reject\n };\n}\n\n// lib/context.ts\nimport * as React from \"react\";\nvar DataRouterContext = React.createContext(null);\nDataRouterContext.displayName = \"DataRouter\";\nvar DataRouterStateContext = React.createContext(null);\nDataRouterStateContext.displayName = \"DataRouterState\";\nvar RSCRouterContext = React.createContext(false);\nfunction useIsRSCRouterContext() {\n return React.useContext(RSCRouterContext);\n}\nvar ViewTransitionContext = React.createContext({\n isTransitioning: false\n});\nViewTransitionContext.displayName = \"ViewTransition\";\nvar FetchersContext = React.createContext(\n /* @__PURE__ */ new Map()\n);\nFetchersContext.displayName = \"Fetchers\";\nvar AwaitContext = React.createContext(null);\nAwaitContext.displayName = \"Await\";\nvar AwaitContextProvider = (props) => React.createElement(AwaitContext.Provider, props);\nvar NavigationContext = React.createContext(\n null\n);\nNavigationContext.displayName = \"Navigation\";\nvar LocationContext = React.createContext(\n null\n);\nLocationContext.displayName = \"Location\";\nvar RouteContext = React.createContext({\n outlet: null,\n matches: [],\n isDataRoute: false\n});\nRouteContext.displayName = \"Route\";\nvar RouteErrorContext = React.createContext(null);\nRouteErrorContext.displayName = \"RouteError\";\nvar ENABLE_DEV_WARNINGS = true;\n\n// lib/hooks.tsx\nimport * as React2 from \"react\";\n\n// lib/errors.ts\nvar ERROR_DIGEST_BASE = \"REACT_ROUTER_ERROR\";\nvar ERROR_DIGEST_REDIRECT = \"REDIRECT\";\nvar ERROR_DIGEST_ROUTE_ERROR_RESPONSE = \"ROUTE_ERROR_RESPONSE\";\nfunction decodeRedirectErrorDigest(digest) {\n if (digest.startsWith(`${ERROR_DIGEST_BASE}:${ERROR_DIGEST_REDIRECT}:{`)) {\n try {\n let parsed = JSON.parse(digest.slice(28));\n if (typeof parsed === \"object\" && parsed && typeof parsed.status === \"number\" && typeof parsed.statusText === \"string\" && typeof parsed.location === \"string\" && typeof parsed.reloadDocument === \"boolean\" && typeof parsed.replace === \"boolean\") {\n return parsed;\n }\n } catch {\n }\n }\n}\nfunction decodeRouteErrorResponseDigest(digest) {\n if (digest.startsWith(\n `${ERROR_DIGEST_BASE}:${ERROR_DIGEST_ROUTE_ERROR_RESPONSE}:{`\n )) {\n try {\n let parsed = JSON.parse(digest.slice(40));\n if (typeof parsed === \"object\" && parsed && typeof parsed.status === \"number\" && typeof parsed.statusText === \"string\") {\n return new ErrorResponseImpl(\n parsed.status,\n parsed.statusText,\n parsed.data\n );\n }\n } catch {\n }\n }\n}\n\n// lib/hooks.tsx\nfunction useHref(to, { relative } = {}) {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useHref() may be used only in the context of a <Router> component.`\n );\n let { basename, navigator } = React2.useContext(NavigationContext);\n let { hash, pathname, search } = useResolvedPath(to, { relative });\n let joinedPathname = pathname;\n if (basename !== \"/\") {\n joinedPathname = pathname === \"/\" ? basename : joinPaths([basename, pathname]);\n }\n return navigator.createHref({ pathname: joinedPathname, search, hash });\n}\nfunction useInRouterContext() {\n return React2.useContext(LocationContext) != null;\n}\nfunction useLocation() {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useLocation() may be used only in the context of a <Router> component.`\n );\n return React2.useContext(LocationContext).location;\n}\nfunction useNavigationType() {\n return React2.useContext(LocationContext).navigationType;\n}\nfunction useMatch(pattern) {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useMatch() may be used only in the context of a <Router> component.`\n );\n let { pathname } = useLocation();\n return React2.useMemo(\n () => matchPath(pattern, decodePath(pathname)),\n [pathname, pattern]\n );\n}\nvar navigateEffectWarning = `You should call navigate() in a React.useEffect(), not when your component is first rendered.`;\nfunction useIsomorphicLayoutEffect(cb) {\n let isStatic = React2.useContext(NavigationContext).static;\n if (!isStatic) {\n React2.useLayoutEffect(cb);\n }\n}\nfunction useNavigate() {\n let { isDataRoute } = React2.useContext(RouteContext);\n return isDataRoute ? useNavigateStable() : useNavigateUnstable();\n}\nfunction useNavigateUnstable() {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useNavigate() may be used only in the context of a <Router> component.`\n );\n let dataRouterContext = React2.useContext(DataRouterContext);\n let { basename, navigator } = React2.useContext(NavigationContext);\n let { matches } = React2.useContext(RouteContext);\n let { pathname: locationPathname } = useLocation();\n let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));\n let activeRef = React2.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React2.useCallback(\n (to, options = {}) => {\n warning(activeRef.current, navigateEffectWarning);\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n navigator.go(to);\n return;\n }\n let path = resolveTo(\n to,\n JSON.parse(routePathnamesJson),\n locationPathname,\n options.relative === \"path\"\n );\n if (dataRouterContext == null && basename !== \"/\") {\n path.pathname = path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n (!!options.replace ? navigator.replace : navigator.push)(\n path,\n options.state,\n options\n );\n },\n [\n basename,\n navigator,\n routePathnamesJson,\n locationPathname,\n dataRouterContext\n ]\n );\n return navigate;\n}\nvar OutletContext = React2.createContext(null);\nfunction useOutletContext() {\n return React2.useContext(OutletContext);\n}\nfunction useOutlet(context) {\n let outlet = React2.useContext(RouteContext).outlet;\n return React2.useMemo(\n () => outlet && /* @__PURE__ */ React2.createElement(OutletContext.Provider, { value: context }, outlet),\n [outlet, context]\n );\n}\nfunction useParams() {\n let { matches } = React2.useContext(RouteContext);\n let routeMatch = matches[matches.length - 1];\n return routeMatch ? routeMatch.params : {};\n}\nfunction useResolvedPath(to, { relative } = {}) {\n let { matches } = React2.useContext(RouteContext);\n let { pathname: locationPathname } = useLocation();\n let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));\n return React2.useMemo(\n () => resolveTo(\n to,\n JSON.parse(routePathnamesJson),\n locationPathname,\n relative === \"path\"\n ),\n [to, routePathnamesJson, locationPathname, relative]\n );\n}\nfunction useRoutes(routes, locationArg) {\n return useRoutesImpl(routes, locationArg);\n}\nfunction useRoutesImpl(routes, locationArg, dataRouterState, onError, future) {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useRoutes() may be used only in the context of a <Router> component.`\n );\n let { navigator } = React2.useContext(NavigationContext);\n let { matches: parentMatches } = React2.useContext(RouteContext);\n let routeMatch = parentMatches[parentMatches.length - 1];\n let parentParams = routeMatch ? routeMatch.params : {};\n let parentPathname = routeMatch ? routeMatch.pathname : \"/\";\n let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : \"/\";\n let parentRoute = routeMatch && routeMatch.route;\n if (ENABLE_DEV_WARNINGS) {\n let parentPath = parentRoute && parentRoute.path || \"\";\n warningOnce(\n parentPathname,\n !parentRoute || parentPath.endsWith(\"*\") || parentPath.endsWith(\"*?\"),\n `You rendered descendant <Routes> (or called \\`useRoutes()\\`) at \"${parentPathname}\" (under <Route path=\"${parentPath}\">) but the parent route path has no trailing \"*\". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.\n\nPlease change the parent <Route path=\"${parentPath}\"> to <Route path=\"${parentPath === \"/\" ? \"*\" : `${parentPath}/*`}\">.`\n );\n }\n let locationFromContext = useLocation();\n let location;\n if (locationArg) {\n let parsedLocationArg = typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n invariant(\n parentPathnameBase === \"/\" || parsedLocationArg.pathname?.startsWith(parentPathnameBase),\n `When overriding the location using \\`<Routes location>\\` or \\`useRoutes(routes, location)\\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is \"${parentPathnameBase}\" but pathname \"${parsedLocationArg.pathname}\" was given in the \\`location\\` prop.`\n );\n location = parsedLocationArg;\n } else {\n location = locationFromContext;\n }\n let pathname = location.pathname || \"/\";\n let remainingPathname = pathname;\n if (parentPathnameBase !== \"/\") {\n let parentSegments = parentPathnameBase.replace(/^\\//, \"\").split(\"/\");\n let segments = pathname.replace(/^\\//, \"\").split(\"/\");\n remainingPathname = \"/\" + segments.slice(parentSegments.length).join(\"/\");\n }\n let matches = matchRoutes(routes, { pathname: remainingPathname });\n if (ENABLE_DEV_WARNINGS) {\n warning(\n parentRoute || matches != null,\n `No routes matched location \"${location.pathname}${location.search}${location.hash}\" `\n );\n warning(\n matches == null || matches[matches.length - 1].route.element !== void 0 || matches[matches.length - 1].route.Component !== void 0 || matches[matches.length - 1].route.lazy !== void 0,\n `Matched leaf route at location \"${location.pathname}${location.search}${location.hash}\" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an \"empty\" page.`\n );\n }\n let renderedMatches = _renderMatches(\n matches && matches.map(\n (match) => Object.assign({}, match, {\n params: Object.assign({}, parentParams, match.params),\n pathname: joinPaths([\n parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes.\n // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses\n // `new URL()` internally and we need to prevent it from treating\n // them as separators\n navigator.encodeLocation ? navigator.encodeLocation(\n match.pathname.replace(/\\?/g, \"%3F\").replace(/#/g, \"%23\")\n ).pathname : match.pathname\n ]),\n pathnameBase: match.pathnameBase === \"/\" ? parentPathnameBase : joinPaths([\n parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes\n // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses\n // `new URL()` internally and we need to prevent it from treating\n // them as separators\n navigator.encodeLocation ? navigator.encodeLocation(\n match.pathnameBase.replace(/\\?/g, \"%3F\").replace(/#/g, \"%23\")\n ).pathname : match.pathnameBase\n ])\n })\n ),\n parentMatches,\n dataRouterState,\n onError,\n future\n );\n if (locationArg && renderedMatches) {\n return /* @__PURE__ */ React2.createElement(\n LocationContext.Provider,\n {\n value: {\n location: {\n pathname: \"/\",\n search: \"\",\n hash: \"\",\n state: null,\n key: \"default\",\n ...location\n },\n navigationType: \"POP\" /* Pop */\n }\n },\n renderedMatches\n );\n }\n return renderedMatches;\n}\nfunction DefaultErrorComponent() {\n let error = useRouteError();\n let message = isRouteErrorResponse(error) ? `${error.status} ${error.statusText}` : error instanceof Error ? error.message : JSON.stringify(error);\n let stack = error instanceof Error ? error.stack : null;\n let lightgrey = \"rgba(200,200,200, 0.5)\";\n let preStyles = { padding: \"0.5rem\", backgroundColor: lightgrey };\n let codeStyles = { padding: \"2px 4px\", backgroundColor: lightgrey };\n let devInfo = null;\n if (ENABLE_DEV_WARNINGS) {\n console.error(\n \"Error handled by React Router default ErrorBoundary:\",\n error\n );\n devInfo = /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(\"p\", null, \"\\u{1F4BF} Hey developer \\u{1F44B}\"), /* @__PURE__ */ React2.createElement(\"p\", null, \"You can provide a way better UX than this when your app throws errors by providing your own \", /* @__PURE__ */ React2.createElement(\"code\", { style: codeStyles }, \"ErrorBoundary\"), \" or\", \" \", /* @__PURE__ */ React2.createElement(\"code\", { style: codeStyles }, \"errorElement\"), \" prop on your route.\"));\n }\n return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(\"h2\", null, \"Unexpected Application Error!\"), /* @__PURE__ */ React2.createElement(\"h3\", { style: { fontStyle: \"italic\" } }, message), stack ? /* @__PURE__ */ React2.createElement(\"pre\", { style: preStyles }, stack) : null, devInfo);\n}\nvar defaultErrorElement = /* @__PURE__ */ React2.createElement(DefaultErrorComponent, null);\nvar RenderErrorBoundary = class extends React2.Component {\n constructor(props) {\n super(props);\n this.state = {\n location: props.location,\n revalidation: props.revalidation,\n error: props.error\n };\n }\n static getDerivedStateFromError(error) {\n return { error };\n }\n static getDerivedStateFromProps(props, state) {\n if (state.location !== props.location || state.revalidation !== \"idle\" && props.revalidation === \"idle\") {\n return {\n error: props.error,\n location: props.location,\n revalidation: props.revalidation\n };\n }\n return {\n error: props.error !== void 0 ? props.error : state.error,\n location: state.location,\n revalidation: props.revalidation || state.revalidation\n };\n }\n componentDidCatch(error, errorInfo) {\n if (this.props.onError) {\n this.props.onError(error, errorInfo);\n } else {\n console.error(\n \"React Router caught the following error during render\",\n error\n );\n }\n }\n render() {\n let error = this.state.error;\n if (this.context && typeof error === \"object\" && error && \"digest\" in error && typeof error.digest === \"string\") {\n const decoded = decodeRouteErrorResponseDigest(error.digest);\n if (decoded) error = decoded;\n }\n let result = error !== void 0 ? /* @__PURE__ */ React2.createElement(RouteContext.Provider, { value: this.props.routeContext }, /* @__PURE__ */ React2.createElement(\n RouteErrorContext.Provider,\n {\n value: error,\n children: this.props.component\n }\n )) : this.props.children;\n if (this.context) {\n return /* @__PURE__ */ React2.createElement(RSCErrorHandler, { error }, result);\n }\n return result;\n }\n};\nRenderErrorBoundary.contextType = RSCRouterContext;\nvar errorRedirectHandledMap = /* @__PURE__ */ new WeakMap();\nfunction RSCErrorHandler({\n children,\n error\n}) {\n let { basename } = React2.useContext(NavigationContext);\n if (typeof error === \"object\" && error && \"digest\" in error && typeof error.digest === \"string\") {\n let redirect2 = decodeRedirectErrorDigest(error.digest);\n if (redirect2) {\n let existingRedirect = errorRedirectHandledMap.get(error);\n if (existingRedirect) throw existingRedirect;\n let parsed = parseToInfo(redirect2.location, basename);\n if (isBrowser && !errorRedirectHandledMap.get(error)) {\n if (parsed.isExternal || redirect2.reloadDocument) {\n window.location.href = parsed.absoluteURL || parsed.to;\n } else {\n const redirectPromise = Promise.resolve().then(\n () => window.__reactRouterDataRouter.navigate(parsed.to, {\n replace: redirect2.replace\n })\n );\n errorRedirectHandledMap.set(error, redirectPromise);\n throw redirectPromise;\n }\n }\n return /* @__PURE__ */ React2.createElement(\n \"meta\",\n {\n httpEquiv: \"refresh\",\n content: `0;url=${parsed.absoluteURL || parsed.to}`\n }\n );\n }\n }\n return children;\n}\nfunction RenderedRoute({ routeContext, match, children }) {\n let dataRouterContext = React2.useContext(DataRouterContext);\n if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {\n dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;\n }\n return /* @__PURE__ */ React2.createElement(RouteContext.Provider, { value: routeContext }, children);\n}\nfunction _renderMatches(matches, parentMatches = [], dataRouterState = null, onErrorHandler = null, future = null) {\n if (matches == null) {\n if (!dataRouterState) {\n return null;\n }\n if (dataRouterState.errors) {\n matches = dataRouterState.matches;\n } else if (parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) {\n matches = dataRouterState.matches;\n } else {\n return null;\n }\n }\n let renderedMatches = matches;\n let errors = dataRouterState?.errors;\n if (errors != null) {\n let errorIndex = renderedMatches.findIndex(\n (m) => m.route.id && errors?.[m.route.id] !== void 0\n );\n invariant(\n errorIndex >= 0,\n `Could not find a matching route for errors on route IDs: ${Object.keys(\n errors\n ).join(\",\")}`\n );\n renderedMatches = renderedMatches.slice(\n 0,\n Math.min(renderedMatches.length, errorIndex + 1)\n );\n }\n let renderFallback = false;\n let fallbackIndex = -1;\n if (dataRouterState) {\n for (let i = 0; i < renderedMatches.length; i++) {\n let match = renderedMatches[i];\n if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {\n fallbackIndex = i;\n }\n if (match.route.id) {\n let { loaderData, errors: errors2 } = dataRouterState;\n let needsToRunLoader = match.route.loader && !loaderData.hasOwnProperty(match.route.id) && (!errors2 || errors2[match.route.id] === void 0);\n if (match.route.lazy || needsToRunLoader) {\n renderFallback = true;\n if (fallbackIndex >= 0) {\n renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);\n } else {\n renderedMatches = [renderedMatches[0]];\n }\n break;\n }\n }\n }\n }\n let onError = dataRouterState && onErrorHandler ? (error, errorInfo) => {\n onErrorHandler(error, {\n location: dataRouterState.location,\n params: dataRouterState.matches?.[0]?.params ?? {},\n unstable_pattern: getRoutePattern(dataRouterState.matches),\n errorInfo\n });\n } : void 0;\n return renderedMatches.reduceRight(\n (outlet, match, index) => {\n let error;\n let shouldRenderHydrateFallback = false;\n let errorElement = null;\n let hydrateFallbackElement = null;\n if (dataRouterState) {\n error = errors && match.route.id ? errors[match.route.id] : void 0;\n errorElement = match.route.errorElement || defaultErrorElement;\n if (renderFallback) {\n if (fallbackIndex < 0 && index === 0) {\n warningOnce(\n \"route-fallback\",\n false,\n \"No `HydrateFallback` element provided to render during initial hydration\"\n );\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = null;\n } else if (fallbackIndex === index) {\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = match.route.hydrateFallbackElement || null;\n }\n }\n }\n let matches2 = parentMatches.concat(renderedMatches.slice(0, index + 1));\n let getChildren = () => {\n let children;\n if (error) {\n children = errorElement;\n } else if (shouldRenderHydrateFallback) {\n children = hydrateFallbackElement;\n } else if (match.route.Component) {\n children = /* @__PURE__ */ React2.createElement(match.route.Component, null);\n } else if (match.route.element) {\n children = match.route.element;\n } else {\n children = outlet;\n }\n return /* @__PURE__ */ React2.createElement(\n RenderedRoute,\n {\n match,\n routeContext: {\n outlet,\n matches: matches2,\n isDataRoute: dataRouterState != null\n },\n children\n }\n );\n };\n return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /* @__PURE__ */ React2.createElement(\n RenderErrorBoundary,\n {\n location: dataRouterState.location,\n revalidation: dataRouterState.revalidation,\n component: errorElement,\n error,\n children: getChildren(),\n routeContext: { outlet: null, matches: matches2, isDataRoute: true },\n onError\n }\n ) : getChildren();\n },\n null\n );\n}\nfunction getDataRouterConsoleError(hookName) {\n return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`;\n}\nfunction useDataRouterContext(hookName) {\n let ctx = React2.useContext(DataRouterContext);\n invariant(ctx, getDataRouterConsoleError(hookName));\n return ctx;\n}\nfunction useDataRouterState(hookName) {\n let state = React2.useContext(DataRouterStateContext);\n invariant(state, getDataRouterConsoleError(hookName));\n return state;\n}\nfunction useRouteContext(hookName) {\n let route = React2.useContext(RouteContext);\n invariant(route, getDataRouterConsoleError(hookName));\n return route;\n}\nfunction useCurrentRouteId(hookName) {\n let route = useRouteContext(hookName);\n let thisRoute = route.matches[route.matches.length - 1];\n invariant(\n thisRoute.route.id,\n `${hookName} can only be used on routes that contain a unique \"id\"`\n );\n return thisRoute.route.id;\n}\nfunction useRouteId() {\n return useCurrentRouteId(\"useRouteId\" /* UseRouteId */);\n}\nfunction useNavigation() {\n let state = useDataRouterState(\"useNavigation\" /* UseNavigation */);\n return state.navigation;\n}\nfunction useRevalidator() {\n let dataRouterContext = useDataRouterContext(\"useRevalidator\" /* UseRevalidator */);\n let state = useDataRouterState(\"useRevalidator\" /* UseRevalidator */);\n let revalidate = React2.useCallback(async () => {\n await dataRouterContext.router.revalidate();\n }, [dataRouterContext.router]);\n return React2.useMemo(\n () => ({ revalidate, state: state.revalidation }),\n [revalidate, state.revalidation]\n );\n}\nfunction useMatches() {\n let { matches, loaderData } = useDataRouterState(\n \"useMatches\" /* UseMatches */\n );\n return React2.useMemo(\n () => matches.map((m) => convertRouteMatchToUiMatch(m, loaderData)),\n [matches, loaderData]\n );\n}\nfunction useLoaderData() {\n let state = useDataRouterState(\"useLoaderData\" /* UseLoaderData */);\n let routeId = useCurrentRouteId(\"useLoaderData\" /* UseLoaderData */);\n return state.loaderData[routeId];\n}\nfunction useRouteLoaderData(routeId) {\n let state = useDataRouterState(\"useRouteLoaderData\" /* UseRouteLoaderData */);\n return state.loaderData[routeId];\n}\nfunction useActionData() {\n let state = useDataRouterState(\"useActionData\" /* UseActionData */);\n let routeId = useCurrentRouteId(\"useLoaderData\" /* UseLoaderData */);\n return state.actionData ? state.actionData[routeId] : void 0;\n}\nfunction useRouteError() {\n let error = React2.useContext(RouteErrorContext);\n let state = useDataRouterState(\"useRouteError\" /* UseRouteError */);\n let routeId = useCurrentRouteId(\"useRouteError\" /* UseRouteError */);\n if (error !== void 0) {\n return error;\n }\n return state.errors?.[routeId];\n}\nfunction useAsyncValue() {\n let value = React2.useContext(AwaitContext);\n return value?._data;\n}\nfunction useAsyncError() {\n let value = React2.useContext(AwaitContext);\n return value?._error;\n}\nvar blockerId = 0;\nfunction useBlocker(shouldBlock) {\n let { router, basename } = useDataRouterContext(\"useBlocker\" /* UseBlocker */);\n let state = useDataRouterState(\"useBlocker\" /* UseBlocker */);\n let [blockerKey, setBlockerKey] = React2.useState(\"\");\n let blockerFunction = React2.useCallback(\n (arg) => {\n if (typeof shouldBlock !== \"function\") {\n return !!shouldBlock;\n }\n if (basename === \"/\") {\n return shouldBlock(arg);\n }\n let { currentLocation, nextLocation, historyAction } = arg;\n return shouldBlock({\n currentLocation: {\n ...currentLocation,\n pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname\n },\n nextLocation: {\n ...nextLocation,\n pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname\n },\n historyAction\n });\n },\n [basename, shouldBlock]\n );\n React2.useEffect(() => {\n let key = String(++blockerId);\n setBlockerKey(key);\n return () => router.deleteBlocker(key);\n }, [router]);\n React2.useEffect(() => {\n if (blockerKey !== \"\") {\n router.getBlocker(blockerKey, blockerFunction);\n }\n }, [router, blockerKey, blockerFunction]);\n return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;\n}\nfunction useNavigateStable() {\n let { router } = useDataRouterContext(\"useNavigate\" /* UseNavigateStable */);\n let id = useCurrentRouteId(\"useNavigate\" /* UseNavigateStable */);\n let activeRef = React2.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React2.useCallback(\n async (to, options = {}) => {\n warning(activeRef.current, navigateEffectWarning);\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n await router.navigate(to);\n } else {\n await router.navigate(to, { fromRouteId: id, ...options });\n }\n },\n [router, id]\n );\n return navigate;\n}\nvar alreadyWarned = {};\nfunction warningOnce(key, cond, message) {\n if (!cond && !alreadyWarned[key]) {\n alreadyWarned[key] = true;\n warning(false, message);\n }\n}\nfunction useRoute(...args) {\n const currentRouteId = useCurrentRouteId(\n \"useRoute\" /* UseRoute */\n );\n const id = args[0] ?? currentRouteId;\n const state = useDataRouterState(\"useRoute\" /* UseRoute */);\n const route = state.matches.find(({ route: route2 }) => route2.id === id);\n if (route === void 0) return void 0;\n return {\n handle: route.route.handle,\n loaderData: state.loaderData[id],\n actionData: state.actionData?.[id]\n };\n}\n\n// lib/components.tsx\nimport * as React3 from \"react\";\n\n// lib/server-runtime/warnings.ts\nvar alreadyWarned2 = {};\nfunction warnOnce(condition, message) {\n if (!condition && !alreadyWarned2[message]) {\n alreadyWarned2[message] = true;\n console.warn(message);\n }\n}\n\n// lib/components.tsx\nvar USE_OPTIMISTIC = \"useOptimistic\";\nvar useOptimisticImpl = React3[USE_OPTIMISTIC];\nvar stableUseOptimisticSetter = () => void 0;\nfunction useOptimisticSafe(val) {\n if (useOptimisticImpl) {\n return useOptimisticImpl(val);\n } else {\n return [val, stableUseOptimisticSetter];\n }\n}\nfunction mapRouteProperties(route) {\n let updates = {\n // Note: this check also occurs in createRoutesFromChildren so update\n // there if you change this -- please and thank you!\n hasErrorBoundary: route.hasErrorBoundary || route.ErrorBoundary != null || route.errorElement != null\n };\n if (route.Component) {\n if (ENABLE_DEV_WARNINGS) {\n if (route.element) {\n warning(\n false,\n \"You should not include both `Component` and `element` on your route - `Component` will be used.\"\n );\n }\n }\n Object.assign(updates, {\n element: React3.createElement(route.Component),\n Component: void 0\n });\n }\n if (route.HydrateFallback) {\n if (ENABLE_DEV_WARNINGS) {\n if (route.hydrateFallbackElement) {\n warning(\n false,\n \"You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used.\"\n );\n }\n }\n Object.assign(updates, {\n hydrateFallbackElement: React3.createElement(route.HydrateFallback),\n HydrateFallback: void 0\n });\n }\n if (route.ErrorBoundary) {\n if (ENABLE_DEV_WARNINGS) {\n if (route.errorElement) {\n warning(\n false,\n \"You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used.\"\n );\n }\n }\n Object.assign(updates, {\n errorElement: React3.createElement(route.ErrorBoundary),\n ErrorBoundary: void 0\n });\n }\n return updates;\n}\nvar hydrationRouteProperties = [\n \"HydrateFallback\",\n \"hydrateFallbackElement\"\n];\nfunction createMemoryRouter(routes, opts) {\n return createRouter({\n basename: opts?.basename,\n getContext: opts?.getContext,\n future: opts?.future,\n history: createMemoryHistory({\n initialEntries: opts?.initialEntries,\n initialIndex: opts?.initialIndex\n }),\n hydrationData: opts?.hydrationData,\n routes,\n hydrationRouteProperties,\n mapRouteProperties,\n dataStrategy: opts?.dataStrategy,\n patchRoutesOnNavigation: opts?.patchRoutesOnNavigation,\n unstable_instrumentations: opts?.unstable_instrumentations\n }).initialize();\n}\nvar Deferred = class {\n constructor() {\n this.status = \"pending\";\n this.promise = new Promise((resolve, reject) => {\n this.resolve = (value) => {\n if (this.status === \"pending\") {\n this.status = \"resolved\";\n resolve(value);\n }\n };\n this.reject = (reason) => {\n if (this.status === \"pending\") {\n this.status = \"rejected\";\n reject(reason);\n }\n };\n });\n }\n};\nfunction RouterProvider({\n router,\n flushSync: reactDomFlushSyncImpl,\n onError,\n unstable_useTransitions\n}) {\n let unstable_rsc = useIsRSCRouterContext();\n unstable_useTransitions = unstable_rsc || unstable_useTransitions;\n let [_state, setStateImpl] = React3.useState(router.state);\n let [state, setOptimisticState] = useOptimisticSafe(_state);\n let [pendingState, setPendingState] = React3.useState();\n let [vtContext, setVtContext] = React3.useState({\n isTransitioning: false\n });\n let [renderDfd, setRenderDfd] = React3.useState();\n let [transition, setTransition] = React3.useState();\n let [interruption, setInterruption] = React3.useState();\n let fetcherData = React3.useRef(/* @__PURE__ */ new Map());\n let setState = React3.useCallback(\n (newState, { deletedFetchers, newErrors, flushSync, viewTransitionOpts }) => {\n if (newErrors && onError) {\n Object.values(newErrors).forEach(\n (error) => onError(error, {\n location: newState.location,\n params: newState.matches[0]?.params ?? {},\n unstable_pattern: getRoutePattern(newState.matches)\n })\n );\n }\n newState.fetchers.forEach((fetcher, key) => {\n if (fetcher.data !== void 0) {\n fetcherData.current.set(key, fetcher.data);\n }\n });\n deletedFetchers.forEach((key) => fetcherData.current.delete(key));\n warnOnce(\n flushSync === false || reactDomFlushSyncImpl != null,\n 'You provided the `flushSync` option to a router update, but you are not using the `<RouterProvider>` from `react-router/dom` so `ReactDOM.flushSync()` is unavailable. Please update your app to `import { RouterProvider } from \"react-router/dom\"` and ensure you have `react-dom` installed as a dependency to use the `flushSync` option.'\n );\n let isViewTransitionAvailable = router.window != null && router.window.document != null && typeof router.window.document.startViewTransition === \"function\";\n warnOnce(\n viewTransitionOpts == null || isViewTransitionAvailable,\n \"You provided the `viewTransition` option to a router update, but you do not appear to be running in a DOM environment as `window.startViewTransition` is not available.\"\n );\n if (!viewTransitionOpts || !isViewTransitionAvailable) {\n if (reactDomFlushSyncImpl && flushSync) {\n reactDomFlushSyncImpl(() => setStateImpl(newState));\n } else if (unstable_useTransitions === false) {\n setStateImpl(newState);\n } else {\n React3.startTransition(() => {\n if (unstable_useTransitions === true) {\n setOptimisticState((s) => getOptimisticRouterState(s, newState));\n }\n setStateImpl(newState);\n });\n }\n return;\n }\n if (reactDomFlushSyncImpl && flushSync) {\n reactDomFlushSyncImpl(() => {\n if (transition) {\n renderDfd?.resolve();\n transition.skipTransition();\n }\n setVtContext({\n isTransitioning: true,\n flushSync: true,\n currentLocation: viewTransitionOpts.currentLocation,\n nextLocation: viewTransitionOpts.nextLocation\n });\n });\n let t = router.window.document.startViewTransition(() => {\n reactDomFlushSyncImpl(() => setStateImpl(newState));\n });\n t.finished.finally(() => {\n reactDomFlushSyncImpl(() => {\n setRenderDfd(void 0);\n setTransition(void 0);\n setPendingState(void 0);\n setVtContext({ isTransitioning: false });\n });\n });\n reactDomFlushSyncImpl(() => setTransition(t));\n return;\n }\n if (transition) {\n renderDfd?.resolve();\n transition.skipTransition();\n setInterruption({\n state: newState,\n currentLocation: viewTransitionOpts.currentLocation,\n nextLocation: viewTransitionOpts.nextLocation\n });\n } else {\n setPendingState(newState);\n setVtContext({\n isTransitioning: true,\n flushSync: false,\n currentLocation: viewTransitionOpts.currentLocation,\n nextLocation: viewTransitionOpts.nextLocation\n });\n }\n },\n [\n router.window,\n reactDomFlushSyncImpl,\n transition,\n renderDfd,\n unstable_useTransitions,\n setOptimisticState,\n onError\n ]\n );\n React3.useLayoutEffect(() => router.subscribe(setState), [router, setState]);\n React3.useEffect(() => {\n if (vtContext.isTransitioning && !vtContext.flushSync) {\n setRenderDfd(new Deferred());\n }\n }, [vtContext]);\n React3.useEffect(() => {\n if (renderDfd && pendingState && router.window) {\n let newState = pendingState;\n let renderPromise = renderDfd.promise;\n let transition2 = router.window.document.startViewTransition(async () => {\n if (unstable_useTransitions === false) {\n setStateImpl(newState);\n } else {\n React3.startTransition(() => {\n if (unstable_useTransitions === true) {\n setOptimisticState((s) => getOptimisticRouterState(s, newState));\n }\n setStateImpl(newState);\n });\n }\n await renderPromise;\n });\n transition2.finished.finally(() => {\n setRenderDfd(void 0);\n setTransition(void 0);\n setPendingState(void 0);\n setVtContext({ isTransitioning: false });\n });\n setTransition(transition2);\n }\n }, [\n pendingState,\n renderDfd,\n router.window,\n unstable_useTransitions,\n setOptimisticState\n ]);\n React3.useEffect(() => {\n if (renderDfd && pendingState && state.location.key === pendingState.location.key) {\n renderDfd.resolve();\n }\n }, [renderDfd, transition, state.location, pendingState]);\n React3.useEffect(() => {\n if (!vtContext.isTransitioning && interruption) {\n setPendingState(interruption.state);\n setVtContext({\n isTransitioning: true,\n flushSync: false,\n currentLocation: interruption.currentLocation,\n nextLocation: interruption.nextLocation\n });\n setInterruption(void 0);\n }\n }, [vtContext.isTransitioning, interruption]);\n let navigator = React3.useMemo(() => {\n return {\n createHref: router.createHref,\n encodeLocation: router.encodeLocation,\n go: (n) => router.navigate(n),\n push: (to, state2, opts) => router.navigate(to, {\n state: state2,\n preventScrollReset: opts?.preventScrollReset\n }),\n replace: (to, state2, opts) => router.navigate(to, {\n replace: true,\n state: state2,\n preventScrollReset: opts?.preventScrollReset\n })\n };\n }, [router]);\n let basename = router.basename || \"/\";\n let dataRouterContext = React3.useMemo(\n () => ({\n router,\n navigator,\n static: false,\n basename,\n onError\n }),\n [router, navigator, basename, onError]\n );\n return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(DataRouterContext.Provider, { value: dataRouterContext }, /* @__PURE__ */ React3.createElement(DataRouterStateContext.Provider, { value: state }, /* @__PURE__ */ React3.createElement(FetchersContext.Provider, { value: fetcherData.current }, /* @__PURE__ */ React3.createElement(ViewTransitionContext.Provider, { value: vtContext }, /* @__PURE__ */ React3.createElement(\n Router,\n {\n basename,\n location: state.location,\n navigationType: state.historyAction,\n navigator,\n unstable_useTransitions\n },\n /* @__PURE__ */ React3.createElement(\n MemoizedDataRoutes,\n {\n routes: router.routes,\n future: router.future,\n state,\n onError\n }\n )\n ))))), null);\n}\nfunction getOptimisticRouterState(currentState, newState) {\n return {\n // Don't surface \"current location specific\" stuff mid-navigation\n // (historyAction, location, matches, loaderData, errors, initialized,\n // restoreScroll, preventScrollReset, blockers, etc.)\n ...currentState,\n // Only surface \"pending/in-flight stuff\"\n // (navigation, revalidation, actionData, fetchers, )\n navigation: newState.navigation.state !== \"idle\" ? newState.navigation : currentState.navigation,\n revalidation: newState.revalidation !== \"idle\" ? newState.revalidation : currentState.revalidation,\n actionData: newState.navigation.state !== \"submitting\" ? newState.actionData : currentState.actionData,\n fetchers: newState.fetchers\n };\n}\nvar MemoizedDataRoutes = React3.memo(DataRoutes);\nfunction DataRoutes({\n routes,\n future,\n state,\n onError\n}) {\n return useRoutesImpl(routes, void 0, state, onError, future);\n}\nfunction MemoryRouter({\n basename,\n children,\n initialEntries,\n initialIndex,\n unstable_useTransitions\n}) {\n let historyRef = React3.useRef();\n if (historyRef.current == null) {\n historyRef.current = createMemoryHistory({\n initialEntries,\n initialIndex,\n v5Compat: true\n });\n }\n let history = historyRef.current;\n let [state, setStateImpl] = React3.useState({\n action: history.action,\n location: history.location\n });\n let setState = React3.useCallback(\n (newState) => {\n if (unstable_useTransitions === false) {\n setStateImpl(newState);\n } else {\n React3.startTransition(() => setStateImpl(newState));\n }\n },\n [unstable_useTransitions]\n );\n React3.useLayoutEffect(() => history.listen(setState), [history, setState]);\n return /* @__PURE__ */ React3.createElement(\n Router,\n {\n basename,\n children,\n location: state.location,\n navigationType: state.action,\n navigator: history,\n unstable_useTransitions\n }\n );\n}\nfunction Navigate({\n to,\n replace: replace2,\n state,\n relative\n}) {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of\n // the router loaded. We can help them understand how to avoid that.\n `<Navigate> may be used only in the context of a <Router> component.`\n );\n let { static: isStatic } = React3.useContext(NavigationContext);\n warning(\n !isStatic,\n `<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.`\n );\n let { matches } = React3.useContext(RouteContext);\n let { pathname: locationPathname } = useLocation();\n let navigate = useNavigate();\n let path = resolveTo(\n to,\n getResolveToMatches(matches),\n locationPathname,\n relative === \"path\"\n );\n let jsonPath = JSON.stringify(path);\n React3.useEffect(() => {\n navigate(JSON.parse(jsonPath), { replace: replace2, state, relative });\n }, [navigate, jsonPath, relative, replace2, state]);\n return null;\n}\nfunction Outlet(props) {\n return useOutlet(props.context);\n}\nfunction Route(props) {\n invariant(\n false,\n `A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.`\n );\n}\nfunction Router({\n basename: basenameProp = \"/\",\n children = null,\n location: locationProp,\n navigationType = \"POP\" /* Pop */,\n navigator,\n static: staticProp = false,\n unstable_useTransitions\n}) {\n invariant(\n !useInRouterContext(),\n `You cannot render a <Router> inside another <Router>. You should never have more than one in your app.`\n );\n let basename = basenameProp.replace(/^\\/*/, \"/\");\n let navigationContext = React3.useMemo(\n () => ({\n basename,\n navigator,\n static: staticProp,\n unstable_useTransitions,\n future: {}\n }),\n [basename, navigator, staticProp, unstable_useTransitions]\n );\n if (typeof locationProp === \"string\") {\n locationProp = parsePath(locationProp);\n }\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n state = null,\n key = \"default\"\n } = locationProp;\n let locationContext = React3.useMemo(() => {\n let trailingPathname = stripBasename(pathname, basename);\n if (trailingPathname == null) {\n return null;\n }\n return {\n location: {\n pathname: trailingPathname,\n search,\n hash,\n state,\n key\n },\n navigationType\n };\n }, [basename, pathname, search, hash, state, key, navigationType]);\n warning(\n locationContext != null,\n `<Router basename=\"${basename}\"> is not able to match the URL \"${pathname}${search}${hash}\" because it does not start with the basename, so the <Router> won't render anything.`\n );\n if (locationContext == null) {\n return null;\n }\n return /* @__PURE__ */ React3.createElement(NavigationContext.Provider, { value: navigationContext }, /* @__PURE__ */ React3.createElement(LocationContext.Provider, { children, value: locationContext }));\n}\nfunction Routes({\n children,\n location\n}) {\n return useRoutes(createRoutesFromChildren(children), location);\n}\nfunction Await({\n children,\n errorElement,\n resolve\n}) {\n let dataRouterContext = React3.useContext(DataRouterContext);\n let dataRouterStateContext = React3.useContext(DataRouterStateContext);\n let onError = React3.useCallback(\n (error, errorInfo) => {\n if (dataRouterContext && dataRouterContext.onError && dataRouterStateContext) {\n dataRouterContext.onError(error, {\n location: dataRouterStateContext.location,\n params: dataRouterStateContext.matches[0]?.params || {},\n unstable_pattern: getRoutePattern(dataRouterStateContext.matches),\n errorInfo\n });\n }\n },\n [dataRouterContext, dataRouterStateContext]\n );\n return /* @__PURE__ */ React3.createElement(\n AwaitErrorBoundary,\n {\n resolve,\n errorElement,\n onError\n },\n /* @__PURE__ */ React3.createElement(ResolveAwait, null, children)\n );\n}\nvar AwaitErrorBoundary = class extends React3.Component {\n constructor(props) {\n super(props);\n this.state = { error: null };\n }\n static getDerivedStateFromError(error) {\n return { error };\n }\n componentDidCatch(error, errorInfo) {\n if (this.props.onError) {\n this.props.onError(error, errorInfo);\n } else {\n console.error(\n \"<Await> caught the following error during render\",\n error,\n errorInfo\n );\n }\n }\n render() {\n let { children, errorElement, resolve } = this.props;\n let promise = null;\n let status = 0 /* pending */;\n if (!(resolve instanceof Promise)) {\n status = 1 /* success */;\n promise = Promise.resolve();\n Object.defineProperty(promise, \"_tracked\", { get: () => true });\n Object.defineProperty(promise, \"_data\", { get: () => resolve });\n } else if (this.state.error) {\n status = 2 /* error */;\n let renderError = this.state.error;\n promise = Promise.reject().catch(() => {\n });\n Object.defineProperty(promise, \"_tracked\", { get: () => true });\n Object.defineProperty(promise, \"_error\", { get: () => renderError });\n } else if (resolve._tracked) {\n promise = resolve;\n status = \"_error\" in promise ? 2 /* error */ : \"_data\" in promise ? 1 /* success */ : 0 /* pending */;\n } else {\n status = 0 /* pending */;\n Object.defineProperty(resolve, \"_tracked\", { get: () => true });\n promise = resolve.then(\n (data2) => Object.defineProperty(resolve, \"_data\", { get: () => data2 }),\n (error) => {\n this.props.onError?.(error);\n Object.defineProperty(resolve, \"_error\", { get: () => error });\n }\n );\n }\n if (status === 2 /* error */ && !errorElement) {\n throw promise._error;\n }\n if (status === 2 /* error */) {\n return /* @__PURE__ */ React3.createElement(AwaitContext.Provider, { value: promise, children: errorElement });\n }\n if (status === 1 /* success */) {\n return /* @__PURE__ */ React3.createElement(AwaitContext.Provider, { value: promise, children });\n }\n throw promise;\n }\n};\nfunction ResolveAwait({\n children\n}) {\n let data2 = useAsyncValue();\n let toRender = typeof children === \"function\" ? children(data2) : children;\n return /* @__PURE__ */ React3.createElement(React3.Fragment, null, toRender);\n}\nfunction createRoutesFromChildren(children, parentPath = []) {\n let routes = [];\n React3.Children.forEach(children, (element, index) => {\n if (!React3.isValidElement(element)) {\n return;\n }\n let treePath = [...parentPath, index];\n if (element.type === React3.Fragment) {\n routes.push.apply(\n routes,\n createRoutesFromChildren(element.props.children, treePath)\n );\n return;\n }\n invariant(\n element.type === Route,\n `[${typeof element.type === \"string\" ? element.type : element.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`\n );\n invariant(\n !element.props.index || !element.props.children,\n \"An index route cannot have child routes.\"\n );\n let route = {\n id: element.props.id || treePath.join(\"-\"),\n caseSensitive: element.props.caseSensitive,\n element: element.props.element,\n Component: element.props.Component,\n index: element.props.index,\n path: element.props.path,\n middleware: element.props.middleware,\n loader: element.props.loader,\n action: element.props.action,\n hydrateFallbackElement: element.props.hydrateFallbackElement,\n HydrateFallback: element.props.HydrateFallback,\n errorElement: element.props.errorElement,\n ErrorBoundary: element.props.ErrorBoundary,\n hasErrorBoundary: element.props.hasErrorBoundary === true || element.props.ErrorBoundary != null || element.props.errorElement != null,\n shouldRevalidate: element.props.shouldRevalidate,\n handle: element.props.handle,\n lazy: element.props.lazy\n };\n if (element.props.children) {\n route.children = createRoutesFromChildren(\n element.props.children,\n treePath\n );\n }\n routes.push(route);\n });\n return routes;\n}\nvar createRoutesFromElements = createRoutesFromChildren;\nfunction renderMatches(matches) {\n return _renderMatches(matches);\n}\nfunction useRouteComponentProps() {\n return {\n params: useParams(),\n loaderData: useLoaderData(),\n actionData: useActionData(),\n matches: useMatches()\n };\n}\nfunction WithComponentProps({\n children\n}) {\n const props = useRouteComponentProps();\n return React3.cloneElement(children, props);\n}\nfunction withComponentProps(Component4) {\n return function WithComponentProps2() {\n const props = useRouteComponentProps();\n return React3.createElement(Component4, props);\n };\n}\nfunction useHydrateFallbackProps() {\n return {\n params: useParams(),\n loaderData: useLoaderData(),\n actionData: useActionData()\n };\n}\nfunction WithHydrateFallbackProps({\n children\n}) {\n const props = useHydrateFallbackProps();\n return React3.cloneElement(children, props);\n}\nfunction withHydrateFallbackProps(HydrateFallback) {\n return function WithHydrateFallbackProps2() {\n const props = useHydrateFallbackProps();\n return React3.createElement(HydrateFallback, props);\n };\n}\nfunction useErrorBoundaryProps() {\n return {\n params: useParams(),\n loaderData: useLoaderData(),\n actionData: useActionData(),\n error: useRouteError()\n };\n}\nfunction WithErrorBoundaryProps({\n children\n}) {\n const props = useErrorBoundaryProps();\n return React3.cloneElement(children, props);\n}\nfunction withErrorBoundaryProps(ErrorBoundary) {\n return function WithErrorBoundaryProps2() {\n const props = useErrorBoundaryProps();\n return React3.createElement(ErrorBoundary, props);\n };\n}\n\n// lib/dom/dom.ts\nvar defaultMethod = \"get\";\nvar defaultEncType = \"application/x-www-form-urlencoded\";\nfunction isHtmlElement(object) {\n return typeof HTMLElement !== \"undefined\" && object instanceof HTMLElement;\n}\nfunction isButtonElement(object) {\n return isHtmlElement(object) && object.tagName.toLowerCase() === \"button\";\n}\nfunction isFormElement(object) {\n return isHtmlElement(object) && object.tagName.toLowerCase() === \"form\";\n}\nfunction isInputElement(object) {\n return isHtmlElement(object) && object.tagName.toLowerCase() === \"input\";\n}\nfunction isModifiedEvent(event) {\n return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);\n}\nfunction shouldProcessLinkClick(event, target) {\n return event.button === 0 && // Ignore everything but left clicks\n (!target || target === \"_self\") && // Let browser handle \"target=_blank\" etc.\n !isModifiedEvent(event);\n}\nfunction createSearchParams(init = \"\") {\n return new URLSearchParams(\n typeof init === \"string\" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo2, key) => {\n let value = init[key];\n return memo2.concat(\n Array.isArray(value) ? value.map((v) => [key, v]) : [[key, value]]\n );\n }, [])\n );\n}\nfunction getSearchParamsForLocation(locationSearch, defaultSearchParams) {\n let searchParams = createSearchParams(locationSearch);\n if (defaultSearchParams) {\n defaultSearchParams.forEach((_, key) => {\n if (!searchParams.has(key)) {\n defaultSearchParams.getAll(key).forEach((value) => {\n searchParams.append(key, value);\n });\n }\n });\n }\n return searchParams;\n}\nvar _formDataSupportsSubmitter = null;\nfunction isFormDataSubmitterSupported() {\n if (_formDataSupportsSubmitter === null) {\n try {\n new FormData(\n document.createElement(\"form\"),\n // @ts-expect-error if FormData supports the submitter parameter, this will throw\n 0\n );\n _formDataSupportsSubmitter = false;\n } catch (e) {\n _formDataSupportsSubmitter = true;\n }\n }\n return _formDataSupportsSubmitter;\n}\nvar supportedFormEncTypes = /* @__PURE__ */ new Set([\n \"application/x-www-form-urlencoded\",\n \"multipart/form-data\",\n \"text/plain\"\n]);\nfunction getFormEncType(encType) {\n if (encType != null && !supportedFormEncTypes.has(encType)) {\n warning(\n false,\n `\"${encType}\" is not a valid \\`encType\\` for \\`<Form>\\`/\\`<fetcher.Form>\\` and will default to \"${defaultEncType}\"`\n );\n return null;\n }\n return encType;\n}\nfunction getFormSubmissionInfo(target, basename) {\n let method;\n let action;\n let encType;\n let formData;\n let body;\n if (isFormElement(target)) {\n let attr = target.getAttribute(\"action\");\n action = attr ? stripBasename(attr, basename) : null;\n method = target.getAttribute(\"method\") || defaultMethod;\n encType = getFormEncType(target.getAttribute(\"enctype\")) || defaultEncType;\n formData = new FormData(target);\n } else if (isButtonElement(target) || isInputElement(target) && (target.type === \"submit\" || target.type === \"image\")) {\n let form = target.form;\n if (form == null) {\n throw new Error(\n `Cannot submit a <button> or <input type=\"submit\"> without a <form>`\n );\n }\n let attr = target.getAttribute(\"formaction\") || form.getAttribute(\"action\");\n action = attr ? stripBasename(attr, basename) : null;\n method = target.getAttribute(\"formmethod\") || form.getAttribute(\"method\") || defaultMethod;\n encType = getFormEncType(target.getAttribute(\"formenctype\")) || getFormEncType(form.getAttribute(\"enctype\")) || defaultEncType;\n formData = new FormData(form, target);\n if (!isFormDataSubmitterSupported()) {\n let { name, type, value } = target;\n if (type === \"image\") {\n let prefix = name ? `${name}.` : \"\";\n formData.append(`${prefix}x`, \"0\");\n formData.append(`${prefix}y`, \"0\");\n } else if (name) {\n formData.append(name, value);\n }\n }\n } else if (isHtmlElement(target)) {\n throw new Error(\n `Cannot submit element that is not <form>, <button>, or <input type=\"submit|image\">`\n );\n } else {\n method = defaultMethod;\n action = null;\n encType = defaultEncType;\n body = target;\n }\n if (formData && encType === \"text/plain\") {\n body = formData;\n formData = void 0;\n }\n return { action, method: method.toLowerCase(), encType, formData, body };\n}\n\n// lib/dom/ssr/single-fetch.tsx\nimport * as React4 from \"react\";\n\n// vendor/turbo-stream-v2/utils.ts\nvar HOLE = -1;\nvar NAN = -2;\nvar NEGATIVE_INFINITY = -3;\nvar NEGATIVE_ZERO = -4;\nvar NULL = -5;\nvar POSITIVE_INFINITY = -6;\nvar UNDEFINED = -7;\nvar TYPE_BIGINT = \"B\";\nvar TYPE_DATE = \"D\";\nvar TYPE_ERROR = \"E\";\nvar TYPE_MAP = \"M\";\nvar TYPE_NULL_OBJECT = \"N\";\nvar TYPE_PROMISE = \"P\";\nvar TYPE_REGEXP = \"R\";\nvar TYPE_SET = \"S\";\nvar TYPE_SYMBOL = \"Y\";\nvar TYPE_URL = \"U\";\nvar TYPE_PREVIOUS_RESOLVED = \"Z\";\nvar Deferred2 = class {\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n }\n};\nfunction createLineSplittingTransform() {\n const decoder = new TextDecoder();\n let leftover = \"\";\n return new TransformStream({\n transform(chunk, controller) {\n const str = decoder.decode(chunk, { stream: true });\n const parts = (leftover + str).split(\"\\n\");\n leftover = parts.pop() || \"\";\n for (const part of parts) {\n controller.enqueue(part);\n }\n },\n flush(controller) {\n if (leftover) {\n controller.enqueue(leftover);\n }\n }\n });\n}\n\n// vendor/turbo-stream-v2/flatten.ts\nfunction flatten(input) {\n const { indices } = this;\n const existing = indices.get(input);\n if (existing) return [existing];\n if (input === void 0) return UNDEFINED;\n if (input === null) return NULL;\n if (Number.isNaN(input)) return NAN;\n if (input === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY;\n if (input === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY;\n if (input === 0 && 1 / input < 0) return NEGATIVE_ZERO;\n const index = this.index++;\n indices.set(input, index);\n stringify.call(this, input, index);\n return index;\n}\nfunction stringify(input, index) {\n const { deferred, plugins, postPlugins } = this;\n const str = this.stringified;\n const stack = [[input, index]];\n while (stack.length > 0) {\n const [input2, index2] = stack.pop();\n const partsForObj = (obj) => Object.keys(obj).map((k) => `\"_${flatten.call(this, k)}\":${flatten.call(this, obj[k])}`).join(\",\");\n let error = null;\n switch (typeof input2) {\n case \"boolean\":\n case \"number\":\n case \"string\":\n str[index2] = JSON.stringify(input2);\n break;\n case \"bigint\":\n str[index2] = `[\"${TYPE_BIGINT}\",\"${input2}\"]`;\n break;\n case \"symbol\": {\n const keyFor = Symbol.keyFor(input2);\n if (!keyFor) {\n error = new Error(\n \"Cannot encode symbol unless created with Symbol.for()\"\n );\n } else {\n str[index2] = `[\"${TYPE_SYMBOL}\",${JSON.stringify(keyFor)}]`;\n }\n break;\n }\n case \"object\": {\n if (!input2) {\n str[index2] = `${NULL}`;\n break;\n }\n const isArray = Array.isArray(input2);\n let pluginHandled = false;\n if (!isArray && plugins) {\n for (const plugin of plugins) {\n const pluginResult = plugin(input2);\n if (Array.isArray(pluginResult)) {\n pluginHandled = true;\n const [pluginIdentifier, ...rest] = pluginResult;\n str[index2] = `[${JSON.stringify(pluginIdentifier)}`;\n if (rest.length > 0) {\n str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(\",\")}`;\n }\n str[index2] += \"]\";\n break;\n }\n }\n }\n if (!pluginHandled) {\n let result = isArray ? \"[\" : \"{\";\n if (isArray) {\n for (let i = 0; i < input2.length; i++)\n result += (i ? \",\" : \"\") + (i in input2 ? flatten.call(this, input2[i]) : HOLE);\n str[index2] = `${result}]`;\n } else if (input2 instanceof Date) {\n const dateTime = input2.getTime();\n str[index2] = `[\"${TYPE_DATE}\",${Number.isNaN(dateTime) ? JSON.stringify(\"invalid\") : dateTime}]`;\n } else if (input2 instanceof URL) {\n str[index2] = `[\"${TYPE_URL}\",${JSON.stringify(input2.href)}]`;\n } else if (input2 instanceof RegExp) {\n str[index2] = `[\"${TYPE_REGEXP}\",${JSON.stringify(\n input2.source\n )},${JSON.stringify(input2.flags)}]`;\n } else if (input2 instanceof Set) {\n if (input2.size > 0) {\n str[index2] = `[\"${TYPE_SET}\",${[...input2].map((val) => flatten.call(this, val)).join(\",\")}]`;\n } else {\n str[index2] = `[\"${TYPE_SET}\"]`;\n }\n } else if (input2 instanceof Map) {\n if (input2.size > 0) {\n str[index2] = `[\"${TYPE_MAP}\",${[...input2].flatMap(([k, v]) => [\n flatten.call(this, k),\n flatten.call(this, v)\n ]).join(\",\")}]`;\n } else {\n str[index2] = `[\"${TYPE_MAP}\"]`;\n }\n } else if (input2 instanceof Promise) {\n str[index2] = `[\"${TYPE_PROMISE}\",${index2}]`;\n deferred[index2] = input2;\n } else if (input2 instanceof Error) {\n str[index2] = `[\"${TYPE_ERROR}\",${JSON.stringify(input2.message)}`;\n if (input2.name !== \"Error\") {\n str[index2] += `,${JSON.stringify(input2.name)}`;\n }\n str[index2] += \"]\";\n } else if (Object.getPrototypeOf(input2) === null) {\n str[index2] = `[\"${TYPE_NULL_OBJECT}\",{${partsForObj(input2)}}]`;\n } else if (isPlainObject2(input2)) {\n str[index2] = `{${partsForObj(input2)}}`;\n } else {\n error = new Error(\"Cannot encode object with prototype\");\n }\n }\n break;\n }\n default: {\n const isArray = Array.isArray(input2);\n let pluginHandled = false;\n if (!isArray && plugins) {\n for (const plugin of plugins) {\n const pluginResult = plugin(input2);\n if (Array.isArray(pluginResult)) {\n pluginHandled = true;\n const [pluginIdentifier, ...rest] = pluginResult;\n str[index2] = `[${JSON.stringify(pluginIdentifier)}`;\n if (rest.length > 0) {\n str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(\",\")}`;\n }\n str[index2] += \"]\";\n break;\n }\n }\n }\n if (!pluginHandled) {\n error = new Error(\"Cannot encode function or unexpected type\");\n }\n }\n }\n if (error) {\n let pluginHandled = false;\n if (postPlugins) {\n for (const plugin of postPlugins) {\n const pluginResult = plugin(input2);\n if (Array.isArray(pluginResult)) {\n pluginHandled = true;\n const [pluginIdentifier, ...rest] = pluginResult;\n str[index2] = `[${JSON.stringify(pluginIdentifier)}`;\n if (rest.length > 0) {\n str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(\",\")}`;\n }\n str[index2] += \"]\";\n break;\n }\n }\n }\n if (!pluginHandled) {\n throw error;\n }\n }\n }\n}\nvar objectProtoNames2 = Object.getOwnPropertyNames(Object.prototype).sort().join(\"\\0\");\nfunction isPlainObject2(thing) {\n const proto = Object.getPrototypeOf(thing);\n return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join(\"\\0\") === objectProtoNames2;\n}\n\n// vendor/turbo-stream-v2/unflatten.ts\nvar globalObj = typeof window !== \"undefined\" ? window : typeof globalThis !== \"undefined\" ? globalThis : void 0;\nfunction unflatten(parsed) {\n const { hydrated, values } = this;\n if (typeof parsed === \"number\") return hydrate.call(this, parsed);\n if (!Array.isArray(parsed) || !parsed.length) throw new SyntaxError();\n const startIndex = values.length;\n for (const value of parsed) {\n values.push(value);\n }\n hydrated.length = values.length;\n return hydrate.call(this, startIndex);\n}\nfunction hydrate(index) {\n const { hydrated, values, deferred, plugins } = this;\n let result;\n const stack = [\n [\n index,\n (v) => {\n result = v;\n }\n ]\n ];\n let postRun = [];\n while (stack.length > 0) {\n const [index2, set] = stack.pop();\n switch (index2) {\n case UNDEFINED:\n set(void 0);\n continue;\n case NULL:\n set(null);\n continue;\n case NAN:\n set(NaN);\n continue;\n case POSITIVE_INFINITY:\n set(Infinity);\n continue;\n case NEGATIVE_INFINITY:\n set(-Infinity);\n continue;\n case NEGATIVE_ZERO:\n set(-0);\n continue;\n }\n if (hydrated[index2]) {\n set(hydrated[index2]);\n continue;\n }\n const value = values[index2];\n if (!value || typeof value !== \"object\") {\n hydrated[index2] = value;\n set(value);\n continue;\n }\n if (Array.isArray(value)) {\n if (typeof value[0] === \"string\") {\n const [type, b, c] = value;\n switch (type) {\n case TYPE_DATE:\n set(hydrated[index2] = new Date(b));\n continue;\n case TYPE_URL:\n set(hydrated[index2] = new URL(b));\n continue;\n case TYPE_BIGINT:\n set(hydrated[index2] = BigInt(b));\n continue;\n case TYPE_REGEXP:\n set(hydrated[index2] = new RegExp(b, c));\n continue;\n case TYPE_SYMBOL:\n set(hydrated[index2] = Symbol.for(b));\n continue;\n case TYPE_SET:\n const newSet = /* @__PURE__ */ new Set();\n hydrated[index2] = newSet;\n for (let i = value.length - 1; i > 0; i--)\n stack.push([\n value[i],\n (v) => {\n newSet.add(v);\n }\n ]);\n set(newSet);\n continue;\n case TYPE_MAP:\n const map = /* @__PURE__ */ new Map();\n hydrated[index2] = map;\n for (let i = value.length - 2; i > 0; i -= 2) {\n const r = [];\n stack.push([\n value[i + 1],\n (v) => {\n r[1] = v;\n }\n ]);\n stack.push([\n value[i],\n (k) => {\n r[0] = k;\n }\n ]);\n postRun.push(() => {\n map.set(r[0], r[1]);\n });\n }\n set(map);\n continue;\n case TYPE_NULL_OBJECT:\n const obj = /* @__PURE__ */ Object.create(null);\n hydrated[index2] = obj;\n for (const key of Object.keys(b).reverse()) {\n const r = [];\n stack.push([\n b[key],\n (v) => {\n r[1] = v;\n }\n ]);\n stack.push([\n Number(key.slice(1)),\n (k) => {\n r[0] = k;\n }\n ]);\n postRun.push(() => {\n obj[r[0]] = r[1];\n });\n }\n set(obj);\n continue;\n case TYPE_PROMISE:\n if (hydrated[b]) {\n set(hydrated[index2] = hydrated[b]);\n } else {\n const d = new Deferred2();\n deferred[b] = d;\n set(hydrated[index2] = d.promise);\n }\n continue;\n case TYPE_ERROR:\n const [, message, errorType] = value;\n let error = errorType && globalObj && globalObj[errorType] ? new globalObj[errorType](message) : new Error(message);\n hydrated[index2] = error;\n set(error);\n continue;\n case TYPE_PREVIOUS_RESOLVED:\n set(hydrated[index2] = hydrated[b]);\n continue;\n default:\n if (Array.isArray(plugins)) {\n const r = [];\n const vals = value.slice(1);\n for (let i = 0; i < vals.length; i++) {\n const v = vals[i];\n stack.push([\n v,\n (v2) => {\n r[i] = v2;\n }\n ]);\n }\n postRun.push(() => {\n for (const plugin of plugins) {\n const result2 = plugin(value[0], ...r);\n if (result2) {\n set(hydrated[index2] = result2.value);\n return;\n }\n }\n throw new SyntaxError();\n });\n continue;\n }\n throw new SyntaxError();\n }\n } else {\n const array = [];\n hydrated[index2] = array;\n for (let i = 0; i < value.length; i++) {\n const n = value[i];\n if (n !== HOLE) {\n stack.push([\n n,\n (v) => {\n array[i] = v;\n }\n ]);\n }\n }\n set(array);\n continue;\n }\n } else {\n const object = {};\n hydrated[index2] = object;\n for (const key of Object.keys(value).reverse()) {\n const r = [];\n stack.push([\n value[key],\n (v) => {\n r[1] = v;\n }\n ]);\n stack.push([\n Number(key.slice(1)),\n (k) => {\n r[0] = k;\n }\n ]);\n postRun.push(() => {\n object[r[0]] = r[1];\n });\n }\n set(object);\n continue;\n }\n }\n while (postRun.length > 0) {\n postRun.pop()();\n }\n return result;\n}\n\n// vendor/turbo-stream-v2/turbo-stream.ts\nasync function decode(readable, options) {\n const { plugins } = options ?? {};\n const done = new Deferred2();\n const reader = readable.pipeThrough(createLineSplittingTransform()).getReader();\n const decoder = {\n values: [],\n hydrated: [],\n deferred: {},\n plugins\n };\n const decoded = await decodeInitial.call(decoder, reader);\n let donePromise = done.promise;\n if (decoded.done) {\n done.resolve();\n } else {\n donePromise = decodeDeferred.call(decoder, reader).then(done.resolve).catch((reason) => {\n for (const deferred of Object.values(decoder.deferred)) {\n deferred.reject(reason);\n }\n done.reject(reason);\n });\n }\n return {\n done: donePromise.then(() => reader.closed),\n value: decoded.value\n };\n}\nasync function decodeInitial(reader) {\n const read = await reader.read();\n if (!read.value) {\n throw new SyntaxError();\n }\n let line;\n try {\n line = JSON.parse(read.value);\n } catch (reason) {\n throw new SyntaxError();\n }\n return {\n done: read.done,\n value: unflatten.call(this, line)\n };\n}\nasync function decodeDeferred(reader) {\n let read = await reader.read();\n while (!read.done) {\n if (!read.value) continue;\n const line = read.value;\n switch (line[0]) {\n case TYPE_PROMISE: {\n const colonIndex = line.indexOf(\":\");\n const deferredId = Number(line.slice(1, colonIndex));\n const deferred = this.deferred[deferredId];\n if (!deferred) {\n throw new Error(`Deferred ID ${deferredId} not found in stream`);\n }\n const lineData = line.slice(colonIndex + 1);\n let jsonLine;\n try {\n jsonLine = JSON.parse(lineData);\n } catch (reason) {\n throw new SyntaxError();\n }\n const value = unflatten.call(this, jsonLine);\n deferred.resolve(value);\n break;\n }\n case TYPE_ERROR: {\n const colonIndex = line.indexOf(\":\");\n const deferredId = Number(line.slice(1, colonIndex));\n const deferred = this.deferred[deferredId];\n if (!deferred) {\n throw new Error(`Deferred ID ${deferredId} not found in stream`);\n }\n const lineData = line.slice(colonIndex + 1);\n let jsonLine;\n try {\n jsonLine = JSON.parse(lineData);\n } catch (reason) {\n throw new SyntaxError();\n }\n const value = unflatten.call(this, jsonLine);\n deferred.reject(value);\n break;\n }\n default:\n throw new SyntaxError();\n }\n read = await reader.read();\n }\n}\nfunction encode(input, options) {\n const { plugins, postPlugins, signal } = options ?? {};\n const encoder = {\n deferred: {},\n index: 0,\n indices: /* @__PURE__ */ new Map(),\n stringified: [],\n plugins,\n postPlugins,\n signal\n };\n const textEncoder = new TextEncoder();\n let lastSentIndex = 0;\n const readable = new ReadableStream({\n async start(controller) {\n const id = flatten.call(encoder, input);\n if (Array.isArray(id)) {\n throw new Error(\"This should never happen\");\n }\n if (id < 0) {\n controller.enqueue(textEncoder.encode(`${id}\n`));\n } else {\n controller.enqueue(\n textEncoder.encode(`[${encoder.stringified.join(\",\")}]\n`)\n );\n lastSentIndex = encoder.stringified.length - 1;\n }\n const seenPromises = /* @__PURE__ */ new WeakSet();\n if (Object.keys(encoder.deferred).length) {\n let raceDone;\n const racePromise = new Promise((resolve, reject) => {\n raceDone = resolve;\n if (signal) {\n const rejectPromise = () => reject(signal.reason || new Error(\"Signal was aborted.\"));\n if (signal.aborted) {\n rejectPromise();\n } else {\n signal.addEventListener(\"abort\", (event) => {\n rejectPromise();\n });\n }\n }\n });\n while (Object.keys(encoder.deferred).length > 0) {\n for (const [deferredId, deferred] of Object.entries(\n encoder.deferred\n )) {\n if (seenPromises.has(deferred)) continue;\n seenPromises.add(\n // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>\n encoder.deferred[Number(deferredId)] = Promise.race([\n racePromise,\n deferred\n ]).then(\n (resolved) => {\n const id2 = flatten.call(encoder, resolved);\n if (Array.isArray(id2)) {\n controller.enqueue(\n textEncoder.encode(\n `${TYPE_PROMISE}${deferredId}:[[\"${TYPE_PREVIOUS_RESOLVED}\",${id2[0]}]]\n`\n )\n );\n encoder.index++;\n lastSentIndex++;\n } else if (id2 < 0) {\n controller.enqueue(\n textEncoder.encode(\n `${TYPE_PROMISE}${deferredId}:${id2}\n`\n )\n );\n } else {\n const values = encoder.stringified.slice(lastSentIndex + 1).join(\",\");\n controller.enqueue(\n textEncoder.encode(\n `${TYPE_PROMISE}${deferredId}:[${values}]\n`\n )\n );\n lastSentIndex = encoder.stringified.length - 1;\n }\n },\n (reason) => {\n if (!reason || typeof reason !== \"object\" || !(reason instanceof Error)) {\n reason = new Error(\"An unknown error occurred\");\n }\n const id2 = flatten.call(encoder, reason);\n if (Array.isArray(id2)) {\n controller.enqueue(\n textEncoder.encode(\n `${TYPE_ERROR}${deferredId}:[[\"${TYPE_PREVIOUS_RESOLVED}\",${id2[0]}]]\n`\n )\n );\n encoder.index++;\n lastSentIndex++;\n } else if (id2 < 0) {\n controller.enqueue(\n textEncoder.encode(\n `${TYPE_ERROR}${deferredId}:${id2}\n`\n )\n );\n } else {\n const values = encoder.stringified.slice(lastSentIndex + 1).join(\",\");\n controller.enqueue(\n textEncoder.encode(\n `${TYPE_ERROR}${deferredId}:[${values}]\n`\n )\n );\n lastSentIndex = encoder.stringified.length - 1;\n }\n }\n ).finally(() => {\n delete encoder.deferred[Number(deferredId)];\n })\n );\n }\n await Promise.race(Object.values(encoder.deferred));\n }\n raceDone();\n }\n await Promise.all(Object.values(encoder.deferred));\n controller.close();\n }\n });\n return readable;\n}\n\n// lib/dom/ssr/data.ts\nasync function createRequestInit(request) {\n let init = { signal: request.signal };\n if (request.method !== \"GET\") {\n init.method = request.method;\n let contentType = request.headers.get(\"Content-Type\");\n if (contentType && /\\bapplication\\/json\\b/.test(contentType)) {\n init.headers = { \"Content-Type\": contentType };\n init.body = JSON.stringify(await request.json());\n } else if (contentType && /\\btext\\/plain\\b/.test(contentType)) {\n init.headers = { \"Content-Type\": contentType };\n init.body = await request.text();\n } else if (contentType && /\\bapplication\\/x-www-form-urlencoded\\b/.test(contentType)) {\n init.body = new URLSearchParams(await request.text());\n } else {\n init.body = await request.formData();\n }\n }\n return init;\n}\n\n// lib/dom/ssr/markup.ts\nvar ESCAPE_LOOKUP = {\n \"&\": \"\\\\u0026\",\n \">\": \"\\\\u003e\",\n \"<\": \"\\\\u003c\",\n \"\\u2028\": \"\\\\u2028\",\n \"\\u2029\": \"\\\\u2029\"\n};\nvar ESCAPE_REGEX = /[&><\\u2028\\u2029]/g;\nfunction escapeHtml(html) {\n return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);\n}\n\n// lib/dom/ssr/invariant.ts\nfunction invariant2(value, message) {\n if (value === false || value === null || typeof value === \"undefined\") {\n throw new Error(message);\n }\n}\n\n// lib/dom/ssr/single-fetch.tsx\nvar SingleFetchRedirectSymbol = Symbol(\"SingleFetchRedirect\");\nvar SingleFetchNoResultError = class extends Error {\n};\nvar SINGLE_FETCH_REDIRECT_STATUS = 202;\nvar NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205]);\nfunction StreamTransfer({\n context,\n identifier,\n reader,\n textDecoder,\n nonce\n}) {\n if (!context.renderMeta || !context.renderMeta.didRenderScripts) {\n return null;\n }\n if (!context.renderMeta.streamCache) {\n context.renderMeta.streamCache = {};\n }\n let { streamCache } = context.renderMeta;\n let promise = streamCache[identifier];\n if (!promise) {\n promise = streamCache[identifier] = reader.read().then((result) => {\n streamCache[identifier].result = {\n done: result.done,\n value: textDecoder.decode(result.value, { stream: true })\n };\n }).catch((e) => {\n streamCache[identifier].error = e;\n });\n }\n if (promise.error) {\n throw promise.error;\n }\n if (promise.result === void 0) {\n throw promise;\n }\n let { done, value } = promise.result;\n let scriptTag = value ? /* @__PURE__ */ React4.createElement(\n \"script\",\n {\n nonce,\n dangerouslySetInnerHTML: {\n __html: `window.__reactRouterContext.streamController.enqueue(${escapeHtml(\n JSON.stringify(value)\n )});`\n }\n }\n ) : null;\n if (done) {\n return /* @__PURE__ */ React4.createElement(React4.Fragment, null, scriptTag, /* @__PURE__ */ React4.createElement(\n \"script\",\n {\n nonce,\n dangerouslySetInnerHTML: {\n __html: `window.__reactRouterContext.streamController.close();`\n }\n }\n ));\n } else {\n return /* @__PURE__ */ React4.createElement(React4.Fragment, null, scriptTag, /* @__PURE__ */ React4.createElement(React4.Suspense, null, /* @__PURE__ */ React4.createElement(\n StreamTransfer,\n {\n context,\n identifier: identifier + 1,\n reader,\n textDecoder,\n nonce\n }\n )));\n }\n}\nfunction getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr, basename, trailingSlashAware) {\n let dataStrategy = getSingleFetchDataStrategyImpl(\n getRouter,\n (match) => {\n let manifestRoute = manifest.routes[match.route.id];\n invariant2(manifestRoute, \"Route not found in manifest\");\n let routeModule = routeModules[match.route.id];\n return {\n hasLoader: manifestRoute.hasLoader,\n hasClientLoader: manifestRoute.hasClientLoader,\n hasShouldRevalidate: Boolean(routeModule?.shouldRevalidate)\n };\n },\n fetchAndDecodeViaTurboStream,\n ssr,\n basename,\n trailingSlashAware\n );\n return async (args) => args.runClientMiddleware(dataStrategy);\n}\nfunction getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, basename, trailingSlashAware, shouldAllowOptOut = () => true) {\n return async (args) => {\n let { request, matches, fetcherKey } = args;\n let router = getRouter();\n if (request.method !== \"GET\") {\n return singleFetchActionStrategy(\n args,\n fetchAndDecode,\n basename,\n trailingSlashAware\n );\n }\n let foundRevalidatingServerLoader = matches.some((m) => {\n let { hasLoader, hasClientLoader } = getRouteInfo(m);\n return m.shouldCallHandler() && hasLoader && !hasClientLoader;\n });\n if (!ssr && !foundRevalidatingServerLoader) {\n return nonSsrStrategy(\n args,\n getRouteInfo,\n fetchAndDecode,\n basename,\n trailingSlashAware\n );\n }\n if (fetcherKey) {\n return singleFetchLoaderFetcherStrategy(\n args,\n fetchAndDecode,\n basename,\n trailingSlashAware\n );\n }\n return singleFetchLoaderNavigationStrategy(\n args,\n router,\n getRouteInfo,\n fetchAndDecode,\n ssr,\n basename,\n trailingSlashAware,\n shouldAllowOptOut\n );\n };\n}\nasync function singleFetchActionStrategy(args, fetchAndDecode, basename, trailingSlashAware) {\n let actionMatch = args.matches.find((m) => m.shouldCallHandler());\n invariant2(actionMatch, \"No action match found\");\n let actionStatus = void 0;\n let result = await actionMatch.resolve(async (handler) => {\n let result2 = await handler(async () => {\n let { data: data2, status } = await fetchAndDecode(\n args,\n basename,\n trailingSlashAware,\n [actionMatch.route.id]\n );\n actionStatus = status;\n return unwrapSingleFetchResult(data2, actionMatch.route.id);\n });\n return result2;\n });\n if (isResponse(result.result) || isRouteErrorResponse(result.result) || isDataWithResponseInit(result.result)) {\n return { [actionMatch.route.id]: result };\n }\n return {\n [actionMatch.route.id]: {\n type: result.type,\n result: data(result.result, actionStatus)\n }\n };\n}\nasync function nonSsrStrategy(args, getRouteInfo, fetchAndDecode, basename, trailingSlashAware) {\n let matchesToLoad = args.matches.filter((m) => m.shouldCallHandler());\n let results = {};\n await Promise.all(\n matchesToLoad.map(\n (m) => m.resolve(async (handler) => {\n try {\n let { hasClientLoader } = getRouteInfo(m);\n let routeId = m.route.id;\n let result = hasClientLoader ? await handler(async () => {\n let { data: data2 } = await fetchAndDecode(\n args,\n basename,\n trailingSlashAware,\n [routeId]\n );\n return unwrapSingleFetchResult(data2, routeId);\n }) : await handler();\n results[m.route.id] = { type: \"data\", result };\n } catch (e) {\n results[m.route.id] = { type: \"error\", result: e };\n }\n })\n )\n );\n return results;\n}\nasync function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, basename, trailingSlashAware, shouldAllowOptOut = () => true) {\n let routesParams = /* @__PURE__ */ new Set();\n let foundOptOutRoute = false;\n let routeDfds = args.matches.map(() => createDeferred2());\n let singleFetchDfd = createDeferred2();\n let results = {};\n let resolvePromise = Promise.all(\n args.matches.map(\n async (m, i) => m.resolve(async (handler) => {\n routeDfds[i].resolve();\n let routeId = m.route.id;\n let { hasLoader, hasClientLoader, hasShouldRevalidate } = getRouteInfo(m);\n let defaultShouldRevalidate = !m.shouldRevalidateArgs || m.shouldRevalidateArgs.actionStatus == null || m.shouldRevalidateArgs.actionStatus < 400;\n let shouldCall = m.shouldCallHandler(defaultShouldRevalidate);\n if (!shouldCall) {\n foundOptOutRoute || (foundOptOutRoute = m.shouldRevalidateArgs != null && // This is a revalidation,\n hasLoader && // for a route with a server loader,\n hasShouldRevalidate === true);\n return;\n }\n if (shouldAllowOptOut(m) && hasClientLoader) {\n if (hasLoader) {\n foundOptOutRoute = true;\n }\n try {\n let result = await handler(async () => {\n let { data: data2 } = await fetchAndDecode(\n args,\n basename,\n trailingSlashAware,\n [routeId]\n );\n return unwrapSingleFetchResult(data2, routeId);\n });\n results[routeId] = { type: \"data\", result };\n } catch (e) {\n results[routeId] = { type: \"error\", result: e };\n }\n return;\n }\n if (hasLoader) {\n routesParams.add(routeId);\n }\n try {\n let result = await handler(async () => {\n let data2 = await singleFetchDfd.promise;\n return unwrapSingleFetchResult(data2, routeId);\n });\n results[routeId] = { type: \"data\", result };\n } catch (e) {\n results[routeId] = { type: \"error\", result: e };\n }\n })\n )\n );\n await Promise.all(routeDfds.map((d) => d.promise));\n let isInitialLoad = !router.state.initialized && router.state.navigation.state === \"idle\";\n if ((isInitialLoad || routesParams.size === 0) && !window.__reactRouterHdrActive) {\n singleFetchDfd.resolve({ routes: {} });\n } else {\n let targetRoutes = ssr && foundOptOutRoute && routesParams.size > 0 ? [...routesParams.keys()] : void 0;\n try {\n let data2 = await fetchAndDecode(\n args,\n basename,\n trailingSlashAware,\n targetRoutes\n );\n singleFetchDfd.resolve(data2.data);\n } catch (e) {\n singleFetchDfd.reject(e);\n }\n }\n await resolvePromise;\n await bubbleMiddlewareErrors(\n singleFetchDfd.promise,\n args.matches,\n routesParams,\n results\n );\n return results;\n}\nasync function bubbleMiddlewareErrors(singleFetchPromise, matches, routesParams, results) {\n try {\n let middlewareError;\n let fetchedData = await singleFetchPromise;\n if (\"routes\" in fetchedData) {\n for (let match of matches) {\n if (match.route.id in fetchedData.routes) {\n let routeResult = fetchedData.routes[match.route.id];\n if (\"error\" in routeResult) {\n middlewareError = routeResult.error;\n if (results[match.route.id]?.result == null) {\n results[match.route.id] = {\n type: \"error\",\n result: middlewareError\n };\n }\n break;\n }\n }\n }\n }\n if (middlewareError !== void 0) {\n Array.from(routesParams.values()).forEach((routeId) => {\n if (results[routeId].result instanceof SingleFetchNoResultError) {\n results[routeId].result = middlewareError;\n }\n });\n }\n } catch (e) {\n }\n}\nasync function singleFetchLoaderFetcherStrategy(args, fetchAndDecode, basename, trailingSlashAware) {\n let fetcherMatch = args.matches.find((m) => m.shouldCallHandler());\n invariant2(fetcherMatch, \"No fetcher match found\");\n let routeId = fetcherMatch.route.id;\n let result = await fetcherMatch.resolve(\n async (handler) => handler(async () => {\n let { data: data2 } = await fetchAndDecode(args, basename, trailingSlashAware, [\n routeId\n ]);\n return unwrapSingleFetchResult(data2, routeId);\n })\n );\n return { [fetcherMatch.route.id]: result };\n}\nfunction stripIndexParam(url) {\n let indexValues = url.searchParams.getAll(\"index\");\n url.searchParams.delete(\"index\");\n let indexValuesToKeep = [];\n for (let indexValue of indexValues) {\n if (indexValue) {\n indexValuesToKeep.push(indexValue);\n }\n }\n for (let toKeep of indexValuesToKeep) {\n url.searchParams.append(\"index\", toKeep);\n }\n return url;\n}\nfunction singleFetchUrl(reqUrl, basename, trailingSlashAware, extension) {\n let url = typeof reqUrl === \"string\" ? new URL(\n reqUrl,\n // This can be called during the SSR flow via PrefetchPageLinksImpl so\n // don't assume window is available\n typeof window === \"undefined\" ? \"server://singlefetch/\" : window.location.origin\n ) : reqUrl;\n if (trailingSlashAware) {\n if (url.pathname.endsWith(\"/\")) {\n url.pathname = `${url.pathname}_.${extension}`;\n } else {\n url.pathname = `${url.pathname}.${extension}`;\n }\n } else {\n if (url.pathname === \"/\") {\n url.pathname = `_root.${extension}`;\n } else if (basename && stripBasename(url.pathname, basename) === \"/\") {\n url.pathname = `${basename.replace(/\\/$/, \"\")}/_root.${extension}`;\n } else {\n url.pathname = `${url.pathname.replace(/\\/$/, \"\")}.${extension}`;\n }\n }\n return url;\n}\nasync function fetchAndDecodeViaTurboStream(args, basename, trailingSlashAware, targetRoutes) {\n let { request } = args;\n let url = singleFetchUrl(request.url, basename, trailingSlashAware, \"data\");\n if (request.method === \"GET\") {\n url = stripIndexParam(url);\n if (targetRoutes) {\n url.searchParams.set(\"_routes\", targetRoutes.join(\",\"));\n }\n }\n let res = await fetch(url, await createRequestInit(request));\n if (res.status >= 400 && !res.headers.has(\"X-Remix-Response\")) {\n throw new ErrorResponseImpl(res.status, res.statusText, await res.text());\n }\n if (res.status === 204 && res.headers.has(\"X-Remix-Redirect\")) {\n return {\n status: SINGLE_FETCH_REDIRECT_STATUS,\n data: {\n redirect: {\n redirect: res.headers.get(\"X-Remix-Redirect\"),\n status: Number(res.headers.get(\"X-Remix-Status\") || \"302\"),\n revalidate: res.headers.get(\"X-Remix-Revalidate\") === \"true\",\n reload: res.headers.get(\"X-Remix-Reload-Document\") === \"true\",\n replace: res.headers.get(\"X-Remix-Replace\") === \"true\"\n }\n }\n };\n }\n if (NO_BODY_STATUS_CODES.has(res.status)) {\n let routes = {};\n if (targetRoutes && request.method !== \"GET\") {\n routes[targetRoutes[0]] = { data: void 0 };\n }\n return {\n status: res.status,\n data: { routes }\n };\n }\n invariant2(res.body, \"No response body to decode\");\n try {\n let decoded = await decodeViaTurboStream(res.body, window);\n let data2;\n if (request.method === \"GET\") {\n let typed = decoded.value;\n if (SingleFetchRedirectSymbol in typed) {\n data2 = { redirect: typed[SingleFetchRedirectSymbol] };\n } else {\n data2 = { routes: typed };\n }\n } else {\n let typed = decoded.value;\n let routeId = targetRoutes?.[0];\n invariant2(routeId, \"No routeId found for single fetch call decoding\");\n if (\"redirect\" in typed) {\n data2 = { redirect: typed };\n } else {\n data2 = { routes: { [routeId]: typed } };\n }\n }\n return { status: res.status, data: data2 };\n } catch (e) {\n throw new Error(\"Unable to decode turbo-stream response\");\n }\n}\nfunction decodeViaTurboStream(body, global) {\n return decode(body, {\n plugins: [\n (type, ...rest) => {\n if (type === \"SanitizedError\") {\n let [name, message, stack] = rest;\n let Constructor = Error;\n if (name && name in global && typeof global[name] === \"function\") {\n Constructor = global[name];\n }\n let error = new Constructor(message);\n error.stack = stack;\n return { value: error };\n }\n if (type === \"ErrorResponse\") {\n let [data2, status, statusText] = rest;\n return {\n value: new ErrorResponseImpl(status, statusText, data2)\n };\n }\n if (type === \"SingleFetchRedirect\") {\n return { value: { [SingleFetchRedirectSymbol]: rest[0] } };\n }\n if (type === \"SingleFetchClassInstance\") {\n return { value: rest[0] };\n }\n if (type === \"SingleFetchFallback\") {\n return { value: void 0 };\n }\n }\n ]\n });\n}\nfunction unwrapSingleFetchResult(result, routeId) {\n if (\"redirect\" in result) {\n let {\n redirect: location,\n revalidate,\n reload,\n replace: replace2,\n status\n } = result.redirect;\n throw redirect(location, {\n status,\n headers: {\n // Three R's of redirecting (lol Veep)\n ...revalidate ? { \"X-Remix-Revalidate\": \"yes\" } : null,\n ...reload ? { \"X-Remix-Reload-Document\": \"yes\" } : null,\n ...replace2 ? { \"X-Remix-Replace\": \"yes\" } : null\n }\n });\n }\n let routeResult = result.routes[routeId];\n if (routeResult == null) {\n throw new SingleFetchNoResultError(\n `No result found for routeId \"${routeId}\"`\n );\n } else if (\"error\" in routeResult) {\n throw routeResult.error;\n } else if (\"data\" in routeResult) {\n return routeResult.data;\n } else {\n throw new Error(`Invalid response found for routeId \"${routeId}\"`);\n }\n}\nfunction createDeferred2() {\n let resolve;\n let reject;\n let promise = new Promise((res, rej) => {\n resolve = async (val) => {\n res(val);\n try {\n await promise;\n } catch (e) {\n }\n };\n reject = async (error) => {\n rej(error);\n try {\n await promise;\n } catch (e) {\n }\n };\n });\n return {\n promise,\n //@ts-ignore\n resolve,\n //@ts-ignore\n reject\n };\n}\n\n// lib/dom/ssr/errorBoundaries.tsx\nimport * as React9 from \"react\";\n\n// lib/dom/ssr/components.tsx\nimport * as React8 from \"react\";\n\n// lib/dom/ssr/routeModules.ts\nasync function loadRouteModule(route, routeModulesCache) {\n if (route.id in routeModulesCache) {\n return routeModulesCache[route.id];\n }\n try {\n let routeModule = await import(\n /* @vite-ignore */\n /* webpackIgnore: true */\n route.module\n );\n routeModulesCache[route.id] = routeModule;\n return routeModule;\n } catch (error) {\n console.error(\n `Error loading route module \\`${route.module}\\`, reloading page...`\n );\n console.error(error);\n if (window.__reactRouterContext && window.__reactRouterContext.isSpaMode && // @ts-expect-error\n import.meta.hot) {\n throw error;\n }\n window.location.reload();\n return new Promise(() => {\n });\n }\n}\n\n// lib/dom/ssr/links.ts\nfunction getKeyedLinksForMatches(matches, routeModules, manifest) {\n let descriptors = matches.map((match) => {\n let module = routeModules[match.route.id];\n let route = manifest.routes[match.route.id];\n return [\n route && route.css ? route.css.map((href) => ({ rel: \"stylesheet\", href })) : [],\n module?.links?.() || []\n ];\n }).flat(2);\n let preloads = getModuleLinkHrefs(matches, manifest);\n return dedupeLinkDescriptors(descriptors, preloads);\n}\nfunction getRouteCssDescriptors(route) {\n if (!route.css) return [];\n return route.css.map((href) => ({ rel: \"stylesheet\", href }));\n}\nasync function prefetchRouteCss(route) {\n if (!route.css) return;\n let descriptors = getRouteCssDescriptors(route);\n await Promise.all(descriptors.map(prefetchStyleLink));\n}\nasync function prefetchStyleLinks(route, routeModule) {\n if (!route.css && !routeModule.links || !isPreloadSupported()) return;\n let descriptors = [];\n if (route.css) {\n descriptors.push(...getRouteCssDescriptors(route));\n }\n if (routeModule.links) {\n descriptors.push(...routeModule.links());\n }\n if (descriptors.length === 0) return;\n let styleLinks = [];\n for (let descriptor of descriptors) {\n if (!isPageLinkDescriptor(descriptor) && descriptor.rel === \"stylesheet\") {\n styleLinks.push({\n ...descriptor,\n rel: \"preload\",\n as: \"style\"\n });\n }\n }\n await Promise.all(styleLinks.map(prefetchStyleLink));\n}\nasync function prefetchStyleLink(descriptor) {\n return new Promise((resolve) => {\n if (descriptor.media && !window.matchMedia(descriptor.media).matches || document.querySelector(\n `link[rel=\"stylesheet\"][href=\"${descriptor.href}\"]`\n )) {\n return resolve();\n }\n let link = document.createElement(\"link\");\n Object.assign(link, descriptor);\n function removeLink() {\n if (document.head.contains(link)) {\n document.head.removeChild(link);\n }\n }\n link.onload = () => {\n removeLink();\n resolve();\n };\n link.onerror = () => {\n removeLink();\n resolve();\n };\n document.head.appendChild(link);\n });\n}\nfunction isPageLinkDescriptor(object) {\n return object != null && typeof object.page === \"string\";\n}\nfunction isHtmlLinkDescriptor(object) {\n if (object == null) {\n return false;\n }\n if (object.href == null) {\n return object.rel === \"preload\" && typeof object.imageSrcSet === \"string\" && typeof object.imageSizes === \"string\";\n }\n return typeof object.rel === \"string\" && typeof object.href === \"string\";\n}\nasync function getKeyedPrefetchLinks(matches, manifest, routeModules) {\n let links = await Promise.all(\n matches.map(async (match) => {\n let route = manifest.routes[match.route.id];\n if (route) {\n let mod = await loadRouteModule(route, routeModules);\n return mod.links ? mod.links() : [];\n }\n return [];\n })\n );\n return dedupeLinkDescriptors(\n links.flat(1).filter(isHtmlLinkDescriptor).filter((link) => link.rel === \"stylesheet\" || link.rel === \"preload\").map(\n (link) => link.rel === \"stylesheet\" ? { ...link, rel: \"prefetch\", as: \"style\" } : { ...link, rel: \"prefetch\" }\n )\n );\n}\nfunction getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, location, mode) {\n let isNew = (match, index) => {\n if (!currentMatches[index]) return true;\n return match.route.id !== currentMatches[index].route.id;\n };\n let matchPathChanged = (match, index) => {\n return (\n // param change, /users/123 -> /users/456\n currentMatches[index].pathname !== match.pathname || // splat param changed, which is not present in match.path\n // e.g. /files/images/avatar.jpg -> files/finances.xls\n currentMatches[index].route.path?.endsWith(\"*\") && currentMatches[index].params[\"*\"] !== match.params[\"*\"]\n );\n };\n if (mode === \"assets\") {\n return nextMatches.filter(\n (match, index) => isNew(match, index) || matchPathChanged(match, index)\n );\n }\n if (mode === \"data\") {\n return nextMatches.filter((match, index) => {\n let manifestRoute = manifest.routes[match.route.id];\n if (!manifestRoute || !manifestRoute.hasLoader) {\n return false;\n }\n if (isNew(match, index) || matchPathChanged(match, index)) {\n return true;\n }\n if (match.route.shouldRevalidate) {\n let routeChoice = match.route.shouldRevalidate({\n currentUrl: new URL(\n location.pathname + location.search + location.hash,\n window.origin\n ),\n currentParams: currentMatches[0]?.params || {},\n nextUrl: new URL(page, window.origin),\n nextParams: match.params,\n defaultShouldRevalidate: true\n });\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n return true;\n });\n }\n return [];\n}\nfunction getModuleLinkHrefs(matches, manifest, { includeHydrateFallback } = {}) {\n return dedupeHrefs(\n matches.map((match) => {\n let route = manifest.routes[match.route.id];\n if (!route) return [];\n let hrefs = [route.module];\n if (route.clientActionModule) {\n hrefs = hrefs.concat(route.clientActionModule);\n }\n if (route.clientLoaderModule) {\n hrefs = hrefs.concat(route.clientLoaderModule);\n }\n if (includeHydrateFallback && route.hydrateFallbackModule) {\n hrefs = hrefs.concat(route.hydrateFallbackModule);\n }\n if (route.imports) {\n hrefs = hrefs.concat(route.imports);\n }\n return hrefs;\n }).flat(1)\n );\n}\nfunction dedupeHrefs(hrefs) {\n return [...new Set(hrefs)];\n}\nfunction sortKeys(obj) {\n let sorted = {};\n let keys = Object.keys(obj).sort();\n for (let key of keys) {\n sorted[key] = obj[key];\n }\n return sorted;\n}\nfunction dedupeLinkDescriptors(descriptors, preloads) {\n let set = /* @__PURE__ */ new Set();\n let preloadsSet = new Set(preloads);\n return descriptors.reduce((deduped, descriptor) => {\n let alreadyModulePreload = preloads && !isPageLinkDescriptor(descriptor) && descriptor.as === \"script\" && descriptor.href && preloadsSet.has(descriptor.href);\n if (alreadyModulePreload) {\n return deduped;\n }\n let key = JSON.stringify(sortKeys(descriptor));\n if (!set.has(key)) {\n set.add(key);\n deduped.push({ key, link: descriptor });\n }\n return deduped;\n }, []);\n}\nvar _isPreloadSupported;\nfunction isPreloadSupported() {\n if (_isPreloadSupported !== void 0) {\n return _isPreloadSupported;\n }\n let el = document.createElement(\"link\");\n _isPreloadSupported = el.relList.supports(\"preload\");\n el = null;\n return _isPreloadSupported;\n}\n\n// lib/dom/ssr/fog-of-war.ts\nimport * as React7 from \"react\";\n\n// lib/dom/ssr/routes.tsx\nimport * as React6 from \"react\";\n\n// lib/dom/ssr/fallback.tsx\nimport * as React5 from \"react\";\nfunction RemixRootDefaultHydrateFallback() {\n return /* @__PURE__ */ React5.createElement(BoundaryShell, { title: \"Loading...\", renderScripts: true }, ENABLE_DEV_WARNINGS ? /* @__PURE__ */ React5.createElement(\n \"script\",\n {\n dangerouslySetInnerHTML: {\n __html: `\n console.log(\n \"\\u{1F4BF} Hey developer \\u{1F44B}. You can provide a way better UX than this \" +\n \"when your app is loading JS modules and/or running \\`clientLoader\\` \" +\n \"functions. Check out https://reactrouter.com/start/framework/route-module#hydratefallback \" +\n \"for more information.\"\n );\n `\n }\n }\n ) : null);\n}\n\n// lib/dom/ssr/routes.tsx\nfunction groupRoutesByParentId(manifest) {\n let routes = {};\n Object.values(manifest).forEach((route) => {\n if (route) {\n let parentId = route.parentId || \"\";\n if (!routes[parentId]) {\n routes[parentId] = [];\n }\n routes[parentId].push(route);\n }\n });\n return routes;\n}\nfunction getRouteComponents(route, routeModule, isSpaMode) {\n let Component4 = getRouteModuleComponent(routeModule);\n let HydrateFallback = routeModule.HydrateFallback && (!isSpaMode || route.id === \"root\") ? routeModule.HydrateFallback : route.id === \"root\" ? RemixRootDefaultHydrateFallback : void 0;\n let ErrorBoundary = routeModule.ErrorBoundary ? routeModule.ErrorBoundary : route.id === \"root\" ? () => /* @__PURE__ */ React6.createElement(RemixRootDefaultErrorBoundary, { error: useRouteError() }) : void 0;\n if (route.id === \"root\" && routeModule.Layout) {\n return {\n ...Component4 ? {\n element: /* @__PURE__ */ React6.createElement(routeModule.Layout, null, /* @__PURE__ */ React6.createElement(Component4, null))\n } : { Component: Component4 },\n ...ErrorBoundary ? {\n errorElement: /* @__PURE__ */ React6.createElement(routeModule.Layout, null, /* @__PURE__ */ React6.createElement(ErrorBoundary, null))\n } : { ErrorBoundary },\n ...HydrateFallback ? {\n hydrateFallbackElement: /* @__PURE__ */ React6.createElement(routeModule.Layout, null, /* @__PURE__ */ React6.createElement(HydrateFallback, null))\n } : { HydrateFallback }\n };\n }\n return { Component: Component4, ErrorBoundary, HydrateFallback };\n}\nfunction createServerRoutes(manifest, routeModules, future, isSpaMode, parentId = \"\", routesByParentId = groupRoutesByParentId(manifest), spaModeLazyPromise = Promise.resolve({ Component: () => null })) {\n return (routesByParentId[parentId] || []).map((route) => {\n let routeModule = routeModules[route.id];\n invariant2(\n routeModule,\n \"No `routeModule` available to create server routes\"\n );\n let dataRoute = {\n ...getRouteComponents(route, routeModule, isSpaMode),\n caseSensitive: route.caseSensitive,\n id: route.id,\n index: route.index,\n path: route.path,\n handle: routeModule.handle,\n // For SPA Mode, all routes are lazy except root. However we tell the\n // router root is also lazy here too since we don't need a full\n // implementation - we just need a `lazy` prop to tell the RR rendering\n // where to stop which is always at the root route in SPA mode\n lazy: isSpaMode ? () => spaModeLazyPromise : void 0,\n // For partial hydration rendering, we need to indicate when the route\n // has a loader/clientLoader, but it won't ever be called during the static\n // render, so just give it a no-op function so we can render down to the\n // proper fallback\n loader: route.hasLoader || route.hasClientLoader ? () => null : void 0\n // We don't need middleware/action/shouldRevalidate on these routes since\n // they're for a static render\n };\n let children = createServerRoutes(\n manifest,\n routeModules,\n future,\n isSpaMode,\n route.id,\n routesByParentId,\n spaModeLazyPromise\n );\n if (children.length > 0) dataRoute.children = children;\n return dataRoute;\n });\n}\nfunction createClientRoutesWithHMRRevalidationOptOut(needsRevalidation, manifest, routeModulesCache, initialState, ssr, isSpaMode) {\n return createClientRoutes(\n manifest,\n routeModulesCache,\n initialState,\n ssr,\n isSpaMode,\n \"\",\n groupRoutesByParentId(manifest),\n needsRevalidation\n );\n}\nfunction preventInvalidServerHandlerCall(type, route) {\n if (type === \"loader\" && !route.hasLoader || type === \"action\" && !route.hasAction) {\n let fn = type === \"action\" ? \"serverAction()\" : \"serverLoader()\";\n let msg = `You are trying to call ${fn} on a route that does not have a server ${type} (routeId: \"${route.id}\")`;\n console.error(msg);\n throw new ErrorResponseImpl(400, \"Bad Request\", new Error(msg), true);\n }\n}\nfunction noActionDefinedError(type, routeId) {\n let article = type === \"clientAction\" ? \"a\" : \"an\";\n let msg = `Route \"${routeId}\" does not have ${article} ${type}, but you are trying to submit to it. To fix this, please add ${article} \\`${type}\\` function to the route`;\n console.error(msg);\n throw new ErrorResponseImpl(405, \"Method Not Allowed\", new Error(msg), true);\n}\nfunction createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSpaMode, parentId = \"\", routesByParentId = groupRoutesByParentId(manifest), needsRevalidation) {\n return (routesByParentId[parentId] || []).map((route) => {\n let routeModule = routeModulesCache[route.id];\n function fetchServerHandler(singleFetch) {\n invariant2(\n typeof singleFetch === \"function\",\n \"No single fetch function available for route handler\"\n );\n return singleFetch();\n }\n function fetchServerLoader(singleFetch) {\n if (!route.hasLoader) return Promise.resolve(null);\n return fetchServerHandler(singleFetch);\n }\n function fetchServerAction(singleFetch) {\n if (!route.hasAction) {\n throw noActionDefinedError(\"action\", route.id);\n }\n return fetchServerHandler(singleFetch);\n }\n function prefetchModule(modulePath) {\n import(\n /* @vite-ignore */\n /* webpackIgnore: true */\n modulePath\n );\n }\n function prefetchRouteModuleChunks(route2) {\n if (route2.clientActionModule) {\n prefetchModule(route2.clientActionModule);\n }\n if (route2.clientLoaderModule) {\n prefetchModule(route2.clientLoaderModule);\n }\n }\n async function prefetchStylesAndCallHandler(handler) {\n let cachedModule = routeModulesCache[route.id];\n let linkPrefetchPromise = cachedModule ? prefetchStyleLinks(route, cachedModule) : Promise.resolve();\n try {\n return handler();\n } finally {\n await linkPrefetchPromise;\n }\n }\n let dataRoute = {\n id: route.id,\n index: route.index,\n path: route.path\n };\n if (routeModule) {\n Object.assign(dataRoute, {\n ...dataRoute,\n ...getRouteComponents(route, routeModule, isSpaMode),\n middleware: routeModule.clientMiddleware,\n handle: routeModule.handle,\n shouldRevalidate: getShouldRevalidateFunction(\n dataRoute.path,\n routeModule,\n route,\n ssr,\n needsRevalidation\n )\n });\n let hasInitialData = initialState && initialState.loaderData && route.id in initialState.loaderData;\n let initialData = hasInitialData ? initialState?.loaderData?.[route.id] : void 0;\n let hasInitialError = initialState && initialState.errors && route.id in initialState.errors;\n let initialError = hasInitialError ? initialState?.errors?.[route.id] : void 0;\n let isHydrationRequest = needsRevalidation == null && (routeModule.clientLoader?.hydrate === true || !route.hasLoader);\n dataRoute.loader = async ({ request, params, context, unstable_pattern }, singleFetch) => {\n try {\n let result = await prefetchStylesAndCallHandler(async () => {\n invariant2(\n routeModule,\n \"No `routeModule` available for critical-route loader\"\n );\n if (!routeModule.clientLoader) {\n return fetchServerLoader(singleFetch);\n }\n return routeModule.clientLoader({\n request,\n params,\n context,\n unstable_pattern,\n async serverLoader() {\n preventInvalidServerHandlerCall(\"loader\", route);\n if (isHydrationRequest) {\n if (hasInitialData) {\n return initialData;\n }\n if (hasInitialError) {\n throw initialError;\n }\n }\n return fetchServerLoader(singleFetch);\n }\n });\n });\n return result;\n } finally {\n isHydrationRequest = false;\n }\n };\n dataRoute.loader.hydrate = shouldHydrateRouteLoader(\n route.id,\n routeModule.clientLoader,\n route.hasLoader,\n isSpaMode\n );\n dataRoute.action = ({ request, params, context, unstable_pattern }, singleFetch) => {\n return prefetchStylesAndCallHandler(async () => {\n invariant2(\n routeModule,\n \"No `routeModule` available for critical-route action\"\n );\n if (!routeModule.clientAction) {\n if (isSpaMode) {\n throw noActionDefinedError(\"clientAction\", route.id);\n }\n return fetchServerAction(singleFetch);\n }\n return routeModule.clientAction({\n request,\n params,\n context,\n unstable_pattern,\n async serverAction() {\n preventInvalidServerHandlerCall(\"action\", route);\n return fetchServerAction(singleFetch);\n }\n });\n });\n };\n } else {\n if (!route.hasClientLoader) {\n dataRoute.loader = (_, singleFetch) => prefetchStylesAndCallHandler(() => {\n return fetchServerLoader(singleFetch);\n });\n }\n if (!route.hasClientAction) {\n dataRoute.action = (_, singleFetch) => prefetchStylesAndCallHandler(() => {\n if (isSpaMode) {\n throw noActionDefinedError(\"clientAction\", route.id);\n }\n return fetchServerAction(singleFetch);\n });\n }\n let lazyRoutePromise;\n async function getLazyRoute() {\n if (lazyRoutePromise) {\n return await lazyRoutePromise;\n }\n lazyRoutePromise = (async () => {\n if (route.clientLoaderModule || route.clientActionModule) {\n await new Promise((resolve) => setTimeout(resolve, 0));\n }\n let routeModulePromise = loadRouteModuleWithBlockingLinks(\n route,\n routeModulesCache\n );\n prefetchRouteModuleChunks(route);\n return await routeModulePromise;\n })();\n return await lazyRoutePromise;\n }\n dataRoute.lazy = {\n loader: route.hasClientLoader ? async () => {\n let { clientLoader } = route.clientLoaderModule ? await import(\n /* @vite-ignore */\n /* webpackIgnore: true */\n route.clientLoaderModule\n ) : await getLazyRoute();\n invariant2(clientLoader, \"No `clientLoader` export found\");\n return (args, singleFetch) => clientLoader({\n ...args,\n async serverLoader() {\n preventInvalidServerHandlerCall(\"loader\", route);\n return fetchServerLoader(singleFetch);\n }\n });\n } : void 0,\n action: route.hasClientAction ? async () => {\n let clientActionPromise = route.clientActionModule ? import(\n /* @vite-ignore */\n /* webpackIgnore: true */\n route.clientActionModule\n ) : getLazyRoute();\n prefetchRouteModuleChunks(route);\n let { clientAction } = await clientActionPromise;\n invariant2(clientAction, \"No `clientAction` export found\");\n return (args, singleFetch) => clientAction({\n ...args,\n async serverAction() {\n preventInvalidServerHandlerCall(\"action\", route);\n return fetchServerAction(singleFetch);\n }\n });\n } : void 0,\n middleware: route.hasClientMiddleware ? async () => {\n let { clientMiddleware } = route.clientMiddlewareModule ? await import(\n /* @vite-ignore */\n /* webpackIgnore: true */\n route.clientMiddlewareModule\n ) : await getLazyRoute();\n invariant2(clientMiddleware, \"No `clientMiddleware` export found\");\n return clientMiddleware;\n } : void 0,\n shouldRevalidate: async () => {\n let lazyRoute = await getLazyRoute();\n return getShouldRevalidateFunction(\n dataRoute.path,\n lazyRoute,\n route,\n ssr,\n needsRevalidation\n );\n },\n handle: async () => (await getLazyRoute()).handle,\n // No need to wrap these in layout since the root route is never\n // loaded via route.lazy()\n Component: async () => (await getLazyRoute()).Component,\n ErrorBoundary: route.hasErrorBoundary ? async () => (await getLazyRoute()).ErrorBoundary : void 0\n };\n }\n let children = createClientRoutes(\n manifest,\n routeModulesCache,\n initialState,\n ssr,\n isSpaMode,\n route.id,\n routesByParentId,\n needsRevalidation\n );\n if (children.length > 0) dataRoute.children = children;\n return dataRoute;\n });\n}\nfunction getShouldRevalidateFunction(path, route, manifestRoute, ssr, needsRevalidation) {\n if (needsRevalidation) {\n return wrapShouldRevalidateForHdr(\n manifestRoute.id,\n route.shouldRevalidate,\n needsRevalidation\n );\n }\n if (!ssr && manifestRoute.hasLoader && !manifestRoute.hasClientLoader) {\n let myParams = path ? compilePath(path)[1].map((p) => p.paramName) : [];\n const didParamsChange = (opts) => myParams.some((p) => opts.currentParams[p] !== opts.nextParams[p]);\n if (route.shouldRevalidate) {\n let fn = route.shouldRevalidate;\n return (opts) => fn({\n ...opts,\n defaultShouldRevalidate: didParamsChange(opts)\n });\n } else {\n return (opts) => didParamsChange(opts);\n }\n }\n return route.shouldRevalidate;\n}\nfunction wrapShouldRevalidateForHdr(routeId, routeShouldRevalidate, needsRevalidation) {\n let handledRevalidation = false;\n return (arg) => {\n if (!handledRevalidation) {\n handledRevalidation = true;\n return needsRevalidation.has(routeId);\n }\n return routeShouldRevalidate ? routeShouldRevalidate(arg) : arg.defaultShouldRevalidate;\n };\n}\nasync function loadRouteModuleWithBlockingLinks(route, routeModules) {\n let routeModulePromise = loadRouteModule(route, routeModules);\n let prefetchRouteCssPromise = prefetchRouteCss(route);\n let routeModule = await routeModulePromise;\n await Promise.all([\n prefetchRouteCssPromise,\n prefetchStyleLinks(route, routeModule)\n ]);\n return {\n Component: getRouteModuleComponent(routeModule),\n ErrorBoundary: routeModule.ErrorBoundary,\n clientMiddleware: routeModule.clientMiddleware,\n clientAction: routeModule.clientAction,\n clientLoader: routeModule.clientLoader,\n handle: routeModule.handle,\n links: routeModule.links,\n meta: routeModule.meta,\n shouldRevalidate: routeModule.shouldRevalidate\n };\n}\nfunction getRouteModuleComponent(routeModule) {\n if (routeModule.default == null) return void 0;\n let isEmptyObject = typeof routeModule.default === \"object\" && Object.keys(routeModule.default).length === 0;\n if (!isEmptyObject) {\n return routeModule.default;\n }\n}\nfunction shouldHydrateRouteLoader(routeId, clientLoader, hasLoader, isSpaMode) {\n return isSpaMode && routeId !== \"root\" || clientLoader != null && (clientLoader.hydrate === true || hasLoader !== true);\n}\n\n// lib/dom/ssr/fog-of-war.ts\nvar nextPaths = /* @__PURE__ */ new Set();\nvar discoveredPathsMaxSize = 1e3;\nvar discoveredPaths = /* @__PURE__ */ new Set();\nvar URL_LIMIT = 7680;\nfunction isFogOfWarEnabled(routeDiscovery, ssr) {\n return routeDiscovery.mode === \"lazy\" && ssr === true;\n}\nfunction getPartialManifest({ sri, ...manifest }, router) {\n let routeIds = new Set(router.state.matches.map((m) => m.route.id));\n let segments = router.state.location.pathname.split(\"/\").filter(Boolean);\n let paths = [\"/\"];\n segments.pop();\n while (segments.length > 0) {\n paths.push(`/${segments.join(\"/\")}`);\n segments.pop();\n }\n paths.forEach((path) => {\n let matches = matchRoutes(router.routes, path, router.basename);\n if (matches) {\n matches.forEach((m) => routeIds.add(m.route.id));\n }\n });\n let initialRoutes = [...routeIds].reduce(\n (acc, id) => Object.assign(acc, { [id]: manifest.routes[id] }),\n {}\n );\n return {\n ...manifest,\n routes: initialRoutes,\n sri: sri ? true : void 0\n };\n}\nfunction getPatchRoutesOnNavigationFunction(manifest, routeModules, ssr, routeDiscovery, isSpaMode, basename) {\n if (!isFogOfWarEnabled(routeDiscovery, ssr)) {\n return void 0;\n }\n return async ({ path, patch, signal, fetcherKey }) => {\n if (discoveredPaths.has(path)) {\n return;\n }\n await fetchAndApplyManifestPatches(\n [path],\n fetcherKey ? window.location.href : path,\n manifest,\n routeModules,\n ssr,\n isSpaMode,\n basename,\n routeDiscovery.manifestPath,\n patch,\n signal\n );\n };\n}\nfunction useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscovery, isSpaMode) {\n React7.useEffect(() => {\n if (!isFogOfWarEnabled(routeDiscovery, ssr) || // @ts-expect-error - TS doesn't know about this yet\n window.navigator?.connection?.saveData === true) {\n return;\n }\n function registerElement(el) {\n let path = el.tagName === \"FORM\" ? el.getAttribute(\"action\") : el.getAttribute(\"href\");\n if (!path) {\n return;\n }\n let pathname = el.tagName === \"A\" ? el.pathname : new URL(path, window.location.origin).pathname;\n if (!discoveredPaths.has(pathname)) {\n nextPaths.add(pathname);\n }\n }\n async function fetchPatches() {\n document.querySelectorAll(\"a[data-discover], form[data-discover]\").forEach(registerElement);\n let lazyPaths = Array.from(nextPaths.keys()).filter((path) => {\n if (discoveredPaths.has(path)) {\n nextPaths.delete(path);\n return false;\n }\n return true;\n });\n if (lazyPaths.length === 0) {\n return;\n }\n try {\n await fetchAndApplyManifestPatches(\n lazyPaths,\n null,\n manifest,\n routeModules,\n ssr,\n isSpaMode,\n router.basename,\n routeDiscovery.manifestPath,\n router.patchRoutes\n );\n } catch (e) {\n console.error(\"Failed to fetch manifest patches\", e);\n }\n }\n let debouncedFetchPatches = debounce(fetchPatches, 100);\n fetchPatches();\n let observer = new MutationObserver(() => debouncedFetchPatches());\n observer.observe(document.documentElement, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: [\"data-discover\", \"href\", \"action\"]\n });\n return () => observer.disconnect();\n }, [ssr, isSpaMode, manifest, routeModules, router, routeDiscovery]);\n}\nfunction getManifestPath(_manifestPath, basename) {\n let manifestPath = _manifestPath || \"/__manifest\";\n if (basename == null) {\n return manifestPath;\n }\n return `${basename}${manifestPath}`.replace(/\\/+/g, \"/\");\n}\nvar MANIFEST_VERSION_STORAGE_KEY = \"react-router-manifest-version\";\nasync function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) {\n const searchParams = new URLSearchParams();\n searchParams.set(\"paths\", paths.sort().join(\",\"));\n searchParams.set(\"version\", manifest.version);\n let url = new URL(\n getManifestPath(manifestPath, basename),\n window.location.origin\n );\n url.search = searchParams.toString();\n if (url.toString().length > URL_LIMIT) {\n nextPaths.clear();\n return;\n }\n let serverPatches;\n try {\n let res = await fetch(url, { signal });\n if (!res.ok) {\n throw new Error(`${res.status} ${res.statusText}`);\n } else if (res.status === 204 && res.headers.has(\"X-Remix-Reload-Document\")) {\n if (!errorReloadPath) {\n console.warn(\n \"Detected a manifest version mismatch during eager route discovery. The next navigation/fetch to an undiscovered route will result in a new document navigation to sync up with the latest manifest.\"\n );\n return;\n }\n try {\n if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) {\n console.error(\n \"Unable to discover routes due to manifest version mismatch.\"\n );\n return;\n }\n sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);\n } catch {\n }\n window.location.href = errorReloadPath;\n console.warn(\"Detected manifest version mismatch, reloading...\");\n await new Promise(() => {\n });\n } else if (res.status >= 400) {\n throw new Error(await res.text());\n }\n try {\n sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);\n } catch {\n }\n serverPatches = await res.json();\n } catch (e) {\n if (signal?.aborted) return;\n throw e;\n }\n let knownRoutes = new Set(Object.keys(manifest.routes));\n let patches = Object.values(serverPatches).reduce((acc, route) => {\n if (route && !knownRoutes.has(route.id)) {\n acc[route.id] = route;\n }\n return acc;\n }, {});\n Object.assign(manifest.routes, patches);\n paths.forEach((p) => addToFifoQueue(p, discoveredPaths));\n let parentIds = /* @__PURE__ */ new Set();\n Object.values(patches).forEach((patch) => {\n if (patch && (!patch.parentId || !patches[patch.parentId])) {\n parentIds.add(patch.parentId);\n }\n });\n parentIds.forEach(\n (parentId) => patchRoutes(\n parentId || null,\n createClientRoutes(patches, routeModules, null, ssr, isSpaMode, parentId)\n )\n );\n}\nfunction addToFifoQueue(path, queue) {\n if (queue.size >= discoveredPathsMaxSize) {\n let first = queue.values().next().value;\n queue.delete(first);\n }\n queue.add(path);\n}\nfunction debounce(callback, wait) {\n let timeoutId;\n return (...args) => {\n window.clearTimeout(timeoutId);\n timeoutId = window.setTimeout(() => callback(...args), wait);\n };\n}\n\n// lib/dom/ssr/components.tsx\nfunction useDataRouterContext2() {\n let context = React8.useContext(DataRouterContext);\n invariant2(\n context,\n \"You must render this element inside a <DataRouterContext.Provider> element\"\n );\n return context;\n}\nfunction useDataRouterStateContext() {\n let context = React8.useContext(DataRouterStateContext);\n invariant2(\n context,\n \"You must render this element inside a <DataRouterStateContext.Provider> element\"\n );\n return context;\n}\nvar FrameworkContext = React8.createContext(void 0);\nFrameworkContext.displayName = \"FrameworkContext\";\nfunction useFrameworkContext() {\n let context = React8.useContext(FrameworkContext);\n invariant2(\n context,\n \"You must render this element inside a <HydratedRouter> element\"\n );\n return context;\n}\nfunction usePrefetchBehavior(prefetch, theirElementProps) {\n let frameworkContext = React8.useContext(FrameworkContext);\n let [maybePrefetch, setMaybePrefetch] = React8.useState(false);\n let [shouldPrefetch, setShouldPrefetch] = React8.useState(false);\n let { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps;\n let ref = React8.useRef(null);\n React8.useEffect(() => {\n if (prefetch === \"render\") {\n setShouldPrefetch(true);\n }\n if (prefetch === \"viewport\") {\n let callback = (entries) => {\n entries.forEach((entry) => {\n setShouldPrefetch(entry.isIntersecting);\n });\n };\n let observer = new IntersectionObserver(callback, { threshold: 0.5 });\n if (ref.current) observer.observe(ref.current);\n return () => {\n observer.disconnect();\n };\n }\n }, [prefetch]);\n React8.useEffect(() => {\n if (maybePrefetch) {\n let id = setTimeout(() => {\n setShouldPrefetch(true);\n }, 100);\n return () => {\n clearTimeout(id);\n };\n }\n }, [maybePrefetch]);\n let setIntent = () => {\n setMaybePrefetch(true);\n };\n let cancelIntent = () => {\n setMaybePrefetch(false);\n setShouldPrefetch(false);\n };\n if (!frameworkContext) {\n return [false, ref, {}];\n }\n if (prefetch !== \"intent\") {\n return [shouldPrefetch, ref, {}];\n }\n return [\n shouldPrefetch,\n ref,\n {\n onFocus: composeEventHandlers(onFocus, setIntent),\n onBlur: composeEventHandlers(onBlur, cancelIntent),\n onMouseEnter: composeEventHandlers(onMouseEnter, setIntent),\n onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent),\n onTouchStart: composeEventHandlers(onTouchStart, setIntent)\n }\n ];\n}\nfunction composeEventHandlers(theirHandler, ourHandler) {\n return (event) => {\n theirHandler && theirHandler(event);\n if (!event.defaultPrevented) {\n ourHandler(event);\n }\n };\n}\nfunction getActiveMatches(matches, errors, isSpaMode) {\n if (isSpaMode && !isHydrated) {\n return [matches[0]];\n }\n if (errors) {\n let errorIdx = matches.findIndex((m) => errors[m.route.id] !== void 0);\n return matches.slice(0, errorIdx + 1);\n }\n return matches;\n}\nvar CRITICAL_CSS_DATA_ATTRIBUTE = \"data-react-router-critical-css\";\nfunction Links({ nonce }) {\n let { isSpaMode, manifest, routeModules, criticalCss } = useFrameworkContext();\n let { errors, matches: routerMatches } = useDataRouterStateContext();\n let matches = getActiveMatches(routerMatches, errors, isSpaMode);\n let keyedLinks = React8.useMemo(\n () => getKeyedLinksForMatches(matches, routeModules, manifest),\n [matches, routeModules, manifest]\n );\n return /* @__PURE__ */ React8.createElement(React8.Fragment, null, typeof criticalCss === \"string\" ? /* @__PURE__ */ React8.createElement(\n \"style\",\n {\n ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: \"\" },\n dangerouslySetInnerHTML: { __html: criticalCss }\n }\n ) : null, typeof criticalCss === \"object\" ? /* @__PURE__ */ React8.createElement(\n \"link\",\n {\n ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: \"\" },\n rel: \"stylesheet\",\n href: criticalCss.href,\n nonce\n }\n ) : null, keyedLinks.map(\n ({ key, link }) => isPageLinkDescriptor(link) ? /* @__PURE__ */ React8.createElement(PrefetchPageLinks, { key, nonce, ...link }) : /* @__PURE__ */ React8.createElement(\"link\", { key, nonce, ...link })\n ));\n}\nfunction PrefetchPageLinks({ page, ...linkProps }) {\n let { router } = useDataRouterContext2();\n let matches = React8.useMemo(\n () => matchRoutes(router.routes, page, router.basename),\n [router.routes, page, router.basename]\n );\n if (!matches) {\n return null;\n }\n return /* @__PURE__ */ React8.createElement(PrefetchPageLinksImpl, { page, matches, ...linkProps });\n}\nfunction useKeyedPrefetchLinks(matches) {\n let { manifest, routeModules } = useFrameworkContext();\n let [keyedPrefetchLinks, setKeyedPrefetchLinks] = React8.useState([]);\n React8.useEffect(() => {\n let interrupted = false;\n void getKeyedPrefetchLinks(matches, manifest, routeModules).then(\n (links) => {\n if (!interrupted) {\n setKeyedPrefetchLinks(links);\n }\n }\n );\n return () => {\n interrupted = true;\n };\n }, [matches, manifest, routeModules]);\n return keyedPrefetchLinks;\n}\nfunction PrefetchPageLinksImpl({\n page,\n matches: nextMatches,\n ...linkProps\n}) {\n let location = useLocation();\n let { future, manifest, routeModules } = useFrameworkContext();\n let { basename } = useDataRouterContext2();\n let { loaderData, matches } = useDataRouterStateContext();\n let newMatchesForData = React8.useMemo(\n () => getNewMatchesForLinks(\n page,\n nextMatches,\n matches,\n manifest,\n location,\n \"data\"\n ),\n [page, nextMatches, matches, manifest, location]\n );\n let newMatchesForAssets = React8.useMemo(\n () => getNewMatchesForLinks(\n page,\n nextMatches,\n matches,\n manifest,\n location,\n \"assets\"\n ),\n [page, nextMatches, matches, manifest, location]\n );\n let dataHrefs = React8.useMemo(() => {\n if (page === location.pathname + location.search + location.hash) {\n return [];\n }\n let routesParams = /* @__PURE__ */ new Set();\n let foundOptOutRoute = false;\n nextMatches.forEach((m) => {\n let manifestRoute = manifest.routes[m.route.id];\n if (!manifestRoute || !manifestRoute.hasLoader) {\n return;\n }\n if (!newMatchesForData.some((m2) => m2.route.id === m.route.id) && m.route.id in loaderData && routeModules[m.route.id]?.shouldRevalidate) {\n foundOptOutRoute = true;\n } else if (manifestRoute.hasClientLoader) {\n foundOptOutRoute = true;\n } else {\n routesParams.add(m.route.id);\n }\n });\n if (routesParams.size === 0) {\n return [];\n }\n let url = singleFetchUrl(\n page,\n basename,\n future.unstable_trailingSlashAwareDataRequests,\n \"data\"\n );\n if (foundOptOutRoute && routesParams.size > 0) {\n url.searchParams.set(\n \"_routes\",\n nextMatches.filter((m) => routesParams.has(m.route.id)).map((m) => m.route.id).join(\",\")\n );\n }\n return [url.pathname + url.search];\n }, [\n basename,\n future.unstable_trailingSlashAwareDataRequests,\n loaderData,\n location,\n manifest,\n newMatchesForData,\n nextMatches,\n page,\n routeModules\n ]);\n let moduleHrefs = React8.useMemo(\n () => getModuleLinkHrefs(newMatchesForAssets, manifest),\n [newMatchesForAssets, manifest]\n );\n let keyedPrefetchLinks = useKeyedPrefetchLinks(newMatchesForAssets);\n return /* @__PURE__ */ React8.createElement(React8.Fragment, null, dataHrefs.map((href) => /* @__PURE__ */ React8.createElement(\"link\", { key: href, rel: \"prefetch\", as: \"fetch\", href, ...linkProps })), moduleHrefs.map((href) => /* @__PURE__ */ React8.createElement(\"link\", { key: href, rel: \"modulepreload\", href, ...linkProps })), keyedPrefetchLinks.map(({ key, link }) => (\n // these don't spread `linkProps` because they are full link descriptors\n // already with their own props\n /* @__PURE__ */ React8.createElement(\"link\", { key, nonce: linkProps.nonce, ...link })\n )));\n}\nfunction Meta() {\n let { isSpaMode, routeModules } = useFrameworkContext();\n let {\n errors,\n matches: routerMatches,\n loaderData\n } = useDataRouterStateContext();\n let location = useLocation();\n let _matches = getActiveMatches(routerMatches, errors, isSpaMode);\n let error = null;\n if (errors) {\n error = errors[_matches[_matches.length - 1].route.id];\n }\n let meta = [];\n let leafMeta = null;\n let matches = [];\n for (let i = 0; i < _matches.length; i++) {\n let _match = _matches[i];\n let routeId = _match.route.id;\n let data2 = loaderData[routeId];\n let params = _match.params;\n let routeModule = routeModules[routeId];\n let routeMeta = [];\n let match = {\n id: routeId,\n data: data2,\n loaderData: data2,\n meta: [],\n params: _match.params,\n pathname: _match.pathname,\n handle: _match.route.handle,\n error\n };\n matches[i] = match;\n if (routeModule?.meta) {\n routeMeta = typeof routeModule.meta === \"function\" ? routeModule.meta({\n data: data2,\n loaderData: data2,\n params,\n location,\n matches,\n error\n }) : Array.isArray(routeModule.meta) ? [...routeModule.meta] : routeModule.meta;\n } else if (leafMeta) {\n routeMeta = [...leafMeta];\n }\n routeMeta = routeMeta || [];\n if (!Array.isArray(routeMeta)) {\n throw new Error(\n \"The route at \" + _match.route.path + \" returns an invalid value. All route meta functions must return an array of meta objects.\\n\\nTo reference the meta function API, see https://remix.run/route/meta\"\n );\n }\n match.meta = routeMeta;\n matches[i] = match;\n meta = [...routeMeta];\n leafMeta = meta;\n }\n return /* @__PURE__ */ React8.createElement(React8.Fragment, null, meta.flat().map((metaProps) => {\n if (!metaProps) {\n return null;\n }\n if (\"tagName\" in metaProps) {\n let { tagName, ...rest } = metaProps;\n if (!isValidMetaTag(tagName)) {\n console.warn(\n `A meta object uses an invalid tagName: ${tagName}. Expected either 'link' or 'meta'`\n );\n return null;\n }\n let Comp = tagName;\n return /* @__PURE__ */ React8.createElement(Comp, { key: JSON.stringify(rest), ...rest });\n }\n if (\"title\" in metaProps) {\n return /* @__PURE__ */ React8.createElement(\"title\", { key: \"title\" }, String(metaProps.title));\n }\n if (\"charset\" in metaProps) {\n metaProps.charSet ?? (metaProps.charSet = metaProps.charset);\n delete metaProps.charset;\n }\n if (\"charSet\" in metaProps && metaProps.charSet != null) {\n return typeof metaProps.charSet === \"string\" ? /* @__PURE__ */ React8.createElement(\"meta\", { key: \"charSet\", charSet: metaProps.charSet }) : null;\n }\n if (\"script:ld+json\" in metaProps) {\n try {\n let json = JSON.stringify(metaProps[\"script:ld+json\"]);\n return /* @__PURE__ */ React8.createElement(\n \"script\",\n {\n key: `script:ld+json:${json}`,\n type: \"application/ld+json\",\n dangerouslySetInnerHTML: { __html: escapeHtml(json) }\n }\n );\n } catch (err) {\n return null;\n }\n }\n return /* @__PURE__ */ React8.createElement(\"meta\", { key: JSON.stringify(metaProps), ...metaProps });\n }));\n}\nfunction isValidMetaTag(tagName) {\n return typeof tagName === \"string\" && /^(meta|link)$/.test(tagName);\n}\nvar isHydrated = false;\nfunction setIsHydrated() {\n isHydrated = true;\n}\nfunction Scripts(scriptProps) {\n let {\n manifest,\n serverHandoffString,\n isSpaMode,\n renderMeta,\n routeDiscovery,\n ssr\n } = useFrameworkContext();\n let { router, static: isStatic, staticContext } = useDataRouterContext2();\n let { matches: routerMatches } = useDataRouterStateContext();\n let isRSCRouterContext = useIsRSCRouterContext();\n let enableFogOfWar = isFogOfWarEnabled(routeDiscovery, ssr);\n if (renderMeta) {\n renderMeta.didRenderScripts = true;\n }\n let matches = getActiveMatches(routerMatches, null, isSpaMode);\n React8.useEffect(() => {\n setIsHydrated();\n }, []);\n let initialScripts = React8.useMemo(() => {\n if (isRSCRouterContext) {\n return null;\n }\n let streamScript = \"window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());\";\n let contextScript = staticContext ? `window.__reactRouterContext = ${serverHandoffString};${streamScript}` : \" \";\n let routeModulesScript = !isStatic ? \" \" : `${manifest.hmr?.runtime ? `import ${JSON.stringify(manifest.hmr.runtime)};` : \"\"}${!enableFogOfWar ? `import ${JSON.stringify(manifest.url)}` : \"\"};\n${matches.map((match, routeIndex) => {\n let routeVarName = `route${routeIndex}`;\n let manifestEntry = manifest.routes[match.route.id];\n invariant2(manifestEntry, `Route ${match.route.id} not found in manifest`);\n let {\n clientActionModule,\n clientLoaderModule,\n clientMiddlewareModule,\n hydrateFallbackModule,\n module\n } = manifestEntry;\n let chunks = [\n ...clientActionModule ? [\n {\n module: clientActionModule,\n varName: `${routeVarName}_clientAction`\n }\n ] : [],\n ...clientLoaderModule ? [\n {\n module: clientLoaderModule,\n varName: `${routeVarName}_clientLoader`\n }\n ] : [],\n ...clientMiddlewareModule ? [\n {\n module: clientMiddlewareModule,\n varName: `${routeVarName}_clientMiddleware`\n }\n ] : [],\n ...hydrateFallbackModule ? [\n {\n module: hydrateFallbackModule,\n varName: `${routeVarName}_HydrateFallback`\n }\n ] : [],\n { module, varName: `${routeVarName}_main` }\n ];\n if (chunks.length === 1) {\n return `import * as ${routeVarName} from ${JSON.stringify(module)};`;\n }\n let chunkImportsSnippet = chunks.map((chunk) => `import * as ${chunk.varName} from \"${chunk.module}\";`).join(\"\\n\");\n let mergedChunksSnippet = `const ${routeVarName} = {${chunks.map((chunk) => `...${chunk.varName}`).join(\",\")}};`;\n return [chunkImportsSnippet, mergedChunksSnippet].join(\"\\n\");\n }).join(\"\\n\")}\n ${enableFogOfWar ? (\n // Inline a minimal manifest with the SSR matches\n `window.__reactRouterManifest = ${JSON.stringify(\n getPartialManifest(manifest, router),\n null,\n 2\n )};`\n ) : \"\"}\n window.__reactRouterRouteModules = {${matches.map((match, index) => `${JSON.stringify(match.route.id)}:route${index}`).join(\",\")}};\n\nimport(${JSON.stringify(manifest.entry.module)});`;\n return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(\n \"script\",\n {\n ...scriptProps,\n suppressHydrationWarning: true,\n dangerouslySetInnerHTML: { __html: contextScript },\n type: void 0\n }\n ), /* @__PURE__ */ React8.createElement(\n \"script\",\n {\n ...scriptProps,\n suppressHydrationWarning: true,\n dangerouslySetInnerHTML: { __html: routeModulesScript },\n type: \"module\",\n async: true\n }\n ));\n }, []);\n let preloads = isHydrated || isRSCRouterContext ? [] : dedupe(\n manifest.entry.imports.concat(\n getModuleLinkHrefs(matches, manifest, {\n includeHydrateFallback: true\n })\n )\n );\n let sri = typeof manifest.sri === \"object\" ? manifest.sri : {};\n warnOnce(\n !isRSCRouterContext,\n \"The <Scripts /> element is a no-op when using RSC and can be safely removed.\"\n );\n return isHydrated || isRSCRouterContext ? null : /* @__PURE__ */ React8.createElement(React8.Fragment, null, typeof manifest.sri === \"object\" ? /* @__PURE__ */ React8.createElement(\n \"script\",\n {\n ...scriptProps,\n \"rr-importmap\": \"\",\n type: \"importmap\",\n suppressHydrationWarning: true,\n dangerouslySetInnerHTML: {\n __html: JSON.stringify({\n integrity: sri\n })\n }\n }\n ) : null, !enableFogOfWar ? /* @__PURE__ */ React8.createElement(\n \"link\",\n {\n rel: \"modulepreload\",\n href: manifest.url,\n crossOrigin: scriptProps.crossOrigin,\n integrity: sri[manifest.url],\n suppressHydrationWarning: true\n }\n ) : null, /* @__PURE__ */ React8.createElement(\n \"link\",\n {\n rel: \"modulepreload\",\n href: manifest.entry.module,\n crossOrigin: scriptProps.crossOrigin,\n integrity: sri[manifest.entry.module],\n suppressHydrationWarning: true\n }\n ), preloads.map((path) => /* @__PURE__ */ React8.createElement(\n \"link\",\n {\n key: path,\n rel: \"modulepreload\",\n href: path,\n crossOrigin: scriptProps.crossOrigin,\n integrity: sri[path],\n suppressHydrationWarning: true\n }\n )), initialScripts);\n}\nfunction dedupe(array) {\n return [...new Set(array)];\n}\nfunction mergeRefs(...refs) {\n return (value) => {\n refs.forEach((ref) => {\n if (typeof ref === \"function\") {\n ref(value);\n } else if (ref != null) {\n ref.current = value;\n }\n });\n };\n}\n\n// lib/dom/ssr/errorBoundaries.tsx\nvar RemixErrorBoundary = class extends React9.Component {\n constructor(props) {\n super(props);\n this.state = { error: props.error || null, location: props.location };\n }\n static getDerivedStateFromError(error) {\n return { error };\n }\n static getDerivedStateFromProps(props, state) {\n if (state.location !== props.location) {\n return { error: props.error || null, location: props.location };\n }\n return { error: props.error || state.error, location: state.location };\n }\n render() {\n if (this.state.error) {\n return /* @__PURE__ */ React9.createElement(\n RemixRootDefaultErrorBoundary,\n {\n error: this.state.error,\n isOutsideRemixApp: true\n }\n );\n } else {\n return this.props.children;\n }\n }\n};\nfunction RemixRootDefaultErrorBoundary({\n error,\n isOutsideRemixApp\n}) {\n console.error(error);\n let heyDeveloper = /* @__PURE__ */ React9.createElement(\n \"script\",\n {\n dangerouslySetInnerHTML: {\n __html: `\n console.log(\n \"\\u{1F4BF} Hey developer \\u{1F44B}. You can provide a way better UX than this when your app throws errors. Check out https://reactrouter.com/how-to/error-boundary for more information.\"\n );\n `\n }\n }\n );\n if (isRouteErrorResponse(error)) {\n return /* @__PURE__ */ React9.createElement(BoundaryShell, { title: \"Unhandled Thrown Response!\" }, /* @__PURE__ */ React9.createElement(\"h1\", { style: { fontSize: \"24px\" } }, error.status, \" \", error.statusText), ENABLE_DEV_WARNINGS ? heyDeveloper : null);\n }\n let errorInstance;\n if (error instanceof Error) {\n errorInstance = error;\n } else {\n let errorString = error == null ? \"Unknown Error\" : typeof error === \"object\" && \"toString\" in error ? error.toString() : JSON.stringify(error);\n errorInstance = new Error(errorString);\n }\n return /* @__PURE__ */ React9.createElement(\n BoundaryShell,\n {\n title: \"Application Error!\",\n isOutsideRemixApp\n },\n /* @__PURE__ */ React9.createElement(\"h1\", { style: { fontSize: \"24px\" } }, \"Application Error\"),\n /* @__PURE__ */ React9.createElement(\n \"pre\",\n {\n style: {\n padding: \"2rem\",\n background: \"hsla(10, 50%, 50%, 0.1)\",\n color: \"red\",\n overflow: \"auto\"\n }\n },\n errorInstance.stack\n ),\n heyDeveloper\n );\n}\nfunction BoundaryShell({\n title,\n renderScripts,\n isOutsideRemixApp,\n children\n}) {\n let { routeModules } = useFrameworkContext();\n if (routeModules.root?.Layout && !isOutsideRemixApp) {\n return children;\n }\n return /* @__PURE__ */ React9.createElement(\"html\", { lang: \"en\" }, /* @__PURE__ */ React9.createElement(\"head\", null, /* @__PURE__ */ React9.createElement(\"meta\", { charSet: \"utf-8\" }), /* @__PURE__ */ React9.createElement(\n \"meta\",\n {\n name: \"viewport\",\n content: \"width=device-width,initial-scale=1,viewport-fit=cover\"\n }\n ), /* @__PURE__ */ React9.createElement(\"title\", null, title)), /* @__PURE__ */ React9.createElement(\"body\", null, /* @__PURE__ */ React9.createElement(\"main\", { style: { fontFamily: \"system-ui, sans-serif\", padding: \"2rem\" } }, children, renderScripts ? /* @__PURE__ */ React9.createElement(Scripts, null) : null)));\n}\n\n// lib/dom/lib.tsx\nimport * as React10 from \"react\";\nvar isBrowser2 = typeof window !== \"undefined\" && typeof window.document !== \"undefined\" && typeof window.document.createElement !== \"undefined\";\ntry {\n if (isBrowser2) {\n window.__reactRouterVersion = // @ts-expect-error\n \"7.12.0\";\n }\n} catch (e) {\n}\nfunction createBrowserRouter(routes, opts) {\n return createRouter({\n basename: opts?.basename,\n getContext: opts?.getContext,\n future: opts?.future,\n history: createBrowserHistory({ window: opts?.window }),\n hydrationData: opts?.hydrationData || parseHydrationData(),\n routes,\n mapRouteProperties,\n hydrationRouteProperties,\n dataStrategy: opts?.dataStrategy,\n patchRoutesOnNavigation: opts?.patchRoutesOnNavigation,\n window: opts?.window,\n unstable_instrumentations: opts?.unstable_instrumentations\n }).initialize();\n}\nfunction createHashRouter(routes, opts) {\n return createRouter({\n basename: opts?.basename,\n getContext: opts?.getContext,\n future: opts?.future,\n history: createHashHistory({ window: opts?.window }),\n hydrationData: opts?.hydrationData || parseHydrationData(),\n routes,\n mapRouteProperties,\n hydrationRouteProperties,\n dataStrategy: opts?.dataStrategy,\n patchRoutesOnNavigation: opts?.patchRoutesOnNavigation,\n window: opts?.window,\n unstable_instrumentations: opts?.unstable_instrumentations\n }).initialize();\n}\nfunction parseHydrationData() {\n let state = window?.__staticRouterHydrationData;\n if (state && state.errors) {\n state = {\n ...state,\n errors: deserializeErrors(state.errors)\n };\n }\n return state;\n}\nfunction deserializeErrors(errors) {\n if (!errors) return null;\n let entries = Object.entries(errors);\n let serialized = {};\n for (let [key, val] of entries) {\n if (val && val.__type === \"RouteErrorResponse\") {\n serialized[key] = new ErrorResponseImpl(\n val.status,\n val.statusText,\n val.data,\n val.internal === true\n );\n } else if (val && val.__type === \"Error\") {\n if (val.__subType) {\n let ErrorConstructor = window[val.__subType];\n if (typeof ErrorConstructor === \"function\") {\n try {\n let error = new ErrorConstructor(val.message);\n error.stack = \"\";\n serialized[key] = error;\n } catch (e) {\n }\n }\n }\n if (serialized[key] == null) {\n let error = new Error(val.message);\n error.stack = \"\";\n serialized[key] = error;\n }\n } else {\n serialized[key] = val;\n }\n }\n return serialized;\n}\nfunction BrowserRouter({\n basename,\n children,\n unstable_useTransitions,\n window: window2\n}) {\n let historyRef = React10.useRef();\n if (historyRef.current == null) {\n historyRef.current = createBrowserHistory({ window: window2, v5Compat: true });\n }\n let history = historyRef.current;\n let [state, setStateImpl] = React10.useState({\n action: history.action,\n location: history.location\n });\n let setState = React10.useCallback(\n (newState) => {\n if (unstable_useTransitions === false) {\n setStateImpl(newState);\n } else {\n React10.startTransition(() => setStateImpl(newState));\n }\n },\n [unstable_useTransitions]\n );\n React10.useLayoutEffect(() => history.listen(setState), [history, setState]);\n return /* @__PURE__ */ React10.createElement(\n Router,\n {\n basename,\n children,\n location: state.location,\n navigationType: state.action,\n navigator: history,\n unstable_useTransitions\n }\n );\n}\nfunction HashRouter({\n basename,\n children,\n unstable_useTransitions,\n window: window2\n}) {\n let historyRef = React10.useRef();\n if (historyRef.current == null) {\n historyRef.current = createHashHistory({ window: window2, v5Compat: true });\n }\n let history = historyRef.current;\n let [state, setStateImpl] = React10.useState({\n action: history.action,\n location: history.location\n });\n let setState = React10.useCallback(\n (newState) => {\n if (unstable_useTransitions === false) {\n setStateImpl(newState);\n } else {\n React10.startTransition(() => setStateImpl(newState));\n }\n },\n [unstable_useTransitions]\n );\n React10.useLayoutEffect(() => history.listen(setState), [history, setState]);\n return /* @__PURE__ */ React10.createElement(\n Router,\n {\n basename,\n children,\n location: state.location,\n navigationType: state.action,\n navigator: history,\n unstable_useTransitions\n }\n );\n}\nfunction HistoryRouter({\n basename,\n children,\n history,\n unstable_useTransitions\n}) {\n let [state, setStateImpl] = React10.useState({\n action: history.action,\n location: history.location\n });\n let setState = React10.useCallback(\n (newState) => {\n if (unstable_useTransitions === false) {\n setStateImpl(newState);\n } else {\n React10.startTransition(() => setStateImpl(newState));\n }\n },\n [unstable_useTransitions]\n );\n React10.useLayoutEffect(() => history.listen(setState), [history, setState]);\n return /* @__PURE__ */ React10.createElement(\n Router,\n {\n basename,\n children,\n location: state.location,\n navigationType: state.action,\n navigator: history,\n unstable_useTransitions\n }\n );\n}\nHistoryRouter.displayName = \"unstable_HistoryRouter\";\nvar ABSOLUTE_URL_REGEX2 = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\nvar Link = React10.forwardRef(\n function LinkWithRef({\n onClick,\n discover = \"render\",\n prefetch = \"none\",\n relative,\n reloadDocument,\n replace: replace2,\n state,\n target,\n to,\n preventScrollReset,\n viewTransition,\n unstable_defaultShouldRevalidate,\n ...rest\n }, forwardedRef) {\n let { basename, unstable_useTransitions } = React10.useContext(NavigationContext);\n let isAbsolute = typeof to === \"string\" && ABSOLUTE_URL_REGEX2.test(to);\n let parsed = parseToInfo(to, basename);\n to = parsed.to;\n let href = useHref(to, { relative });\n let [shouldPrefetch, prefetchRef, prefetchHandlers] = usePrefetchBehavior(\n prefetch,\n rest\n );\n let internalOnClick = useLinkClickHandler(to, {\n replace: replace2,\n state,\n target,\n preventScrollReset,\n relative,\n viewTransition,\n unstable_defaultShouldRevalidate,\n unstable_useTransitions\n });\n function handleClick(event) {\n if (onClick) onClick(event);\n if (!event.defaultPrevented) {\n internalOnClick(event);\n }\n }\n let link = (\n // eslint-disable-next-line jsx-a11y/anchor-has-content\n /* @__PURE__ */ React10.createElement(\n \"a\",\n {\n ...rest,\n ...prefetchHandlers,\n href: parsed.absoluteURL || href,\n onClick: parsed.isExternal || reloadDocument ? onClick : handleClick,\n ref: mergeRefs(forwardedRef, prefetchRef),\n target,\n \"data-discover\": !isAbsolute && discover === \"render\" ? \"true\" : void 0\n }\n )\n );\n return shouldPrefetch && !isAbsolute ? /* @__PURE__ */ React10.createElement(React10.Fragment, null, link, /* @__PURE__ */ React10.createElement(PrefetchPageLinks, { page: href })) : link;\n }\n);\nLink.displayName = \"Link\";\nvar NavLink = React10.forwardRef(\n function NavLinkWithRef({\n \"aria-current\": ariaCurrentProp = \"page\",\n caseSensitive = false,\n className: classNameProp = \"\",\n end = false,\n style: styleProp,\n to,\n viewTransition,\n children,\n ...rest\n }, ref) {\n let path = useResolvedPath(to, { relative: rest.relative });\n let location = useLocation();\n let routerState = React10.useContext(DataRouterStateContext);\n let { navigator, basename } = React10.useContext(NavigationContext);\n let isTransitioning = routerState != null && // Conditional usage is OK here because the usage of a data router is static\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useViewTransitionState(path) && viewTransition === true;\n let toPathname = navigator.encodeLocation ? navigator.encodeLocation(path).pathname : path.pathname;\n let locationPathname = location.pathname;\n let nextLocationPathname = routerState && routerState.navigation && routerState.navigation.location ? routerState.navigation.location.pathname : null;\n if (!caseSensitive) {\n locationPathname = locationPathname.toLowerCase();\n nextLocationPathname = nextLocationPathname ? nextLocationPathname.toLowerCase() : null;\n toPathname = toPathname.toLowerCase();\n }\n if (nextLocationPathname && basename) {\n nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname;\n }\n const endSlashPosition = toPathname !== \"/\" && toPathname.endsWith(\"/\") ? toPathname.length - 1 : toPathname.length;\n let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === \"/\";\n let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(toPathname.length) === \"/\");\n let renderProps = {\n isActive,\n isPending,\n isTransitioning\n };\n let ariaCurrent = isActive ? ariaCurrentProp : void 0;\n let className;\n if (typeof classNameProp === \"function\") {\n className = classNameProp(renderProps);\n } else {\n className = [\n classNameProp,\n isActive ? \"active\" : null,\n isPending ? \"pending\" : null,\n isTransitioning ? \"transitioning\" : null\n ].filter(Boolean).join(\" \");\n }\n let style = typeof styleProp === \"function\" ? styleProp(renderProps) : styleProp;\n return /* @__PURE__ */ React10.createElement(\n Link,\n {\n ...rest,\n \"aria-current\": ariaCurrent,\n className,\n ref,\n style,\n to,\n viewTransition\n },\n typeof children === \"function\" ? children(renderProps) : children\n );\n }\n);\nNavLink.displayName = \"NavLink\";\nvar Form = React10.forwardRef(\n ({\n discover = \"render\",\n fetcherKey,\n navigate,\n reloadDocument,\n replace: replace2,\n state,\n method = defaultMethod,\n action,\n onSubmit,\n relative,\n preventScrollReset,\n viewTransition,\n unstable_defaultShouldRevalidate,\n ...props\n }, forwardedRef) => {\n let { unstable_useTransitions } = React10.useContext(NavigationContext);\n let submit = useSubmit();\n let formAction = useFormAction(action, { relative });\n let formMethod = method.toLowerCase() === \"get\" ? \"get\" : \"post\";\n let isAbsolute = typeof action === \"string\" && ABSOLUTE_URL_REGEX2.test(action);\n let submitHandler = (event) => {\n onSubmit && onSubmit(event);\n if (event.defaultPrevented) return;\n event.preventDefault();\n let submitter = event.nativeEvent.submitter;\n let submitMethod = submitter?.getAttribute(\"formmethod\") || method;\n let doSubmit = () => submit(submitter || event.currentTarget, {\n fetcherKey,\n method: submitMethod,\n navigate,\n replace: replace2,\n state,\n relative,\n preventScrollReset,\n viewTransition,\n unstable_defaultShouldRevalidate\n });\n if (unstable_useTransitions && navigate !== false) {\n React10.startTransition(() => doSubmit());\n } else {\n doSubmit();\n }\n };\n return /* @__PURE__ */ React10.createElement(\n \"form\",\n {\n ref: forwardedRef,\n method: formMethod,\n action: formAction,\n onSubmit: reloadDocument ? onSubmit : submitHandler,\n ...props,\n \"data-discover\": !isAbsolute && discover === \"render\" ? \"true\" : void 0\n }\n );\n }\n);\nForm.displayName = \"Form\";\nfunction ScrollRestoration({\n getKey,\n storageKey,\n ...props\n}) {\n let remixContext = React10.useContext(FrameworkContext);\n let { basename } = React10.useContext(NavigationContext);\n let location = useLocation();\n let matches = useMatches();\n useScrollRestoration({ getKey, storageKey });\n let ssrKey = React10.useMemo(\n () => {\n if (!remixContext || !getKey) return null;\n let userKey = getScrollRestorationKey(\n location,\n matches,\n basename,\n getKey\n );\n return userKey !== location.key ? userKey : null;\n },\n // Nah, we only need this the first time for the SSR render\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n if (!remixContext || remixContext.isSpaMode) {\n return null;\n }\n let restoreScroll = ((storageKey2, restoreKey) => {\n if (!window.history.state || !window.history.state.key) {\n let key = Math.random().toString(32).slice(2);\n window.history.replaceState({ key }, \"\");\n }\n try {\n let positions = JSON.parse(sessionStorage.getItem(storageKey2) || \"{}\");\n let storedY = positions[restoreKey || window.history.state.key];\n if (typeof storedY === \"number\") {\n window.scrollTo(0, storedY);\n }\n } catch (error) {\n console.error(error);\n sessionStorage.removeItem(storageKey2);\n }\n }).toString();\n return /* @__PURE__ */ React10.createElement(\n \"script\",\n {\n ...props,\n suppressHydrationWarning: true,\n dangerouslySetInnerHTML: {\n __html: `(${restoreScroll})(${escapeHtml(\n JSON.stringify(storageKey || SCROLL_RESTORATION_STORAGE_KEY)\n )}, ${escapeHtml(JSON.stringify(ssrKey))})`\n }\n }\n );\n}\nScrollRestoration.displayName = \"ScrollRestoration\";\nfunction getDataRouterConsoleError2(hookName) {\n return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`;\n}\nfunction useDataRouterContext3(hookName) {\n let ctx = React10.useContext(DataRouterContext);\n invariant(ctx, getDataRouterConsoleError2(hookName));\n return ctx;\n}\nfunction useDataRouterState2(hookName) {\n let state = React10.useContext(DataRouterStateContext);\n invariant(state, getDataRouterConsoleError2(hookName));\n return state;\n}\nfunction useLinkClickHandler(to, {\n target,\n replace: replaceProp,\n state,\n preventScrollReset,\n relative,\n viewTransition,\n unstable_defaultShouldRevalidate,\n unstable_useTransitions\n} = {}) {\n let navigate = useNavigate();\n let location = useLocation();\n let path = useResolvedPath(to, { relative });\n return React10.useCallback(\n (event) => {\n if (shouldProcessLinkClick(event, target)) {\n event.preventDefault();\n let replace2 = replaceProp !== void 0 ? replaceProp : createPath(location) === createPath(path);\n let doNavigate = () => navigate(to, {\n replace: replace2,\n state,\n preventScrollReset,\n relative,\n viewTransition,\n unstable_defaultShouldRevalidate\n });\n if (unstable_useTransitions) {\n React10.startTransition(() => doNavigate());\n } else {\n doNavigate();\n }\n }\n },\n [\n location,\n navigate,\n path,\n replaceProp,\n state,\n target,\n to,\n preventScrollReset,\n relative,\n viewTransition,\n unstable_defaultShouldRevalidate,\n unstable_useTransitions\n ]\n );\n}\nfunction useSearchParams(defaultInit) {\n warning(\n typeof URLSearchParams !== \"undefined\",\n `You cannot use the \\`useSearchParams\\` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.`\n );\n let defaultSearchParamsRef = React10.useRef(createSearchParams(defaultInit));\n let hasSetSearchParamsRef = React10.useRef(false);\n let location = useLocation();\n let searchParams = React10.useMemo(\n () => (\n // Only merge in the defaults if we haven't yet called setSearchParams.\n // Once we call that we want those to take precedence, otherwise you can't\n // remove a param with setSearchParams({}) if it has an initial value\n getSearchParamsForLocation(\n location.search,\n hasSetSearchParamsRef.current ? null : defaultSearchParamsRef.current\n )\n ),\n [location.search]\n );\n let navigate = useNavigate();\n let setSearchParams = React10.useCallback(\n (nextInit, navigateOptions) => {\n const newSearchParams = createSearchParams(\n typeof nextInit === \"function\" ? nextInit(new URLSearchParams(searchParams)) : nextInit\n );\n hasSetSearchParamsRef.current = true;\n navigate(\"?\" + newSearchParams, navigateOptions);\n },\n [navigate, searchParams]\n );\n return [searchParams, setSearchParams];\n}\nvar fetcherId = 0;\nvar getUniqueFetcherId = () => `__${String(++fetcherId)}__`;\nfunction useSubmit() {\n let { router } = useDataRouterContext3(\"useSubmit\" /* UseSubmit */);\n let { basename } = React10.useContext(NavigationContext);\n let currentRouteId = useRouteId();\n let routerFetch = router.fetch;\n let routerNavigate = router.navigate;\n return React10.useCallback(\n async (target, options = {}) => {\n let { action, method, encType, formData, body } = getFormSubmissionInfo(\n target,\n basename\n );\n if (options.navigate === false) {\n let key = options.fetcherKey || getUniqueFetcherId();\n await routerFetch(key, currentRouteId, options.action || action, {\n unstable_defaultShouldRevalidate: options.unstable_defaultShouldRevalidate,\n preventScrollReset: options.preventScrollReset,\n formData,\n body,\n formMethod: options.method || method,\n formEncType: options.encType || encType,\n flushSync: options.flushSync\n });\n } else {\n await routerNavigate(options.action || action, {\n unstable_defaultShouldRevalidate: options.unstable_defaultShouldRevalidate,\n preventScrollReset: options.preventScrollReset,\n formData,\n body,\n formMethod: options.method || method,\n formEncType: options.encType || encType,\n replace: options.replace,\n state: options.state,\n fromRouteId: currentRouteId,\n flushSync: options.flushSync,\n viewTransition: options.viewTransition\n });\n }\n },\n [routerFetch, routerNavigate, basename, currentRouteId]\n );\n}\nfunction useFormAction(action, { relative } = {}) {\n let { basename } = React10.useContext(NavigationContext);\n let routeContext = React10.useContext(RouteContext);\n invariant(routeContext, \"useFormAction must be used inside a RouteContext\");\n let [match] = routeContext.matches.slice(-1);\n let path = { ...useResolvedPath(action ? action : \".\", { relative }) };\n let location = useLocation();\n if (action == null) {\n path.search = location.search;\n let params = new URLSearchParams(path.search);\n let indexValues = params.getAll(\"index\");\n let hasNakedIndexParam = indexValues.some((v) => v === \"\");\n if (hasNakedIndexParam) {\n params.delete(\"index\");\n indexValues.filter((v) => v).forEach((v) => params.append(\"index\", v));\n let qs = params.toString();\n path.search = qs ? `?${qs}` : \"\";\n }\n }\n if ((!action || action === \".\") && match.route.index) {\n path.search = path.search ? path.search.replace(/^\\?/, \"?index&\") : \"?index\";\n }\n if (basename !== \"/\") {\n path.pathname = path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n return createPath(path);\n}\nfunction useFetcher({\n key\n} = {}) {\n let { router } = useDataRouterContext3(\"useFetcher\" /* UseFetcher */);\n let state = useDataRouterState2(\"useFetcher\" /* UseFetcher */);\n let fetcherData = React10.useContext(FetchersContext);\n let route = React10.useContext(RouteContext);\n let routeId = route.matches[route.matches.length - 1]?.route.id;\n invariant(fetcherData, `useFetcher must be used inside a FetchersContext`);\n invariant(route, `useFetcher must be used inside a RouteContext`);\n invariant(\n routeId != null,\n `useFetcher can only be used on routes that contain a unique \"id\"`\n );\n let defaultKey = React10.useId();\n let [fetcherKey, setFetcherKey] = React10.useState(key || defaultKey);\n if (key && key !== fetcherKey) {\n setFetcherKey(key);\n }\n let { deleteFetcher, getFetcher, resetFetcher, fetch: routerFetch } = router;\n React10.useEffect(() => {\n getFetcher(fetcherKey);\n return () => deleteFetcher(fetcherKey);\n }, [deleteFetcher, getFetcher, fetcherKey]);\n let load = React10.useCallback(\n async (href, opts) => {\n invariant(routeId, \"No routeId available for fetcher.load()\");\n await routerFetch(fetcherKey, routeId, href, opts);\n },\n [fetcherKey, routeId, routerFetch]\n );\n let submitImpl = useSubmit();\n let submit = React10.useCallback(\n async (target, opts) => {\n await submitImpl(target, {\n ...opts,\n navigate: false,\n fetcherKey\n });\n },\n [fetcherKey, submitImpl]\n );\n let reset = React10.useCallback(\n (opts) => resetFetcher(fetcherKey, opts),\n [resetFetcher, fetcherKey]\n );\n let FetcherForm = React10.useMemo(() => {\n let FetcherForm2 = React10.forwardRef(\n (props, ref) => {\n return /* @__PURE__ */ React10.createElement(Form, { ...props, navigate: false, fetcherKey, ref });\n }\n );\n FetcherForm2.displayName = \"fetcher.Form\";\n return FetcherForm2;\n }, [fetcherKey]);\n let fetcher = state.fetchers.get(fetcherKey) || IDLE_FETCHER;\n let data2 = fetcherData.get(fetcherKey);\n let fetcherWithComponents = React10.useMemo(\n () => ({\n Form: FetcherForm,\n submit,\n load,\n reset,\n ...fetcher,\n data: data2\n }),\n [FetcherForm, submit, load, reset, fetcher, data2]\n );\n return fetcherWithComponents;\n}\nfunction useFetchers() {\n let state = useDataRouterState2(\"useFetchers\" /* UseFetchers */);\n return Array.from(state.fetchers.entries()).map(([key, fetcher]) => ({\n ...fetcher,\n key\n }));\n}\nvar SCROLL_RESTORATION_STORAGE_KEY = \"react-router-scroll-positions\";\nvar savedScrollPositions = {};\nfunction getScrollRestorationKey(location, matches, basename, getKey) {\n let key = null;\n if (getKey) {\n if (basename !== \"/\") {\n key = getKey(\n {\n ...location,\n pathname: stripBasename(location.pathname, basename) || location.pathname\n },\n matches\n );\n } else {\n key = getKey(location, matches);\n }\n }\n if (key == null) {\n key = location.key;\n }\n return key;\n}\nfunction useScrollRestoration({\n getKey,\n storageKey\n} = {}) {\n let { router } = useDataRouterContext3(\"useScrollRestoration\" /* UseScrollRestoration */);\n let { restoreScrollPosition, preventScrollReset } = useDataRouterState2(\n \"useScrollRestoration\" /* UseScrollRestoration */\n );\n let { basename } = React10.useContext(NavigationContext);\n let location = useLocation();\n let matches = useMatches();\n let navigation = useNavigation();\n React10.useEffect(() => {\n window.history.scrollRestoration = \"manual\";\n return () => {\n window.history.scrollRestoration = \"auto\";\n };\n }, []);\n usePageHide(\n React10.useCallback(() => {\n if (navigation.state === \"idle\") {\n let key = getScrollRestorationKey(location, matches, basename, getKey);\n savedScrollPositions[key] = window.scrollY;\n }\n try {\n sessionStorage.setItem(\n storageKey || SCROLL_RESTORATION_STORAGE_KEY,\n JSON.stringify(savedScrollPositions)\n );\n } catch (error) {\n warning(\n false,\n `Failed to save scroll positions in sessionStorage, <ScrollRestoration /> will not work properly (${error}).`\n );\n }\n window.history.scrollRestoration = \"auto\";\n }, [navigation.state, getKey, basename, location, matches, storageKey])\n );\n if (typeof document !== \"undefined\") {\n React10.useLayoutEffect(() => {\n try {\n let sessionPositions = sessionStorage.getItem(\n storageKey || SCROLL_RESTORATION_STORAGE_KEY\n );\n if (sessionPositions) {\n savedScrollPositions = JSON.parse(sessionPositions);\n }\n } catch (e) {\n }\n }, [storageKey]);\n React10.useLayoutEffect(() => {\n let disableScrollRestoration = router?.enableScrollRestoration(\n savedScrollPositions,\n () => window.scrollY,\n getKey ? (location2, matches2) => getScrollRestorationKey(location2, matches2, basename, getKey) : void 0\n );\n return () => disableScrollRestoration && disableScrollRestoration();\n }, [router, basename, getKey]);\n React10.useLayoutEffect(() => {\n if (restoreScrollPosition === false) {\n return;\n }\n if (typeof restoreScrollPosition === \"number\") {\n window.scrollTo(0, restoreScrollPosition);\n return;\n }\n try {\n if (location.hash) {\n let el = document.getElementById(\n decodeURIComponent(location.hash.slice(1))\n );\n if (el) {\n el.scrollIntoView();\n return;\n }\n }\n } catch {\n warning(\n false,\n `\"${location.hash.slice(\n 1\n )}\" is not a decodable element ID. The view will not scroll to it.`\n );\n }\n if (preventScrollReset === true) {\n return;\n }\n window.scrollTo(0, 0);\n }, [location, restoreScrollPosition, preventScrollReset]);\n }\n}\nfunction useBeforeUnload(callback, options) {\n let { capture } = options || {};\n React10.useEffect(() => {\n let opts = capture != null ? { capture } : void 0;\n window.addEventListener(\"beforeunload\", callback, opts);\n return () => {\n window.removeEventListener(\"beforeunload\", callback, opts);\n };\n }, [callback, capture]);\n}\nfunction usePageHide(callback, options) {\n let { capture } = options || {};\n React10.useEffect(() => {\n let opts = capture != null ? { capture } : void 0;\n window.addEventListener(\"pagehide\", callback, opts);\n return () => {\n window.removeEventListener(\"pagehide\", callback, opts);\n };\n }, [callback, capture]);\n}\nfunction usePrompt({\n when,\n message\n}) {\n let blocker = useBlocker(when);\n React10.useEffect(() => {\n if (blocker.state === \"blocked\") {\n let proceed = window.confirm(message);\n if (proceed) {\n setTimeout(blocker.proceed, 0);\n } else {\n blocker.reset();\n }\n }\n }, [blocker, message]);\n React10.useEffect(() => {\n if (blocker.state === \"blocked\" && !when) {\n blocker.reset();\n }\n }, [blocker, when]);\n}\nfunction useViewTransitionState(to, { relative } = {}) {\n let vtContext = React10.useContext(ViewTransitionContext);\n invariant(\n vtContext != null,\n \"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?\"\n );\n let { basename } = useDataRouterContext3(\n \"useViewTransitionState\" /* useViewTransitionState */\n );\n let path = useResolvedPath(to, { relative });\n if (!vtContext.isTransitioning) {\n return false;\n }\n let currentPath = stripBasename(vtContext.currentLocation.pathname, basename) || vtContext.currentLocation.pathname;\n let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname;\n return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null;\n}\n\n// lib/dom/server.tsx\nimport * as React11 from \"react\";\nfunction StaticRouter({\n basename,\n children,\n location: locationProp = \"/\"\n}) {\n if (typeof locationProp === \"string\") {\n locationProp = parsePath(locationProp);\n }\n let action = \"POP\" /* Pop */;\n let location = {\n pathname: locationProp.pathname || \"/\",\n search: locationProp.search || \"\",\n hash: locationProp.hash || \"\",\n state: locationProp.state != null ? locationProp.state : null,\n key: locationProp.key || \"default\"\n };\n let staticNavigator = getStatelessNavigator();\n return /* @__PURE__ */ React11.createElement(\n Router,\n {\n basename,\n children,\n location,\n navigationType: action,\n navigator: staticNavigator,\n static: true,\n unstable_useTransitions: false\n }\n );\n}\nfunction StaticRouterProvider({\n context,\n router,\n hydrate: hydrate2 = true,\n nonce\n}) {\n invariant(\n router && context,\n \"You must provide `router` and `context` to <StaticRouterProvider>\"\n );\n let dataRouterContext = {\n router,\n navigator: getStatelessNavigator(),\n static: true,\n staticContext: context,\n basename: context.basename || \"/\"\n };\n let fetchersContext = /* @__PURE__ */ new Map();\n let hydrateScript = \"\";\n if (hydrate2 !== false) {\n let data2 = {\n loaderData: context.loaderData,\n actionData: context.actionData,\n errors: serializeErrors(context.errors)\n };\n let json = escapeHtml(JSON.stringify(JSON.stringify(data2)));\n hydrateScript = `window.__staticRouterHydrationData = JSON.parse(${json});`;\n }\n let { state } = dataRouterContext.router;\n return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(DataRouterContext.Provider, { value: dataRouterContext }, /* @__PURE__ */ React11.createElement(DataRouterStateContext.Provider, { value: state }, /* @__PURE__ */ React11.createElement(FetchersContext.Provider, { value: fetchersContext }, /* @__PURE__ */ React11.createElement(ViewTransitionContext.Provider, { value: { isTransitioning: false } }, /* @__PURE__ */ React11.createElement(\n Router,\n {\n basename: dataRouterContext.basename,\n location: state.location,\n navigationType: state.historyAction,\n navigator: dataRouterContext.navigator,\n static: dataRouterContext.static,\n unstable_useTransitions: false\n },\n /* @__PURE__ */ React11.createElement(\n DataRoutes2,\n {\n routes: router.routes,\n future: router.future,\n state\n }\n )\n ))))), hydrateScript ? /* @__PURE__ */ React11.createElement(\n \"script\",\n {\n suppressHydrationWarning: true,\n nonce,\n dangerouslySetInnerHTML: { __html: hydrateScript }\n }\n ) : null);\n}\nfunction DataRoutes2({\n routes,\n future,\n state\n}) {\n return useRoutesImpl(routes, void 0, state, void 0, future);\n}\nfunction serializeErrors(errors) {\n if (!errors) return null;\n let entries = Object.entries(errors);\n let serialized = {};\n for (let [key, val] of entries) {\n if (isRouteErrorResponse(val)) {\n serialized[key] = { ...val, __type: \"RouteErrorResponse\" };\n } else if (val instanceof Error) {\n serialized[key] = {\n message: val.message,\n __type: \"Error\",\n // If this is a subclass (i.e., ReferenceError), send up the type so we\n // can re-create the same type during hydration.\n ...val.name !== \"Error\" ? {\n __subType: val.name\n } : {}\n };\n } else {\n serialized[key] = val;\n }\n }\n return serialized;\n}\nfunction getStatelessNavigator() {\n return {\n createHref,\n encodeLocation,\n push(to) {\n throw new Error(\n `You cannot use navigator.push() on the server because it is a stateless environment. This error was probably triggered when you did a \\`navigate(${JSON.stringify(to)})\\` somewhere in your app.`\n );\n },\n replace(to) {\n throw new Error(\n `You cannot use navigator.replace() on the server because it is a stateless environment. This error was probably triggered when you did a \\`navigate(${JSON.stringify(to)}, { replace: true })\\` somewhere in your app.`\n );\n },\n go(delta) {\n throw new Error(\n `You cannot use navigator.go() on the server because it is a stateless environment. This error was probably triggered when you did a \\`navigate(${delta})\\` somewhere in your app.`\n );\n },\n back() {\n throw new Error(\n `You cannot use navigator.back() on the server because it is a stateless environment.`\n );\n },\n forward() {\n throw new Error(\n `You cannot use navigator.forward() on the server because it is a stateless environment.`\n );\n }\n };\n}\nfunction createStaticHandler2(routes, opts) {\n return createStaticHandler(routes, {\n ...opts,\n mapRouteProperties\n });\n}\nfunction createStaticRouter(routes, context, opts = {}) {\n let manifest = {};\n let dataRoutes = convertRoutesToDataRoutes(\n routes,\n mapRouteProperties,\n void 0,\n manifest\n );\n let matches = context.matches.map((match) => {\n let route = manifest[match.route.id] || match.route;\n return {\n ...match,\n route\n };\n });\n let msg = (method) => `You cannot use router.${method}() on the server because it is a stateless environment`;\n return {\n get basename() {\n return context.basename;\n },\n get future() {\n return {\n v8_middleware: false,\n ...opts?.future\n };\n },\n get state() {\n return {\n historyAction: \"POP\" /* Pop */,\n location: context.location,\n matches,\n loaderData: context.loaderData,\n actionData: context.actionData,\n errors: context.errors,\n initialized: true,\n navigation: IDLE_NAVIGATION,\n restoreScrollPosition: null,\n preventScrollReset: false,\n revalidation: \"idle\",\n fetchers: /* @__PURE__ */ new Map(),\n blockers: /* @__PURE__ */ new Map()\n };\n },\n get routes() {\n return dataRoutes;\n },\n get window() {\n return void 0;\n },\n initialize() {\n throw msg(\"initialize\");\n },\n subscribe() {\n throw msg(\"subscribe\");\n },\n enableScrollRestoration() {\n throw msg(\"enableScrollRestoration\");\n },\n navigate() {\n throw msg(\"navigate\");\n },\n fetch() {\n throw msg(\"fetch\");\n },\n revalidate() {\n throw msg(\"revalidate\");\n },\n createHref,\n encodeLocation,\n getFetcher() {\n return IDLE_FETCHER;\n },\n deleteFetcher() {\n throw msg(\"deleteFetcher\");\n },\n resetFetcher() {\n throw msg(\"resetFetcher\");\n },\n dispose() {\n throw msg(\"dispose\");\n },\n getBlocker() {\n return IDLE_BLOCKER;\n },\n deleteBlocker() {\n throw msg(\"deleteBlocker\");\n },\n patchRoutes() {\n throw msg(\"patchRoutes\");\n },\n _internalFetchControllers: /* @__PURE__ */ new Map(),\n _internalSetRoutes() {\n throw msg(\"_internalSetRoutes\");\n },\n _internalSetStateDoNotUseOrYouWillBreakYourApp() {\n throw msg(\"_internalSetStateDoNotUseOrYouWillBreakYourApp\");\n }\n };\n}\nfunction createHref(to) {\n return typeof to === \"string\" ? to : createPath(to);\n}\nfunction encodeLocation(to) {\n let href = typeof to === \"string\" ? to : createPath(to);\n href = href.replace(/ $/, \"%20\");\n let encoded = ABSOLUTE_URL_REGEX3.test(href) ? new URL(href) : new URL(href, \"http://localhost\");\n return {\n pathname: encoded.pathname,\n search: encoded.search,\n hash: encoded.hash\n };\n}\nvar ABSOLUTE_URL_REGEX3 = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\n\nexport {\n Action,\n createMemoryHistory,\n createBrowserHistory,\n createHashHistory,\n invariant,\n createPath,\n parsePath,\n createContext,\n RouterContextProvider,\n convertRoutesToDataRoutes,\n matchRoutes,\n generatePath,\n matchPath,\n stripBasename,\n resolvePath,\n data,\n redirect,\n redirectDocument,\n replace,\n ErrorResponseImpl,\n isRouteErrorResponse,\n instrumentHandler,\n IDLE_NAVIGATION,\n IDLE_FETCHER,\n IDLE_BLOCKER,\n createRouter,\n createStaticHandler,\n getStaticContextFromError,\n isDataWithResponseInit,\n isResponse,\n isRedirectStatusCode,\n isRedirectResponse,\n isMutationMethod,\n DataRouterContext,\n DataRouterStateContext,\n RSCRouterContext,\n ViewTransitionContext,\n FetchersContext,\n AwaitContextProvider,\n NavigationContext,\n LocationContext,\n RouteContext,\n ENABLE_DEV_WARNINGS,\n decodeRedirectErrorDigest,\n decodeRouteErrorResponseDigest,\n useHref,\n useInRouterContext,\n useLocation,\n useNavigationType,\n useMatch,\n useNavigate,\n useOutletContext,\n useOutlet,\n useParams,\n useResolvedPath,\n useRoutes,\n useNavigation,\n useRevalidator,\n useMatches,\n useLoaderData,\n useRouteLoaderData,\n useActionData,\n useRouteError,\n useAsyncValue,\n useAsyncError,\n useBlocker,\n useRoute,\n warnOnce,\n mapRouteProperties,\n hydrationRouteProperties,\n createMemoryRouter,\n RouterProvider,\n MemoryRouter,\n Navigate,\n Outlet,\n Route,\n Router,\n Routes,\n Await,\n createRoutesFromChildren,\n createRoutesFromElements,\n renderMatches,\n WithComponentProps,\n withComponentProps,\n WithHydrateFallbackProps,\n withHydrateFallbackProps,\n WithErrorBoundaryProps,\n withErrorBoundaryProps,\n createSearchParams,\n escapeHtml,\n encode,\n createRequestInit,\n SingleFetchRedirectSymbol,\n SINGLE_FETCH_REDIRECT_STATUS,\n NO_BODY_STATUS_CODES,\n StreamTransfer,\n getTurboStreamSingleFetchDataStrategy,\n getSingleFetchDataStrategyImpl,\n stripIndexParam,\n singleFetchUrl,\n decodeViaTurboStream,\n RemixErrorBoundary,\n createServerRoutes,\n createClientRoutesWithHMRRevalidationOptOut,\n noActionDefinedError,\n createClientRoutes,\n shouldHydrateRouteLoader,\n getPatchRoutesOnNavigationFunction,\n useFogOFWarDiscovery,\n getManifestPath,\n FrameworkContext,\n CRITICAL_CSS_DATA_ATTRIBUTE,\n Links,\n PrefetchPageLinks,\n Meta,\n setIsHydrated,\n Scripts,\n createBrowserRouter,\n createHashRouter,\n BrowserRouter,\n HashRouter,\n HistoryRouter,\n Link,\n NavLink,\n Form,\n ScrollRestoration,\n useLinkClickHandler,\n useSearchParams,\n useSubmit,\n useFormAction,\n useFetcher,\n useFetchers,\n useScrollRestoration,\n useBeforeUnload,\n usePrompt,\n useViewTransitionState,\n StaticRouter,\n StaticRouterProvider,\n createStaticHandler2,\n createStaticRouter\n};\n","/**\n * react-router v7.12.0\n *\n * Copyright (c) Remix Software Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.md file in the root directory of this source tree.\n *\n * @license MIT\n */\n\"use client\";\nimport {\n RSCRouterGlobalErrorBoundary,\n deserializeErrors,\n getHydrationData,\n populateRSCRouteModules\n} from \"./chunk-FNSCYPCZ.mjs\";\nimport {\n CRITICAL_CSS_DATA_ATTRIBUTE,\n ErrorResponseImpl,\n FrameworkContext,\n RSCRouterContext,\n RemixErrorBoundary,\n RouterProvider,\n createBrowserHistory,\n createClientRoutes,\n createClientRoutesWithHMRRevalidationOptOut,\n createContext,\n createRequestInit,\n createRouter,\n decodeViaTurboStream,\n getPatchRoutesOnNavigationFunction,\n getSingleFetchDataStrategyImpl,\n getTurboStreamSingleFetchDataStrategy,\n hydrationRouteProperties,\n invariant,\n isMutationMethod,\n mapRouteProperties,\n noActionDefinedError,\n setIsHydrated,\n shouldHydrateRouteLoader,\n singleFetchUrl,\n stripIndexParam,\n useFogOFWarDiscovery\n} from \"./chunk-EPOLDU6W.mjs\";\n\n// lib/dom-export/dom-router-provider.tsx\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nfunction RouterProvider2(props) {\n return /* @__PURE__ */ React.createElement(RouterProvider, { flushSync: ReactDOM.flushSync, ...props });\n}\n\n// lib/dom-export/hydrated-router.tsx\nimport * as React2 from \"react\";\nvar ssrInfo = null;\nvar router = null;\nfunction initSsrInfo() {\n if (!ssrInfo && window.__reactRouterContext && window.__reactRouterManifest && window.__reactRouterRouteModules) {\n if (window.__reactRouterManifest.sri === true) {\n const importMap = document.querySelector(\"script[rr-importmap]\");\n if (importMap?.textContent) {\n try {\n window.__reactRouterManifest.sri = JSON.parse(\n importMap.textContent\n ).integrity;\n } catch (err) {\n console.error(\"Failed to parse import map\", err);\n }\n }\n }\n ssrInfo = {\n context: window.__reactRouterContext,\n manifest: window.__reactRouterManifest,\n routeModules: window.__reactRouterRouteModules,\n stateDecodingPromise: void 0,\n router: void 0,\n routerInitialized: false\n };\n }\n}\nfunction createHydratedRouter({\n getContext,\n unstable_instrumentations\n}) {\n initSsrInfo();\n if (!ssrInfo) {\n throw new Error(\n \"You must be using the SSR features of React Router in order to skip passing a `router` prop to `<RouterProvider>`\"\n );\n }\n let localSsrInfo = ssrInfo;\n if (!ssrInfo.stateDecodingPromise) {\n let stream = ssrInfo.context.stream;\n invariant(stream, \"No stream found for single fetch decoding\");\n ssrInfo.context.stream = void 0;\n ssrInfo.stateDecodingPromise = decodeViaTurboStream(stream, window).then((value) => {\n ssrInfo.context.state = value.value;\n localSsrInfo.stateDecodingPromise.value = true;\n }).catch((e) => {\n localSsrInfo.stateDecodingPromise.error = e;\n });\n }\n if (ssrInfo.stateDecodingPromise.error) {\n throw ssrInfo.stateDecodingPromise.error;\n }\n if (!ssrInfo.stateDecodingPromise.value) {\n throw ssrInfo.stateDecodingPromise;\n }\n let routes = createClientRoutes(\n ssrInfo.manifest.routes,\n ssrInfo.routeModules,\n ssrInfo.context.state,\n ssrInfo.context.ssr,\n ssrInfo.context.isSpaMode\n );\n let hydrationData = void 0;\n if (ssrInfo.context.isSpaMode) {\n let { loaderData } = ssrInfo.context.state;\n if (ssrInfo.manifest.routes.root?.hasLoader && loaderData && \"root\" in loaderData) {\n hydrationData = {\n loaderData: {\n root: loaderData.root\n }\n };\n }\n } else {\n hydrationData = getHydrationData({\n state: ssrInfo.context.state,\n routes,\n getRouteInfo: (routeId) => ({\n clientLoader: ssrInfo.routeModules[routeId]?.clientLoader,\n hasLoader: ssrInfo.manifest.routes[routeId]?.hasLoader === true,\n hasHydrateFallback: ssrInfo.routeModules[routeId]?.HydrateFallback != null\n }),\n location: window.location,\n basename: window.__reactRouterContext?.basename,\n isSpaMode: ssrInfo.context.isSpaMode\n });\n if (hydrationData && hydrationData.errors) {\n hydrationData.errors = deserializeErrors(hydrationData.errors);\n }\n }\n let router2 = createRouter({\n routes,\n history: createBrowserHistory(),\n basename: ssrInfo.context.basename,\n getContext,\n hydrationData,\n hydrationRouteProperties,\n unstable_instrumentations,\n mapRouteProperties,\n future: {\n middleware: ssrInfo.context.future.v8_middleware\n },\n dataStrategy: getTurboStreamSingleFetchDataStrategy(\n () => router2,\n ssrInfo.manifest,\n ssrInfo.routeModules,\n ssrInfo.context.ssr,\n ssrInfo.context.basename,\n ssrInfo.context.future.unstable_trailingSlashAwareDataRequests\n ),\n patchRoutesOnNavigation: getPatchRoutesOnNavigationFunction(\n ssrInfo.manifest,\n ssrInfo.routeModules,\n ssrInfo.context.ssr,\n ssrInfo.context.routeDiscovery,\n ssrInfo.context.isSpaMode,\n ssrInfo.context.basename\n )\n });\n ssrInfo.router = router2;\n if (router2.state.initialized) {\n ssrInfo.routerInitialized = true;\n router2.initialize();\n }\n router2.createRoutesForHMR = /* spacer so ts-ignore does not affect the right hand of the assignment */\n createClientRoutesWithHMRRevalidationOptOut;\n window.__reactRouterDataRouter = router2;\n return router2;\n}\nfunction HydratedRouter(props) {\n if (!router) {\n router = createHydratedRouter({\n getContext: props.getContext,\n unstable_instrumentations: props.unstable_instrumentations\n });\n }\n let [criticalCss, setCriticalCss] = React2.useState(\n process.env.NODE_ENV === \"development\" ? ssrInfo?.context.criticalCss : void 0\n );\n React2.useEffect(() => {\n if (process.env.NODE_ENV === \"development\") {\n setCriticalCss(void 0);\n }\n }, []);\n React2.useEffect(() => {\n if (process.env.NODE_ENV === \"development\" && criticalCss === void 0) {\n document.querySelectorAll(`[${CRITICAL_CSS_DATA_ATTRIBUTE}]`).forEach((element) => element.remove());\n }\n }, [criticalCss]);\n let [location2, setLocation] = React2.useState(router.state.location);\n React2.useLayoutEffect(() => {\n if (ssrInfo && ssrInfo.router && !ssrInfo.routerInitialized) {\n ssrInfo.routerInitialized = true;\n ssrInfo.router.initialize();\n }\n }, []);\n React2.useLayoutEffect(() => {\n if (ssrInfo && ssrInfo.router) {\n return ssrInfo.router.subscribe((newState) => {\n if (newState.location !== location2) {\n setLocation(newState.location);\n }\n });\n }\n }, [location2]);\n invariant(ssrInfo, \"ssrInfo unavailable for HydratedRouter\");\n useFogOFWarDiscovery(\n router,\n ssrInfo.manifest,\n ssrInfo.routeModules,\n ssrInfo.context.ssr,\n ssrInfo.context.routeDiscovery,\n ssrInfo.context.isSpaMode\n );\n return (\n // This fragment is important to ensure we match the <ServerRouter> JSX\n // structure so that useId values hydrate correctly\n /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(\n FrameworkContext.Provider,\n {\n value: {\n manifest: ssrInfo.manifest,\n routeModules: ssrInfo.routeModules,\n future: ssrInfo.context.future,\n criticalCss,\n ssr: ssrInfo.context.ssr,\n isSpaMode: ssrInfo.context.isSpaMode,\n routeDiscovery: ssrInfo.context.routeDiscovery\n }\n },\n /* @__PURE__ */ React2.createElement(RemixErrorBoundary, { location: location2 }, /* @__PURE__ */ React2.createElement(\n RouterProvider2,\n {\n router,\n unstable_useTransitions: props.unstable_useTransitions,\n onError: props.onError\n }\n ))\n ), /* @__PURE__ */ React2.createElement(React2.Fragment, null))\n );\n}\n\n// lib/rsc/browser.tsx\nimport * as React3 from \"react\";\nimport * as ReactDOM2 from \"react-dom\";\nfunction createCallServer({\n createFromReadableStream,\n createTemporaryReferenceSet,\n encodeReply,\n fetch: fetchImplementation = fetch\n}) {\n const globalVar = window;\n let landedActionId = 0;\n return async (id, args) => {\n let actionId = globalVar.__routerActionID = (globalVar.__routerActionID ?? (globalVar.__routerActionID = 0)) + 1;\n const temporaryReferences = createTemporaryReferenceSet();\n const payloadPromise = fetchImplementation(\n new Request(location.href, {\n body: await encodeReply(args, { temporaryReferences }),\n method: \"POST\",\n headers: {\n Accept: \"text/x-component\",\n \"rsc-action-id\": id\n }\n })\n ).then((response) => {\n if (!response.body) {\n throw new Error(\"No response body\");\n }\n return createFromReadableStream(response.body, {\n temporaryReferences\n });\n });\n React3.startTransition(\n () => (\n // @ts-expect-error - Needs React 19 types\n Promise.resolve(payloadPromise).then(async (payload) => {\n if (payload.type === \"redirect\") {\n if (payload.reload || isExternalLocation(payload.location)) {\n window.location.href = payload.location;\n return;\n }\n React3.startTransition(() => {\n globalVar.__reactRouterDataRouter.navigate(payload.location, {\n replace: payload.replace\n });\n });\n return;\n }\n if (payload.type !== \"action\") {\n throw new Error(\"Unexpected payload type\");\n }\n const rerender = await payload.rerender;\n if (rerender && landedActionId < actionId && globalVar.__routerActionID <= actionId) {\n if (rerender.type === \"redirect\") {\n if (rerender.reload || isExternalLocation(rerender.location)) {\n window.location.href = rerender.location;\n return;\n }\n React3.startTransition(() => {\n globalVar.__reactRouterDataRouter.navigate(rerender.location, {\n replace: rerender.replace\n });\n });\n return;\n }\n React3.startTransition(() => {\n let lastMatch;\n for (const match of rerender.matches) {\n globalVar.__reactRouterDataRouter.patchRoutes(\n lastMatch?.id ?? null,\n [createRouteFromServerManifest(match)],\n true\n );\n lastMatch = match;\n }\n window.__reactRouterDataRouter._internalSetStateDoNotUseOrYouWillBreakYourApp(\n {\n loaderData: Object.assign(\n {},\n globalVar.__reactRouterDataRouter.state.loaderData,\n rerender.loaderData\n ),\n errors: rerender.errors ? Object.assign(\n {},\n globalVar.__reactRouterDataRouter.state.errors,\n rerender.errors\n ) : null\n }\n );\n });\n }\n }).catch(() => {\n })\n )\n );\n return payloadPromise.then((payload) => {\n if (payload.type !== \"action\" && payload.type !== \"redirect\") {\n throw new Error(\"Unexpected payload type\");\n }\n return payload.actionResult;\n });\n };\n}\nfunction createRouterFromPayload({\n fetchImplementation,\n createFromReadableStream,\n getContext,\n payload\n}) {\n const globalVar = window;\n if (globalVar.__reactRouterDataRouter && globalVar.__reactRouterRouteModules)\n return {\n router: globalVar.__reactRouterDataRouter,\n routeModules: globalVar.__reactRouterRouteModules\n };\n if (payload.type !== \"render\") throw new Error(\"Invalid payload type\");\n globalVar.__reactRouterRouteModules = globalVar.__reactRouterRouteModules ?? {};\n populateRSCRouteModules(globalVar.__reactRouterRouteModules, payload.matches);\n let patches = /* @__PURE__ */ new Map();\n payload.patches?.forEach((patch) => {\n invariant(patch.parentId, \"Invalid patch parentId\");\n if (!patches.has(patch.parentId)) {\n patches.set(patch.parentId, []);\n }\n patches.get(patch.parentId)?.push(patch);\n });\n let routes = payload.matches.reduceRight((previous, match) => {\n const route = createRouteFromServerManifest(\n match,\n payload\n );\n if (previous.length > 0) {\n route.children = previous;\n let childrenToPatch = patches.get(match.id);\n if (childrenToPatch) {\n route.children.push(\n ...childrenToPatch.map((r) => createRouteFromServerManifest(r))\n );\n }\n }\n return [route];\n }, []);\n globalVar.__reactRouterDataRouter = createRouter({\n routes,\n getContext,\n basename: payload.basename,\n history: createBrowserHistory(),\n hydrationData: getHydrationData({\n state: {\n loaderData: payload.loaderData,\n actionData: payload.actionData,\n errors: payload.errors\n },\n routes,\n getRouteInfo: (routeId) => {\n let match = payload.matches.find((m) => m.id === routeId);\n invariant(match, \"Route not found in payload\");\n return {\n clientLoader: match.clientLoader,\n hasLoader: match.hasLoader,\n hasHydrateFallback: match.hydrateFallbackElement != null\n };\n },\n location: payload.location,\n basename: payload.basename,\n isSpaMode: false\n }),\n async patchRoutesOnNavigation({ path, signal }) {\n if (discoveredPaths.has(path)) {\n return;\n }\n await fetchAndApplyManifestPatches(\n [path],\n createFromReadableStream,\n fetchImplementation,\n signal\n );\n },\n // FIXME: Pass `build.ssr` into this function\n dataStrategy: getRSCSingleFetchDataStrategy(\n () => globalVar.__reactRouterDataRouter,\n true,\n payload.basename,\n createFromReadableStream,\n fetchImplementation\n )\n });\n if (globalVar.__reactRouterDataRouter.state.initialized) {\n globalVar.__routerInitialized = true;\n globalVar.__reactRouterDataRouter.initialize();\n } else {\n globalVar.__routerInitialized = false;\n }\n let lastLoaderData = void 0;\n globalVar.__reactRouterDataRouter.subscribe(({ loaderData, actionData }) => {\n if (lastLoaderData !== loaderData) {\n globalVar.__routerActionID = (globalVar.__routerActionID ?? (globalVar.__routerActionID = 0)) + 1;\n }\n });\n globalVar.__reactRouterDataRouter._updateRoutesForHMR = (routeUpdateByRouteId) => {\n const oldRoutes = window.__reactRouterDataRouter.routes;\n const newRoutes = [];\n function walkRoutes(routes2, parentId) {\n return routes2.map((route) => {\n const routeUpdate = routeUpdateByRouteId.get(route.id);\n if (routeUpdate) {\n const {\n routeModule,\n hasAction,\n hasComponent,\n hasErrorBoundary,\n hasLoader\n } = routeUpdate;\n const newRoute = createRouteFromServerManifest({\n clientAction: routeModule.clientAction,\n clientLoader: routeModule.clientLoader,\n element: route.element,\n errorElement: route.errorElement,\n handle: route.handle,\n hasAction,\n hasComponent,\n hasErrorBoundary,\n hasLoader,\n hydrateFallbackElement: route.hydrateFallbackElement,\n id: route.id,\n index: route.index,\n links: routeModule.links,\n meta: routeModule.meta,\n parentId,\n path: route.path,\n shouldRevalidate: routeModule.shouldRevalidate\n });\n if (route.children) {\n newRoute.children = walkRoutes(route.children, route.id);\n }\n return newRoute;\n }\n const updatedRoute = { ...route };\n if (route.children) {\n updatedRoute.children = walkRoutes(route.children, route.id);\n }\n return updatedRoute;\n });\n }\n newRoutes.push(\n ...walkRoutes(oldRoutes, void 0)\n );\n window.__reactRouterDataRouter._internalSetRoutes(newRoutes);\n };\n return {\n router: globalVar.__reactRouterDataRouter,\n routeModules: globalVar.__reactRouterRouteModules\n };\n}\nvar renderedRoutesContext = createContext();\nfunction getRSCSingleFetchDataStrategy(getRouter, ssr, basename, createFromReadableStream, fetchImplementation) {\n let dataStrategy = getSingleFetchDataStrategyImpl(\n getRouter,\n (match) => {\n let M = match;\n return {\n hasLoader: M.route.hasLoader,\n hasClientLoader: M.route.hasClientLoader,\n hasComponent: M.route.hasComponent,\n hasAction: M.route.hasAction,\n hasClientAction: M.route.hasClientAction,\n hasShouldRevalidate: M.route.hasShouldRevalidate\n };\n },\n // pass map into fetchAndDecode so it can add payloads\n getFetchAndDecodeViaRSC(createFromReadableStream, fetchImplementation),\n ssr,\n basename,\n // .rsc requests are always trailing slash aware\n true,\n // If the route has a component but we don't have an element, we need to hit\n // the server loader flow regardless of whether the client loader calls\n // `serverLoader` or not, otherwise we'll have nothing to render.\n (match) => {\n let M = match;\n return M.route.hasComponent && !M.route.element;\n }\n );\n return async (args) => args.runClientMiddleware(async () => {\n let context = args.context;\n context.set(renderedRoutesContext, []);\n let results = await dataStrategy(args);\n const renderedRoutesById = /* @__PURE__ */ new Map();\n for (const route of context.get(renderedRoutesContext)) {\n if (!renderedRoutesById.has(route.id)) {\n renderedRoutesById.set(route.id, []);\n }\n renderedRoutesById.get(route.id).push(route);\n }\n React3.startTransition(() => {\n for (const match of args.matches) {\n const renderedRoutes = renderedRoutesById.get(match.route.id);\n if (renderedRoutes) {\n for (const rendered of renderedRoutes) {\n window.__reactRouterDataRouter.patchRoutes(\n rendered.parentId ?? null,\n [createRouteFromServerManifest(rendered)],\n true\n );\n }\n }\n }\n });\n return results;\n });\n}\nfunction getFetchAndDecodeViaRSC(createFromReadableStream, fetchImplementation) {\n return async (args, basename, trailingSlashAware, targetRoutes) => {\n let { request, context } = args;\n let url = singleFetchUrl(request.url, basename, trailingSlashAware, \"rsc\");\n if (request.method === \"GET\") {\n url = stripIndexParam(url);\n if (targetRoutes) {\n url.searchParams.set(\"_routes\", targetRoutes.join(\",\"));\n }\n }\n let res = await fetchImplementation(\n new Request(url, await createRequestInit(request))\n );\n if (res.status >= 400 && !res.headers.has(\"X-Remix-Response\")) {\n throw new ErrorResponseImpl(res.status, res.statusText, await res.text());\n }\n invariant(res.body, \"No response body to decode\");\n try {\n const payload = await createFromReadableStream(res.body, {\n temporaryReferences: void 0\n });\n if (payload.type === \"redirect\") {\n return {\n status: res.status,\n data: {\n redirect: {\n redirect: payload.location,\n reload: payload.reload,\n replace: payload.replace,\n revalidate: false,\n status: payload.status\n }\n }\n };\n }\n if (payload.type !== \"render\") {\n throw new Error(\"Unexpected payload type\");\n }\n context.get(renderedRoutesContext).push(...payload.matches);\n let results = { routes: {} };\n const dataKey = isMutationMethod(request.method) ? \"actionData\" : \"loaderData\";\n for (let [routeId, data] of Object.entries(payload[dataKey] || {})) {\n results.routes[routeId] = { data };\n }\n if (payload.errors) {\n for (let [routeId, error] of Object.entries(payload.errors)) {\n results.routes[routeId] = { error };\n }\n }\n return { status: res.status, data: results };\n } catch (e) {\n throw new Error(\"Unable to decode RSC response\");\n }\n };\n}\nfunction RSCHydratedRouter({\n createFromReadableStream,\n fetch: fetchImplementation = fetch,\n payload,\n routeDiscovery = \"eager\",\n getContext\n}) {\n if (payload.type !== \"render\") throw new Error(\"Invalid payload type\");\n let { router: router2, routeModules } = React3.useMemo(\n () => createRouterFromPayload({\n payload,\n fetchImplementation,\n getContext,\n createFromReadableStream\n }),\n [createFromReadableStream, payload, fetchImplementation, getContext]\n );\n React3.useEffect(() => {\n setIsHydrated();\n }, []);\n React3.useLayoutEffect(() => {\n const globalVar = window;\n if (!globalVar.__routerInitialized) {\n globalVar.__routerInitialized = true;\n globalVar.__reactRouterDataRouter.initialize();\n }\n }, []);\n let [{ routes, state }, setState] = React3.useState(() => ({\n routes: cloneRoutes(router2.routes),\n state: router2.state\n }));\n React3.useLayoutEffect(\n () => router2.subscribe((newState) => {\n if (diffRoutes(router2.routes, routes))\n React3.startTransition(() => {\n setState({\n routes: cloneRoutes(router2.routes),\n state: newState\n });\n });\n }),\n [router2.subscribe, routes, router2]\n );\n const transitionEnabledRouter = React3.useMemo(\n () => ({\n ...router2,\n state,\n routes\n }),\n [router2, routes, state]\n );\n React3.useEffect(() => {\n if (routeDiscovery === \"lazy\" || // @ts-expect-error - TS doesn't know about this yet\n window.navigator?.connection?.saveData === true) {\n return;\n }\n function registerElement(el) {\n let path = el.tagName === \"FORM\" ? el.getAttribute(\"action\") : el.getAttribute(\"href\");\n if (!path) {\n return;\n }\n let pathname = el.tagName === \"A\" ? el.pathname : new URL(path, window.location.origin).pathname;\n if (!discoveredPaths.has(pathname)) {\n nextPaths.add(pathname);\n }\n }\n async function fetchPatches() {\n document.querySelectorAll(\"a[data-discover], form[data-discover]\").forEach(registerElement);\n let paths = Array.from(nextPaths.keys()).filter((path) => {\n if (discoveredPaths.has(path)) {\n nextPaths.delete(path);\n return false;\n }\n return true;\n });\n if (paths.length === 0) {\n return;\n }\n try {\n await fetchAndApplyManifestPatches(\n paths,\n createFromReadableStream,\n fetchImplementation\n );\n } catch (e) {\n console.error(\"Failed to fetch manifest patches\", e);\n }\n }\n let debouncedFetchPatches = debounce(fetchPatches, 100);\n fetchPatches();\n let observer = new MutationObserver(() => debouncedFetchPatches());\n observer.observe(document.documentElement, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: [\"data-discover\", \"href\", \"action\"]\n });\n }, [routeDiscovery, createFromReadableStream, fetchImplementation]);\n const frameworkContext = {\n future: {\n // These flags have no runtime impact so can always be false. If we add\n // flags that drive runtime behavior they'll need to be proxied through.\n v8_middleware: false,\n unstable_subResourceIntegrity: false,\n unstable_trailingSlashAwareDataRequests: true\n // always on for RSC\n },\n isSpaMode: false,\n ssr: true,\n criticalCss: \"\",\n manifest: {\n routes: {},\n version: \"1\",\n url: \"\",\n entry: {\n module: \"\",\n imports: []\n }\n },\n routeDiscovery: { mode: \"lazy\", manifestPath: \"/__manifest\" },\n routeModules\n };\n return /* @__PURE__ */ React3.createElement(RSCRouterContext.Provider, { value: true }, /* @__PURE__ */ React3.createElement(RSCRouterGlobalErrorBoundary, { location: state.location }, /* @__PURE__ */ React3.createElement(FrameworkContext.Provider, { value: frameworkContext }, /* @__PURE__ */ React3.createElement(\n RouterProvider,\n {\n router: transitionEnabledRouter,\n flushSync: ReactDOM2.flushSync\n }\n ))));\n}\nfunction createRouteFromServerManifest(match, payload) {\n let hasInitialData = payload && match.id in payload.loaderData;\n let initialData = payload?.loaderData[match.id];\n let hasInitialError = payload?.errors && match.id in payload.errors;\n let initialError = payload?.errors?.[match.id];\n let isHydrationRequest = match.clientLoader?.hydrate === true || !match.hasLoader || // If the route has a component but we don't have an element, we need to hit\n // the server loader flow regardless of whether the client loader calls\n // `serverLoader` or not, otherwise we'll have nothing to render.\n match.hasComponent && !match.element;\n invariant(window.__reactRouterRouteModules);\n populateRSCRouteModules(window.__reactRouterRouteModules, match);\n let dataRoute = {\n id: match.id,\n element: match.element,\n errorElement: match.errorElement,\n handle: match.handle,\n hasErrorBoundary: match.hasErrorBoundary,\n hydrateFallbackElement: match.hydrateFallbackElement,\n index: match.index,\n loader: match.clientLoader ? async (args, singleFetch) => {\n try {\n let result = await match.clientLoader({\n ...args,\n serverLoader: () => {\n preventInvalidServerHandlerCall(\n \"loader\",\n match.id,\n match.hasLoader\n );\n if (isHydrationRequest) {\n if (hasInitialData) {\n return initialData;\n }\n if (hasInitialError) {\n throw initialError;\n }\n }\n return callSingleFetch(singleFetch);\n }\n });\n return result;\n } finally {\n isHydrationRequest = false;\n }\n } : (\n // We always make the call in this RSC world since even if we don't\n // have a `loader` we may need to get the `element` implementation\n (_, singleFetch) => callSingleFetch(singleFetch)\n ),\n action: match.clientAction ? (args, singleFetch) => match.clientAction({\n ...args,\n serverAction: async () => {\n preventInvalidServerHandlerCall(\n \"action\",\n match.id,\n match.hasLoader\n );\n return await callSingleFetch(singleFetch);\n }\n }) : match.hasAction ? (_, singleFetch) => callSingleFetch(singleFetch) : () => {\n throw noActionDefinedError(\"action\", match.id);\n },\n path: match.path,\n shouldRevalidate: match.shouldRevalidate,\n // We always have a \"loader\" in this RSC world since even if we don't\n // have a `loader` we may need to get the `element` implementation\n hasLoader: true,\n hasClientLoader: match.clientLoader != null,\n hasAction: match.hasAction,\n hasClientAction: match.clientAction != null,\n hasShouldRevalidate: match.shouldRevalidate != null\n };\n if (typeof dataRoute.loader === \"function\") {\n dataRoute.loader.hydrate = shouldHydrateRouteLoader(\n match.id,\n match.clientLoader,\n match.hasLoader,\n false\n );\n }\n return dataRoute;\n}\nfunction callSingleFetch(singleFetch) {\n invariant(typeof singleFetch === \"function\", \"Invalid singleFetch parameter\");\n return singleFetch();\n}\nfunction preventInvalidServerHandlerCall(type, routeId, hasHandler) {\n if (!hasHandler) {\n let fn = type === \"action\" ? \"serverAction()\" : \"serverLoader()\";\n let msg = `You are trying to call ${fn} on a route that does not have a server ${type} (routeId: \"${routeId}\")`;\n console.error(msg);\n throw new ErrorResponseImpl(400, \"Bad Request\", new Error(msg), true);\n }\n}\nvar nextPaths = /* @__PURE__ */ new Set();\nvar discoveredPathsMaxSize = 1e3;\nvar discoveredPaths = /* @__PURE__ */ new Set();\nvar URL_LIMIT = 7680;\nfunction getManifestUrl(paths) {\n if (paths.length === 0) {\n return null;\n }\n if (paths.length === 1) {\n return new URL(`${paths[0]}.manifest`, window.location.origin);\n }\n const globalVar = window;\n let basename = (globalVar.__reactRouterDataRouter.basename ?? \"\").replace(\n /^\\/|\\/$/g,\n \"\"\n );\n let url = new URL(`${basename}/.manifest`, window.location.origin);\n url.searchParams.set(\"paths\", paths.sort().join(\",\"));\n return url;\n}\nasync function fetchAndApplyManifestPatches(paths, createFromReadableStream, fetchImplementation, signal) {\n let url = getManifestUrl(paths);\n if (url == null) {\n return;\n }\n if (url.toString().length > URL_LIMIT) {\n nextPaths.clear();\n return;\n }\n let response = await fetchImplementation(new Request(url, { signal }));\n if (!response.body || response.status < 200 || response.status >= 300) {\n throw new Error(\"Unable to fetch new route matches from the server\");\n }\n let payload = await createFromReadableStream(response.body, {\n temporaryReferences: void 0\n });\n if (payload.type !== \"manifest\") {\n throw new Error(\"Failed to patch routes\");\n }\n paths.forEach((p) => addToFifoQueue(p, discoveredPaths));\n React3.startTransition(() => {\n payload.patches.forEach((p) => {\n window.__reactRouterDataRouter.patchRoutes(\n p.parentId ?? null,\n [createRouteFromServerManifest(p)]\n );\n });\n });\n}\nfunction addToFifoQueue(path, queue) {\n if (queue.size >= discoveredPathsMaxSize) {\n let first = queue.values().next().value;\n if (typeof first === \"string\") queue.delete(first);\n }\n queue.add(path);\n}\nfunction debounce(callback, wait) {\n let timeoutId;\n return (...args) => {\n window.clearTimeout(timeoutId);\n timeoutId = window.setTimeout(() => callback(...args), wait);\n };\n}\nfunction isExternalLocation(location2) {\n const newLocation = new URL(location2, window.location.href);\n return newLocation.origin !== window.location.origin;\n}\nfunction cloneRoutes(routes) {\n if (!routes) return void 0;\n return routes.map((route) => ({\n ...route,\n children: cloneRoutes(route.children)\n }));\n}\nfunction diffRoutes(a, b) {\n if (a.length !== b.length) return true;\n return a.some((route, index) => {\n if (route.element !== b[index].element) return true;\n if (route.errorElement !== b[index].errorElement)\n return true;\n if (route.hydrateFallbackElement !== b[index].hydrateFallbackElement)\n return true;\n if (route.hasErrorBoundary !== b[index].hasErrorBoundary)\n return true;\n if (route.hasLoader !== b[index].hasLoader) return true;\n if (route.hasClientLoader !== b[index].hasClientLoader)\n return true;\n if (route.hasAction !== b[index].hasAction) return true;\n if (route.hasClientAction !== b[index].hasClientAction)\n return true;\n return diffRoutes(route.children || [], b[index].children || []);\n });\n}\n\n// lib/rsc/html-stream/browser.ts\nfunction getRSCStream() {\n let encoder = new TextEncoder();\n let streamController = null;\n let rscStream = new ReadableStream({\n start(controller) {\n if (typeof window === \"undefined\") {\n return;\n }\n let handleChunk = (chunk) => {\n if (typeof chunk === \"string\") {\n controller.enqueue(encoder.encode(chunk));\n } else {\n controller.enqueue(chunk);\n }\n };\n window.__FLIGHT_DATA || (window.__FLIGHT_DATA = []);\n window.__FLIGHT_DATA.forEach(handleChunk);\n window.__FLIGHT_DATA.push = (chunk) => {\n handleChunk(chunk);\n return 0;\n };\n streamController = controller;\n }\n });\n if (typeof document !== \"undefined\" && document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => {\n streamController?.close();\n });\n } else {\n streamController?.close();\n }\n return rscStream;\n}\nexport {\n HydratedRouter,\n RouterProvider2 as RouterProvider,\n RSCHydratedRouter as unstable_RSCHydratedRouter,\n createCallServer as unstable_createCallServer,\n getRSCStream as unstable_getRSCStream\n};\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n","import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n","/**\n * Chat image attachments — the WIRE contract.\n *\n * Transport lives in `@wolffm/cdn-client` (upload, `urlFor`, catalogue search,\n * the accepted-type and size limits it parity-tests against the `cdn-api`\n * worker). What remains here is the part that package deliberately does not\n * own: **the shape watchparty puts on the wire and validates on both sides.**\n *\n * This module must stay free of `@wolffm/cdn-client`, and that is structural\n * rather than stylistic — `@watchparty/shared` is imported by the SERVER, and\n * the key predicate below is what `ChatSend`/`ChatBroadcast` validate with. A\n * browser-oriented client package has no business in the server's bundle.\n *\n * **A chat message persists the KEY, never an absolute URL.** `cdn.hadoku.me`\n * is same-site with the app, which was a deliberate trade-off, and the\n * isolation upgrade (a separate registrable domain) is still on the table.\n * Storing keys makes that move a config change; storing absolute URLs would\n * make it a migration over all chat history — the most expensive place in this\n * system to be wrong. Every app that hotlinked Tenor GIFs lost its entire chat\n * back-scroll on 2026-06-30 for exactly this reason.\n */\n/**\n * Public read base for CDN objects.\n *\n * A literal rather than an env lookup on purpose: this value is needed in the\n * BROWSER bundle, where `process.env` does not exist — the `_env` guard used\n * by `PRODUCTION_UI_URL` in `defaults.ts` would resolve to the placeholder in\n * exactly the context that has to work. It is also not a secret in any sense:\n * it appears in the `src` of every image the app renders, and `hadoku.me`'s\n * CSP names it explicitly in `img-src`. Overridable per-deployment via the\n * `cdnBase` mount prop / `VITE_CDN_BASE`, and handed to `createCdnClient`.\n */\nexport const DEFAULT_CDN_BASE = 'https://cdn.hadoku.me';\n/**\n * `<64 lowercase hex chars><ext>`. Anchored, no capture of user-controlled text.\n *\n * **Deliberately stricter than `@wolffm/cdn-client`'s `isKey`,** which accepts\n * any `[a-z0-9]{1,8}` extension. This is an ALLOWLIST, so it also refuses\n * `.svg` — a scriptable document, not an image, and one served same-site with\n * the app could set a `Domain=.hadoku.me` cookie. The CDN refuses SVG by\n * sniffing bytes; this refuses it on the wire as well, so a key that somehow\n * existed still could not be rendered.\n *\n * `jpe?g` because the worker maps `image/jpeg` to `.jpg` but the older `.jpeg`\n * spelling is accepted defensively.\n */\n/**\n * **The key shape IS the trust boundary**, and it is validated in THREE places\n * on purpose — a key arrives from another client, so it is data, not input:\n *\n * 1. `ChatSend`/`ChatBroadcast` Zod (`protocol.ts`) — the server refuses to\n * persist or broadcast a bad key.\n * 2. `normalizeChatMessage` (`ui/lib/socket.ts`) — inbound messages are\n * re-checked at the client boundary; bad entries are dropped, not rendered.\n * 3. `chatImageUrl()` returns null — last line: render nothing rather than a\n * guessed URL.\n *\n * `uploadChatImage` also validates the key the SERVICE returned, because a\n * malformed one would be persisted into chat history permanently.\n *\n * A key is `<sha256-hex><ext>`: it cannot contain a scheme, host, traversal or\n * quote, which is the only reason it is safe to interpolate into an `<img src>`.\n * The extension list is an ALLOWLIST and is deliberately stricter than\n * `cdn-client.isKey` (which accepts any `[a-z0-9]{1,8}`) so that it also refuses\n * `.svg` — a scriptable document served same-site with the app, which could set\n * a `Domain=.hadoku.me` cookie. Do NOT add a client-side SVG conversion;\n * hadoku_site has a test that fails on purpose if the accepted set widens.\n */\nexport const CHAT_IMAGE_KEY_RE = /^[0-9a-f]{64}\\.(?:png|jpe?g|gif|webp|avif)$/;\n/**\n * True when `value` is a well-formed CDN object key.\n *\n * Applied in three places, all deliberate — a key arrives over the wire from\n * another client, so it is data, not a value we produced:\n * - the `ChatSend`/`ChatBroadcast` Zod schemas, so the server refuses to\n * persist or broadcast a bad one;\n * - `normalizeChatMessage` at the client boundary, so a bad entry is dropped\n * rather than rendered;\n * - `resolveChatImageUrl`, which returns null rather than a guessed URL —\n * `cdn.urlFor` composes unconditionally and is not a validator.\n */\nexport function isChatImageKey(value) {\n return typeof value === 'string' && CHAT_IMAGE_KEY_RE.test(value);\n}\n","/**\n * Centralized default values shared across server, UI, E2E, and scripts.\n *\n * This is the single source of truth for all configuration defaults.\n * Consumers should import from here instead of hardcoding values.\n */\n// ─── Ports ──────────────────────────────────────────────────────────────\n/** Default server HTTP port (matches hadoku_site PM2 ecosystem — CF tunnel routes watchparty.hadoku.me → :8080). */\nexport const DEFAULT_HTTP_PORT = 8080;\n/** Default Vite dev server port */\nexport const DEFAULT_UI_PORT = 5173;\n/** E2E test UI port (avoids colliding with dev) */\nexport const DEFAULT_E2E_UI_PORT = 5175;\n/** E2E test server port (avoids colliding with prod/dev) */\nexport const DEFAULT_E2E_SERVER_PORT = 8082;\n/** Common dev proxy port (e.g. hadoku-site reverse proxy) */\nexport const DEFAULT_DEV_PROXY_PORT = 8080;\n// ─── Server defaults ────────────────────────────────────────────────────\nexport const DEFAULT_MEDIA_ROOT = './media';\nexport const DEFAULT_CATALOG_TTL = 30;\nexport const DEFAULT_MAX_WS_PAYLOAD_BYTES = 4096;\nexport const DEFAULT_WS_BACKPRESSURE_THRESHOLD_BYTES = 262_144;\nexport const DEFAULT_LOG_DIR = './logs';\nexport const DEFAULT_LOG_RETENTION_DAYS = 14;\n/// Local SQLite store for per-friend-key match stats + lifetime aggregates.\n/// `stats.sqlite` will sit inside this dir. Gitignored; created at startup.\nexport const DEFAULT_STATS_DB_DIR = './data';\n// Drift thresholds\nexport const DEFAULT_DRIFT_SOFT_MS = 80;\n// Presence timing\nexport const DEFAULT_PRESENCE_TTL_MS = 15_000;\n// Limits\nexport const DEFAULT_MAX_ROOMS = 50;\n/** Cap on live EPHEMERAL rooms (`<app>-*`, see apps/server/src/rooms/ephemeralRooms.ts).\n * Separate from MAX_ROOMS because those rooms are minted by joining, one per\n * draft or match, and must neither crowd out the curated rooms nor be crowded\n * out by them. Still bounded: a friend-tier key is the only gate, and an\n * unbounded namespace would be a room-per-request memory leak behind it.\n *\n * 800 is MEASURED, not guessed — `scripts/stress/ramp.mjs`, 2026-09-19, on the\n * box that runs production. The 200 it replaces was a guess, and it was low:\n * 1600 rooms / 6400 sockets ran at 10% of one core with zero dropped joins,\n * so the room axis never reached a knee at all. 800 is that verified-clean\n * figure halved.\n *\n * What DOES have a knee is message throughput, and it binds regardless of how\n * the rooms are arranged: healthy to 4800 chat/s (86% of one core, p99 10ms),\n * knee at 7200/s (p99 1.3s, event-loop lag p99 61ms), collapse at 9600/s.\n * At 800 rooms every room would have to sustain 6 messages/second to reach\n * that, so the cap sits ~6x under the real constraint.\n *\n * Memory per room is bounded by DEFAULT_CHAT_MAX_MESSAGES (200) rather than by\n * room lifetime, so 800 rooms is tens of MB — the cap is an abuse bound, not a\n * capacity one. Node's event loop is single-threaded, so the ceiling to watch\n * is 100% of ONE core, not of the box.\n *\n * SHARED across every namespace in EPHEMERAL_ROOM_NAMESPACES, so a second app\n * draws on the same 800 — which the measurement above says is fine, since the\n * room axis never reached a knee at twice this. If that stops being true the\n * fix is a per-namespace cap, not a bigger shared one. */\nexport const DEFAULT_MAX_EPHEMERAL_ROOMS = 800;\n/** Child apps admitted to the unprovisioned room namespace: a key spelled\n * `<namespace>-<sessionId>` is joinable without POST /api/rooms.\n *\n * A LIST rather than a shape on purpose — see the header of\n * apps/server/src/rooms/ephemeralRooms.ts for why an enumerable namespace is\n * what keeps a mistyped or deleted curated key failing loudly instead of\n * silently minting an empty room. Overridden wholesale by\n * EPHEMERAL_ROOM_NAMESPACES; adding an app is a line in hadoku_site's pm2\n * wrapper, not a watchparty deploy. */\nexport const DEFAULT_EPHEMERAL_ROOM_NAMESPACES = ['cardtable'];\n// HTTP rate limiting (token buckets; see apps/server/src/middleware/rateLimit.ts)\n//\n// Sized from measurement, not guesswork: a fragment is 2002 ms / ~1.9 MiB, so a\n// steady viewer makes 1.0 req/s; a join or a seek is a ~30-request burst; five\n// concurrent rooms is ~5 req/s steady, and five rooms joining at once is ~150\n// requests in a few seconds. The per-user ceiling is deliberately far above\n// that: five concurrent room streams from ONE user must never 429.\n/** Per-user bucket size: absorbs ~20 join/seek bursts back to back. */\nexport const DEFAULT_RATE_LIMIT_USER_CAPACITY = 600;\n/** Per-user refill, tokens per second (1800/min — 30x one viewer's steady rate). */\nexport const DEFAULT_RATE_LIMIT_USER_REFILL_PER_S = 30;\n/** Global bucket size. Pathology catch only: an order of magnitude over any real party. */\nexport const DEFAULT_RATE_LIMIT_GLOBAL_CAPACITY = 2000;\n/** Global refill, tokens per second. The largest realistic party is ~8 req/s. */\nexport const DEFAULT_RATE_LIMIT_GLOBAL_REFILL_PER_S = 200;\n/** Retry-After (seconds) floor on a global 503, so a stampede does not retry instantly. */\nexport const DEFAULT_RATE_LIMIT_GLOBAL_RETRY_AFTER_S = 2;\n/** Most in-flight (non-terminal) submissions one user may hold, regardless of bytes. */\nexport const DEFAULT_SUBMISSION_PENDING_COUNT_CAP = 25;\n// Media serving\nexport const DEFAULT_MAX_CONCURRENT_MEDIA = 12;\nexport const DEFAULT_FRAGMENT_CACHE_MB = 64;\nexport const DEFAULT_QUEUE_TIMEOUT_MS = 45_000;\n/** Cache-Control max-age (seconds) for media BYTES under /media.\n * Deliberately minutes, not hours: cross-viewer fragment reuse happens within\n * seconds, while a longer TTL would widen the window in which a `--force`\n * re-ingest leaves stale bytes cached against fresh byte offsets. Manifests\n * (*.json) are always `no-cache` regardless of this value. */\nexport const DEFAULT_MEDIA_CACHE_MAX_AGE_S = 300;\nexport const DEFAULT_MAX_CACHEABLE_BYTES = 2_097_152; // 2MB\n// ─── WebSocket ─────────────────────────────────────────────────────────\n/** Socket.io path used by both server and UI */\nexport const DEFAULT_WS_PATH = '/watchparty/ws';\n/** Socket.io ping timeout (ms) for client keepalive */\nexport const DEFAULT_SOCKET_PING_TIMEOUT_MS = 300_000;\n// ─── Rate limiting ─────────────────────────────────────────────────────\n/** Control events: capacity per window */\nexport const DEFAULT_CONTROL_RATE_CAPACITY = 10;\n/** Control events: window in seconds */\nexport const DEFAULT_CONTROL_RATE_WINDOW_S = 5;\n/** Seek events: capacity per window */\nexport const DEFAULT_SEEK_RATE_CAPACITY = 5;\n/** Seek events: window in seconds */\nexport const DEFAULT_SEEK_RATE_WINDOW_S = 1;\n/** Chat messages: capacity per window */\nexport const DEFAULT_CHAT_RATE_CAPACITY = 3;\n/** Chat messages: window in seconds */\nexport const DEFAULT_CHAT_RATE_WINDOW_S = 1;\n/** Identity updates: capacity per window. A single join legitimately costs up\n * to 2 (name + sprite), so 2 left zero headroom — a reconnect + one sprite\n * retry instantly tripped the limit (cedar-ridge \"Coz\" incident, 2026-06-04).\n * 5 gives a join + a few corrections room to breathe. */\nexport const DEFAULT_IDENTITY_RATE_CAPACITY = 5;\n/** Identity updates: refill interval in ms */\nexport const DEFAULT_IDENTITY_RATE_WINDOW_MS = 10_000;\n// ─── Chat ──────────────────────────────────────────────────────────────\n/** Max chat message length in characters */\nexport const DEFAULT_CHAT_MAX_LENGTH = 500;\n/** Local chat send cooldown in ms */\nexport const DEFAULT_CHAT_COOLDOWN_MS = 1_000;\n/** Max chat messages retained per room (server-side Redis cap) */\nexport const DEFAULT_CHAT_MAX_MESSAGES = 200;\n/** Max chat messages retained in the UI store for display */\nexport const DEFAULT_CHAT_UI_BUFFER = 500;\n/** Number of chat messages sent to a client on join */\nexport const DEFAULT_CHAT_HISTORY_JOIN_LIMIT = 100;\n/** Default page size for chat history pagination */\nexport const DEFAULT_CHAT_PAGE_LIMIT = 50;\n/** Maximum page size cap for chat history pagination */\nexport const DEFAULT_CHAT_PAGE_LIMIT_MAX = 100;\n/** Max image attachments on a single chat message. Small on purpose: the\n * attachments ride the websocket as keys, and the chat log sits beside a\n * synchronized video player where a tall message pushes the room out of view. */\nexport const DEFAULT_CHAT_MAX_IMAGES = 4;\n// ─── GC / background ──────────────────────────────────────────────────\n/** Room idle threshold before GC (10 minutes) */\nexport const DEFAULT_GC_ROOM_IDLE_MS = 10 * 60 * 1_000;\n/** Empty room grace period before GC destroy (2 minutes) */\nexport const DEFAULT_GC_ROOM_EMPTY_GRACE_MS = 2 * 60 * 1_000;\n/** GC sweep loop interval (10 seconds) */\nexport const DEFAULT_GC_INTERVAL_MS = 10_000;\n/** Rate limiter bucket prune age (1 hour) */\nexport const DEFAULT_RATE_LIMITER_PRUNE_AGE_MS = 3_600_000;\n/** Log cleanup loop interval (1 hour) */\nexport const DEFAULT_LOG_CLEANUP_INTERVAL_MS = 3_600_000;\n// ─── Health ────────────────────────────────────────────────────────────\n/** Interval between health snapshot broadcasts to the leader */\nexport const DEFAULT_HEALTH_BROADCAST_INTERVAL_MS = 3_000;\n// ─── Application heartbeat ─────────────────────────────────────────────\n/** App-level heartbeat: disconnect sockets that stop sending time_ping for this long */\nexport const DEFAULT_APP_HEARTBEAT_TIMEOUT_MS = 60_000;\n// ─── Media scheduler tuning ────────────────────────────────────────────\n/** Warn-and-act on a media Range stream that has written no bytes for this long.\n * Lower → noisier but catches stalled streams faster; raise on flaky upstreams. */\nexport const DEFAULT_STUCK_STREAM_THRESHOLD_MS = 15_000;\n/** Kill a media Range stream that has been stuck (no bytes written) this long.\n * Without this, a stuck stream holds its concurrency slot until the OS times\n * out — under sustained load the pool drains and every fresh fetch queues for\n * 45s → 503 cascade. Reproduced in iter3 (2026-05-25): audio_jpn_X.m4a hit\n * 40s+ TTFB at origin, all 4 viewers cascaded into HTTP 500. Threshold must\n * be > STUCK_STREAM_THRESHOLD_MS so warns precede the kill. */\nexport const DEFAULT_STUCK_STREAM_ABORT_MS = 30_000;\n/** A media client (by ip) is considered \"currently active\" if it has dispatched\n * a request within this window. Used by the priority-queue fairness logic. */\nexport const DEFAULT_MEDIA_CLIENT_ACTIVE_WINDOW_MS = 30_000;\n/** Rolling window for per-client throughput/queue stats summaries. */\nexport const DEFAULT_MEDIA_CLIENT_STATS_WINDOW_MS = 60_000;\n/** Buffer-ahead-ms below which a viewer's request is flagged as \"emergency\"\n * and dispatched into the reserve slot ahead of regular waiters. */\nexport const DEFAULT_EMERGENCY_BUFFER_MS = 3_000;\n/** How often the media-scheduler emits its periodic summary log when there is\n * active traffic. Skipped entirely when the system is idle. */\nexport const DEFAULT_MEDIA_SCHEDULER_SUMMARY_INTERVAL_MS = 30_000;\n/** Grace window after a socket disconnect before we broadcast a \"leave\" chat\n * system message. Lets transient reconnects (CF tunnel hiccups, refresh,\n * cellular↔wifi handoff on phones) avoid noisy join/leave churn. 60s\n * covers cellular↔wifi handoff stabilization — was 15s before Bug 2 in\n * the 2026-05-20 cedar-ridge retrospective showed phones with measured\n * reconnect gaps up to 60s producing spam. */\nexport const DEFAULT_CHAT_RECONNECT_GRACE_MS = 60_000;\n/** Periodic heartbeat byte interval (ms) for `streamE2eProcess` — keeps\n * Cloudflare-Free from idling out long-silent ingest/test streams. */\nexport const DEFAULT_STREAM_KEEPALIVE_HEARTBEAT_MS = 20_000;\n// ─── Client log endpoint ───────────────────────────────────────────────\n/** Max log entries per client-log POST request */\nexport const DEFAULT_CLIENT_LOG_MAX_ENTRIES = 50;\n// ─── Production URLs ───────────────────────────────────────────────────\n// Set via PRODUCTION_UI_URL / PRODUCTION_SERVER_URL env vars (e.g. in CI or .env).\n// Defaults to example.com so the public repo never leaks a real domain.\n// Guard: `process` is unavailable when this module is bundled for the browser.\nconst _env = typeof process !== 'undefined' && process.env ? process.env : {};\nexport const PRODUCTION_UI_URL = _env.PRODUCTION_UI_URL || 'https://example.com/watchparty/';\nexport const PRODUCTION_SERVER_URL = _env.PRODUCTION_SERVER_URL || 'https://watchparty.example.com';\n// ─── Stress test defaults ──────────────────────────────────────────────\nexport const DEFAULT_STRESS_VIEWERS = 10;\nexport const DEFAULT_STRESS_DURATION_SECS = 120;\nexport const DEFAULT_STRESS_MONITOR_INTERVAL_SECS = 10;\n// ─── Pino log levels ───────────────────────────────────────────────────\nexport const PINO_LEVEL_ERROR = 50;\nexport const PINO_LEVEL_WARN = 40;\nexport const PINO_LEVEL_INFO = 30;\nexport const PINO_LEVEL_DEBUG = 20;\n","/**\n * Tierlist scoring — turning N private S-to-F boards into one room board.\n *\n * This module is PURE and shared by client and server on purpose. The board\n * every viewer sees must be byte-identical to the one the leader sees and to\n * the one written into the stats DB; a hand-ported second copy of these rules\n * would drift silently and nobody would notice, because a plausible-but-wrong\n * tierlist looks exactly like a correct one.\n *\n * ── What is stored vs what is derived ──────────────────────────────────────\n * ONLY the raw letters are ever persisted (`Record<mediaId, TTier>` per voter).\n * Everything below runs at render time. That means the curve can be retuned\n * later without touching a single stored ballot, and the UI can always show\n * the raw picks next to the derived tier so the board stays auditable against\n * what people actually chose. Do NOT persist the output of `placeTierlist`\n * as if it were input.\n *\n * ── Why the raw average is not enough ──────────────────────────────────────\n * Averaging shrinks variance by ~sqrt(nVoters). Even when every individual\n * uses the full S-to-F range, the room means bunch toward the middle, and\n * rounding them lands most clips in B and C — a flat, unreadable board. That\n * compression is an ARTIFACT of averaging, not a finding about the clips, so\n * expanding it back is not fabricating signal.\n *\n * ── The rule: rescale the spread, never move the centre ────────────────────\n * A clip starts at the plain rounded average of its letters. When the board is\n * compressed (but not unanimous) each clip is nudged toward a more spread\n * board, and NEVER by more than `NUDGE_MAX_SHIFT` tiers.\n *\n * That clamp is load-bearing and structural, not a tuning knob. Because the\n * nudge is anchored on each clip's OWN average, an all-S board has every clip\n * anchored at S and the nudge can only ever step one tier — so a room that\n * genuinely loved everything stays top-heavy and CANNOT be turned into a bell\n * curve. Do not replace the clamp with a pure quantile allocation: quantile\n * moves the centre too, which is exactly the failure this design exists to\n * avoid.\n *\n * ── Why the gate has two sides (both verified, do not remove either) ───────\n * Nudging unconditionally was tried and is wrong at BOTH ends:\n * - Below `NUDGE_MIN_SD`: a unanimous board (everyone said B to everything,\n * sd = 0) got shifted a whole tier to A. Moving a perfect consensus is\n * indefensible.\n * - At or above `NUDGE_MAX_SD`: an already well-spread board\n * (S1 A2 B3 C3 D2 F2) was rearranged into a worse one (S2 A4 B1 C4 D1 F1).\n * There was nothing to fix.\n * So the nudge runs only in the band between them.\n *\n * ── Voter centring only bites on PARTIAL ballots ───────────────────────────\n * Subtracting each voter's own mean is provably a no-op when everyone rated\n * every clip — measured difference exactly 0.0000 — because it shifts every\n * clip by the same constant and cancels. It matters only when voters rated\n * DIFFERENT subsets: a late joiner, or someone who left before the end. That\n * is the common case in a watchparty, which is why it is here. The mean must\n * be taken over the clips THAT VOTER rated, never over all clips; taking it\n * over all clips silently reduces it to the no-op case.\n */\nimport { z } from 'zod';\nexport const Tier = z.enum(['S', 'A', 'B', 'C', 'D', 'F']);\n/** Display order, best first. Also the row order of the board. */\nexport const TIER_ORDER = ['S', 'A', 'B', 'C', 'D', 'F'];\n/** Numeric level per tier. Higher is better; F = 1 so that no level is 0\n * (a 0 would make \"unrated\" and \"rated F\" indistinguishable in a sum). */\nexport const TIER_LEVEL = { S: 6, A: 5, B: 4, C: 3, D: 2, F: 1 };\nconst MIN_LEVEL = 1;\nconst MAX_LEVEL = 6;\n/** Nudge gate, lower bound. Below this the room has effectively agreed and the\n * board is left exactly as the averages placed it. */\nexport const NUDGE_MIN_SD = 0.35;\n/** Nudge gate, upper bound. At or above this the board already reads well and\n * is left alone. */\nexport const NUDGE_MAX_SD = 1.0;\n/** Hard cap on how far the nudge may move a clip from its own average, in\n * tiers. This is what makes a genuine lean impossible to flatten. */\nexport const NUDGE_MAX_SHIFT = 1;\n/** One step of within-tier order, in score units.\n *\n * Deliberately two orders of magnitude below a tier (1.0): a clip's position\n * in its row refines the ORDER of that row and must never change which row it\n * is in. See `subRankOffset` for why this is applied AFTER placement rather\n * than folded into the score the tier is derived from. */\nexport const SUB_TIER_STEP = 0.01;\n/** Ceiling on the total sub-rank offset. Keeps the integer part of a displayed\n * score equal to its tier level even for an absurdly long row, which is the\n * property that makes the number readable at a glance (an S clip reads 6.0x,\n * never 7.0). */\nexport const SUB_TIER_MAX = 0.49;\n/** Target share per tier, S..F, used only to rank-order a compressed board.\n * Deliberately mild — a strong shape would fight the clamp and never win. */\nexport const TARGET_SHAPE = [0.08, 0.17, 0.25, 0.25, 0.17, 0.08];\n/** Flatten a ballot to `mediaId -> tier`, discarding order. */\nexport function ballotPicks(ballot) {\n const out = {};\n for (const tier of TIER_ORDER) {\n for (const mediaId of ballot.board[tier] ?? [])\n out[mediaId] = tier;\n }\n return out;\n}\n/** Clamp to the tier scale and convert a numeric level to a letter. */\nexport function levelToTier(level) {\n const rounded = Math.round(level);\n const clamped = Math.max(MIN_LEVEL, Math.min(MAX_LEVEL, rounded));\n // TIER_ORDER is best-first (S=6 at index 0), so index = MAX - level.\n return TIER_ORDER[MAX_LEVEL - clamped];\n}\n/** Population standard deviation. Population, not sample: these are all the\n * clips in the playlist, not a draw from a larger pool. */\nfunction stdev(values) {\n if (values.length === 0)\n return 0;\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n const variance = values.reduce((a, v) => a + (v - mean) * (v - mean), 0) / values.length;\n return Math.sqrt(variance);\n}\n/**\n * Rank each clip onto a tier by `TARGET_SHAPE`.\n *\n * Clips with an identical score MUST come out on the same tier — otherwise the\n * arbitrary order of two equal clips decides which row they land in, and two\n * clients sorting equal scores differently would render different boards. Ties\n * are therefore repaired to the tier their group's MIDPOINT position falls in.\n */\nfunction rankTiers(scores) {\n const n = scores.size;\n const cuts = [];\n let run = 0;\n for (let i = 0; i < TARGET_SHAPE.length - 1; i++) {\n run += TARGET_SHAPE[i] * n;\n cuts.push(run);\n }\n const tierAt = (position) => {\n for (let j = 0; j < cuts.length; j++) {\n if (position < cuts[j])\n return MAX_LEVEL - j;\n }\n return MIN_LEVEL;\n };\n // Order by score desc, mediaId asc — the same total order used for display,\n // so ranking and rendering can never disagree.\n const order = [...scores.keys()].sort((a, b) => {\n const d = scores.get(b) - scores.get(a);\n return d !== 0 ? d : a.localeCompare(b);\n });\n const position = new Map();\n order.forEach((id, i) => position.set(id, i));\n const out = new Map();\n for (const id of order)\n out.set(id, tierAt(position.get(id)));\n // Tie repair: every clip sharing a score takes the group's midpoint tier.\n // That ties stay TOGETHER is the invariant (tested). Midpoint specifically —\n // rather than the group's best or worst position — is a judgment call: it\n // keeps a tied pair straddling a cut from being pulled wholly into the more\n // generous row. Change it if you prefer, but keep them on one row.\n const groups = new Map();\n for (const [id, score] of scores) {\n const key = Math.round(score * 1e6) / 1e6;\n const g = groups.get(key);\n if (g)\n g.push(id);\n else\n groups.set(key, [id]);\n }\n for (const group of groups.values()) {\n if (group.length < 2)\n continue;\n const mid = group.reduce((a, id) => a + position.get(id), 0) / group.length;\n const tier = tierAt(mid);\n for (const id of group)\n out.set(id, tier);\n }\n return out;\n}\n/**\n * Collapse a set of ballots into one board.\n *\n * `mediaIds` is the playlist's full clip list and fixes the universe — a clip\n * nobody rated comes back in `unrated` rather than being given an invented\n * score.\n */\nexport function placeTierlist(mediaIds, ballots) {\n // Flatten each ballot once: tier, plus the clip's rank from the BOTTOM of\n // its row and that row's size. Rank-from-bottom so the top of a row scores\n // highest, matching how a tierlist is read.\n const picksOf = new Map();\n const rankOf = new Map();\n for (const ballot of ballots) {\n picksOf.set(ballot.voterId, ballotPicks(ballot));\n const ranks = new Map();\n for (const tier of TIER_ORDER) {\n const row = ballot.board[tier] ?? [];\n row.forEach((mediaId, i) => ranks.set(mediaId, row.length - 1 - i));\n }\n rankOf.set(ballot.voterId, ranks);\n }\n // ── Per-voter mean, over the clips THAT VOTER rated ────────────────────\n const voterMean = new Map();\n let grandTotal = 0;\n let grandCount = 0;\n for (const ballot of ballots) {\n const picks = picksOf.get(ballot.voterId);\n const levels = mediaIds\n .filter(id => picks[id] !== undefined)\n .map(id => TIER_LEVEL[picks[id]]);\n if (levels.length === 0)\n continue;\n const sum = levels.reduce((a, b) => a + b, 0);\n voterMean.set(ballot.voterId, sum / levels.length);\n grandTotal += sum;\n grandCount += levels.length;\n }\n // Re-anchor the centred deviations on the grand mean so scores stay on the\n // 1..6 tier scale instead of hovering around zero.\n const grandMean = grandCount > 0 ? grandTotal / grandCount : 0;\n // ── Voter-centred score per clip ───────────────────────────────────────\n const scores = new Map();\n const votesByClip = new Map();\n /** Did every rater of this clip give it the same letter? */\n const isUnanimous = new Map();\n const unrated = [];\n const subRank = new Map();\n for (const mediaId of mediaIds) {\n const raw = {};\n let deviationSum = 0;\n let rankSum = 0;\n let raters = 0;\n for (const ballot of ballots) {\n const pick = picksOf.get(ballot.voterId)[mediaId];\n if (pick === undefined)\n continue;\n const mean = voterMean.get(ballot.voterId);\n if (mean === undefined)\n continue;\n raw[ballot.voterId] = pick;\n deviationSum += TIER_LEVEL[pick] - mean;\n rankSum += rankOf.get(ballot.voterId)?.get(mediaId) ?? 0;\n raters++;\n }\n votesByClip.set(mediaId, raw);\n if (raters === 0) {\n unrated.push(mediaId);\n continue;\n }\n scores.set(mediaId, deviationSum / raters + grandMean);\n isUnanimous.set(mediaId, new Set(Object.values(raw)).size === 1);\n // Mean rank-from-bottom across the voters who placed it, scaled into score\n // units and capped. With a single voter this is exactly the ladder the\n // feature was asked for: five clips in one row score X.04 down to X.00.\n subRank.set(mediaId, Math.min(SUB_TIER_MAX, SUB_TIER_STEP * (rankSum / raters)));\n }\n if (scores.size === 0) {\n return { placed: [], unrated, spread: 0, nudged: false };\n }\n // ── Absolute placement — the honest baseline ───────────────────────────\n const absolute = new Map();\n for (const [id, score] of scores) {\n absolute.set(id, Math.max(MIN_LEVEL, Math.min(MAX_LEVEL, Math.round(score))));\n }\n // ── Gated, clamped nudge ───────────────────────────────────────────────\n const spread = stdev([...scores.values()]);\n const nudged = spread >= NUDGE_MIN_SD && spread < NUDGE_MAX_SD;\n const finalLevel = new Map(absolute);\n if (nudged) {\n const ranked = rankTiers(scores);\n for (const [id, abs] of absolute) {\n // NEVER overrule unanimity. The nudge exists to undo the variance that\n // AVERAGING removes; a clip its raters all put in one tier had nothing\n // averaged away, so there is nothing to restore and moving it just\n // contradicts them.\n //\n // This is not a corner case — it is every single-voter board, where each\n // clip is trivially unanimous. Without the guard a lone voter's board\n // came back shifted a whole tier DOWN: two shows placed in S were\n // revealed in A (observed on production, rainbow-roost). `absolute` was\n // right the whole time; the nudge was the only thing moving them.\n if (isUnanimous.get(id))\n continue;\n const want = ranked.get(id);\n finalLevel.set(id, Math.max(abs - NUDGE_MAX_SHIFT, Math.min(abs + NUDGE_MAX_SHIFT, want)));\n }\n }\n // ── Deterministic output order ─────────────────────────────────────────\n // Tier desc, then score desc, then mediaId asc. The mediaId tiebreak is what\n // guarantees every client renders the same board for equal scores.\n const placed = [...scores.keys()]\n .map(mediaId => {\n const tier = levelToTier(finalLevel.get(mediaId));\n const offset = subRank.get(mediaId) ?? 0;\n return {\n mediaId,\n tier,\n absoluteTier: levelToTier(absolute.get(mediaId)),\n // Tier level + position in the row. NOT the placement score — see the\n // field comment for why folding them together breaks placement.\n score: TIER_LEVEL[tier] + offset,\n placementScore: scores.get(mediaId),\n subRankOffset: offset,\n votes: votesByClip.get(mediaId) ?? {},\n };\n })\n .sort((a, b) => {\n const byTier = TIER_LEVEL[b.tier] - TIER_LEVEL[a.tier];\n if (byTier !== 0)\n return byTier;\n // Within a row: sub-rank first (that IS the row order people set), then\n // the consensus that put them in the row, then mediaId so two clients\n // sorting equal boards can never disagree.\n const byScore = b.score - a.score;\n if (byScore !== 0)\n return byScore;\n const byPlacement = b.placementScore - a.placementScore;\n if (byPlacement !== 0)\n return byPlacement;\n return a.mediaId.localeCompare(b.mediaId);\n });\n return { placed, unrated, spread, nudged };\n}\n/**\n * Map a legacy `VoteValue` onto a tier.\n *\n * The vote playlist's four values are a coarse tierlist already, so an existing\n * vote board can be read as one. `mid` deliberately maps to C rather than B:\n * the vote scale is not symmetric (one positive extreme, one step down, a\n * neutral, one negative) and C is the neutral row of a six-tier board.\n */\nexport const VOTE_TO_TIER = {\n super_upvote: 'S',\n upvote: 'A',\n mid: 'C',\n downvote: 'F',\n};\n","import { z } from 'zod';\nimport { CHAT_IMAGE_KEY_RE } from './chatImages.js';\nimport { DEFAULT_CHAT_MAX_LENGTH, DEFAULT_CHAT_MAX_IMAGES } from './defaults.js';\n/** Upper bound on a reported image dimension. Guards against a client sending\n * an absurd number that would drive a huge CSS aspect-ratio box. */\nconst MAX_IMAGE_DIMENSION = 20_000;\n/** Upper bound on an image's `alt` text. The meme library's longest title sits\n * around 110 chars; this leaves room without letting one attachment carry\n * more prose than the message itself. */\nconst MAX_IMAGE_TITLE_LENGTH = 300;\n// Identity-update Zod schema — used by the server's identity_update WS handler\n// to validate inbound payloads (presence.ts). Kept here next to the other\n// inbound schemas like JoinIn / ChatSend.\nexport const IdentityUpdateSchema = z.object({\n name: z.string().min(1).max(32).optional(),\n sprite: z.string().min(1).max(32).optional(),\n /** \"My avatar settings just changed — re-read my picture\" (the fleet\n * settings popout's `hadoku:avatar` event). Carries no picture: the server\n * resolves it from prefs-api by registry userId, never from the client. */\n avatar: z.literal(true).optional(),\n});\n// Wire event names — the single source of truth.\n// Use these instead of string literals when subscribing/emitting. New events MUST be added here\n// so server + client + tests can't drift. (Family-specific events live in PLAYLIST_EVENTS / READY_EVENTS below.)\nexport const CORE_EVENTS = {\n JOIN: 'join',\n SNAPSHOT: 'snapshot',\n CONTROL: 'control',\n CONTROL_ACK: 'control_ack',\n CONTROL_BROADCAST: 'control_broadcast',\n CHAT_SEND: 'chat_send',\n CHAT_BROADCAST: 'chat_broadcast',\n CHAT_HISTORY: 'chat_history',\n PRESENCE: 'presence',\n PRESENCE_PING: 'presence_ping',\n IDENTITY_UPDATE: 'identity_update',\n TIME_PING: 'time_ping',\n TIME_PONG: 'time_pong',\n HEALTH_REPORT: 'health_report',\n HEALTH_SNAPSHOT: 'health_snapshot',\n BUFFER_STATUS: 'buffer_status',\n CLIENT_READY: 'client_ready',\n // 'ready_state' here = playback-readiness gate (distinct from READY_EVENTS.STATE = \"ready check\" UX feature)\n READY_STATE: 'ready_state',\n ERROR: 'error',\n};\n// Control kinds per protocol.md\nexport const ControlKind = z.enum(['play', 'pause', 'seek', 'load', 'home']);\n// Optional identity fields (name + sprite) allow client roster population immediately after join.\n// These are advisory and not authenticated; server will simply echo through presence lists.\n// NOTE: room_key now determines identity (viewer vs leader) via server-side lookup.\n// leader_key and override fields removed - identity is embedded in the room_key itself.\n// How the client is framed. `client_url` is read from the app's own window and\n// is identical for a direct load and for the nested-iframe entry from the\n// hadoku.me home page, so nothing in the logs could distinguish the two entry\n// paths (2026-08-04). Optional + backward compatible: older clients omit it.\nexport const EmbedContext = z.object({\n framed: z.boolean(),\n depth: z.number().int().nonnegative().max(10)\n});\nexport const JoinIn = z.object({\n room_key: z.string(),\n name: z.string().min(1).max(32).optional(),\n sprite: z.string().min(1).max(32).optional(),\n embed: EmbedContext.optional(),\n /** Which media-delivery path this client resolved to ('range' | 'fragment').\n * Optional so older clients still validate. Reported so a party's logs can be split by\n * arm — without it an A/B rollout is unmeasurable, exactly as entry path was before\n * `embed` existed. */\n delivery_arm: z.enum(['range', 'fragment']).optional(),\n /** Browser-persisted device id (`hadoku_device_id`, owned by\n * @wolffm/prefs-client). Lets the server derive a `dev:`-tier\n * ParticipantId for a client with no friend key, so an anonymous viewer\n * keeps their identity across a reload instead of becoming a new person.\n *\n * Optional because it genuinely is: a first-ever visit, or a browser with\n * storage blocked, sends nothing and gets an `eph:` identity. Also keeps\n * older clients validating.\n *\n * CLIENT-ASSERTED — nothing proves it, so it must never gate a capability.\n * See `isAuthenticatedTier` in @wolffm/rooms-protocol. */\n device_id: z.string().min(1).max(128).optional(),\n /** Random per PAGE LOAD, carried on every rejoin from that page. A join whose\n * tab id matches a live connection of the same participant is that tab\n * reconnecting, so the server retires the old connection at once instead of\n * showing it as a second row until the heartbeat reaps it (mistral-bluff\n * 2026-10-20). Never broadcast: it is what lets a rejoin evict a connection.\n * CLIENT-ASSERTED, so it never gates a capability. */\n tab_id: z.string().min(8).max(64).optional(),\n /** Present on a rejoin only: why this page's previous connection ended, as the\n * BROWSER saw it, and for how long it was gone. The server cannot know either\n * — a connection cut upstream never reaches it as a close. */\n reconnect: z.object({\n count: z.number().int().nonnegative(),\n reason: z.string().max(64),\n offline_ms: z.number().int().nonnegative(),\n }).optional(),\n});\nexport const Snapshot = z.object({\n // The room's id — the same for every participant, unlike the key each one\n // joined with (a leader key is a credential). What a game bundle is told\n // its room is (GameBundleSlot).\n room_id: z.string(),\n play_state: z.enum(['idle', 'playing', 'paused', 'ended']),\n playhead_ms: z.number().int().nonnegative(),\n leader_id: z.string().nullable(),\n media_id: z.string().nullable(),\n server_seq: z.number().int().nonnegative(),\n server_ts: z.number().int().nonnegative()\n});\nexport const ControlIn = z.object({\n client_seq: z.number().int().positive(),\n kind: ControlKind,\n to_ms: z.number().int().nonnegative().optional(),\n media_id: z.string().optional()\n // leader_id removed - not needed since set_leader control was removed\n});\n/**\n * A CDN image attachment on a chat message.\n *\n * `key` is validated against the content-addressed shape rather than accepted\n * as free text: it ends up in an `<img src>` on every client in the room, so\n * the schema is the trust boundary. `w`/`h` are the intrinsic pixel dimensions,\n * measured client-side before upload (the CDN deliberately does not return\n * them) so the chat log can reserve layout space and not reflow when the image\n * loads — which matters more here than in most chat apps, because the log sits\n * beside a synchronized video player where reflow is very visible.\n */\nexport const ChatImage = z.object({\n key: z.string().regex(CHAT_IMAGE_KEY_RE, 'not a CDN image key'),\n /**\n * Intrinsic pixels, or **0 meaning \"unknown\"**.\n *\n * `nonnegative`, not `positive`: `measureImage()` falls back to 0x0 when a\n * file cannot be decoded (a corrupt paste, or a format `createImageBitmap`\n * and the `<img>` fallback both refuse), and the renderer has always handled\n * that — `hasDims = w > 0 && h > 0` drops it to natural flow instead of\n * reserving a box. The schema disagreed, so such a message failed validation\n * and was DROPPED by the server: the paste vanished and the user's typed\n * text went with it, with nothing said. Widening is backward compatible —\n * every message already in history carries positive dimensions.\n */\n w: z.number().int().nonnegative().max(MAX_IMAGE_DIMENSION),\n h: z.number().int().nonnegative().max(MAX_IMAGE_DIMENSION),\n /**\n * Human-readable description, rendered as the `alt` text.\n *\n * Present for a meme picked from the shared library (where it is frequently\n * the ONLY text describing the image, so a meme-heavy log is unusable with a\n * screen reader without it) and absent for a pasted screenshot, which has no\n * title to carry. Optional so that older clients — and every message already\n * in chat history — still validate.\n *\n * It is untrusted text from another client and is rendered as an attribute\n * value only, never as markup. Bounded so one message cannot carry a\n * paragraph; the library's own titles run well under this.\n */\n title: z.string().max(MAX_IMAGE_TITLE_LENGTH).optional(),\n});\n/**\n * Inbound chat. `text` may be empty ONLY when the message carries at least one\n * image — the refine keeps \"no empty messages\" true while allowing an\n * image-only paste, which is the common case.\n */\nexport const ChatSend = z.object({\n text: z.string().max(DEFAULT_CHAT_MAX_LENGTH),\n style: z.string().max(64).optional(),\n images: z.array(ChatImage).max(DEFAULT_CHAT_MAX_IMAGES).optional(),\n}).refine((d) => d.text.length > 0 || (d.images?.length ?? 0) > 0, { message: 'message must carry text or at least one image' });\n// System message types for chat\nexport const SystemMessageType = z.enum(['join', 'leave', 'media_change', 'identity_change', 'recap']);\n// Chat broadcast payload (outbound from server)\nexport const ChatBroadcast = z.object({\n id: z.string(),\n client_id: z.string(),\n // The sender's participant handle — stable across their reconnects, unlike\n // `client_id`. Optional: system messages and pre-existing history have none.\n author: z.string().optional(),\n name: z.string(),\n sprite: z.string().nullable(),\n text: z.string(),\n ts: z.number(),\n // Optional so a client on an older bundle still validates a message that\n // has none, and so system messages (which never carry images) stay unchanged.\n images: z.array(ChatImage).max(DEFAULT_CHAT_MAX_IMAGES).optional(),\n isSystem: z.boolean().optional(),\n systemType: SystemMessageType.optional()\n});\n// Health reporting (client → server)\nexport const HealthReport = z.object({\n avg_download_rate_bps: z.number().nonnegative(),\n buffered_ahead_ms: z.number().nonnegative(),\n rtt_ms: z.number().nonnegative(),\n playhead_ms: z.number().nonnegative(),\n is_buffering: z.boolean(),\n fragments_loaded: z.number().int().nonnegative(),\n fragments_pending: z.number().int().nonnegative(),\n fragments_error: z.number().int().nonnegative(),\n video_ready_state: z.number().int().optional(),\n /** Buffered-ahead of the WORST AUDIO track, ms. `buffered_ahead_ms` above is\n * already the min across video and audio; this is reported separately so the\n * health card (and any later analysis) can say WHICH track is starving.\n * -1 means \"no audio FragmentManager\" (media still loading, or audio not yet\n * attached) and must never be treated as a zero-length buffer. Defaults to\n * -1 so older clients, which never send it, are read as \"unknown\". */\n audio_buffered_ahead_ms: z.number().default(-1),\n // Nominal media duration (ms) = last fragment's end. Lets the leader's health\n // card distinguish \"near end-of-stream, little buffer ahead is expected\" from\n // a real low-buffer stall. Defaults to 0 so older clients still validate.\n duration_ms: z.number().nonnegative().default(0),\n /** Media delivery path this client is actually using. Reported HERE and not only at\n * join because the join-time value is provisional — /api/flags lands after the socket\n * connects, so the arm is not final until FragmentManager first reads it. Optional so\n * older clients still validate. */\n delivery_arm: z.enum(['range', 'fragment']).optional(),\n /** Page state, so a stall can be read against what the viewer could see.\n * Without it \"he says he saw nothing\" and \"his player froze for 55s\" could\n * not be reconciled (mistral-bluff 2026-10-20). All optional: older\n * clients omit them, and `net_*` exist only where the browser exposes\n * navigator.connection (Chromium). */\n page_visible: z.boolean().optional(),\n page_focused: z.boolean().optional(),\n muted: z.boolean().optional(),\n online: z.boolean().optional(),\n net_type: z.string().max(16).optional(),\n net_rtt_ms: z.number().nonnegative().optional(),\n net_downlink_mbps: z.number().nonnegative().optional(),\n /** ms since this connection last received a time_pong — a half-open\n * socket shows here as a growing number while everything else looks fine. */\n pong_age_ms: z.number().int().nonnegative().optional(),\n reported_at: z.number().int().nonnegative()\n});\n// Health snapshot (server → leader): per-client health with identity\nexport const ClientHealth = HealthReport.extend({\n client_id: z.string(),\n name: z.string(),\n sprite_id: z.string().nullable(),\n /** Set when this connected client's last report is older than the freshness\n * window: how old it is, ms. The card then shows the client as silent\n * rather than dropping it — a viewer whose reports cannot get through is the\n * one the leader most needs to see. */\n stale_ms: z.number().int().nonnegative().optional(),\n});\nexport const HealthSnapshot = z.object({\n clients: z.array(ClientHealth),\n server_ts: z.number().int().nonnegative()\n});\n// Buffer status (server → all clients in room): lightweight per-client buffer data\nexport const BufferClient = z.object({\n client_id: z.string(),\n sprite_id: z.string().nullable(),\n name: z.string(),\n buffered_ahead_ms: z.number().nonnegative(),\n // playhead + duration let the viewer buffer ring apply the same near-end\n // exemption the leader's health card uses: near end-of-stream there is\n // legitimately little buffer ahead, so a low buffered_ahead_ms there must NOT\n // render \"critical\" red. Default 0 so older clients still validate.\n playhead_ms: z.number().nonnegative().default(0),\n duration_ms: z.number().nonnegative().default(0),\n /** The video element's readyState, forwarded so the viewer buffer ring can\n * apply the same \"plenty buffered but the element cannot advance\" rule the\n * leader's card uses (see components/bufferHealth.ts). -1 = unknown/older\n * client, which must never trip the rule. */\n video_ready_state: z.number().int().default(-1),\n});\nexport const BufferStatus = z.object({\n clients: z.array(BufferClient),\n server_ts: z.number().int().nonnegative(),\n});\n// Client readiness signal (client → server)\nexport const ClientReady = z.object({\n media_id: z.string(),\n});\n// ---------------------------------------------------------------------------\n// Playlist protocol\n// ---------------------------------------------------------------------------\nimport { Tier } from './tierlist.js';\nexport const VoteValue = z.enum(['super_upvote', 'upvote', 'mid', 'downvote']);\nexport const PlaylistVideo = z.object({\n mediaId: z.string(),\n displayName: z.string(),\n // Enrichment fields — present for flat-playlist ingest output, absent for\n // subfolder-layout playlist clips. All optional so old playlist.json stays valid.\n description: z.string().optional(),\n thumbnail: z.string().optional(), // media-relative path, e.g. output/fmp4/.../poster.jpg\n durationMs: z.number().optional(),\n uploadDate: z.string().optional(), // YouTube upload date 'YYYY-MM-DD'; drives playlist order\n});\n// Playlist type — `vote` is the rate-and-reveal playlist (per-video votes,\n// reveal popup); `basic` is a plain sequential watch-through with no voting.\n// Defaults to `vote` so a type-less playlist.json keeps its original behavior.\n//\n// There is deliberately no `tierlist` type: the tierlist is a GLOBAL board, not\n// a playback mode, and coupling it to playlist loading was a mistake that made\n// it vanish on every media change.\nexport const PlaylistType = z.enum(['basic', 'vote']);\nexport const PlaylistConfig = z.object({\n id: z.string(),\n name: z.string(),\n type: PlaylistType.default('vote'),\n videos: z.array(PlaylistVideo),\n cover: z.string().optional(), // media-relative path to the playlist cover image\n});\n// Client -> Server\nexport const PlaylistLoadIn = z.object({ playlistId: z.string() });\nexport const PlaylistSelectIn = z.object({ index: z.number().int().min(0) });\nexport const PlaylistVoteUpdateIn = z.object({\n playlistId: z.string(),\n mediaId: z.string(),\n vote: VoteValue,\n});\n/** Leader removes one voter from the revealed results. `voterKey` is a key of\n * `PlaylistResultsOut.votes` — the reveal-time id, which survives the voter\n * leaving (removal is mostly used on people who already left). */\nexport const PlaylistVoteRemoveIn = z.object({ voterKey: z.string().min(1).max(128) });\n/** Server -> a removed voter: drop your stored ballot. Carries the media ids\n * because on REJOIN it arrives before playlist_state (deliberately — that\n * state is what triggers the client's re-send), so the client cannot look the\n * playlist up yet. */\nexport const PlaylistVotesClearedOut = z.object({ playlistId: z.string(), mediaIds: z.array(z.string()) });\n// Server -> Client\nexport const PlaylistStateOut = z.object({\n playlist: PlaylistConfig.nullable(),\n activeIndex: z.number().int().nullable(),\n myVotes: z.record(z.string(), VoteValue), // mediaId -> VoteValue\n});\nexport const PlaylistVoteProgressItem = z.object({\n clientId: z.string(),\n name: z.string(),\n votedCount: z.number().int().nonnegative(),\n totalVideos: z.number().int().nonnegative(),\n});\nexport const PlaylistVoteProgressOut = z.object({\n progress: z.array(PlaylistVoteProgressItem),\n});\nexport const PlaylistResultsOut = z.object({\n playlist: PlaylistConfig,\n votes: z.record(z.string(), z.record(z.string(), VoteValue)), // votes[clientId][mediaId]\n names: z.record(z.string(), z.string()), // clientId -> display name\n /** clientId -> sprite id, frozen at reveal, so a voter who has since LEFT\n * (and so is gone from the live roster) still renders. Optional: older\n * servers omit it and clients fall back to the roster. */\n sprites: z.record(z.string(), z.string()).optional(),\n /** clientId -> avatar picture URL, frozen at reveal like `sprites`. Only\n * people who have a picture; everyone else shows their character. */\n pictures: z.record(z.string(), z.string()).optional(),\n /** True when this re-sends results after a voter was removed. A client whose\n * reveal is closed ignores it, rather than having the popup reappear. */\n update: z.boolean().optional(),\n});\nexport const PLAYLIST_EVENTS = {\n LOAD: 'playlist_load',\n SELECT: 'playlist_select',\n VOTE_UPDATE: 'playlist_vote_update',\n REVEAL_REQUEST: 'playlist_reveal_request',\n STATE: 'playlist_state',\n VOTE_PROGRESS: 'playlist_vote_progress',\n RESULTS: 'playlist_results',\n /** Leader -> server: drop a voter from the revealed results. */\n VOTE_REMOVE: 'playlist_vote_remove',\n /** Server -> the removed voter: forget the ballot you hold in localStorage. */\n VOTES_CLEARED: 'playlist_votes_cleared',\n};\n// ---------------------------------------------------------------------------\n// Tierlist protocol — ONE GLOBAL BOARD\n// ---------------------------------------------------------------------------\n//\n// Not room state, and not a playlist. The tierlist is one board the whole site\n// shares: openable from anywhere, persisted in SQLite, and outliving every\n// room. An earlier version hung it off a loaded playlist, which meant it\n// vanished when the room changed media and two rooms could not see the same\n// votes.\n//\n// `voterId` on this wire is an OPAQUE token, never the friend key — that IS the\n// X-User-Key credential, and a board every viewer receives cannot carry it.\n/** One rankable entry. `id` doubles as the media path, so card art resolves by\n * the usual `<id>/poster.jpg` convention. */\nexport const TierlistItem = z.object({\n id: z.string(),\n displayName: z.string(),\n thumbnail: z.string().optional(),\n});\n/** `config/tierlist.json` — which entries are eligible this season. */\nexport const TierlistConfig = z.object({\n items: z.array(TierlistItem),\n});\n/** A board: the ordered item ids in each tier. Order within a row is part of\n * the ballot (it feeds the sub-rank), not presentation. */\nexport const TierlistBoard = z.partialRecord(Tier, z.array(z.string()));\n/** Client -> Server. Saving REPLACES the caller's whole board. */\nexport const TierlistSaveIn = z.object({ board: TierlistBoard });\n/** One entry on the shared board. Mirrors `PlacedClip` in tierlist.ts. */\nexport const TierlistPlacedOut = z.object({\n mediaId: z.string(),\n tier: Tier,\n absoluteTier: Tier,\n /** Tier level + within-row position. Integer part is the tier. */\n score: z.number(),\n /** The consensus mean that decided the tier. Never the displayed number. */\n placementScore: z.number(),\n subRankOffset: z.number(),\n votes: z.record(z.string(), Tier), // opaque voterId -> the letter they gave\n});\n/** The whole board as one client should see it: the shared result, plus that\n * caller's own arrangement. */\nexport const TierlistSnapshotOut = z.object({\n items: z.array(TierlistItem),\n placed: z.array(TierlistPlacedOut),\n unrated: z.array(z.string()),\n spread: z.number(),\n nudged: z.boolean(),\n names: z.record(z.string(), z.string()),\n sprites: z.record(z.string(), z.string()),\n /** Voter id -> avatar picture URL, for voters who have one. Optional so a\n * browser on a newer bundle still reads an older server's board. */\n pictures: z.record(z.string(), z.string()).optional(),\n voterCount: z.number().int().nonnegative(),\n myBoard: TierlistBoard,\n});\nexport const TIERLIST_EVENTS = {\n /** Broadcast to EVERY connected socket when anyone saves. Carries no board —\n * it is a \"re-fetch\" ping, because the shared result is identical for all\n * viewers but `myBoard` is not, and one payload cannot serve both. */\n UPDATED: 'tierlist_updated',\n};\n// Ready check — leader-triggered \"are you all ready to keep going?\" prompt.\n// Server tracks per-client ready state while a check is active. Cleared\n// automatically when the leader unpauses (control/play). No payload on\n// start/stop — sender role authorizes the action.\nexport const ReadyCheckStartIn = z.object({});\nexport const ReadyToggleIn = z.object({ ready: z.boolean() });\nexport const ReadyStateOut = z.object({\n active: z.boolean(),\n ready: z.array(z.string()), // clientIds who have flagged ready\n});\nexport const READY_EVENTS = {\n START: 'ready_check_start',\n TOGGLE: 'ready_check_toggle',\n STATE: 'ready_check_state', // distinct from buffer-readiness 'ready_state'\n};\n// ---------------------------------------------------------------------------\n// The room's game: a SELECTION. Every game is a bundle with its own server\n// (GAMES `module` entries), so the room only records which one is open.\n// ---------------------------------------------------------------------------\nexport const GAME_EVENTS = {\n SELECT: 'game_select', // leader -> server (open a game for the room; null closes it)\n ACTIVE: 'game_active', // server -> room (the open game id; null = none)\n SYNC: 'game_sync', // client -> server (which game is open? on mount/reconnect)\n};\n// `gameId: null` turns the active game off for the whole room.\nexport const GameSelectIn = z.object({\n gameId: z.string().min(1).max(32).nullable(),\n});\n// Broadcast when the open game changes, or sent to one socket on game_sync.\nexport const GameActiveOut = z.object({\n gameId: z.string().nullable(),\n});\n","// The playable characters: one table, read by the client, the server and —\n// through a contract test — the Bomberman game's Rust (`game/src/assets.rs`).\n//\n// Grouped by the show they come from. Each set is one page of the character\n// picker, so a set holds at most CHARACTER_PAGE_SIZE characters. `color` is the\n// character's chat/name colour, taken from their hair. Display names are NOT\n// here: they live in the deployment's git-ignored media/sprites/names.json.\n//\n// `rev` is the portrait's revision: bump it when the art in media/sprites/ is\n// redrawn in place. Sprite PNGs are served immutable for a year, so without a\n// new URL a browser that has seen the old image keeps showing it.\nexport const CHARACTER_SETS = [\n {\n id: 'fantasy',\n characters: [\n { id: 'sage', color: '#7f7c84' },\n { id: 'herald', color: '#bddaf9' },\n { id: 'cleric', color: '#78855e' },\n { id: 'knight', color: '#cfccc0' },\n { id: 'mage', color: '#794983' },\n { id: 'brawler', color: '#af4a33' },\n { id: 'wanderer', color: '#936f42' },\n { id: 'rogue', color: '#667240' },\n ],\n },\n {\n id: 'cyber',\n characters: [\n { id: 'gunner', color: '#b6a472' },\n { id: 'chief', color: '#a47e4d' },\n { id: 'walker', color: '#e0443a', rev: 2 },\n { id: 'operative', color: '#347cae' },\n ],\n },\n {\n id: 'stream',\n characters: [\n { id: 'idol', color: '#eb82bf' },\n { id: 'recluse', color: '#6d6880' },\n { id: 'phantom', color: '#a4a3ae' },\n { id: 'harlequin', color: '#e5d5c5' },\n { id: 'doll', color: '#a02633', rev: 2 },\n { id: 'imp', color: '#b398cb' },\n ],\n },\n {\n id: 'arcane',\n characters: [\n { id: 'apprentice', color: '#c6c15b' },\n { id: 'prodigy', color: '#5b4a6a' },\n { id: 'dreamer', color: '#97d0e4' },\n { id: 'sunny', color: '#ee989b' },\n { id: 'mentor', color: '#e1e0dc' },\n ],\n },\n];\nexport const CHARACTER_PAGE_SIZE = 8;\nconst ENTRIES = CHARACTER_SETS.flatMap((s) => s.characters);\n// Canonical character (sprite) order — every set, in set order. Used everywhere\n// a UI roster or server sprite-pool needs a deterministic iteration order, so\n// auto-assignment hands out the first set before any later one.\nexport const CHARACTER_ORDER = ENTRIES.map((c) => c.id);\nexport const CHARACTER_COLORS = Object.fromEntries(ENTRIES.map((c) => [c.id, c.color]));\n/** Portrait revision per character; 1 for art that has never been redrawn. */\nexport const CHARACTER_ART_REV = Object.fromEntries(ENTRIES.map((c) => [c.id, 'rev' in c ? c.rev : 1]));\n/**\n * A character's portrait, as a path under the watchparty server's root. A\n * redrawn portrait carries `?v=<rev>` so the year-long immutable cache cannot\n * keep serving the old art; untouched ones keep their bare URL and stay cached.\n * The UI prefixes its server origin; GET /api/characters hands it to everyone\n * else, so the rule is spelled once.\n */\nexport function portraitPath(id) {\n const rev = CHARACTER_ART_REV[id];\n return `/media/sprites/square_${id}.png${rev > 1 ? `?v=${rev}` : ''}`;\n}\n/** Narrow an arbitrary sprite string (it arrives off the wire) to a CharacterId. */\nexport function isCharacterId(sprite) {\n return !!sprite && CHARACTER_ORDER.includes(sprite);\n}\n","/**\n * Playback tuning constants shared across client, server, simulation, and tests.\n *\n * All buffer/fetch behavior should reference these values so there is exactly\n * one place to tweak when optimising for different network conditions.\n */\n// ─── Client fetch behavior ──────────────────────────────────────────────────\n/** Max parallel fragment fetches per viewer */\nexport const MAX_CONCURRENT_JOBS = 4;\n/** How far ahead of playhead (ms) to prefetch fragments */\nexport const BUFFER_AHEAD_MS = 30_000;\n/** Buffer required (ms) before playback starts or resumes after a stall */\nexport const INITIAL_BUFFER_MS = 5_000;\n// ─── Health status thresholds ────────────────────────────────────────────────\n/** Buffer below this (ms) → \"Critical\" status */\nexport const CRITICAL_BUFFER_MS = 2_000;\n/** Buffer below this (ms) → \"Low Buffer\" / warning status */\nexport const LOW_BUFFER_MS = 5_000;\n// ─── Stall + sync thresholds ────────────────────────────────────────────────\n/** Leader stall longer than this (ms) → leader auto-emits a pause control so viewers\n * don't drift out ahead of the still-buffering leader. See useStallRecovery. */\nexport const LEADER_STALL_PAUSE_THRESHOLD_MS = 2_000;\n/** Same gap-pattern must persist this long (ms) before logging an unfillable-gap warn,\n * to filter out transient append-queue churn. See fragmentManager._maybeWarnStableGaps. */\nexport const STABLE_GAP_DWELL_MS = 5_000;\n// ─── Prefetch + buffer-gate tuning ──────────────────────────────────────────\n/** Background prefetch tick interval (ms) for usePrefetch + audio mirror. */\nexport const DEFAULT_PREFETCH_INTERVAL_MS = 2_000;\n/** Maximum wall-clock time (ms) waiting for INITIAL_BUFFER_MS of buffer before\n * releasing initializePlayback. After this, playback starts with whatever's buffered. */\nexport const DEFAULT_BUFFER_GATE_TIMEOUT_MS = 10_000;\n/** Number of front-of-stream fragments included in the INIT-DIGEST telemetry event. */\nexport const INIT_DIGEST_TRACK_COUNT = 10;\n// ─── Fragment fetch retry/error behavior ────────────────────────────────────\n/** When fetchInit() fails, retry after this delay (ms). */\nexport const INIT_RETRY_DELAY_MS = 2_000;\n/** Consecutive fetchInit() failures before giving up on the current MediaSource\n * and signalling a fast recovery (reject append/buffer waiters → MediaPlayer\n * recreates the MediaSource) instead of looping forever every\n * INIT_RETRY_DELAY_MS. Without this cap a persistent init failure froze\n * playback for ~65s: the retry loop logged silently while initializePlayback\n * blocked on two 30s waitForAppend timeouts before recreating (cedar-ridge\n * 2026-06-25, DemonLord s01e04). At 3 × 2s this recovers in ~6s. */\nexport const MAX_INIT_FETCH_RETRIES = 3;\n/** After endOfStream() is called but a SourceBuffer is still updating, retry on\n * this interval (ms). See FragmentManager.tryEndOfStream. */\nexport const END_OF_STREAM_RETRY_INTERVAL_MS = 50;\n/** A fragment that has exhausted MAX_FETCH_ERROR_CYCLES rounds of retries is\n * declared permanently unservable. Reset attempts beyond this are skipped. */\nexport const MAX_FETCH_ERROR_CYCLES = 3;\n/** Fragment error states older than this (ms) are reset to pending so retries\n * can resume (provided cycle budget remains). See prefetchAround. */\nexport const ERROR_RESET_AGE_MS = 30_000;\n/** How long processAppendQueue may hold the SAME queue head behind a\n * lower-indexed pending fetch before declaring that fetch dead and breaking\n * the hold (ms).\n *\n * The sequential-append guard has no timeout of its own: it holds the whole\n * append queue while ANY pending fetch has a lower index than the head. That\n * is correct for a fetch that will land, and a permanent wedge for one that\n * will not. A fragment whose append is reported discarded goes back to\n * 'pending' and is re-fetched, re-taking the lower index — so a fragment that\n * keeps getting discarded holds every later append forever.\n *\n * That is the audio-side freeze from cedar-ridge 2026-08-25: audio appends\n * #556–562 were each reported discarded, the audio queue backed up to 15\n * items, and `waitForAppend` timed out on #569 after 30s while the playhead\n * sat pinned at the audio buffer's leading edge.\n *\n * 20s is deliberately longer than a slow fragment fetch under load (the\n * adaptive fetch timeout runs 30–120s, but a fetch that is actually\n * progressing re-enters the queue well inside this window) and well short of\n * the 30s `waitForAppend` timeout it exists to pre-empt. */\nexport const APPEND_HOLD_MAX_MS = 20_000;\n/** Buffer-ahead-ms header value sent on background pre-buffer fetches so the\n * server's priority queue treats them as lowest-priority and yields to live viewers. */\nexport const BACKGROUND_FETCH_PRIORITY_MS = 99_999;\n// ─── Time sync ──────────────────────────────────────────────────────────────\n/** Interval (ms) the client emits `time_ping` to derive its drift offset. */\nexport const DEFAULT_CLIENT_TIME_PING_INTERVAL_MS = 5_000;\n// ─── Output filenames ──────────────────────────────────────────────────────\n/** Filename used by ingest for the fragmented MP4 muxed output. Consumed by the\n * client to convert a media URL into the corresponding audio-base URL. */\nexport const FRAGMENT_MP4_FILENAME = 'output_frag.mp4';\n/** Subdirectory of the media output where per-language audio fragments live. */\nexport const AUDIO_DIR = 'audio';\n","/**\n * Auth + transport constants shared across server, client, tests, and tooling.\n *\n * `BEARER_PREFIX` is the literal \"Bearer \" token (note the trailing space) used\n * by both halves of an Authorization header (`Bearer <token>`).\n *\n * `HADOKU_SESSION_COOKIE` is the cookie name that mf-loader / edge-router /\n * server-side session validation all key off. Don't rename without coordinating\n * across hadoku_site too.\n *\n * Endpoint paths are kept here so test runners, scripts/dod-validate.ts, and\n * UI health probes all share the same string.\n */\nexport const BEARER_PREFIX = 'Bearer ';\nexport const HADOKU_SESSION_COOKIE = 'hadoku_session';\nexport const HEALTH_ENDPOINT = '/healthz';\nexport const METRICS_ENDPOINT = '/metrics';\nexport const DEBUG_LOGS_ENDPOINT = '/debug/logs';\n","/**\n * Fragment-delivery rollout flag — shared by server and client so both agree on what a given\n * setting means.\n *\n * Three modes:\n * off — everyone uses the Range path (the shipping default)\n * on — everyone uses the edge-cacheable fragment route, falling back to Range on failure\n * ab — a deterministic `percent` slice uses the fragment route; the rest stay on Range\n *\n * `ab` exists so the two delivery paths can be compared inside ONE party, on the same media, at\n * the same time. That matters because the numbers this feature is meant to move (TTFB, cache\n * hit rate, stalls) swing wildly with time of day, which media is loaded, and who is watching —\n * comparing two separate runs would mostly measure those.\n *\n * Assignment is a pure hash of the client id, so a viewer keeps its arm across reconnects\n * within a session and cannot flap between paths mid-episode.\n */\nexport const DEFAULT_FRAGMENT_DELIVERY_FLAG = { mode: 'off', percent: 0 };\nexport const FRAGMENT_DELIVERY_MODES = ['off', 'on', 'ab'];\nexport function isFragmentDeliveryMode(v) {\n return typeof v === 'string' && FRAGMENT_DELIVERY_MODES.includes(v);\n}\n/** Clamp/normalise anything (env string, JSON body, stored value) into a valid flag. */\nexport function normalizeFragmentDeliveryFlag(raw) {\n const o = (raw && typeof raw === 'object' ? raw : {});\n const mode = isFragmentDeliveryMode(o.mode) ? o.mode : DEFAULT_FRAGMENT_DELIVERY_FLAG.mode;\n const n = Number(o.percent);\n const percent = Number.isFinite(n) ? Math.min(100, Math.max(0, Math.round(n))) : 0;\n return { mode, percent };\n}\n/**\n * FNV-1a over the client id. Small, dependency-free, and — the actual requirement — identical\n * on both sides, so the arm the server reports in telemetry is the arm the client used.\n */\nfunction hashClientId(clientId) {\n let h = 0x811c9dc5;\n for (let i = 0; i < clientId.length; i++) {\n h ^= clientId.charCodeAt(i);\n h = Math.imul(h, 0x01000193) >>> 0;\n }\n return h >>> 0;\n}\n/**\n * Which delivery path should this client use?\n *\n * `override` is the local escape hatch (`?fragmentDelivery=0|1`) and wins over the server flag\n * in BOTH directions — so a viewer hitting a bad fragment-route session can force themselves\n * back onto Range without waiting for an operator, and an operator can test the route on a\n * single client while the room-wide flag is off.\n */\nexport function resolveDeliveryArm(flag, clientId, override) {\n if (override === true)\n return 'fragment';\n if (override === false)\n return 'range';\n const f = normalizeFragmentDeliveryFlag(flag);\n if (f.mode === 'on')\n return 'fragment';\n if (f.mode === 'off')\n return 'range';\n // 'ab'. percent 0 => nobody, percent 100 => everybody; both must hold exactly, so compare\n // against `percent` with a strict `<` on a 0-99 bucket.\n if (f.percent <= 0)\n return 'range';\n if (f.percent >= 100)\n return 'fragment';\n if (!clientId)\n return 'range'; // no stable identity => never in the experiment arm\n return hashClientId(clientId) % 100 < f.percent ? 'fragment' : 'range';\n}\n","/**\n * User submissions — \"a user asked for this media\".\n *\n * The wire contract and the state machine, shared by client and server so the\n * two cannot hold different ideas about which moves are legal. Nothing here\n * fetches, uploads or ingests: wave 1 stores a request and its adjudication,\n * and the later waves attach the machinery that walks it forward.\n *\n * ── `ownerUserId` is a userId, NEVER a credential ──────────────────────────\n * Every row keys on the stable userId whoami returns, not on the raw\n * `X-User-Key`. Issue #144 is exactly the mistake of keying five stats tables\n * on the credential: a key rotation then orphans rows that still hold a\n * secret, and two aliases of one rotated user never collapse. Hashing the\n * credential does not fix it either — a key-derived id is still key-derived.\n * This store is being written after that lesson; do not reproduce it.\n *\n * ── The transition table is DATA, on purpose ───────────────────────────────\n * `SUBMISSION_TRANSITIONS` is the single rule every later wave consults. A\n * fetcher, an uploader, a moderation UI and an operator script will all move\n * submissions between states; if each one hand-writes \"is this move allowed\"\n * they will disagree, and the disagreement shows up as a submission wedged in\n * a state nothing advances. `canTransition` is the only predicate.\n */\nimport { z } from 'zod';\n/** How the bytes are expected to arrive. */\nexport const SubmissionKind = z.enum(['url', 'magnet', 'upload']);\n/**\n * Lifecycle. The happy path is\n * `pending → approved → fetching → ingesting → ready`; `rejected` and\n * `failed` are the two ways out of it.\n *\n * Moderation is approve-first (operator, 2026-09-24): nothing reaches the\n * catalog without passing through `approved`, so `pending` is not a formality\n * that a later wave may skip.\n */\nexport const SubmissionState = z.enum([\n 'pending', 'approved', 'fetching', 'ingesting', 'ready', 'rejected', 'failed',\n]);\n/**\n * Every legal move, keyed by the state you are leaving.\n *\n * Deliberate calls, so a later wave does not read an omission as an oversight:\n *\n * - **`ready` and `rejected` are terminal.** A request that has landed in the\n * catalog, or that an operator has refused, is finished. Wanting it again is\n * a new submission — which keeps the audit trail honest about who asked for\n * what, and when.\n * - **Nothing returns to `pending`.** `pending` means \"never adjudicated\". A\n * submission cannot become un-adjudicated, so a retry re-enters at\n * `approved` (the decision still stands), never at the top.\n * - **`fetching` and `ingesting` cannot be rejected.** Killing work in flight\n * needs cancellation semantics — a way to stop the yt-dlp child and clean up\n * a part-written file — and none exists yet. Adding `fetching → rejected`\n * without that leaves an orphaned process writing into a directory nobody\n * owns. Add the edge together with the killer that makes it true.\n * - **`failed` is recoverable, once approved.** A fetch that died on a network\n * blip should not cost the user their place in the queue.\n */\nexport const SUBMISSION_TRANSITIONS = {\n pending: ['approved', 'rejected'],\n approved: ['fetching', 'rejected', 'failed'],\n fetching: ['ingesting', 'failed'],\n ingesting: ['ready', 'failed'],\n ready: [],\n rejected: [],\n failed: ['approved'],\n};\n/** States nothing can leave. Derived, so it cannot drift from the table. */\nexport const SUBMISSION_TERMINAL_STATES = Object.keys(SUBMISSION_TRANSITIONS)\n .filter(s => SUBMISSION_TRANSITIONS[s].length === 0);\n/**\n * The one predicate. Total over `unknown` rather than over the enum, because\n * both ends read states back out of SQLite and off the wire, where a value\n * that is not in the enum at all is a reachable outcome — and must be `false`\n * rather than a throw or a crash inside a transaction.\n *\n * A self-transition is NOT legal. `from === to` is a write that changes\n * nothing; treating it as a move would let a caller \"advance\" a submission\n * and log a state change that never happened.\n */\nexport function canTransition(from, to) {\n const legal = SUBMISSION_TRANSITIONS[from];\n if (!legal)\n return false;\n return legal.includes(to);\n}\n/** One submission, as it is stored and as it goes on the wire. */\nexport const Submission = z.object({\n id: z.string().min(1),\n /** Stable userId from whoami. Never the raw `X-User-Key`. */\n ownerUserId: z.string().min(1),\n kind: SubmissionKind,\n /** The magnet URI, the https URL, or the filetransfer binding id. */\n source: z.string().min(1),\n title: z.string().optional(),\n /**\n * The anime series folder (PascalCase, e.g. `SparksOfTomorrow`) a `magnet`\n * submission belongs to — wave 4 (2026-10-01: \"magnets are in scope, and\n * user content is NOT restricted to the playlist tree\"). `undefined` for\n * `url`/`upload`, which always land in the playlist tree regardless of\n * title. The scraper derives its own destination from this same string, so\n * it is stored verbatim rather than normalized — a normalization that\n * disagreed with the scraper's own folder-name assumption would silently\n * misroute the copy.\n */\n series: z.string().optional(),\n state: SubmissionState,\n createdAt: z.number().int().nonnegative(),\n updatedAt: z.number().int().nonnegative(),\n /** Why it failed, or why an operator rejected it. */\n error: z.string().optional(),\n /** Size once known. 0 means \"known to be empty\"; absent means \"not yet known\" —\n * the same distinction `chatImages` draws for image dimensions. */\n bytes: z.number().int().nonnegative().optional(),\n});\n/** Longest `source` accepted at the boundary. A magnet with a long tracker\n * list is legitimately over 1KB; nothing real approaches this. */\nexport const SUBMISSION_SOURCE_MAX_CHARS = 4096;\n/** Longest caller-supplied title. */\nexport const SUBMISSION_TITLE_MAX_CHARS = 300;\n/** Longest caller-supplied series name. Comfortably over the longest real\n * series folder name in the library; bounded for the same reason title is —\n * it ends up as a filesystem path segment. */\nexport const SUBMISSION_SERIES_MAX_CHARS = 100;\n/** `POST /api/submissions` request body. */\nexport const SubmissionCreateIn = z.object({\n kind: SubmissionKind,\n source: z.string().min(1).max(SUBMISSION_SOURCE_MAX_CHARS),\n title: z.string().min(1).max(SUBMISSION_TITLE_MAX_CHARS).optional(),\n /** Required for `kind: 'magnet'` by `checkSource`; ignored for `url`/`upload`. */\n series: z.string().min(1).max(SUBMISSION_SERIES_MAX_CHARS).optional(),\n});\n/** `POST /api/submissions/:id/reject` request body — the reason is optional,\n * and lands in the submission's `error` so the requester can be told why. */\nexport const SubmissionRejectIn = z.object({\n reason: z.string().min(1).max(SUBMISSION_TITLE_MAX_CHARS).optional(),\n});\n/** List response shape, for `GET /api/submissions` and `.../mine`. */\nexport const SubmissionListOut = z.object({\n submissions: z.array(Submission),\n});\n// ── Caps (operator, 2026-09-24) ────────────────────────────────────────────\n// They live in shared rather than in the server's config so the submit UI can\n// show the same number the server enforces, instead of a second copy that\n// drifts.\n//\n// `DEFAULT_SUBMISSION_PENDING_BYTES_CAP` IS enforced — at submit, by\n// `POST /api/submissions`, which answers 429 with {@link SubmissionQuotaOut}.\n// The other two are still defaults only: the upload cap lands with the upload\n// path that can weigh a file, and retention with the prune that reads it.\n/** Total bytes one user may have submitted-but-not-yet-ready. 20 GB. */\nexport const DEFAULT_SUBMISSION_PENDING_BYTES_CAP = 20 * 1024 * 1024 * 1024;\n/** Largest single upload. 4 GB. */\nexport const DEFAULT_SUBMISSION_MAX_UPLOAD_BYTES = 4 * 1024 * 1024 * 1024;\n/** Days a fetched source is kept after a successful ingest, unless pinned. */\nexport const DEFAULT_SUBMISSION_SOURCE_RETENTION_DAYS = 14;\n/**\n * `429` body when a submit would exceed the per-user pending cap.\n *\n * **The numbers are in the body on purpose.** A bare 429 tells a friend \"no\"\n * and nothing else, so the only recovery is to guess which of their own\n * requests to abandon. With both figures the UI can say \"you are holding\n * 21.4 GB of a 20 GB allowance\" against the same values the server enforced,\n * rather than a second copy that drifts.\n *\n * ── What an unknown size contributes: nothing ──────────────────────────────\n * A `url` or `magnet` row has `bytes` absent until its fetch lands — the size\n * is genuinely unknown, and the schema says so (absent ≠ 0). The cap therefore\n * binds on MEASURED bytes. The alternative is to charge an unknown row some\n * assumed size, which is a number nobody measured: too small and the cap does\n * not bind, too large and a friend's second request is refused on the strength\n * of a guess about their first. The honest consequence is that many\n * not-yet-fetched requests pass the check and the cap starts biting as soon as\n * real sizes land — a *count* cap is the tool for the other half, and it\n * belongs with the fetch path that can measure.\n */\nexport const SubmissionQuotaOut = z.object({\n error: z.literal('submissions/quota_exceeded'),\n /** The caller's measured bytes in non-terminal submissions, right now. */\n pendingBytes: z.number().int().nonnegative(),\n /** The cap that was applied, from the server's config. */\n capBytes: z.number().int().nonnegative(),\n});\n","import { z } from 'zod';\n/**\n * The room's game list, as DATA.\n *\n * The leader's Play tab used to be a hardcoded array in `GamePicker.tsx`, so\n * every new game was a watchparty code change. Now the server reads the list\n * from the `GAMES` env var (JSON), serves it at `GET /api/games`, and the UI\n * renders and mounts whatever it says. The shape is `GameEntry` from\n * `@wolffm/rooms-protocol` — this file is only its runtime validation, and\n * `apps/ui/src/lib/gameCatalog.ts` checks the two agree at compile time.\n *\n * Validated at BOTH ends: the server so a bad env value is reported where the\n * operator set it, the browser because a module URL is about to be imported.\n */\n/** Same charset as a room-key segment; `game_select` carries it on the wire. */\nconst GAME_ID_RE = /^[a-z0-9][a-z0-9-]{0,31}$/;\n/** Any origin works: the check is that resolving against it cannot leave it. */\nconst PROBE_ORIGIN = 'https://game-catalog.invalid';\n/**\n * A root-relative path on the page's own origin, and nothing else.\n *\n * Absolute URLs are refused outright, not just cross-origin ones: the catalog\n * does not know the page's origin, so `https://hadoku.me/x` cannot be told\n * apart from `https://evil.example/x` here. `//host/x` (protocol-relative) and\n * `/\\host/x` (browsers read the backslash as a slash) both leave the origin\n * despite the leading `/`, which is why this resolves the path rather than\n * just checking its first character.\n */\nexport function isSameOriginPath(value) {\n if (!value.startsWith('/') || value.startsWith('//'))\n return false;\n if (/[\\\\\\s]/.test(value) || [...value].some((c) => c.charCodeAt(0) < 0x20 || c.charCodeAt(0) === 0x7f))\n return false;\n try {\n return new URL(value, PROBE_ORIGIN).origin === PROBE_ORIGIN;\n }\n catch {\n return false;\n }\n}\nconst SameOriginPath = z.string().min(2).max(512).refine(isSameOriginPath, {\n message: 'must be a root-relative path on the page origin (e.g. /cardtable/embed/x.js)',\n});\nconst GameEntryBase = {\n id: z.string().regex(GAME_ID_RE),\n name: z.string().min(1).max(64),\n cover: SameOriginPath.optional(),\n};\nexport const GameEntrySchema = z.object({ ...GameEntryBase, kind: z.literal('module'), url: SameOriginPath }).strict();\nexport const GameCatalogSchema = z.array(GameEntrySchema).max(32).refine((games) => new Set(games.map((g) => g.id)).size === games.length, { message: 'game ids must be unique' });\n/** What a deployment gets without `GAMES`: Bomberman, served by hadoku-bomberman\n * under its own edge mount. */\nexport const DEFAULT_GAME_CATALOG = [\n { id: 'bomberman', name: 'Bomberman', kind: 'module', url: '/bomberman/embed/bomberman-embed.js' },\n];\n/**\n * Parse the `GAMES` env value. Unset keeps the default list; set REPLACES it,\n * and `[]` turns games off. A malformed ENTRY is dropped, not coerced, and a\n * duplicate id keeps its first entry — the same fail-closed rule as\n * `EPHEMERAL_ROOM_NAMESPACES`. A value that is not a JSON array at all falls\n * back to the default rather than taking every game away over a typo.\n */\nexport function parseGameCatalog(raw) {\n if (raw === undefined)\n return { games: [...DEFAULT_GAME_CATALOG], problems: [] };\n let value;\n try {\n value = JSON.parse(raw);\n }\n catch {\n return { games: [...DEFAULT_GAME_CATALOG], problems: ['GAMES is not valid JSON; using the default list'] };\n }\n if (!Array.isArray(value)) {\n return { games: [...DEFAULT_GAME_CATALOG], problems: ['GAMES is not a JSON array; using the default list'] };\n }\n const games = [];\n const problems = [];\n for (const [i, item] of value.entries()) {\n const parsed = GameEntrySchema.safeParse(item);\n if (!parsed.success) {\n problems.push(`GAMES[${i}] dropped: ${parsed.error.issues.map((x) => `${x.path.join('.') || '(entry)'} ${x.message}`).join('; ')}`);\n continue;\n }\n if (games.some((g) => g.id === parsed.data.id)) {\n problems.push(`GAMES[${i}] dropped: duplicate id ${parsed.data.id}`);\n continue;\n }\n if (games.length >= 32) {\n problems.push(`GAMES[${i}] dropped: more than 32 games`);\n continue;\n }\n games.push(parsed.data);\n }\n return { games, problems };\n}\n","/**\n * Search in the Add media drawer — shows (AniList, TMDB) and YouTube videos.\n *\n * The wire contract only. The server owns every rule that decides what a\n * result MEANS — which names a release might carry, which folder a show lands\n * in, whether it is already on the scraper's watch list — so the client\n * renders what it is handed and sends back an id, never a name or a pattern.\n */\nimport { z } from 'zod';\nexport const ShowSource = z.enum(['anilist', 'tmdb']);\nexport const ShowResult = z.object({\n source: ShowSource,\n /** The provider's own id, as a string (AniList and TMDB both use integers). */\n id: z.string(),\n title: z.string(),\n year: z.number().int().nullable(),\n /** AniList `format` (TV, ONA, MOVIE…) or `TV` for TMDB. */\n format: z.string().nullable(),\n episodes: z.number().int().nullable(),\n /** Same-origin proxied poster (`/api/search/thumb?u=…`), or null. */\n poster: z.string().nullable(),\n /** The folder this show would land in — `SousouNoFrieren`. */\n series: z.string(),\n /** On the scraper's watch list already (by series). */\n onWatchlist: z.boolean(),\n /**\n * Not addable: a movie, or a title with no usable Latin-script name. The\n * scraper matches releases by `SxxExx`, so a film can never arrive through it.\n */\n addable: z.boolean(),\n});\nexport const ShowSearchOut = z.object({\n results: z.array(ShowResult),\n /** Providers that answered. TMDB is absent when no token is configured. */\n sources: z.array(ShowSource),\n});\nexport const VideoResult = z.object({\n id: z.string(),\n url: z.string(),\n title: z.string(),\n channel: z.string().nullable(),\n durationS: z.number().nullable(),\n thumb: z.string().nullable(),\n});\nexport const VideoSearchOut = z.object({ results: z.array(VideoResult) });\nexport const WatchlistAddIn = z.object({\n source: ShowSource,\n id: z.string().regex(/^\\d{1,12}$/),\n});\nexport const WatchlistAddOut = z.object({ series: z.string(), title: z.string() });\n/** Shortest query worth sending to a provider. */\nexport const SEARCH_MIN_QUERY = 2;\nexport const SEARCH_MAX_QUERY = 100;\n","// src/constants.ts\nvar MAX_BYTES = {\n image: 10 * 1024 * 1024,\n audio: 50 * 1024 * 1024\n};\nvar ACCEPTED_IMAGE_TYPES = [\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n \"image/avif\"\n];\nvar ACCEPTED_AUDIO_TYPES = [\n \"audio/mpeg\",\n \"audio/flac\",\n \"audio/ogg\",\n \"audio/mp4\",\n \"audio/wav\"\n];\nvar AUDIO_TYPE_ALIASES = {\n \"audio/mp3\": \"audio/mpeg\",\n \"audio/x-mp3\": \"audio/mpeg\",\n \"audio/x-mpeg\": \"audio/mpeg\",\n \"audio/x-flac\": \"audio/flac\",\n \"audio/opus\": \"audio/ogg\",\n \"audio/x-m4a\": \"audio/mp4\",\n \"audio/m4a\": \"audio/mp4\",\n \"audio/x-wav\": \"audio/wav\",\n \"audio/wave\": \"audio/wav\",\n \"audio/vnd.wave\": \"audio/wav\"\n};\nfunction kindOfType(type) {\n const t = type.toLowerCase();\n if (ACCEPTED_IMAGE_TYPES.includes(t)) return \"image\";\n if (ACCEPTED_AUDIO_TYPES.includes(t) || t in AUDIO_TYPE_ALIASES) {\n return \"audio\";\n }\n return null;\n}\nvar DEFAULT_SEARCH_LIMIT = 24;\nvar SEARCH_DEBOUNCE_MS = 250;\n\n// src/errors.ts\nvar CdnError = class extends Error {\n reason;\n /** HTTP status, when there was a response. */\n status;\n /**\n * Seconds to wait before retrying, from the server's `Retry-After`.\n *\n * Only ever set on a `rate-limited` error, and null even then if the server\n * sent no header. It is what makes that reason actionable: \"slow down\" with\n * no number leaves a UI guessing, and a guess that is too short turns one\n * 429 into a loop of them.\n */\n retryAfterSeconds;\n constructor(reason, message, status = null, retryAfterSeconds = null) {\n super(message);\n this.name = \"CdnError\";\n this.reason = reason;\n this.status = status;\n this.retryAfterSeconds = retryAfterSeconds;\n }\n};\nfunction parseRetryAfter(header, now = Date.now()) {\n if (!header) return null;\n const trimmed = header.trim();\n if (!trimmed) return null;\n const seconds = Number(trimmed);\n if (Number.isFinite(seconds)) return seconds >= 0 ? Math.ceil(seconds) : null;\n const at = Date.parse(trimmed);\n if (Number.isNaN(at)) return null;\n return Math.max(0, Math.ceil((at - now) / 1e3));\n}\nfunction reasonForStatus(status) {\n switch (status) {\n case 401:\n return \"unauthenticated\";\n case 403:\n return \"forbidden\";\n case 400:\n return \"invalid\";\n case 413:\n return \"too-large\";\n case 415:\n return \"unsupported-type\";\n case 429:\n return \"rate-limited\";\n case 500:\n case 502:\n case 503:\n case 504:\n return \"unavailable\";\n default:\n return \"unknown\";\n }\n}\nasync function errorFromResponse(response) {\n const reason = reasonForStatus(response.status);\n let message = `CDN request failed (${response.status})`;\n try {\n const body = await response.json();\n if (typeof body?.message === \"string\") message = body.message;\n else if (typeof body?.error === \"string\") message = body.error;\n } catch {\n }\n return new CdnError(\n reason,\n message,\n response.status,\n reason === \"rate-limited\" ? parseRetryAfter(response.headers.get(\"Retry-After\")) : null\n );\n}\n\n// src/client.ts\nvar DEFAULT_UPLOAD_PATH = \"/cdn/api/upload\";\nvar KEY_PATTERN = /^[0-9a-f]{64}\\.[a-z0-9]{1,8}$/;\nfunction preflight(file) {\n if (file.size === 0) {\n throw new CdnError(\"invalid\", \"File is empty\");\n }\n const kind = file.type ? kindOfType(file.type) : null;\n if (file.type && !kind) {\n throw new CdnError(\"unsupported-type\", `${file.type} is not an accepted image or audio format`);\n }\n const max = kind ? MAX_BYTES[kind] : Math.max(MAX_BYTES.image, MAX_BYTES.audio);\n if (file.size > max) {\n throw new CdnError(\"too-large\", `File is ${file.size} bytes; the maximum is ${max}`);\n }\n}\nfunction normalizeItem(raw) {\n if (typeof raw !== \"object\" || raw === null) return null;\n const r = raw;\n if (typeof r.key !== \"string\" || !r.key) return null;\n return {\n key: r.key,\n title: typeof r.title === \"string\" ? r.title : \"\",\n tags: Array.isArray(r.tags) ? r.tags.filter((t) => typeof t === \"string\") : [],\n width: typeof r.width === \"number\" && r.width > 0 ? r.width : null,\n height: typeof r.height === \"number\" && r.height > 0 ? r.height : null,\n contentType: typeof r.contentType === \"string\" ? r.contentType : \"image/*\"\n };\n}\nfunction createCdnClient(options) {\n const cdnBase = options.cdnBase.replace(/\\/+$/, \"\");\n const uploadPath = options.uploadPath ?? DEFAULT_UPLOAD_PATH;\n const doFetch = options.fetch ?? globalThis.fetch.bind(globalThis);\n async function request(url, init) {\n let response;\n try {\n response = await doFetch(url, init);\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") throw err;\n throw new CdnError(\"network\", err instanceof Error ? err.message : \"Request failed\");\n }\n if (!response.ok) throw await errorFromResponse(response);\n return response;\n }\n return {\n cdnBase,\n uploadPath,\n async upload(file, uploadOptions) {\n preflight(file);\n const response = await request(uploadPath, {\n method: \"POST\",\n body: file,\n signal: uploadOptions?.signal,\n // Same-origin from a hadoku.me app, so the session cookie travels\n // and no key handling is needed here.\n credentials: \"same-origin\"\n });\n return await response.json();\n },\n urlFor(key) {\n return `${cdnBase}/${key.replace(/^\\/+/, \"\")}`;\n },\n isKey(value) {\n return KEY_PATTERN.test(value);\n },\n catalogue(basePath, catalogueOptions) {\n const base = basePath.replace(/\\/+$/, \"\");\n const defaultSurface = catalogueOptions?.surface;\n return {\n async search(searchOptions = {}) {\n const params = new URLSearchParams();\n const query = searchOptions.query?.trim();\n if (query) params.set(\"q\", query);\n params.set(\"limit\", String(searchOptions.limit ?? DEFAULT_SEARCH_LIMIT));\n if (searchOptions.cursor) params.set(\"cursor\", searchOptions.cursor);\n const response = await request(`${base}?${params.toString()}`, {\n method: \"GET\",\n signal: searchOptions.signal,\n credentials: \"same-origin\"\n });\n const body = await response.json();\n const rows = Array.isArray(body.results) ? body.results : [];\n return {\n results: rows.map(normalizeItem).filter((i) => i !== null),\n next: typeof body.next === \"string\" && body.next ? body.next : null\n };\n },\n recordUse(key, useOptions) {\n const surface = useOptions?.surface ?? defaultSurface;\n const query = surface ? `?surface=${encodeURIComponent(surface)}` : \"\";\n void doFetch(`${base}/${encodeURIComponent(key)}/use${query}`, {\n method: \"POST\",\n credentials: \"same-origin\"\n }).catch(() => void 0);\n }\n };\n }\n };\n}\n\n// src/input.ts\nfunction filesFromClipboard(clipboardData, kinds = [\"image\"]) {\n if (!clipboardData) return [];\n const accept = (file) => isAccepted(file, kinds);\n const fromFiles = clipboardData.files ? Array.from(clipboardData.files) : [];\n if (fromFiles.length > 0) return fromFiles.filter(accept);\n const items = clipboardData.items ? Array.from(clipboardData.items) : [];\n return items.filter((item) => item.kind === \"file\").map((item) => item.getAsFile()).filter((file) => file !== null).filter(accept);\n}\nfunction filesFromDrop(dataTransfer, kinds = [\"image\"]) {\n if (!dataTransfer?.files) return [];\n return Array.from(dataTransfer.files).filter((file) => isAccepted(file, kinds));\n}\nfunction isAccepted(file, kinds) {\n if (!file.type) return true;\n const kind = kindOfType(file.type);\n return kind !== null && kinds.includes(kind);\n}\nfunction isImageLike(file) {\n return isAccepted(file, [\"image\"]);\n}\nasync function measureImage(file) {\n const creator = globalThis.createImageBitmap;\n if (typeof creator !== \"function\") return null;\n try {\n const bitmap = await creator(file);\n const dims = { width: bitmap.width, height: bitmap.height };\n bitmap.close?.();\n return dims;\n } catch {\n return null;\n }\n}\n\nexport {\n MAX_BYTES,\n ACCEPTED_IMAGE_TYPES,\n ACCEPTED_AUDIO_TYPES,\n AUDIO_TYPE_ALIASES,\n kindOfType,\n DEFAULT_SEARCH_LIMIT,\n SEARCH_DEBOUNCE_MS,\n CdnError,\n reasonForStatus,\n createCdnClient,\n filesFromClipboard,\n filesFromDrop,\n isAccepted,\n isImageLike,\n measureImage\n};\n","/**\n * The app's handle on `@wolffm/cdn-client`.\n *\n * Transport — upload, URL composition, catalogue search — now lives in that\n * shared package (`hadoku_site/packages/cdn-client`), which every ecosystem app\n * integrates with. What stays here is the watchparty-specific SHIM: the\n * composer's attachment model, the wire schema, and the picker's markup. That\n * split is deliberate — `/tube/` comments want the same transport and nothing\n * like the same layout.\n *\n * The client is memoised per `cdnBase`, and `setRuntimeConfig` can legitimately\n * change `cdnBase` at mount time — so a once-only singleton would pin the wrong\n * origin, and a fresh object per call would throw away a shared instance that\n * non-React callers use too.\n *\n * It is NOT memoised to protect `useCatalogueSearch` any more. It used to be:\n * that hook keyed its catalogue on the client's IDENTITY, so a fresh object per\n * render re-ran the effect, which set state, which re-rendered — a permanent\n * loop, not the \"re-fetch per keystroke\" this comment used to claim. Measured\n * upstream at ~2 catalogue requests a second for as long as the picker stayed\n * mounted, with the component otherwise idle.\n *\n * cdn-client 1.0.3 fixes it at the source — the hooks key on the client's\n * CONFIGURATION and read it through a ref — so an unstable client is now merely\n * wasteful allocation rather than a request storm. The `^1.0.3` floor below is\n * what makes that a guarantee instead of a coincidence.\n */\nimport { createCdnClient, type CdnClient } from '@wolffm/cdn-client';\nimport { DEFAULT_CDN_BASE, isChatImageKey } from '@watchparty/shared';\n\nlet cached: { base: string; client: CdnClient } | null = null;\nlet cdnBase: string = DEFAULT_CDN_BASE;\n\nexport interface ChatMediaConfig {\n /** Public read base for CDN objects, e.g. `https://cdn.hadoku.me`. */\n cdnBase: string;\n}\n\n/** Point chat media at a CDN. Called from `setRuntimeConfig` at app boot. */\nexport function setChatMediaConfig(config: Partial<ChatMediaConfig>): void {\n if (config.cdnBase) cdnBase = config.cdnBase;\n}\n\n/** The configured base, trailing slash stripped. */\nexport function getChatMediaCdnBase(): string {\n return cdnBase.replace(/\\/+$/, '');\n}\n\n/** The shared client, stable for as long as `cdnBase` is. */\nexport function getCdnClient(): CdnClient {\n const base = getChatMediaCdnBase();\n if (!cached || cached.base !== base) {\n cached = { base, client: createCdnClient({ cdnBase: base }) };\n }\n return cached.client;\n}\n\n/**\n * Compose the render URL for a stored key, or `null` if the key is not one.\n *\n * **The null case is load-bearing and is NOT what `client.urlFor` does.**\n * `urlFor` concatenates unconditionally — it is a convenience that makes\n * storing keys the easy path, not a validator. A key reaches this app over the\n * wire from another client, so it is data: interpolating an unchecked one\n * would put attacker-controlled text into an `<img src>`.\n *\n * The check uses watchparty's `isChatImageKey`, not `client.isKey`, and the\n * difference matters. The package accepts any `[a-z0-9]{1,8}` extension;\n * `CHAT_IMAGE_KEY_RE` is an ALLOWLIST (png/jpg/jpeg/gif/webp/avif), so it also\n * refuses `.svg` — a scriptable document served same-site with the app. It is\n * the same predicate the Zod wire schema enforces, so render and protocol\n * cannot disagree.\n */\nexport function resolveChatImageUrl(key: string): string | null {\n if (!isChatImageKey(key)) return null;\n const base = getChatMediaCdnBase();\n if (!base) return null;\n return getCdnClient().urlFor(key);\n}\n","import { createContext, useContext } from 'react';\nimport { DEFAULT_HTTP_PORT, DEFAULT_CDN_BASE } from '@watchparty/shared';\nimport { setChatMediaConfig } from './chatMedia';\n\n/**\n * Where chat image bytes are read from in local dev.\n *\n * NOT a cosmetic difference. hadoku.me runs Cloudflare hotlink protection,\n * which answers a request carrying a `localhost` Referer with `403\n * text/plain`; Chrome surfaces that as `ERR_BLOCKED_BY_ORB` and the image\n * simply never appears. Its extension list (jpg/jpeg/png/gif/ico) predates\n * WebP, so `.webp` renders and everything else does not — a split that reads\n * like a bug in the app rather than an edge policy.\n *\n * `apps/ui/vite.config.ts` proxies this path to the CDN server-side with the\n * Referer stripped. Production keeps the real `cdnBase`, so no request path\n * differs in prod. Override either with `VITE_CDN_BASE`.\n */\nconst DEV_CDN_PROXY_BASE = '/_cdn';\n\nexport interface WatchpartyConfig {\n serverOrigin: string;\n defaultRoomKey: string;\n /** Public read base for chat image attachments (see `chatImages.ts`). Only\n * the RENDER side needs it — uploads go to the same-origin `/cdn/api/upload`\n * so the browser never handles a key. */\n cdnBase: string;\n}\n\nexport const DEFAULT_CONFIG: WatchpartyConfig = {\n serverOrigin: import.meta.env.VITE_SERVER_ORIGIN || `http://localhost:${DEFAULT_HTTP_PORT}`,\n defaultRoomKey: 'dev-room',\n cdnBase: import.meta.env.VITE_CDN_BASE || (import.meta.env.DEV ? DEV_CDN_PROXY_BASE : DEFAULT_CDN_BASE),\n};\n\n// Runtime config used by non-component code (socket, catalog, etc.)\nlet runtimeConfig: WatchpartyConfig = { ...DEFAULT_CONFIG };\n\nexport function setRuntimeConfig(config: Partial<WatchpartyConfig>) {\n // Filter out undefined values to preserve defaults\n const filtered = Object.fromEntries(\n Object.entries(config).filter(([_, v]) => v !== undefined)\n );\n runtimeConfig = { ...runtimeConfig, ...filtered };\n // The chat-media layer keeps its own copy so it can render a key without\n // reaching into this app's config — the property its extraction into\n // `@wolffm/chat-media` depends on. Mirrored here so a host that overrides\n // `cdnBase` (mount prop, VITE_CDN_BASE) configures both in one call.\n setChatMediaConfig({ cdnBase: runtimeConfig.cdnBase });\n}\n\nexport function getRuntimeConfig(): WatchpartyConfig {\n return runtimeConfig;\n}\n\n// React Context for component tree\nexport const ConfigContext = createContext<WatchpartyConfig>(DEFAULT_CONFIG);\n\nexport function useConfig(): WatchpartyConfig {\n return useContext(ConfigContext);\n}\n\n/** Returns the server origin with trailing slash stripped. */\nexport function getServerOrigin(config: WatchpartyConfig): string {\n return config.serverOrigin?.replace(/\\/$/, '') || '';\n}\n\n/** Returns the runtime config's server origin with trailing slash stripped. */\nexport function getRuntimeServerOrigin(): string {\n return getServerOrigin(getRuntimeConfig());\n}\n\n/** Returns the runtime config's CDN base with trailing slash stripped. */\nexport function getRuntimeCdnBase(): string {\n return getRuntimeConfig().cdnBase?.replace(/\\/$/, '') || '';\n}\n","/**\n * Single source of truth for every localStorage key the UI reads or writes.\n *\n * - `ANON_KEY` — anonymous (public) user's preferences slot.\n * Authed users get `${ANON_KEY}:${userId}` (composed by `storageKey()`\n * in preferences.ts).\n * - `DEBUG_FLAG` — opt-in client log verbosity (see debug.ts).\n * - `REPORT_LOGS_FLAG` — opt-in to forward client logs to the server.\n * - `voteKey(owner, playlistId, mediaId)` — per-video vote in a playlist\n * session, scoped to WHO cast it (see `voteOwnerScope`). Unscoped, a\n * second person on the same browser inherited and re-submitted the first\n * person's ballot.\n * (see PlaylistPanel.tsx).\n *\n * This module is import-cycle-free on purpose: it has no other UI lib\n * dependencies so both debug.ts and preferences.ts can safely import it.\n */\nexport const STORAGE_KEYS = {\n ANON_KEY: 'watchparty_preferences',\n DEBUG_FLAG: 'wp:debug',\n REPORT_LOGS_FLAG: 'wp:reportLogs',\n voteKey: (owner: string, playlistId: string, mediaId: string) =>\n `watchparty_vote:${owner}:${playlistId}:${mediaId}`,\n} as const;\n","/**\n * localStorage access that cannot throw.\n *\n * Every call site in this app has to handle the same two facts: storage may be\n * unavailable (private mode, blocked site data, a sandboxed iframe — reading it\n * THROWS rather than returning null), and this bundle also runs where there is\n * no `window` at all. Twelve sites had hand-rolled that `try`/`catch`, each\n * with its own fallback spelling, and a missed one is an uncaught exception on\n * a path no test covers because the test environment always has storage.\n *\n * Absence and failure are deliberately NOT distinguished: no caller has ever\n * wanted to tell \"the user blocked storage\" apart from \"nothing stored yet\",\n * and a helper that returned a discriminated result would just get `?? null`'d\n * at every site.\n */\n\nfunction storage(): Storage | null {\n try {\n // `globalThis.localStorage`, NOT `window.localStorage` — they are the same\n // object in a browser, but the narrower spelling is wrong twice: it is\n // absent in a worker context, and the UI test suite runs in vitest's `node`\n // environment where specs stub the GLOBAL (`vi.stubGlobal('localStorage',\n // …)`). Requiring `window` made ten existing specs read every stub as\n // \"storage unavailable\".\n //\n // The property access itself throws in a sandboxed iframe, so it sits\n // inside the try alongside the read.\n return globalThis.localStorage ?? null;\n } catch {\n return null;\n }\n}\n\n/** Read a key. `null` when absent, unavailable, or the read threw. */\nexport function readStored(key: string): string | null {\n try {\n return storage()?.getItem(key) ?? null;\n } catch {\n return null;\n }\n}\n\n/** Write a key. Returns whether it landed — callers that care can fall back. */\nexport function writeStored(key: string, value: string): boolean {\n try {\n const s = storage();\n // NOT `storage()?.setItem(...); return true` — that optional chain\n // short-circuits when storage is absent and still reports success, which\n // is the exact lie this return value exists to prevent.\n if (!s) return false;\n s.setItem(key, value);\n return true;\n } catch {\n // Also covers a full quota, not just a blocked store.\n return false;\n }\n}\n\n/** Every key currently stored. Empty when storage is unavailable. */\nexport function storedKeys(): string[] {\n try {\n const s = storage();\n if (!s) return [];\n const keys: string[] = [];\n for (let i = 0; i < s.length; i++) {\n const k = s.key(i);\n if (k !== null) keys.push(k);\n }\n return keys;\n } catch {\n return [];\n }\n}\n\n/** Remove a key. Silent when storage is unavailable. */\nexport function removeStored(key: string): void {\n try {\n storage()?.removeItem(key);\n } catch { /* nothing to undo */ }\n}\n\n/**\n * Read a key that holds a boolean-ish flag. `null` when unset, so a caller can\n * tell \"explicitly false\" from \"never set\" — which is the distinction the\n * fragment-delivery override and the debug flag both depend on.\n */\nexport function readStoredFlag(key: string): boolean | null {\n const raw = readStored(key);\n if (raw === null) return null;\n if (raw === 'true') return true;\n if (raw === 'false') return false;\n return null;\n}\n","/**\n * `window.__*` handles for devtools and E2E — registered everywhere, PUBLISHED\n * only when a host asks.\n *\n * Six modules used to assign their handle at import time (`__SOCKET__`,\n * `__ZUSTAND_STORE__`, `__wpDebug`, `__DISPLAY_NAMES__`, `__WP_PERF__`,\n * `__WP_SOUNDS__`). That is harmless when watchparty owns the whole page, and\n * wrong the moment it is a component on someone else's: importing\n * `@wolffm/watchparty-ui/room-chrome` would plant a live socket and the whole\n * store on the host's `window` without being asked.\n *\n * So a module REGISTERS its handle here, and nothing reaches `window` until\n * `exposeDebugGlobals()` is called. `mount()` — the whole-app entry, which\n * every E2E spec drives through these handles — calls it at boot, so the app\n * behaves exactly as before. `RoomChrome` calls it only for `debug`.\n *\n * A handle registered AFTER exposure is published immediately, so the order of\n * module evaluation and the call does not matter.\n */\n\nconst registry = new Map<string, unknown>();\nlet exposed = false;\n\nexport function registerDebugGlobal(name: string, value: unknown): void {\n registry.set(name, value);\n if (exposed) publish(name, value);\n}\n\nexport function exposeDebugGlobals(): void {\n exposed = true;\n for (const [name, value] of registry) publish(name, value);\n}\n\nfunction publish(name: string, value: unknown): void {\n if (typeof window === 'undefined') return;\n (window as unknown as Record<string, unknown>)[name] = value;\n}\n","/**\n * Debug logging utility for Watchparty UI\n *\n * Usage:\n * import { debug, warn, error } from './debug';\n *\n * debug('socket', 'Connected to server');\n * warn('chat', 'Message rate limited');\n * error('room', 'Failed to join room', err);\n *\n * Enable debug mode:\n * - Set localStorage.setItem('wp:debug', 'true')\n * - Or add ?debug=true to URL\n * - Or set window.__WP_DEBUG__ = true\n *\n * Filter by category:\n * - localStorage.setItem('wp:debug', 'socket,chat') - only show socket and chat logs\n *\n * Error reporting:\n * - All error() and warn() calls are automatically sent to the server\n * - Server endpoint: POST /api/client-log\n */\n\nimport { DEFAULT_UI_PORT, DEFAULT_HTTP_PORT } from '@watchparty/shared';\nimport { getRuntimeConfig } from './config';\nimport { STORAGE_KEYS } from './storageKeys';\nimport { readStored, writeStored, removeStored } from './browserStorage';\nimport { registerDebugGlobal } from './debugGlobals';\n\ndeclare global {\n interface Window {\n __WP_DEBUG__?: boolean;\n }\n}\n\ntype LogLevel = 'debug' | 'warn' | 'error';\n\ninterface LogEntry {\n level: LogLevel;\n category: string;\n message: string;\n data?: unknown;\n timestamp: number;\n}\n\n// Log history for debugging\nconst logHistory: LogEntry[] = [];\nconst MAX_HISTORY = 500;\n\n// Log queue for batching server reports\nlet logQueue: LogEntry[] = [];\nlet logFlushTimeout: ReturnType<typeof setTimeout> | null = null;\nconst LOG_FLUSH_DELAY = 1000; // Batch logs for 1 second\nconst LOG_FLUSH_DELAY_FAST = 200; // Faster flush when report-all is active\n\n// Room context for correlating client logs with server session logs\nlet currentRoomContext: { room_key: string; client_id: string } | null = null;\n\n/**\n * Set room context so client logs include room_key and client_id.\n * Call on join (with context) and on disconnect (with null).\n */\nexport function setLogRoomContext(ctx: { room_key: string; client_id: string } | null): void {\n currentRoomContext = ctx;\n}\n\n// Check if report-all mode is enabled (send all log levels to server)\nexport function isReportAllEnabled(): boolean {\n return readStored(STORAGE_KEYS.REPORT_LOGS_FLAG) === 'true';\n}\n\n// Check if debug mode is enabled\nexport function isDebugEnabled(): boolean {\n if (typeof window === 'undefined') return false;\n\n // Check window flag\n if (window.__WP_DEBUG__) return true;\n\n // Check URL param\n const params = new URLSearchParams(window.location.search);\n if (params.get('debug') === 'true') return true;\n\n // Check localStorage. NOT readStoredFlag: any value other than 'false'\n // enables debug, because the flag doubles as a comma-separated category\n // filter (see getAllowedCategories) — 'buffer,seek' means \"on, for those\".\n const stored = readStored(STORAGE_KEYS.DEBUG_FLAG);\n return stored !== null && stored !== 'false';\n}\n\n// Get allowed categories (empty = all)\nfunction getAllowedCategories(): Set<string> | null {\n const stored = readStored(STORAGE_KEYS.DEBUG_FLAG);\n if (!stored || stored === 'true') return null; // All categories\n\n // Parse comma-separated categories\n const categories = stored.split(',').map(c => c.trim().toLowerCase()).filter(Boolean);\n return categories.length > 0 ? new Set(categories) : null;\n}\n\n// Format timestamp\nfunction formatTime(): string {\n const now = new Date();\n return now.toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n fractionalSecondDigits: 3\n });\n}\n\n// Add to history\nfunction addToHistory(entry: LogEntry) {\n logHistory.push(entry);\n if (logHistory.length > MAX_HISTORY) {\n logHistory.shift();\n }\n}\n\n// Style for console output\nconst styles = {\n debug: 'color: #64748b; font-weight: normal;',\n warn: 'color: #f59e0b; font-weight: bold;',\n error: 'color: #ef4444; font-weight: bold;',\n category: 'color: #3b82f6; font-weight: bold;',\n time: 'color: #6b7280; font-weight: normal;',\n};\n\n/** JSON.stringify with a fallback for circular or unserializable data. */\nfunction safeStringify(data: unknown): string {\n try { return JSON.stringify(data); } catch { return '[unserializable]'; }\n}\n\n/**\n * Internal shared log implementation.\n *\n * @param level - Log level (determines console style and history entry level)\n * @param consoleFn - The console function to call (console.log / console.warn / console.error)\n * @param alwaysReport - If true, always queue for server regardless of report-all mode\n * @param alwaysShow - If true, always print to console even when debug mode is off\n * @param category - Log category for filtering\n * @param message - Log message\n * @param data - Optional structured data\n */\nfunction _log(\n level: LogLevel,\n consoleFn: typeof console.log,\n alwaysReport: boolean,\n alwaysShow: boolean,\n category: string,\n message: string,\n data?: unknown,\n): void {\n const entry: LogEntry = {\n level,\n category,\n message,\n data,\n timestamp: Date.now(),\n };\n addToHistory(entry);\n\n if (alwaysReport) {\n queueLogForServer(entry);\n } else if (isReportAllEnabled()) {\n queueLogForServer(entry);\n }\n\n if (!alwaysShow) {\n if (!isDebugEnabled()) return;\n const allowed = getAllowedCategories();\n if (allowed && !allowed.has(category.toLowerCase())) return;\n }\n\n const time = formatTime();\n // Stringify data inline so Playwright msg.text() captures it\n // (msg.text() only returns the first console argument).\n const suffix = data !== undefined ? ' ' + safeStringify(data) : '';\n consoleFn(\n `%c[${time}]%c [${category}]%c ${message}${suffix}`,\n styles.time,\n styles.category,\n styles[level],\n );\n}\n\n/**\n * Debug log - only shows in debug mode\n */\nexport function debug(category: string, message: string, data?: unknown): void {\n _log('debug', console.log, false, false, category, message, data);\n}\n\n/**\n * Warning log - always reports to server, only shows in console in debug mode\n */\nexport function warn(category: string, message: string, data?: unknown): void {\n _log('warn', console.warn, true, false, category, message, data);\n}\n\n/**\n * Error log - always shows and reports to server\n */\nexport function error(category: string, message: string, data?: unknown): void {\n _log('error', console.error, true, true, category, message, data);\n}\n\n/**\n * Get log history (useful for debugging)\n */\nfunction getLogHistory(): LogEntry[] {\n return [...logHistory];\n}\n\n/**\n * Clear log history\n */\nfunction clearLogHistory(): void {\n logHistory.length = 0;\n}\n\n/**\n * Enable debug mode programmatically\n */\nfunction enableDebug(categories?: string[]): void {\n const value = categories && categories.length > 0 ? categories.join(',') : 'true';\n writeStored(STORAGE_KEYS.DEBUG_FLAG, value);\n console.log('[wp] Debug mode enabled');\n}\n\n/**\n * Disable debug mode\n */\nfunction disableDebug(): void {\n removeStored(STORAGE_KEYS.DEBUG_FLAG);\n console.log('[wp] Debug mode disabled');\n}\n\n// Max serialized size for a single log entry's data field (chars)\nconst MAX_DATA_SIZE = 1024;\n// Max payload size per request (stay well under server's 64kb limit)\nconst MAX_BATCH_SIZE = 50_000;\n\n/**\n * Truncate data field to prevent oversized payloads\n */\nfunction truncateData(data: unknown): unknown {\n if (data === undefined || data === null) return data;\n try {\n const json = JSON.stringify(data);\n if (json.length <= MAX_DATA_SIZE) return data;\n // For objects, try to keep keys but truncate values\n if (typeof data === 'object' && !Array.isArray(data)) {\n const truncated: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(data as Record<string, unknown>)) {\n const vStr = JSON.stringify(v);\n truncated[k] = vStr && vStr.length > 200 ? `[truncated ${vStr.length} chars]` : v;\n }\n return truncated;\n }\n return `[truncated ${json.length} chars]`;\n } catch {\n return '[unserializable]';\n }\n}\n\n/**\n * Synchronous best-effort log delivery for events that IMMEDIATELY precede a\n * page reload (window.location.reload). The normal async batch in\n * flushLogsToServer() is lost when the document tears down, so the reason a\n * client auto-reloaded never reached the server (observed 2026-06-16: 31\n * POST-AUTO-RELOAD with 0 trigger logs). navigator.sendBeacon is built for\n * exactly this — the browser guarantees delivery during unload. Also console.warns.\n */\nexport function beaconLog(level: string, category: string, message: string, data?: unknown): void {\n try { console.warn(`[${category}] ${message}`, data ?? ''); } catch { /* noop */ }\n try {\n if (typeof navigator === 'undefined' || typeof navigator.sendBeacon !== 'function') return;\n const config = getRuntimeConfig();\n let origin = config.serverOrigin || '';\n if (origin === '/' || !origin) {\n if (typeof window !== 'undefined') {\n const loc = window.location;\n origin = (loc.hostname === 'localhost' || loc.hostname === '127.0.0.1') && loc.port === String(DEFAULT_UI_PORT)\n ? `${loc.protocol}//${loc.hostname}:${DEFAULT_HTTP_PORT}`\n : loc.origin;\n }\n }\n const url = `${origin.replace(/\\/$/, '')}/api/client-log`;\n const body = JSON.stringify({ logs: [{\n level, category, message,\n data: truncateData(data),\n timestamp: Date.now(),\n url: typeof window !== 'undefined' ? window.location.href : undefined,\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : undefined,\n room_key: currentRoomContext?.room_key,\n client_id: currentRoomContext?.client_id,\n }] });\n navigator.sendBeacon(url, new Blob([body], { type: 'application/json' }));\n } catch { /* noop */ }\n}\n\n/**\n * Send queued logs to the server\n */\nasync function flushLogsToServer(): Promise<void> {\n if (logQueue.length === 0) return;\n\n const batch = logQueue;\n logQueue = [];\n logFlushTimeout = null;\n\n try {\n const config = getRuntimeConfig();\n let origin = config.serverOrigin || '';\n if (origin === '/' || !origin) {\n if (typeof window !== 'undefined') {\n const loc = window.location;\n if ((loc.hostname === 'localhost' || loc.hostname === '127.0.0.1') && loc.port === String(DEFAULT_UI_PORT)) {\n origin = `${loc.protocol}//${loc.hostname}:${DEFAULT_HTTP_PORT}`;\n } else {\n origin = loc.origin;\n }\n }\n }\n\n const url = `${origin.replace(/\\/$/, '')}/api/client-log`;\n\n const prepared = batch.map(e => ({\n level: e.level,\n category: e.category,\n message: e.message,\n data: truncateData(e.data),\n timestamp: e.timestamp,\n url: typeof window !== 'undefined' ? window.location.href : undefined,\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : undefined,\n room_key: currentRoomContext?.room_key,\n client_id: currentRoomContext?.client_id,\n }));\n\n // Split into chunks that fit under the server limit\n let chunk: typeof prepared = [];\n let chunkSize = 0;\n for (const entry of prepared) {\n const entrySize = JSON.stringify(entry).length + 1; // +1 for comma\n if (chunkSize + entrySize > MAX_BATCH_SIZE && chunk.length > 0) {\n await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ logs: chunk }),\n });\n chunk = [];\n chunkSize = 0;\n }\n chunk.push(entry);\n chunkSize += entrySize;\n }\n if (chunk.length > 0) {\n await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ logs: chunk }),\n });\n }\n } catch (err: unknown) {\n console.warn('[wp] log flush failed (client logs may be lost):', errorFields(err).error);\n }\n}\n\n/**\n * Queue a log entry to be sent to the server\n */\nfunction queueLogForServer(entry: LogEntry): void {\n logQueue.push(entry);\n\n // Debounce the flush (faster in report-all mode)\n if (!logFlushTimeout) {\n const delay = isReportAllEnabled() ? LOG_FLUSH_DELAY_FAST : LOG_FLUSH_DELAY;\n logFlushTimeout = setTimeout(() => { void flushLogsToServer(); }, delay);\n }\n}\n\n/**\n * Narrow an unknown thrown value to the `{ error, name }` pair every log site\n * in this app reports.\n *\n * Catch sites used to annotate the variable `any` and reach into it directly\n * (`e?.message`), which turns off strict mode at precisely the point where the\n * value is least trustworthy — a thrown string or a rejected non-Error then\n * logs `undefined` instead of saying what happened.\n */\nexport function errorFields(err: unknown): { error: string; name: string } {\n return err instanceof Error\n ? { error: err.message, name: err.name }\n : { error: String(err), name: typeof err };\n}\n\n// Console access — published only when the host opts in (lib/debugGlobals.ts).\nregisterDebugGlobal('__wpDebug', {\n enable: enableDebug,\n disable: disableDebug,\n history: getLogHistory,\n clear: clearLogHistory,\n});\n","import {\n CHARACTER_ORDER,\n CHARACTER_COLORS,\n isCharacterId,\n portraitPath,\n type CharacterId,\n} from '@watchparty/shared';\nimport { getRuntimeConfig } from './config';\nimport { debug, errorFields } from './debug';\nimport { registerDebugGlobal } from './debugGlobals';\n\n// Re-export so existing `from './characters'` imports keep working.\nexport { CHARACTER_ORDER, isCharacterId };\nexport type { CharacterId };\n\nexport function colorForSprite(sprite: string | null | undefined): string {\n return isCharacterId(sprite) ? CHARACTER_COLORS[sprite] : 'var(--color-neutral-bg)';\n}\n\n/**\n * The portrait URL for a sprite. Takes the raw value off the wire and answers\n * undefined for anything that is not a character, so a bogus sprite renders no\n * image instead of a 404. The path rule, cache-busting included, is\n * `portraitPath` in @watchparty/shared.\n */\nexport function spriteUrlFor(sprite: string | null | undefined): string | undefined {\n if (!isCharacterId(sprite)) return undefined;\n const origin = getRuntimeConfig().serverOrigin.replace(/\\/$/, '');\n return `${origin}${portraitPath(sprite)}`;\n}\n\n// --- Optional display name mapping (loaded from media/sprites/names.json) ---\n\nlet displayNames: Record<string, string> | null = null;\nlet loadPromise: Promise<void> | null = null;\n\n/** Fetch display names from server. No-op if already loaded or file doesn't exist. */\nexport function loadDisplayNames(): Promise<void> {\n if (displayNames) return Promise.resolve();\n if (loadPromise) return loadPromise;\n loadPromise = (async () => {\n try {\n const origin = getRuntimeConfig().serverOrigin.replace(/\\/$/, '');\n // no-cache, not force-cache: the server sent this file `immutable` for a\n // year until new characters were added, so a returning browser holds a\n // copy that predates them. Revalidating is what gets past it.\n const res = await fetch(`${origin}/media/sprites/names.json`, { cache: 'no-cache' });\n if (!res.ok) return; // File doesn't exist — use defaults\n const data = await res.json();\n displayNames = data;\n registerDebugGlobal('__DISPLAY_NAMES__', data);\n debug('characters', 'Loaded display names', data);\n } catch (e: unknown) {\n // names.json may not exist — degrade to sprite IDs.\n debug('characters', 'display names fetch failed (degrading to sprite IDs)', errorFields(e));\n }\n })();\n return loadPromise;\n}\n\n/** Get the display name for a sprite ID. Falls back to capitalized ID. */\nexport function displayNameFor(id: string): string {\n return displayNames?.[id] || id.charAt(0).toUpperCase() + id.slice(1);\n}\n\n/** Check if a name matches any display name or sprite ID (case-insensitive). */\nexport function isCharacterName(name: string): boolean {\n const lower = name.toLowerCase();\n if (CHARACTER_ORDER.some(c => c === lower)) return true;\n if (displayNames) {\n return Object.values(displayNames).some(dn => dn.toLowerCase() === lower);\n }\n return false;\n}\n","/**\n * Auth state passed in via mf-loader mount props.\n *\n * mf-loader (hadoku_site) resolves the HttpOnly `hadoku_session` cookie\n * through /session/whoami before our bundle loads and passes `userType` plus\n * `userId` — the key registry's userId, or null — as mount props. We stash\n * them in module scope so non-component code (socket setup, fetch wrappers)\n * can read identity without prop-drilling.\n *\n * There is NO session id here, on purpose (#151, hadoku_site#459). It is a\n * bearer credential for a 30-day sliding session, and about twenty bundles\n * share the hadoku.me origin, so a copy readable by page JavaScript is one\n * XSS away from being stolen. Same-origin requests carry the cookie by\n * default and edge-router resolves it exactly as it resolved `X-Session-Id`.\n * Do not read `props.sessionId` or `localStorage.hadoku_session_id` again.\n */\n\nimport { warn, errorFields } from './debug';\n\n// The full hadoku ladder. This mirrors the server's UserType; a tier missing\n// here is not a type error at the boundary (the value arrives as a string from\n// mount props) — it just makes every comparison against it fail silently.\ntype UserType = 'admin' | 'wife' | 'service' | 'friend' | 'member' | 'public';\n\ntype AuthState = {\n /** False until the host's `setAuth` lands. Before it (the store's\n * module-init read) nobody knows who this is. */\n resolved: boolean;\n userType: UserType;\n /** Display name from /session/whoami; null until fetched (or for public users). */\n name: string | null;\n /** Registry userId: the host's `userId`, or whoami's. Null for anonymous\n * viewers and for a registry row that has none. */\n accountId: string | null;\n};\n\nconst _state: AuthState = {\n resolved: false,\n userType: 'public',\n name: null,\n accountId: null,\n};\n\n/**\n * The user id `@wolffm/prefs-client` builds its cache key from, mirroring its\n * `whoami` (`dist/index.js`, `whoami()`):\n * - account known -> the registry userId\n * - anonymous -> 'anon'\n * - before setAuth, or signed in with no account -> null: the SDK's key is\n * not knowable (for the latter it is `session:<id>`, which this bundle no\n * longer reads), and guessing is how a signed-in visitor gets seeded from\n * someone else's row (prod prefs-cross-user, 2026-10-05: the shared\n * `anon` row handed UserB UserA's name).\n */\nexport function getPrefsCacheUserId(): string | null {\n if (_state.accountId) return _state.accountId;\n if (!_state.resolved) return null;\n return _state.userType === 'public' ? 'anon' : null;\n}\n\nexport function setAuth(input: { userType?: UserType; userId?: string | null }) {\n _state.resolved = true;\n if (input.userType) _state.userType = input.userType;\n // Before hadoku_site 002584fe the prop was the SESSION id, or 'public' —\n // never an account. Only a registry userId names one.\n if (input.userId !== undefined) {\n _state.accountId = input.userId && input.userId !== 'public' ? input.userId : null;\n }\n}\n\nexport function getUserType(): UserType {\n return _state.userType;\n}\n\n// Rank ladder, LOW to HIGH — the browser-side mirror of TIER_RANK in\n// apps/server/src/middleware/whoami.ts. This bundle cannot import the server's\n// copy, so it must be kept complete: an unlisted tier gets rank -1 and every\n// affordance below is hidden from it.\nconst TIER_RANK: Record<UserType, number> = {\n public: 0,\n member: 1,\n friend: 2,\n service: 3,\n wife: 4,\n admin: 5,\n};\n\nfunction tierAtLeast(tier: UserType, minimum: UserType): boolean {\n return (TIER_RANK[tier] ?? -1) >= TIER_RANK[minimum];\n}\n\n/**\n * True when the user is service tier or above. Use this to gate UI affordances\n * tied to service-tier endpoints (room creation, leader URLs).\n *\n * Ranks, never equality. This read `=== 'service' || === 'admin'` until\n * 2026-08-04, which is the same exact-match allowlist that was fixed in the\n * SERVER's adminAuth at the same time — but this copy was missed, so the server\n * would have admitted a `wife` caller to those endpoints while the UI hid the\n * buttons that reach them. A UI-only version of the bug is still the bug.\n */\nexport function isPrivileged(): boolean {\n return tierAtLeast(_state.userType, 'service');\n}\n\n/** The registry userId, or 'public' when there is none. */\nexport function getUserId(): string {\n return _state.accountId ?? 'public';\n}\n\n/**\n * Whose browser-local copy of a ballot this is: the account when known, else\n * the shared anonymous scope, else `unscoped` for a signed-in viewer whose\n * account is not known — never another person's scope.\n */\nexport function voteOwnerScope(): string {\n return getPrefsCacheUserId() ?? 'unscoped';\n}\n\n/**\n * Fetch /session/whoami to populate `name` (display name from the friend-key\n * registry). The cookie is sent automatically; no headers needed. Idempotent\n * — safe to call multiple times. Returns the resolved name (or null).\n */\nexport async function loadWhoami(): Promise<string | null> {\n if (_state.userType === 'public') return null;\n if (_state.name) return _state.name;\n try {\n const res = await fetch('/session/whoami', {\n credentials: 'include',\n cache: 'no-store',\n });\n if (!res.ok) return null;\n const data = await res.json() as { valid?: boolean; name?: string | null; userId?: string | null };\n if (data.valid) {\n _state.accountId = typeof data.userId === 'string' && data.userId ? data.userId : null;\n }\n if (data.valid && typeof data.name === 'string') {\n _state.name = data.name;\n return data.name;\n }\n } catch (e: unknown) {\n warn('auth', 'whoami fetch failed', errorFields(e));\n }\n return null;\n}\n","/**\n * Watchparty app-specific preferences client.\n *\n * Holds everything user-related that's NOT theme (theme lives in\n * themePrefs.ts under the platform-global 'portfolio' appId). Scope is\n * 'user' so the same identity sees the same settings across devices —\n * cross-device sync is the main reason for migrating off the old\n * watchparty_preferences localStorage + /api/me/prefs system.\n *\n * Bug pattern to avoid (per the migration brief): write-only\n * `void watchpartyPrefs.save(...)` without a corresponding usePrefs\n * subscription causes settings to revert on browser close. Either use\n * the React hook OR subscribe via `watchpartyPrefs.subscribe(...)` in\n * the boot path so the in-memory zustand store stays in sync with the\n * SDK's cache + server.\n */\nimport { z } from 'zod';\nimport { createPrefsClient } from '@wolffm/prefs-client';\n\nexport const WatchpartyPrefsSchema = z.object({\n // Identity. There is deliberately NO `name`: a person's name is their\n // hadoku key-registry name, resolved by the server from whoami and renamed\n // through hadoku_site's POST /session/name (operator decision 2026-10-08).\n // A watchparty-only copy disagreed with cardtable's and is not read.\n //\n // `sprite` is neither read nor written by watchparty any more: the\n // character is chosen in the fleet settings popout and read from prefs-api\n // (lib/avatar.ts). It stays in the schema because prefs-api still reads it:\n // it is the fallback character for a person who never chose one at the\n // top level (operator decision 2026-10-31).\n sprite: z.string().optional(),\n\n // Chat settings\n chatCollapsed: z.boolean().optional(),\n floatingChatEnabled: z.boolean().optional(),\n // RoomChrome's chat column (roomChrome/chatLayout.ts) — separate from the\n // app's chatCollapsed on purpose.\n chromeChatCollapsed: z.boolean().optional(),\n chromeChatWidth: z.number().optional(),\n\n // Media settings\n volume: z.number().min(0).max(1).optional(),\n muted: z.boolean().optional(),\n preferredAudioLang: z.string().optional(),\n subtitlesEnabled: z.boolean().optional(),\n subtitleStyle: z.string().optional(),\n\n});\n\nexport type WatchpartyPrefs = z.infer<typeof WatchpartyPrefsSchema>;\n\nexport const watchpartyPrefs = createPrefsClient({\n appId: 'watchparty',\n schema: WatchpartyPrefsSchema,\n});\n","/**\n * Compatibility adapter over @wolffm/prefs-client.\n *\n * Existing callers (store.ts, ChatPanel.tsx, entry.tsx, Room.tsx) keep\n * using `loadPreferences()` / `savePref()` / `syncFromServerIfFirstLoad()`.\n * Under the hood we route to two SDK clients:\n * - themePrefs (appId: 'portfolio', scope: 'device') — platform-global\n * - watchpartyPrefs (appId: 'watchparty', scope: 'user') — app-specific\n *\n * Why an adapter instead of rewriting every consumer per the brief: the\n * zustand store reads `loadPreferences()` synchronously at module\n * init (line 155 of store.ts), so flipping to the async `usePrefs()` hook\n * everywhere would mean restructuring store boot. Adapter keeps the API\n * sync and reads the SDK's localStorage cache directly for the\n * first-paint values; SDK-driven server refreshes then call into the\n * store's rehydrateFromPrefs() via subscribers wired up in\n * syncFromServerIfFirstLoad.\n *\n * Bug pattern to avoid (carried from the cross-ecosystem rollout):\n * write-only `void watchpartyPrefs.save(...)` without a usePrefs\n * subscription causes settings to revert on browser close. We satisfy\n * the subscription requirement via the `subscribe(...)` wiring at boot\n * — every change anywhere drives the store back into sync.\n */\n\nimport { debug, warn } from './debug';\nimport { getUserId, getPrefsCacheUserId } from './auth';\nimport { themePrefs, type ThemePrefs } from '@wolffm/themes';\nimport { watchpartyPrefs, type WatchpartyPrefs } from '../prefs/watchpartyPrefs';\nimport { readStored, removeStored, storedKeys, writeStored } from './browserStorage';\n\n// Keep the old type export so callers don't need re-imports.\ninterface UserPreferences extends ThemePrefs, WatchpartyPrefs {}\n\n// Keys routed to the platform-global theme client. Everything else lands\n// on the watchparty client.\nconst THEME_KEYS = new Set<string>(['theme', 'themeMode']);\ntype ThemeKey = keyof ThemePrefs;\n// `sprite` stays in the schema (prefs-api falls back to it for someone who\n// never chose a character at the top level) but watchparty no longer writes\n// it: the character is chosen in the fleet settings popout (lib/avatar.ts).\ntype WatchpartyKey = Exclude<keyof WatchpartyPrefs, 'sprite'>;\ntype PrefKey = ThemeKey | WatchpartyKey;\n\n/** SDK cache key, or null while the SDK's own key for this session is not yet\n * knowable. Mirrors @wolffm/prefs-client's construction\n * (`prefs-cache:<whoami userId>:<appId>`). It used to build the key from the\n * SESSION id, which the SDK never uses for a signed-in account — so the boot\n * read always missed and `writeThrough` wrote rows nothing read. See\n * `getPrefsCacheUserId`. */\nfunction sdkCacheKey(appId: string): string | null {\n const uid = getPrefsCacheUserId();\n return uid ? `prefs-cache:${uid}:${appId}` : null;\n}\n\n/**\n * A real user is coming, but we do not know which SDK cache row is theirs.\n *\n * Everything keyed on identity is untrustworthy in this window — the shared\n * `anon` row and the in-memory mirror can both hold the PREVIOUS user's\n * preferences. With the session→account record (`getPrefsCacheUserId`) this\n * window is normally only a signed-in visitor's FIRST boot in this browser.\n */\nfunction identityPendingUnresolved(): boolean {\n return getPrefsCacheUserId() === null;\n}\n\n/** Sync read of the SDK's localStorage cache for the current user.\n * Returns the merged blob if present; {} otherwise. Used by the zustand\n * store at module-init before the SDK has had a chance to async-init. */\nfunction readSdkCache(appId: string): Record<string, unknown> {\n // NEVER seed a signed-in visitor from the shared `anon` row.\n //\n // `sdkCacheKey` used to map an unresolved identity to `prefs-cache:anon:<app>`,\n // which every user of this browser shares and which keeps whatever the LAST\n // session left in it. At module-init the identity is unresolved (mf-loader\n // calls setAuth after importing this bundle), so a signed-in visitor was\n // seeded with the PREVIOUS user's name and sprite — and `rehydrateFromPrefs` only applies fields that\n // are PRESENT, so a user whose own prefs are empty never cleared them.\n // Reproduced 2026-08-10: UserB signs in with their own key and session and\n // shows UserA's identity indefinitely.\n //\n // Returning {} (no key) means such a visitor starts from defaults and gets\n // their real prefs when the pull lands, a beat later. A genuinely anonymous\n // visitor has no session mirror and still reads the anon row, so pre-auth\n // picks survive. A returning visitor reads their OWN row by account id.\n const key = sdkCacheKey(appId);\n if (!key) return {};\n const raw = readStored(key);\n if (!raw) return {};\n try {\n // The try still earns its place: JSON.parse throws on a corrupt cache\n // entry, which readStored cannot protect against.\n const parsed = JSON.parse(raw) as { blob?: Record<string, unknown> };\n return parsed?.blob ?? {};\n } catch {\n return {};\n }\n}\n\n/**\n * Strip the retired `name` field from every watchparty prefs row this browser\n * holds. Returns how many rows it rewrote.\n *\n * A person's name is their key-registry name (2026-10-08); watchparty's own\n * `name` pref is gone and nothing reads it. hadoku_site sweeps the server rows;\n * these local copies are what that cannot reach — the SDK cache row of every\n * account that ever used this browser, the `anon` row (never synced at all),\n * and a pre-SDK `watchparty_preferences[:uid]` blob, which `loadPreferences`\n * still folds in. Only the one field goes; everything else in each row is left\n * exactly as it was. Idempotent: a row without `name` is not rewritten.\n */\nexport function stripRetiredNameFromCaches(): number {\n let rewritten = 0;\n for (const key of storedKeys()) {\n const sdkRow = key.startsWith('prefs-cache:') && key.endsWith(':watchparty');\n const legacyRow = key === LEGACY_PREFIX || (key.startsWith(`${LEGACY_PREFIX}:`) && !key.endsWith(':_serverSynced_v1'));\n if (!sdkRow && !legacyRow) continue;\n const raw = readStored(key);\n if (!raw) continue;\n let parsed: Record<string, unknown> | null;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown> | null;\n } catch {\n continue; // a corrupt row is its owner's to replace, not ours to guess at\n }\n // An SDK row is `{ blob, userVersion, ... }`; a legacy one is the blob itself.\n const blob = sdkRow ? (parsed?.blob as Record<string, unknown> | undefined) : parsed;\n if (!blob || typeof blob !== 'object' || !('name' in blob)) continue;\n const { name: _retired, ...rest } = blob;\n const next = sdkRow ? { ...parsed, blob: rest } : rest;\n if (writeStored(key, JSON.stringify(next))) rewritten++;\n }\n if (rewritten > 0) debug('preferences', 'Stripped retired name from cached prefs rows', { rewritten });\n return rewritten;\n}\n\n// IN-MEMORY MIRROR of the SDK's currentBlob. Updated by subscribe handlers\n// in syncFromServerIfFirstLoad. The 2026-05-27 cedar-ridge telemetry\n// showed `sdkAppBytesPost:0` IMMEDIATELY AFTER read() resolved with\n// data: the SDK's storage.set wrapper swallows quota / private-mode /\n// blocked-storage errors silently, so the localStorage cache stays\n// empty even though the SDK's in-memory currentBlob is populated. With\n// only-cache reads, every page load lost the data. These vars are the\n// sync-readable backstop: when localStorage write fails, subscribers\n// still capture the blob here, and loadPreferences picks it up. Means\n// even with completely broken localStorage, the store boots with the\n// user's real identity as soon as the first SDK fetch resolves.\nlet latestThemeBlob: ThemePrefs | null = null;\nlet latestAppBlob: WatchpartyPrefs | null = null;\n\n/** Synchronous read for store-init / rehydrate time.\n *\n * Legacy `watchparty_preferences[:userId]` is merged as a fallback ONCE\n * per userId per page session (tracked by `legacyMergedFor` below).\n * Subsequent reads for the same userId return SDK-only — because the\n * legacy blob can hold STALE values for fields the user has since\n * changed via the SDK in this session. Example bug if we kept merging:\n *\n * 1. Two settings change in a row → savePref('volume') +\n * savePref('subtitleStyle').\n * 2. save({volume}) fires its notify before save({subtitleStyle}) starts →\n * my subscribe handler rehydrates while SDK has ONLY {volume}.\n * 3. loadPreferences merges {...legacy{subtitleStyle:'old'}, ...sdk}\n * → returns subtitleStyle from legacy.\n * 4. rehydrateFromPrefs applies the old style — REVERTING the click the\n * user just made.\n *\n * Per-uid flag: module-init runs under userId='public' (pre-setAuth);\n * entry.tsx then calls rehydrateFromPrefs() post-setAuth which resolves\n * the real uid. Each gets its own one-shot legacy merge so the keyed\n * slot's data still flows on first authed read.\n *\n * Why the fallback exists at all: returning users hit this code with\n * EMPTY SDK caches (their data was on the old /api/me/prefs endpoint,\n * not the new hadoku.me/prefs prefs-store). Without it, the store boots\n * with defaults; ensureAutoIdentity in Room.tsx then picks Frieren+sage\n * off the unused-character list before the async migration completes,\n * and connectAndJoin ships the wrong identity (the 2026-05-26 cedar-\n * ridge regression). */\nconst legacyMergedFor = new Set<string>();\nexport function loadPreferences(): UserPreferences {\n // Read order (most → least authoritative for sync reads):\n // 1. SDK localStorage cache — written by SDK's writeCache after every\n // server read. Survives page reloads. Source of truth when working.\n // 2. In-memory subscriber state — backstop when storage.set silently\n // failed (quota/private mode/blocked). SDK still notified us with\n // currentBlob even though cache stayed empty.\n // 3. Legacy `watchparty_preferences[:userId]` — pre-SDK key, merged\n // ONCE per uid per page session. See legacyMergedFor below.\n // A session is coming but has not resolved: serve NOTHING, from any source.\n //\n // Guarding `readSdkCache` alone was not enough — verified against production,\n // the leak survived it. Source 2, the in-memory subscriber mirror, is fed by\n // the SDK's `subscribe`, and the SDK emits its ANON blob before it resolves\n // the user. So blanking the cache just moved the previous user's values one\n // fallback down: `Object.keys(cacheApp).length > 0 ? cacheApp : latestAppBlob`\n // handed back exactly the same data.\n //\n // Both sources are keyed on an identity we do not have yet, so neither can be\n // trusted to belong to THIS user. Defaults for a beat, then the real prefs.\n if (identityPendingUnresolved()) {\n debug('preferences', 'Boot read deferred — session pending, identity unresolved');\n return {};\n }\n\n const cacheTheme = readSdkCache('portfolio');\n const cacheApp = readSdkCache('watchparty');\n const themeBlob = Object.keys(cacheTheme).length > 0\n ? cacheTheme\n : ((latestThemeBlob as Record<string, unknown> | null) ?? {});\n const appBlob = Object.keys(cacheApp).length > 0\n ? cacheApp\n : ((latestAppBlob as Record<string, unknown> | null) ?? {});\n const uid = getUserId() || 'public';\n\n if (legacyMergedFor.has(uid)) {\n debug('preferences', 'Loaded (sync, SDK-only after first read)', {\n uid,\n sdkThemeKeys: Object.keys(themeBlob).length,\n sdkAppKeys: Object.keys(appBlob).length,\n // 'mem' indicates in-memory backstop fired (cache was empty,\n // we used latestBlob instead).\n themeSource: Object.keys(cacheTheme).length > 0 ? 'cache' : 'mem',\n appSource: Object.keys(cacheApp).length > 0 ? 'cache' : 'mem',\n });\n return { ...appBlob, ...themeBlob };\n }\n\n legacyMergedFor.add(uid);\n const legacy = readLegacy() ?? {};\n const merged = { ...legacy, ...appBlob, ...themeBlob } as UserPreferences;\n debug('preferences', 'Loaded (sync, first read — legacy + SDK)', {\n uid,\n sdkThemeKeys: Object.keys(themeBlob).length,\n sdkAppKeys: Object.keys(appBlob).length,\n legacyKeys: Object.keys(legacy).length,\n themeSource: Object.keys(cacheTheme).length > 0 ? 'cache' : 'mem',\n appSource: Object.keys(cacheApp).length > 0 ? 'cache' : 'mem',\n });\n return merged;\n}\n\n/** Save a single preference. Routes to the correct SDK client. Fire-and-\n * forget — the SDK debounces PUTs internally + we don't want callsites\n * to be async. `.catch(log)` per the cross-ecosystem bug pattern.\n *\n * Note: theme writes ALWAYS go to scope:'device' (per platform contract\n * — see hadoku_site themePrefs.ts). Everything else is scope:'user'\n * which is the SDK default. */\n/**\n * Did THIS page load write any preference while genuinely anonymous?\n *\n * Gates `promoteAnonPrefsToUser()` — see the call site in `syncFromServer` for\n * why promoting unconditionally leaks one user's identity to the next.\n */\nlet anonWritesThisLoad = false;\n\n/** True only while no real session identity has resolved yet. */\nfunction isAnonymousNow(): boolean {\n const uid = getUserId();\n return !uid || uid === 'public';\n}\n\nexport function savePref<K extends PrefKey>(key: K, value: UserPreferences[K]): void {\n if (isAnonymousNow()) anonWritesThisLoad = true;\n if (THEME_KEYS.has(key as string)) {\n void themePrefs\n .save({ [key]: value } as Partial<ThemePrefs>, { scope: 'device' })\n .catch(err => warn('preferences', 'themePrefs.save failed', { key, err: (err as Error)?.message }));\n } else {\n void watchpartyPrefs\n .save({ [key]: value } as Partial<WatchpartyPrefs>)\n .catch(err => warn('preferences', 'watchpartyPrefs.save failed', { key, err: (err as Error)?.message }));\n }\n debug('preferences', 'Saved (via SDK)', { key, value });\n}\n\n/** First-load server pull + subscriber wiring.\n *\n * The old implementation pulled from `/api/me/prefs` and gated with a\n * per-user \"_serverSynced_v1\" localStorage flag. The SDK handles the\n * pull itself (server-driven cache refresh on first `read()`); we just\n * need to:\n * 1. Trigger the read for both clients (so the server is consulted).\n * 2. Subscribe to ongoing updates and rehydrate the zustand store on\n * each change — drives cross-tab sync + late-server-resolve.\n * 3. Promote anon prefs to the user slot if applicable (auth landed\n * after the user already saved some anon settings).\n *\n * Returns true if the SDK reads succeeded. Errors are non-fatal; callers\n * should proceed to join regardless. In-flight dedup via the cached\n * promise so entry.tsx + Room.tsx can both call it without racing.\n */\nlet syncInFlight: Promise<boolean> | null = null;\nlet subscribedOnce = false;\nexport function syncFromServerIfFirstLoad(): Promise<boolean> {\n if (syncInFlight) return syncInFlight;\n syncInFlight = (async () => {\n if (typeof window === 'undefined') return false;\n try {\n // Subscribe FIRST so the read()'s initial cache notification +\n // any background refresh both flow into the store. Idempotent —\n // we only attach once per page lifetime.\n if (!subscribedOnce) {\n subscribedOnce = true;\n // Capture the blob into the in-memory mirror first, then trigger\n // a rehydrate. The mirror is loadPreferences's backstop for when\n // localStorage cache writes silently fail (the 2026-05-27 bug\n // where the SDK successfully fetched data but couldn't persist\n // it to localStorage, so every reload re-fetched async + lost\n // the race against ensureAutoIdentity → Frieren).\n //\n // ALSO write through to localStorage ourselves with explicit\n // error logging. If the SDK's storage.set silently failed, this\n // surfaces the cause + lets us see whether it's the SDK or the\n // browser. If our write succeeds, next page load gets a hot\n // cache and the in-memory backstop won't be needed.\n themePrefs.subscribe(blob => {\n latestThemeBlob = blob;\n writeThrough('portfolio', blob);\n rehydrate('theme');\n });\n watchpartyPrefs.subscribe(blob => {\n latestAppBlob = blob;\n writeThrough('watchparty', blob);\n rehydrate('watchparty');\n });\n }\n\n const [themeFromServer, appFromServer] = await Promise.all([\n themePrefs.read(),\n watchpartyPrefs.read(),\n ]);\n\n // CRITICAL: synchronously rehydrate the store BEFORE this promise\n // resolves. The subscribe-driven rehydrate path uses a dynamic\n // `import('./store')` (to break the store↔preferences module\n // cycle), which means notify → subscribe → rehydrate is ASYNC\n // — the import-promise resolves on a later microtask. Room.tsx\n // awaits syncFromServerIfFirstLoad and then reads\n // useAppStore.getState() immediately; without this inline\n // rehydrate, the store hasn't picked up the SDK data yet AT THAT\n // POINT, so ensureAutoIdentity sees empty name and assigns\n // Frieren+sage even though the SDK successfully fetched Hadoku\n // from the server (the 2026-05-26/27 cedar-ridge regression).\n // After this line: the store reflects the SDK's just-fetched\n // values, and Room.tsx's getState() will see them.\n try {\n // Static import would create a cycle (store imports preferences\n // at module top), but at the moment THIS function is invoked the\n // store module IS fully initialized — module-init has long since\n // completed. So we can safely require()-at-call-time without\n // tripping the cycle.\n const { useAppStore } = await import('./store');\n useAppStore.getState().rehydrateFromPrefs();\n } catch (err) {\n warn('preferences', 'inline rehydrate after SDK read failed', { err: (err as Error)?.message });\n }\n\n // Boot diagnostic: log what the SDK actually read from hadoku.me/prefs.\n // Lets us see whether the server has data for this user vs whether\n // the issue is purely client-side. 2026-05-26 added during cedar-ridge\n // regression investigation — pair with the entry.tsx boot beacon.\n //\n // Also re-check localStorage RIGHT NOW: the SDK's refreshFromServer\n // is supposed to writeCache after every fetch. If sdkAppBytes is 0\n // here despite a non-empty appFromServer, then writeCache is\n // silently failing (quota? private mode? some other code wiping?)\n // — that's the entire reason the boot beacon shows empty cache\n // even though the server clearly has data. This second snapshot\n // tells us whether the cache write is the problem.\n const themeKeyPost = sdkCacheKey('portfolio');\n const appKeyPost = sdkCacheKey('watchparty');\n const sdkThemePost = themeKeyPost ? readStored(themeKeyPost) : null;\n const sdkAppPost = appKeyPost ? readStored(appKeyPost) : null;\n // debug, not warn — same rationale as the boot beacon in entry.tsx:\n // closed-investigation instrumentation that fired on every boot.\n debug('preferences', 'sdk.read', {\n themeKeys: Object.keys(themeFromServer ?? {}),\n appKeys: Object.keys(appFromServer ?? {}),\n // Post-fetch cache state: should be non-zero if SDK wrote it.\n sdkThemeBytesPost: sdkThemePost?.length ?? 0,\n sdkAppBytesPost: sdkAppPost?.length ?? 0,\n });\n\n // One-shot migration: users with prefs only in the legacy\n // `watchparty_preferences[:userId]` localStorage key (from the pre-SDK\n // implementation) would otherwise see fresh defaults on the new code,\n // since the SDK fetches from hadoku.me/prefs which has nothing for\n // them yet. If the SDK is empty for this user AND the legacy key has\n // data, split it across the two clients and save. SDK save() does\n // API-Always-Wins reconciliation on 409, so cross-device conflicts\n // (another device already migrated under this user) resolve cleanly.\n await migrateLegacyIfNeeded(themeFromServer, appFromServer);\n\n // Surface pre-auth picks under the newly-known identity — but ONLY if\n // this page load actually made some.\n //\n // `promoteAnonPrefsToUser()` copies the SDK's `anon` row into the current\n // user's row. The anon row is shared by every user of the browser, and it\n // keeps whatever the LAST session left in it, so promoting on every boot\n // hands one user's preferences to the next one who signs in. Reproduced\n // 2026-08-10: UserA signs in and sets an identity; UserB then signs in\n // with their own key and session and sees UserA's name and sprite —\n // persistently, because B's own (empty) server prefs never overwrite it.\n // It stayed hidden because a user with existing server prefs has them\n // pulled over the promoted values a moment later.\n //\n // A genuine pre-auth pick can only exist if we WROTE one while anonymous\n // in this page's lifetime, which `savePref` records. A user who arrived\n // already authenticated has nothing to promote, and the anon row they can\n // see belongs to somebody else.\n if (anonWritesThisLoad) {\n debug('preferences', 'Promoting this load\\'s pre-auth picks to the signed-in user');\n await Promise.all([\n themePrefs.promoteAnonPrefsToUser().catch(() => {}),\n watchpartyPrefs.promoteAnonPrefsToUser().catch(() => {}),\n ]);\n } else {\n debug('preferences', 'Skipping anon promotion — no pre-auth writes this load');\n }\n\n debug('preferences', 'First-load SDK sync complete');\n return true;\n } catch (err) {\n warn('preferences', 'First-load SDK sync failed (non-fatal)', { err: (err as Error)?.message });\n return false;\n }\n })();\n return syncInFlight;\n}\n\n// ── Legacy localStorage migration ─────────────────────────────────────────\n//\n// Pre-SDK builds wrote everything to ONE localStorage key:\n// anon: `watchparty_preferences`\n// authed: `watchparty_preferences:{userId}`\n//\n// On first load with the SDK in place, the migration below splits that\n// blob across the two new SDK clients (themePrefs / watchpartyPrefs) and\n// deletes the legacy key. Only runs when the SDK is empty for the current\n// user — never overwrites real SDK data. Cross-device conflicts (another\n// device already migrated under this user) resolve via the SDK's\n// API-Always-Wins 409 reconciliation in save().\n\nconst LEGACY_PREFIX = 'watchparty_preferences';\n\n// Before anything reads a cached row (LEGACY_PREFIX must be initialised first).\nstripRetiredNameFromCaches();\n\nfunction legacyKey(): string {\n const uid = getUserId();\n return !uid || uid === 'public' ? LEGACY_PREFIX : `${LEGACY_PREFIX}:${uid}`;\n}\n\nfunction readLegacy(): Record<string, unknown> | null {\n const raw = readStored(legacyKey());\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return null;\n return parsed as Record<string, unknown>;\n } catch {\n return null; // corrupt entry — JSON.parse is what throws here\n }\n}\n\nfunction deleteLegacy(): void {\n removeStored(legacyKey());\n // Also wipe the per-user \"_serverSynced_v1\" flag from the old\n // syncFromServerIfFirstLoad implementation — it has no meaning under the SDK\n // and would just be dead storage.\n removeStored(`${legacyKey()}:_serverSynced_v1`);\n}\n\nasync function migrateLegacyIfNeeded(\n themeFromServer: ThemePrefs,\n appFromServer: WatchpartyPrefs,\n): Promise<void> {\n const legacy = readLegacy();\n if (!legacy || Object.keys(legacy).length === 0) return;\n\n // Per-client \"is SDK populated for this user yet?\" — checked separately\n // so a user whose theme is already on the platform-global portfolio row\n // (e.g. set elsewhere in the hadoku ecosystem) still gets their app\n // prefs migrated. Previous all-or-nothing check skipped the entire\n // migration when EITHER client had any field set, which silently\n // stranded watchparty-specific prefs in legacy localStorage forever.\n const sdkHasTheme = Object.keys(themeFromServer ?? {}).length > 0;\n const sdkHasApp = Object.keys(appFromServer ?? {}).length > 0;\n\n // Field-by-field allowlist with type guards. Older clients may have\n // written stray pre-schema fields; they get dropped without tripping\n // Zod parse downstream.\n const themePatch: Partial<ThemePrefs> = {};\n const appPatch: Partial<WatchpartyPrefs> = {};\n for (const [k, v] of Object.entries(legacy)) {\n if (sdkHasTheme) {\n // Theme SDK row is authoritative; skip the theme half entirely.\n } else if (k === 'theme' && typeof v === 'string') {\n themePatch.theme = v;\n } else if (k === 'themeMode' && (v === 'simple' || v === 'advanced')) {\n themePatch.themeMode = v;\n }\n if (sdkHasApp) {\n // App SDK row is authoritative; skip the app half entirely.\n } else if (k === 'chatCollapsed' && typeof v === 'boolean') appPatch.chatCollapsed = v;\n else if (k === 'floatingChatEnabled' && typeof v === 'boolean') appPatch.floatingChatEnabled = v;\n else if (k === 'volume' && typeof v === 'number' && v >= 0 && v <= 1) appPatch.volume = v;\n else if (k === 'muted' && typeof v === 'boolean') appPatch.muted = v;\n else if (k === 'preferredAudioLang' && typeof v === 'string') appPatch.preferredAudioLang = v;\n else if (k === 'subtitlesEnabled' && typeof v === 'boolean') appPatch.subtitlesEnabled = v;\n else if (k === 'subtitleStyle' && typeof v === 'string') appPatch.subtitleStyle = v;\n }\n\n const themeKeys = Object.keys(themePatch);\n const appKeys = Object.keys(appPatch);\n\n if (themeKeys.length === 0 && appKeys.length === 0) {\n // Either both SDK rows already had data (legacy is now stale) OR the\n // legacy blob had no recognizable schema fields. Either way, drop it.\n deleteLegacy();\n return;\n }\n\n debug('preferences', 'Migrating legacy localStorage prefs to SDK', {\n themeKeys,\n appKeys,\n sdkHasTheme,\n sdkHasApp,\n });\n try {\n await Promise.all([\n themeKeys.length > 0 ? themePrefs.save(themePatch, { scope: 'device' }) : Promise.resolve(),\n appKeys.length > 0 ? watchpartyPrefs.save(appPatch) : Promise.resolve(),\n ]);\n deleteLegacy();\n debug('preferences', 'Legacy migration complete');\n } catch (err) {\n warn('preferences', 'Legacy migration save failed — will retry next load', {\n err: (err as Error)?.message,\n });\n // Don't deleteLegacy — leave it for the next first-load to try again.\n }\n}\n\n/** Mirror the SDK's currentBlob into localStorage ourselves. The SDK's\n * built-in storage.set wraps localStorage.setItem in a try/catch that\n * swallows errors silently — so the cache stayed empty even though the\n * SDK had data in memory (the 2026-05-27 sdkAppBytesPost:0 bug).\n *\n * Here we attempt the write + warn on failure with the actual exception.\n * If THIS write succeeds when the SDK's didn't, the SDK's silent-catch\n * is the bug. If THIS write also fails, localStorage is genuinely\n * broken in this browser (quota / private mode / blocked) and the\n * in-memory mirror is the only path forward. Either way the warn\n * text in server.jsonl tells us which.\n */\nlet writeFailureWarned = false;\n// Deliberately NOT lib/browserStorage's writeStored: that returns a boolean and\n// discards the exception, and the whole point of this function is to warn with\n// the actual error so server.jsonl can say WHICH failure happened.\nfunction writeThrough(appId: 'portfolio' | 'watchparty', blob: Record<string, unknown>): void {\n // Not knowable yet → nothing to write through TO. Writing a guessed row is\n // how the old sessionId-keyed shim piled up rows nothing ever read.\n const key = sdkCacheKey(appId);\n if (!key) return;\n try {\n const env = {\n blob,\n userVersion: 0,\n deviceVersion: 0,\n cachedAt: Date.now(),\n };\n localStorage.setItem(key, JSON.stringify(env));\n } catch (err) {\n if (!writeFailureWarned) {\n writeFailureWarned = true;\n warn('preferences', 'writeThrough localStorage failed (in-memory backstop only)', {\n appId,\n err: (err as Error)?.message,\n name: (err as Error)?.name,\n });\n }\n }\n}\n\n/** Lazy import + invoke rehydrateFromPrefs on the zustand store. Imported\n * inside the call to avoid the module-init cycle (store.ts imports from\n * here at top level). */\nfunction rehydrate(reason: string): void {\n void import('./store')\n .then(({ useAppStore }) => {\n try {\n useAppStore.getState().rehydrateFromPrefs();\n } catch (err) {\n warn('preferences', 'rehydrateFromPrefs threw', { reason, err: (err as Error)?.message });\n }\n })\n .catch(err => warn('preferences', 'store import failed', { reason, err: (err as Error)?.message }));\n}\n","/**\n * The chat column's geometry inside `RoomChrome`: collapsed or open, and how\n * wide when open. Pure, so the rules a host's layout depends on are tested\n * without a browser.\n *\n * Saved per viewer under their OWN pref keys (`chromeChatCollapsed`,\n * `chromeChatWidth`), not the app's `chatCollapsed`: a host's table and\n * watchparty's player want the chat differently, and sharing the key would\n * make hiding chat over a card game also hide it beside the next episode.\n */\n\n/** The column's width before the viewer has dragged it: the 20rem it always was. */\nexport const CHAT_WIDTH_DEFAULT_PX = 320;\n/** Narrower than this and the toolbar's buttons and the input stop fitting. */\nexport const CHAT_WIDTH_MIN_PX = 240;\nexport const CHAT_WIDTH_MAX_PX = 640;\n/** However wide the viewer drags, the host keeps at least this much. */\nexport const HOST_MIN_PX = 320;\n/** The collapsed column: just wide enough for the button that reopens it. */\nexport const COLLAPSED_RAIL_PX = 36;\n/** One arrow-key press on the resize handle. */\nexport const KEYBOARD_STEP_PX = 16;\n\n/**\n * A width the column may take. `frameWidth` (the whole chrome's width, when\n * known) caps it so the host always keeps `HOST_MIN_PX`; on a frame too narrow\n * for both, the chat's minimum wins, since a chat narrower than its toolbar is\n * broken while a squeezed host is merely squeezed. A saved value that is not a\n * finite number (a corrupt or foreign pref) is the default, never NaN px.\n */\nexport function clampChatWidth(px: number, frameWidth?: number): number {\n if (!Number.isFinite(px)) return CHAT_WIDTH_DEFAULT_PX;\n let max = CHAT_WIDTH_MAX_PX;\n if (frameWidth !== undefined && Number.isFinite(frameWidth) && frameWidth > 0) {\n max = Math.min(max, frameWidth - HOST_MIN_PX);\n }\n max = Math.max(max, CHAT_WIDTH_MIN_PX);\n return Math.round(Math.min(max, Math.max(CHAT_WIDTH_MIN_PX, px)));\n}\n\n/** The column sits on the RIGHT, so dragging its left edge leftward widens it. */\nexport function widthFromDrag(startWidth: number, startX: number, currentX: number, frameWidth?: number): number {\n return clampChatWidth(startWidth + (startX - currentX), frameWidth);\n}\n\n/** The handle's keyboard contract (a vertical `separator`): Left widens,\n * Right narrows, Home/End jump to the bounds. `null` for any other key, so\n * the caller leaves it alone. */\nexport function widthFromKey(width: number, key: string, frameWidth?: number): number | null {\n switch (key) {\n case 'ArrowLeft': return clampChatWidth(width + KEYBOARD_STEP_PX, frameWidth);\n case 'ArrowRight': return clampChatWidth(width - KEYBOARD_STEP_PX, frameWidth);\n case 'Home': return clampChatWidth(CHAT_WIDTH_MIN_PX, frameWidth);\n case 'End': return clampChatWidth(CHAT_WIDTH_MAX_PX, frameWidth);\n default: return null;\n }\n}\n\nexport interface ChatLayoutState {\n collapsed: boolean;\n /** The column's RENDERED width in CSS px — the rail's while collapsed —\n * i.e. how much of the frame the host does not have. */\n width: number;\n}\n\nexport function chatLayoutState(collapsed: boolean, width: number): ChatLayoutState {\n return { collapsed, width: collapsed ? COLLAPSED_RAIL_PX : width };\n}\n","import { create } from 'zustand';\nimport type { THealthSnapshot, TBufferStatus, TPlaylistConfig, TVoteValue, TPlaylistVoteProgressOut, TPlaylistResultsOut, TTier, TTierlistSnapshotOut } from '@watchparty/shared';\nimport type { TChatImage } from '@watchparty/shared';\nimport { DEFAULT_CHAT_UI_BUFFER } from '@watchparty/shared';\nimport { CHARACTER_ORDER, displayNameFor } from './characters';\nimport { debug, warn } from './debug';\nimport { loadPreferences, savePref } from './preferences';\nimport type { ProbedRoomKeyType } from './leaderAffordance';\nimport { registerDebugGlobal } from './debugGlobals';\nimport { clampChatWidth, CHAT_WIDTH_DEFAULT_PX } from '../roomChrome/chatLayout';\n\n// --- Phase 2 types ---\nexport interface RosterUser {\n clientId: string;\n /** Participant handle (see `PresenceUser.author`); absent from older servers. */\n author?: string;\n name: string;\n sprite: string | null;\n isLeader?: boolean;\n /** `name` is the person's key-registry name — see `PresenceUser.registry_name`. */\n registryName?: boolean;\n /** Their avatar picture (Discord, Steam, uploaded), shown INSTEAD of the\n * character portrait wherever the room shows who they are — never in a\n * game, which keeps the character. Absent = the character is the picture. */\n avatarUrl?: string;\n}\n\nexport interface SnapshotState {\n /** The room's id (not the key this client joined with); null before join. */\n roomId: string | null;\n mediaId: string | null;\n playheadMs: number;\n playing: boolean;\n serverSeq: number; // last authoritative seq applied\n leaderId: string | null;\n}\n\ninterface MeState {\n clientId: string | null;\n nextClientSeq: number; // local incrementing control seq (client scoped)\n}\n\ninterface DriftState {\n rtts: number[]; // last 5 RTT samples (ms)\n offsetMs: number; // estimated serverTime - clientTime\n}\n\nexport interface ChatMessage {\n id: string; // could be server seq or timestamp derived\n clientId: string;\n /** Sender's participant handle — survives their reconnect, unlike clientId. */\n author?: string;\n name: string;\n sprite: string | null;\n text: string;\n ts: number; // epoch ms\n isSystem?: boolean;\n systemType?: string; // 'join' | 'leave' | 'media_change'\n /** CDN image attachments. Content-addressed KEYS, never absolute URLs —\n * see `chatImages.ts` in @watchparty/shared for why that matters. */\n images?: TChatImage[];\n}\n\n// Media preferences state\ninterface MediaPrefsState {\n volume: number;\n muted: boolean;\n preferredAudioLang: string;\n subtitlesEnabled: boolean;\n subtitleStyle: string;\n}\n\n// Buffer state for UI feedback\nexport interface BufferState {\n isBuffering: boolean;\n bufferedEndMs: number;\n}\n\ninterface AppState {\n // existing identity\n ready: boolean;\n name: string;\n sprite: string | null;\n // networking + protocol state\n me: MeState;\n snapshot: SnapshotState;\n roster: Record<string, RosterUser>; // keyed by clientId\n chat: ChatMessage[];\n chatCollapsed: boolean;\n /** RoomChrome's own collapse + width (roomChrome/chatLayout.ts). */\n chromeChatCollapsed: boolean;\n chromeChatWidth: number;\n floatingChatEnabled: boolean;\n drift: DriftState;\n snapshotReceivedAt: number; // client timestamp when playheadMs was last updated from server\n loadGeneration: number; // bumped on every load broadcast to force seek effect re-evaluation\n readiness: { mediaId: string | null; ready: boolean; readyCount: number; total: number };\n bufferState: BufferState;\n toasts: { id: string; kind: 'error' | 'info'; msg: string; ts: number }[];\n // media preferences\n mediaPrefs: MediaPrefsState;\n // admin health monitor\n healthSnapshot: THealthSnapshot | null;\n sidebarTab: 'chat' | 'health' | 'playlist';\n // buffer loading overlay (all clients)\n bufferStatus: TBufferStatus | null;\n // Autoplay muted bridge: true when the browser blocked AUDIBLE autoplay so\n // we started muted; cleared when sound resumes on the first interaction.\n // Drives a \"tap for sound\" hint. Transient — never persisted.\n mutedForAutoplay: boolean;\n // playlist mode (Phase 4)\n playlist: TPlaylistConfig | null;\n activePlaylistIndex: number | null;\n myVotes: Record<string, TVoteValue>; // mediaId -> vote\n voteProgress: TPlaylistVoteProgressOut['progress']; // leader: per-client progress\n playlistResults: TPlaylistResultsOut | null; // set after reveal\n // The GLOBAL tierlist. Not room state and not a playlist: one board the\n // whole site shares, fetched over HTTP and openable from anywhere.\n tierlistOpen: boolean;\n tierlist: TTierlistSnapshotOut | null;\n /** The board being edited right now — starts as the saved one, diverges as\n * you drag, and is what Save sends. Kept apart from `tierlist.myBoard` so\n * an incoming refresh (someone else saved) cannot overwrite your edits. */\n tierlistDraft: Partial<Record<TTier, string[]>>;\n tierlistSaving: boolean;\n // Ready-check (PR-6): leader-triggered \"are you ready?\" prompt. Set of\n // clientIds that have flagged ready. Cleared automatically by the server\n // on the next leader unpause.\n readyCheck: { active: boolean; ready: string[] };\n // What a room key entitles this client to, from the /api/rooms/validate\n // probe, tagged with the key it answers for. Lets the presenter-only toolbar\n // buttons render before the socket join resolves leadership — see\n // lib/leaderAffordance.ts. null = no probe has answered yet (or it failed).\n roomKeyType: ProbedRoomKeyType | null;\n // Waiting-room game: leader-selected room-wide active game. null = no\n // game; non-null = every client's idle screen auto-mounts the iframe.\n activeGameId: string | null;\n // The open game's settings, for the \"App preferences\" section of the\n // settings popout: draws them into an element and returns the cleanup\n // (gameBundleHost's `mountSettings`). null when no open game offers any.\n // Set by the overlay GameBundleSlot only.\n gameSettings: ((el: HTMLElement) => (() => void) | null) | null;\n // actions\n setReady: () => void;\n /** This connection's identity. Never saved: the character is chosen in the\n * fleet settings popout and lives in prefs-api (lib/avatar.ts), the name is\n * the key registry's, and anything else is what the server or an automatic\n * retry handed this connection. */\n setSessionIdentity: (name: string, sprite: string | null) => void;\n ensureAutoIdentity: () => void;\n ensureMe: (clientId: string) => void;\n applySnapshot: (snap: Partial<SnapshotState> & { users?: RosterUser[] }) => void;\n upsertUser: (u: RosterUser) => void;\n removeUser: (clientId: string) => void;\n appendChat: (m: ChatMessage) => void;\n setChat: (messages: ChatMessage[]) => void;\n toggleChatCollapsed: () => void;\n toggleChromeChatCollapsed: () => void;\n setChromeChatWidth: (px: number) => void;\n toggleFloatingChat: () => void;\n allocateClientSeq: () => number;\n // leaderId is `| null` on purpose: null means \"no leader\", a real state the\n // server broadcasts. Typing it `string | undefined` made that unrepresentable\n // (surfaced when the UI was first typechecked, 2026-08-17).\n updateControlState: (delta: { playheadMs?: number; playing?: boolean; serverSeq?: number; leaderId?: string | null }) => void;\n bumpLoadGeneration: () => void;\n addRttSample: (rtt: number, serverTime?: number, clientSendTs?: number) => void;\n pushToast: (kind: 'error' | 'info', msg: string) => void;\n popToast: (id: string) => void;\n setReadiness: (r: { mediaId: string | null; ready: boolean; readyCount: number; total: number }) => void;\n setBufferState: (state: Partial<BufferState>) => void;\n setMutedForAutoplay: (v: boolean) => void;\n // media pref actions\n setVolume: (volume: number) => void;\n setMuted: (muted: boolean) => void;\n setPreferredAudioLang: (lang: string) => void;\n setSubtitlesEnabled: (enabled: boolean) => void;\n setSubtitleStyle: (style: string) => void;\n // admin health monitor actions\n setHealthSnapshot: (snapshot: THealthSnapshot) => void;\n setSidebarTab: (tab: 'chat' | 'health' | 'playlist') => void;\n setBufferStatus: (status: TBufferStatus) => void;\n // playlist actions\n applyPlaylistState: (state: { playlist: TPlaylistConfig | null; activeIndex: number | null; myVotes: Record<string, TVoteValue> }) => void;\n setVoteProgress: (progress: TPlaylistVoteProgressOut['progress']) => void;\n setPlaylistResults: (results: TPlaylistResultsOut | null) => void;\n setTierlistOpen: (open: boolean) => void;\n setTierlistSnapshot: (snap: TTierlistSnapshotOut, adoptDraft: boolean) => void;\n setTierlistSaving: (saving: boolean) => void;\n moveTierlistItem: (itemId: string, tier: TTier | null, index?: number) => void;\n // Ready-check actions\n setReadyCheckState: (state: { active: boolean; ready: string[] }) => void;\n // Waiting-room game action — set on inbound game_active.\n setActiveGameId: (gameId: string | null) => void;\n setGameSettings: (mount: ((el: HTMLElement) => (() => void) | null) | null) => void;\n setRoomKeyType: (probed: ProbedRoomKeyType) => void;\n // Prefs rehydrate — called by entry.tsx after setAuth() resolves the\n // userId. The eager loadPreferences() at module-init below runs with\n // userId='public' (auth hasn't been wired yet), so for authed users it\n // reads the anonymous slot — which is typically empty after the first\n // migration, leaving every reload starting from defaults. rehydrate\n // re-reads from the correct user-keyed slot once auth is known.\n rehydrateFromPrefs: () => void;\n}\n\n// Load saved preferences at startup\nconst savedPrefs = loadPreferences();\n\nexport const useAppStore = create<AppState>((set, get) => ({\n ready: false,\n name: '',\n sprite: null,\n me: { clientId: null, nextClientSeq: 1 },\n snapshot: { roomId: null, mediaId: null, playheadMs: 0, playing: false, serverSeq: 0, leaderId: null },\n roster: {},\n chat: [],\n chatCollapsed: savedPrefs.chatCollapsed ?? false,\n chromeChatCollapsed: savedPrefs.chromeChatCollapsed ?? false,\n chromeChatWidth: clampChatWidth(savedPrefs.chromeChatWidth ?? CHAT_WIDTH_DEFAULT_PX),\n // Hardcoded on for everyone — the per-user toggle was removed from the\n // control bar; FloatingChat + toggleFloatingChat code is kept for future\n // re-enablement but the value is no longer user-controllable.\n floatingChatEnabled: true,\n drift: { rtts: [], offsetMs: 0 },\n snapshotReceivedAt: Date.now(),\n loadGeneration: 0,\n readiness: { mediaId: null, ready: false, readyCount: 0, total: 0 },\n bufferState: { isBuffering: false, bufferedEndMs: 0 },\n toasts: [],\n mediaPrefs: {\n volume: savedPrefs.volume ?? 1,\n muted: savedPrefs.muted ?? false,\n preferredAudioLang: savedPrefs.preferredAudioLang || 'jpn',\n subtitlesEnabled: savedPrefs.subtitlesEnabled ?? true,\n subtitleStyle: (['classic', 'cinema', 'minimal', 'contrast'].includes(savedPrefs.subtitleStyle as string)\n ? savedPrefs.subtitleStyle\n : 'classic') as string,\n },\n healthSnapshot: null,\n sidebarTab: 'chat' as const,\n bufferStatus: null,\n mutedForAutoplay: false,\n playlist: null,\n activePlaylistIndex: null,\n myVotes: {},\n voteProgress: [],\n playlistResults: null,\n tierlistOpen: false,\n tierlist: null,\n tierlistDraft: {},\n tierlistSaving: false,\n readyCheck: { active: false, ready: [] },\n activeGameId: null,\n gameSettings: null,\n roomKeyType: null,\n setReady: () => {\n debug('store', 'App ready');\n set({ ready: true });\n },\n setSessionIdentity: (name, sprite) => {\n debug('store', 'Session identity set (not persisted)', { name, sprite });\n set({ name, sprite });\n },\n ensureAutoIdentity: () => set((s) => {\n if (s.name) return {};\n // A requested character (prefs-api, lib/avatar.ts) names the identity\n // rather than being overwritten by an auto-assignment.\n if (s.sprite) {\n const name = displayNameFor(s.sprite);\n debug('store', 'Auto-identity: deriving name from the requested sprite', { name, sprite: s.sprite });\n return { name };\n }\n // No requested sprite — pick the first available from the current roster.\n const usedSprites = new Set(Object.values(s.roster).map(r => r.sprite).filter(Boolean));\n debug('store', 'ensureAutoIdentity checking', {\n rosterSize: Object.keys(s.roster).length,\n usedSprites: Array.from(usedSprites)\n });\n for (const c of CHARACTER_ORDER) {\n if (!usedSprites.has(c)) {\n const name = displayNameFor(c);\n debug('store', 'Auto-identity assigned', { name, sprite: c });\n return { name, sprite: c };\n }\n }\n // All characters taken — leave identity unset; the server error handler\n // will retry with the next available once we get a sprite_taken response.\n warn('store', 'All characters taken, leaving identity unset');\n return {};\n }),\n ensureMe: (clientId) => {\n debug('store', 'Client ID set', { clientId });\n set((s) => ({ me: { ...s.me, clientId } }));\n },\n applySnapshot: (snap) => set((s) => {\n const rosterUpdates: Record<string, RosterUser> = { ...s.roster };\n if (snap.users) {\n for (const u of snap.users) rosterUpdates[u.clientId] = u;\n }\n // Use !== undefined (not ??) so that explicit null values (e.g. mediaId: null from 'home')\n // are applied correctly instead of falling back to the previous value\n const mediaId = snap.mediaId !== undefined ? snap.mediaId : s.snapshot.mediaId;\n const leaderId = snap.leaderId !== undefined ? snap.leaderId : s.snapshot.leaderId;\n debug('store', 'Snapshot applied', {\n mediaId,\n playing: snap.playing ?? s.snapshot.playing,\n serverSeq: snap.serverSeq ?? s.snapshot.serverSeq,\n userCount: snap.users?.length ?? 0\n });\n const newPlayheadMs = snap.playheadMs ?? s.snapshot.playheadMs;\n return {\n snapshot: {\n roomId: snap.roomId !== undefined ? snap.roomId : s.snapshot.roomId,\n mediaId,\n playheadMs: newPlayheadMs,\n playing: snap.playing ?? s.snapshot.playing,\n serverSeq: snap.serverSeq ?? s.snapshot.serverSeq,\n leaderId\n },\n roster: rosterUpdates,\n // Always update — initial snapshot on join often has playheadMs=0\n // matching the store default, so the old playheadChanged guard left\n // snapshotReceivedAt at page-load time. This inflated viewer correction\n // elapsed by browser launch + buffer gate duration, causing 60-115s drift.\n snapshotReceivedAt: Date.now(),\n };\n }),\n upsertUser: (u) => {\n debug('store', 'User upserted', { clientId: u.clientId, name: u.name, isLeader: u.isLeader });\n set((s) => ({ roster: { ...s.roster, [u.clientId]: u } }));\n },\n removeUser: (clientId) => {\n debug('store', 'User removed', { clientId });\n set((s) => {\n const copy = { ...s.roster }; delete copy[clientId]; return { roster: copy };\n });\n },\n appendChat: (m) => {\n debug('chat', 'Message appended', { id: m.id, from: m.name, isSystem: m.isSystem });\n set((s) => ({ chat: [...s.chat, m].slice(-DEFAULT_CHAT_UI_BUFFER) }));\n },\n setChat: (messages) => set({ chat: messages.slice(-DEFAULT_CHAT_UI_BUFFER) }),\n toggleChatCollapsed: () => set((s) => {\n const newVal = !s.chatCollapsed;\n savePref('chatCollapsed', newVal);\n return { chatCollapsed: newVal };\n }),\n toggleChromeChatCollapsed: () => set((s) => {\n const newVal = !s.chromeChatCollapsed;\n savePref('chromeChatCollapsed', newVal);\n return { chromeChatCollapsed: newVal };\n }),\n setChromeChatWidth: (px) => set(() => {\n const width = clampChatWidth(px);\n savePref('chromeChatWidth', width);\n return { chromeChatWidth: width };\n }),\n toggleFloatingChat: () => set((s) => {\n const newVal = !s.floatingChatEnabled;\n savePref('floatingChatEnabled', newVal);\n return { floatingChatEnabled: newVal };\n }),\n allocateClientSeq: () => {\n const n = get().me.nextClientSeq;\n set((s) => ({ me: { ...s.me, nextClientSeq: n + 1 } }));\n return n;\n },\n bumpLoadGeneration: () => set((s) => ({ loadGeneration: s.loadGeneration + 1 })),\n updateControlState: (delta) => {\n debug('store', 'updateControlState called', delta);\n set((s) => ({\n snapshot: { ...s.snapshot, ...delta },\n // Always update snapshotReceivedAt — any control_broadcast from the\n // server resets the elapsed-time calculation. The old condition\n // (playheadMs !== s.snapshot.playheadMs) missed media reloads that\n // set playheadMs=0 when it was already 0, causing prefetch to use\n // wall-clock-since-page-load as the expected position.\n snapshotReceivedAt: Date.now(),\n }));\n },\n addRttSample: (rtt, serverTime, clientSendTs) => set((s) => {\n const rtts = [...s.drift.rtts, rtt].slice(-5);\n let offsetMs = s.drift.offsetMs;\n if (serverTime && clientSendTs) {\n const clientMid = clientSendTs + rtt / 2;\n offsetMs = serverTime - clientMid;\n }\n return { drift: { rtts, offsetMs } };\n })\n ,\n pushToast: (kind, msg) => {\n debug('store', 'Toast pushed', { kind, msg });\n set((s) => ({ toasts: [...s.toasts, { id: Math.random().toString(36).slice(2), kind, msg, ts: Date.now() }].slice(-5) }));\n },\n popToast: (id) => set((s) => ({ toasts: s.toasts.filter(t => t.id !== id) })),\n setReadiness: (r) => set({ readiness: { mediaId: r.mediaId, ready: r.ready, readyCount: r.readyCount, total: r.total } }),\n setBufferState: (state) => set((s) => ({ bufferState: { ...s.bufferState, ...state } })),\n setMutedForAutoplay: (v) => set({ mutedForAutoplay: v }),\n // Media preference actions\n setVolume: (volume) => set((s) => {\n savePref('volume', volume);\n return { mediaPrefs: { ...s.mediaPrefs, volume } };\n }),\n setMuted: (muted) => set((s) => {\n savePref('muted', muted);\n return { mediaPrefs: { ...s.mediaPrefs, muted } };\n }),\n setPreferredAudioLang: (lang) => set((s) => {\n savePref('preferredAudioLang', lang);\n return { mediaPrefs: { ...s.mediaPrefs, preferredAudioLang: lang } };\n }),\n setSubtitlesEnabled: (enabled) => set((s) => {\n savePref('subtitlesEnabled', enabled);\n return { mediaPrefs: { ...s.mediaPrefs, subtitlesEnabled: enabled } };\n }),\n setSubtitleStyle: (style) => set((s) => {\n savePref('subtitleStyle', style);\n return { mediaPrefs: { ...s.mediaPrefs, subtitleStyle: style } };\n }),\n setHealthSnapshot: (snapshot) => set({ healthSnapshot: snapshot }),\n setBufferStatus: (status) => set({ bufferStatus: status }),\n applyPlaylistState: (state) => set({\n playlist: state.playlist,\n activePlaylistIndex: state.activeIndex,\n myVotes: state.myVotes,\n // Clear stale results when a new playlist state arrives\n playlistResults: null,\n }),\n setVoteProgress: (progress) => set({ voteProgress: progress }),\n setPlaylistResults: (results) => set({ playlistResults: results }),\n\n setTierlistOpen: (open) => set({ tierlistOpen: open }),\n setTierlistSaving: (saving) => set({ tierlistSaving: saving }),\n /**\n * Apply a server snapshot.\n *\n * `adoptDraft` is false for a refresh triggered by SOMEONE ELSE saving: the\n * shared result must update live, but replacing the draft would yank cards\n * out from under someone mid-drag. It is true only when this client opens the\n * board or saves its own, which are the two moments its draft is not ahead of\n * the server.\n */\n setTierlistSnapshot: (snap, adoptDraft) => set(prev => ({\n tierlist: snap,\n tierlistDraft: adoptDraft ? { ...snap.myBoard } : prev.tierlistDraft,\n })),\n /**\n * Move one item on the draft board. Local only — nothing reaches the server\n * until Save, which is the whole point of the Save button.\n *\n * Remove from every row FIRST, so a move within a row reorders rather than\n * duplicating, then insert at `index`. Absent from every row — not\n * present-with-a-low-value — is what keeps \"not rated\" distinguishable from\n * \"rated F\" in placeTierlist.\n */\n moveTierlistItem: (itemId, tier, index) => set(state => {\n const next: Partial<Record<TTier, string[]>> = {};\n for (const [t, row] of Object.entries(state.tierlistDraft)) {\n const without = (row ?? []).filter(id => id !== itemId);\n if (without.length > 0) next[t as TTier] = without;\n }\n if (tier !== null) {\n const row = next[tier] ?? [];\n const at = Math.max(0, Math.min(index ?? row.length, row.length));\n row.splice(at, 0, itemId);\n next[tier] = row;\n }\n return { tierlistDraft: next };\n }),\n setReadyCheckState: (state) => set({ readyCheck: state }),\n setActiveGameId: (gameId) => set({ activeGameId: gameId }),\n setGameSettings: (mount) => set({ gameSettings: mount }),\n setRoomKeyType: (probed) => set({ roomKeyType: probed }),\n rehydrateFromPrefs: () => set((s) => {\n // Re-read from localStorage. Triggered both from entry.tsx after\n // setAuth (boot path) AND from the SDK subscribe callback in\n // preferences.ts (when SDK cache changes — saves, cross-tab events,\n // background server refresh).\n //\n // ONLY write fields that are PRESENT in prefs. Older logic always\n // wrote all fields and used `|| default` for absent ones — that\n // reverted in-flight user actions any time the SDK had partial data.\n // With the present-only check, fields absent from prefs simply leave the\n // store value alone.\n //\n // The prefs row's `sprite` is NOT read: the character comes from\n // prefs-api's avatar settings (lib/avatar.ts), which already fall back to\n // that field for someone who never chose at the top level.\n const prefs = loadPreferences();\n const next: Partial<AppState> = {};\n if (prefs.chatCollapsed !== undefined) next.chatCollapsed = prefs.chatCollapsed;\n if (prefs.chromeChatCollapsed !== undefined) next.chromeChatCollapsed = prefs.chromeChatCollapsed;\n if (prefs.chromeChatWidth !== undefined) next.chromeChatWidth = clampChatWidth(prefs.chromeChatWidth);\n // floatingChatEnabled is hardcoded on (toggle removed from UI); never rehydrate.\n\n // Media prefs: only build the nested object if AT LEAST ONE media key\n // is present in prefs — otherwise we'd write a whole mediaPrefs object\n // with defaults, undoing in-memory tweaks the user made without saving.\n const mediaKeys = ['volume', 'muted', 'preferredAudioLang', 'subtitlesEnabled', 'subtitleStyle'] as const;\n const hasMedia = mediaKeys.some(k => prefs[k] !== undefined);\n if (hasMedia) {\n const m = { ...s.mediaPrefs };\n if (prefs.volume !== undefined) m.volume = prefs.volume;\n if (prefs.muted !== undefined) m.muted = prefs.muted;\n if (prefs.preferredAudioLang !== undefined) m.preferredAudioLang = prefs.preferredAudioLang;\n if (prefs.subtitlesEnabled !== undefined) m.subtitlesEnabled = prefs.subtitlesEnabled;\n if (prefs.subtitleStyle !== undefined && ['classic', 'cinema', 'minimal', 'contrast'].includes(prefs.subtitleStyle)) {\n m.subtitleStyle = prefs.subtitleStyle;\n }\n next.mediaPrefs = m;\n }\n return next;\n }),\n setSidebarTab: (tab) => set((s) => {\n // If switching to the same tab, toggle back to chat\n // Also uncollapse the sidebar if it's collapsed\n if (s.sidebarTab === tab && tab !== 'chat') {\n return { sidebarTab: 'chat' };\n }\n return { sidebarTab: tab, chatCollapsed: false };\n }),\n}));\n\n// E2E handle — published only when the host opts in (lib/debugGlobals.ts).\nregisterDebugGlobal('__ZUSTAND_STORE__', useAppStore);\n","import { useEffect } from 'react';\nimport { useAppStore } from '../lib/store';\n\n/** `className` positions the stack. The app pins it to the viewport; the\n * embeddable room chrome keeps it inside its own column rather than over the\n * host's page. */\nexport default function Toasts({ className = 'fixed bottom-4 left-1/2 -translate-x-1/2' }: { className?: string }) {\n const toasts = useAppStore(s => s.toasts);\n const pop = useAppStore(s => s.popToast);\n useEffect(() => {\n const timers = toasts.map(t => setTimeout(() => pop(t.id), 4000));\n return () => { timers.forEach(clearTimeout); };\n }, [toasts, pop]);\n return (\n <div className={`${className} flex flex-col gap-2 z-50`}>\n {toasts.map(t => (\n <div key={t.id} className={`px-3 py-2 rounded text-sm shadow font-medium border ${t.kind==='error' ? 'bg-danger-bg text-on-danger-bg border-danger' : 'bg-bg-card border-border-light text-text'}`}>{t.msg}</div>\n ))}\n </div>\n );\n}\n","import { useEffect, useRef } from 'react';\n\ninterface Star {\n x: number; y: number; z: number; speed: number; size: number; alpha: number;\n // Color twinkle / rare hue cycling\n colorRare: boolean; colorPhase: number; colorSpeed: number; colorMode: number;\n // Brightness twinkle (new model)\n twinkleAmount: number; // amplitude factor (0..~0.5 used to derive dim floor)\n twinkleEnabled: boolean; // whether this star participates in brightness interpolation\n dimFloor: number; // fraction of alpha at darkest (0..1)\n twinkleStart: number; // starting alpha value for current segment\n twinkleTarget: number; // target alpha value for current segment\n twinkleT: number; // progress time (frame units) in current segment\n twinkleDuration: number; // total duration (frame units) of current segment\n microPhase: number; // small fast phase for subtle sparkle (ultra mostly)\n microSpeed: number;\n ultraRare: boolean; trail?: { x: number; y: number }[]; maxTrail?: number; currentAlpha?: number;\n lifeMsRemaining: number; // remaining life in milliseconds\n lifeMsTotal: number; // total assigned life\n}\n\nconst STAR_COUNT = 400; \n\nexport default function StarfieldCanvas() {\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\n const starsRef = useRef<Star[]>([]);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n // Resize canvas to match its parent container (not window)\n const resize = () => {\n const parent = canvas.parentElement;\n if (parent) {\n const rect = parent.getBoundingClientRect();\n canvas.width = rect.width;\n canvas.height = rect.height;\n } else {\n // Fallback to window dimensions\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n }\n };\n resize();\n\n // Use ResizeObserver for responsive parent sizing\n const resizeObserver = new ResizeObserver(resize);\n if (canvas.parentElement) {\n resizeObserver.observe(canvas.parentElement);\n }\n window.addEventListener('resize', resize);\n\n let creationCounter = 0; // tracks total stars ever created (including replacements) if we decide to extend taper later\n\n function biasForIndex(i: number) {\n if (i < 300) return { scale: 0.5, demote: 0.5 }; // first 300 -> 50%\n if (i < 400) return { scale: 0.6, demote: 0.4 }; // next 100 -> 40%\n if (i < 500) return { scale: 0.7, demote: 0.3 }; // next 100 -> 30%\n if (i < 600) return { scale: 0.8, demote: 0.2 }; // next 100 -> 20%\n if (i < 700) return { scale: 0.9, demote: 0.1 }; // next 100 -> 10%\n return { scale: 1.0, demote: 0 }; // afterward -> no reduction\n }\n\n function makeStar(x?: number, y?: number, initial=false, index?: number): Star {\n // Bias toward smaller z (slower/smaller) making large/bright rare\n let r = Math.random();\n // Determine bias bucket\n const creationIndex = index ?? creationCounter;\n if (index === undefined) creationCounter++;\n const bias = initial ? biasForIndex(creationIndex) : { scale: 1.0, demote: 0 };\n let ultraRare = r > 0.998; // base ultra threshold (~0.2%)\n let rare = !ultraRare && r > 0.98; // base rare threshold (~2%)\n if (bias.demote > 0) {\n if (ultraRare && Math.random() < bias.demote) ultraRare = false;\n if (rare && Math.random() < bias.demote) rare = false;\n }\n // If this is part of the initial population, suppress rare / ultra entirely per request\n if (initial) {\n ultraRare = false;\n rare = false;\n }\n // Color-twinkle rare: pick from remaining base population (~1% of non-rare/non-ultra)\n const colorRare = rare; // only rare stars twinkle (white↔blue or white↔red)\n let z: number;\n if (ultraRare) {\n // Force ultra-rare into highest depth band so they are always fast/bright\n z = 0.92 + Math.random() * 0.08; // 0.92 - 1.0\n } else if (rare) {\n z = 0.85 + Math.random() * 0.15;\n } else {\n z = 0.05 + (Math.random() ** 2.2) * 0.75; // mostly 0.05-0.6 range\n }\n // Utility triangular distribution (center bias => extremes rarer)\n const tri = (min: number, max: number) => {\n const u1 = Math.random();\n const u2 = Math.random();\n return min + ((u1 + u2) / 2) * (max - min);\n };\n // Broaden size range with center bias; ultra can get larger; allow smaller floor\n let sizeBase = tri(0.9, 1.4) + (z ** 1.2) * (ultraRare ? 5.5 : rare ? 4.0 : 3.2);\n const sizeVariance = tri(0.85, 1.25); // multiplicative tweak (extremes rarer)\n let size = sizeBase * sizeVariance;\n if (initial && bias.scale < 1) size *= bias.scale; // tapered size reduction\n // Broaden alpha range; allow overbright (>1) which will be rendered with an additive pass\n let alpha: number;\n if (ultraRare) {\n // Ultra: high baseline with large possible overbright tail (1.05 - 1.55)\n alpha = 1.05 + Math.random() * 0.50; \n } else if (rare) {\n // Rare: mid-high brightness (approx 0.65 - 1.25)\n alpha = 0.55 + (z ** 1.05) * 0.70 + Math.random() * 0.25; // typical ~0.8-1.1\n if (alpha > 1.25) alpha = 1.25;\n } else {\n // Common: ~0.15 - 1.05 (most <0.9)\n alpha = 0.15 + (z ** 1.05) * 0.60 + Math.random() * 0.15;\n if (alpha > 1.05) alpha = 1.05;\n }\n if (!ultraRare && alpha < 0.15) alpha = 0.15; // raise minimal base brightness to 15%\n // Speed now broader with variance factor; maintain z influence\n const speedBase = 0.035 + tri(0, 0.08); // lower floor & occasional higher base\n const speedScale = (z ** 1.45) * (ultraRare ? 4.9 : rare ? 1.55 : 1.25);\n let speed = speedBase + speedScale * tri(0.85, 1.3);\n if (initial && bias.scale < 1) speed *= bias.scale; // tapered speed reduction\n // Additional minor coupling to size/alpha (extremes give mild boost)\n const normAlpha = Math.min(1, alpha);\n const normSize = Math.min(1, (size - 1) / 4.5);\n speed *= 1 + 0.18 * Math.max(normAlpha, normSize);\n if (ultraRare && speed < 1.25) speed = 1.25 + Math.random() * 0.4;\n const cw = canvas!.width;\n const ch = canvas!.height;\n const twinkleAmount = 0.18 + Math.random() * 0.28; // base amplitude for brightness variance\n // Enable twinkle for ~18% of non-ultra stars; ultra always twinkle for distinctiveness\n const twinkleEnabled = ultraRare || Math.random() < 0.18;\n // Deeper dim for common stars, shallower for rare/ultra\n const dimFloor = ultraRare ? 0.55 : (colorRare ? 0.38 : Math.max(0.10, 0.28 - twinkleAmount * 0.25));\n // Immediate visibility: choose a starting brightness within allowed range\n const startVal = alpha * (dimFloor + Math.random() * (1 - dimFloor));\n const targetVal = alpha * (dimFloor + Math.random() * (1 - dimFloor));\n const duration = (ultraRare ? 130 : colorRare ? 160 : 120) + Math.random() * (ultraRare ? 140 : 150); // frame units (~2-5s)\n // Lifetime 10s..120s weighted by speed.\n // All stars can occupy full range; slow stars biased longer (typically >=40s) but still small chance below 40.\n // Fast stars biased shorter. Achieved via exponent shaping + floor lift proportional to (1 - speedNorm).\n const EXPECTED_MAX_SPEED = 2.5; // heuristic ceiling for normalization\n const speedNorm = Math.min(1, speed / EXPECTED_MAX_SPEED);\n const MIN_SEC = 10;\n const MAX_SEC = 120;\n const spanSec = MAX_SEC - MIN_SEC; // 110\n let u = Math.random();\n const exp = 0.8 + speedNorm * 1.4; // slow ~0.8 (bias high), fast ~2.2 (bias low)\n u = Math.pow(u, exp);\n const floorLift = (1 - speedNorm) * ((40 - MIN_SEC) / spanSec); // up to ~0.2727 for slowest so min ~40s typical\n u = u * (1 - floorLift) + floorLift; // raise lower bound proportionally for slow stars\n const lifeMsTotal = (MIN_SEC + u * spanSec) * 1000; // final ms\n return {\n x: x == null ? Math.random() * cw : x,\n y: y != null ? y : (initial ? Math.random() * ch : -Math.random() * ch),\n z,\n speed,\n size,\n alpha,\n colorRare,\n colorPhase: Math.random() * Math.PI * 2,\n colorSpeed: 0.01 + Math.random() * 0.02,\n colorMode: Math.random() < 0.5 ? 0 : 1,\n twinkleAmount,\n twinkleEnabled,\n dimFloor,\n twinkleStart: startVal,\n twinkleTarget: targetVal,\n twinkleT: 0,\n twinkleDuration: duration,\n microPhase: Math.random() * Math.PI * 2,\n microSpeed: (ultraRare ? 0.18 : 0.10) + Math.random() * 0.05,\n ultraRare,\n trail: ultraRare ? [] : undefined,\n currentAlpha: startVal,\n lifeMsRemaining: lifeMsTotal,\n lifeMsTotal\n };\n }\n\n if (!starsRef.current.length) {\n for (let i = 0; i < STAR_COUNT; i++) starsRef.current.push(makeStar(undefined, undefined, true, i));\n }\n\n let frameId: number;\n let lastTime = performance.now();\n\n // Cap delta to prevent burst behavior when tab regains focus after being hidden.\n // RAF pauses while tab is hidden but performance.now() keeps running, so without\n // this cap we'd get a huge deltaMs that kills/respawns many stars at once.\n const MAX_DELTA_MS = 50; // ~3 frames at 60fps\n\n function drawCurvedBottomRect(x: number, y: number, size: number, speed: number) {\n const maxExpectedSpeed = 2.0;\n const n = Math.min(1, speed / maxExpectedSpeed);\n const bottomR = (0.15 + 0.75 * n) * size; // more curvature with speed\n const w = size;\n const h = size;\n const r = Math.min(bottomR, h * 0.95, w * 0.48);\n const x0 = x;\n const y0 = y;\n const x1 = x + w;\n const y1 = y + h;\n const c = ctx!;\n c.beginPath();\n c.moveTo(x0, y0);\n c.lineTo(x1, y0); // top edge\n c.lineTo(x1, y1 - r);\n c.quadraticCurveTo(x1, y1, x1 - r, y1);\n c.lineTo(x0 + r, y1);\n c.quadraticCurveTo(x0, y1, x0, y1 - r);\n c.lineTo(x0, y0);\n c.closePath();\n c.fill();\n }\n\n // New brightness model: interpolate between random targets (value noise) to avoid flicker at troughs\n function updateAlpha(s: Star, dt: number) {\n if (dt > 3) dt = 3; // cap runaway dt\n if (!s.twinkleEnabled) { // no brightness interpolation; maintain stable alpha\n s.currentAlpha = s.alpha;\n return;\n }\n s.twinkleT += dt;\n if (s.twinkleT >= s.twinkleDuration) {\n // Start a new segment\n s.twinkleStart = s.twinkleTarget;\n // Pick a new target in [dimFloor*alpha, alpha]\n s.twinkleTarget = s.alpha * (s.dimFloor + Math.random() * (1 - s.dimFloor));\n // Duration with some variability; ultra get longer smoother drifts\n const baseDur = s.ultraRare ? 150 : (s.colorRare ? 140 : 110);\n const jitter = s.ultraRare ? 170 : 140;\n s.twinkleDuration = baseDur + Math.random() * jitter;\n s.twinkleT = 0;\n }\n const p = Math.min(1, s.twinkleT / s.twinkleDuration);\n // Smoothstep easing\n const eased = p * p * (3 - 2 * p);\n let val = s.twinkleStart + (s.twinkleTarget - s.twinkleStart) * eased;\n // Ultra rare micro sparkle (very subtle, high frequency, low amplitude)\n s.microPhase += s.microSpeed * dt;\n if (s.ultraRare) {\n const micro = Math.sin(s.microPhase) * 0.04; // ±0.04\n val = Math.min(1, Math.max(s.alpha * s.dimFloor, val * (1 + micro)));\n }\n s.currentAlpha = val;\n }\n\n // Update only color related state & return fillStyle\n function updateColor(s: Star, dt: number): string {\n if (s.ultraRare) {\n s.colorPhase += (s.colorSpeed * 2.2) * dt; // faster cycle for ultra rare\n const colors = [\n [255, 120, 220], // pink\n [120, 255, 170], // green\n [255, 255, 255] // white\n ];\n const cycle = s.colorPhase % colors.length;\n const idx = Math.floor(cycle);\n const next = (idx + 1) % colors.length;\n const t = cycle - idx;\n const c0 = colors[idx];\n const c1 = colors[next];\n const rCol = Math.round(c0[0] + (c1[0] - c0[0]) * t);\n const gCol = Math.round(c0[1] + (c1[1] - c0[1]) * t);\n const bCol = Math.round(c0[2] + (c1[2] - c0[2]) * t);\n return `rgb(${rCol},${gCol},${bCol})`;\n }\n if (s.colorRare) {\n s.colorPhase += s.colorSpeed * dt;\n const t = (Math.sin(s.colorPhase) + 1) / 2; // 0..1\n if (s.colorMode === 0) {\n const rCol = Math.round(255 - (255 - 90) * t);\n const gCol = Math.round(255 - (255 - 150) * t);\n const bCol = 255;\n return `rgb(${rCol},${gCol},${bCol})`;\n } else {\n const rCol = 255;\n const gCol = Math.round(255 - (255 - 80) * t);\n const bCol = Math.round(255 - (255 - 80) * t);\n return `rgb(${rCol},${gCol},${bCol})`;\n }\n }\n return '#ffffff';\n }\n const render = () => {\n const now = performance.now();\n const deltaMs = Math.min(now - lastTime, MAX_DELTA_MS);\n const dt = deltaMs / 16.666; // frame units (~60fps)\n lastTime = now;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n const OFFSCREEN_BUFFER = 220; // allow trails to finish below view\n for (let i = 0; i < starsRef.current.length; i++) {\n const s = starsRef.current[i];\n // Maintain/update trail data before drawing\n if (s.ultraRare) {\n if (!s.trail) s.trail = [];\n if (!s.maxTrail) {\n const maxExpectedSpeed = 1.9;\n const base = s.speed * 14;\n const norm = Math.min(1, s.speed / maxExpectedSpeed);\n const scaled = base * (1 + 8 * norm);\n s.maxTrail = Math.min(300, Math.floor(scaled));\n }\n s.trail.push({ x: s.x + s.size / 2, y: s.y + s.size / 2 });\n if (s.trail.length > s.maxTrail) s.trail.splice(0, s.trail.length - s.maxTrail);\n }\n // Lifetime handling\n s.lifeMsRemaining -= deltaMs;\n if (s.lifeMsRemaining <= 0) {\n // Respawn new star from top (non-initial)\n const newStar = makeStar(Math.random() * canvas.width, undefined, false);\n // Position just above view\n newStar.y = -newStar.size - 1;\n starsRef.current[i] = newStar;\n continue;\n }\n s.y += s.speed * dt;\n if (s.y - s.size > canvas.height + OFFSCREEN_BUFFER) {\n starsRef.current[i] = makeStar(Math.random() * canvas.width, -s.size - 1);\n continue;\n }\n updateAlpha(s, dt);\n const baseAlphaRaw = s.currentAlpha ?? s.alpha; // previous baseAlpha replaced by fade logic\n const FADE_MS = 1500; // fade duration window\n const lifeFade = s.lifeMsRemaining < FADE_MS ? Math.max(0, s.lifeMsRemaining / FADE_MS) : 1;\n const baseAlpha = baseAlphaRaw * lifeFade;\n let starFillStyle = updateColor(s, dt);\n if (s.ultraRare) {\n const enhanced = baseAlpha;\n if (s.trail && s.trail.length) {\n const len = s.trail.length;\n for (let ti = 0; ti < len; ti++) {\n const tp = s.trail[len - 1 - ti];\n const linear = (1 - ti / len);\n const fade = Math.pow(linear, 3);\n ctx.globalAlpha = Math.min(1, enhanced) * fade * 0.6;\n const scale = 0.35 + 0.65 * fade;\n ctx.fillStyle = starFillStyle;\n const drawSize = s.size * scale;\n ctx.fillRect(tp.x - drawSize / 2, tp.y - drawSize / 2, drawSize, drawSize);\n }\n }\n ctx.globalAlpha = Math.min(1, enhanced * 1.02);\n ctx.fillStyle = starFillStyle;\n const headLeft = s.x - s.size * 0.1;\n const headTop = s.y - s.size * 0.1;\n drawCurvedBottomRect(headLeft, headTop, s.size * 1.2, s.speed);\n // Overbright additive pass for alpha >1\n if (enhanced > 1.02) {\n const over = Math.min(1, (enhanced - 1) * 0.85); // compress tail\n ctx.save();\n ctx.globalCompositeOperation = 'lighter';\n ctx.globalAlpha = over;\n ctx.fillStyle = starFillStyle;\n const glowSize = s.size * 0.75;\n drawCurvedBottomRect(headLeft + s.size * 0.225, headTop + s.size * 0.225, glowSize, s.speed);\n ctx.restore();\n }\n } else {\n ctx.globalAlpha = Math.min(1, baseAlpha);\n ctx.fillStyle = starFillStyle;\n drawCurvedBottomRect(s.x, s.y, s.size, s.speed);\n if (baseAlpha > 1.01) {\n const over = Math.min(0.9, (baseAlpha - 1) * 0.8);\n ctx.save();\n ctx.globalCompositeOperation = 'lighter';\n ctx.globalAlpha = over;\n ctx.fillStyle = starFillStyle;\n const glowSize = s.size * 0.55;\n drawCurvedBottomRect(s.x + s.size * 0.225, s.y + s.size * 0.225, glowSize, s.speed);\n ctx.restore();\n }\n }\n }\n ctx.globalAlpha = 1;\n frameId = requestAnimationFrame(render);\n };\n frameId = requestAnimationFrame(render);\n return () => {\n cancelAnimationFrame(frameId);\n window.removeEventListener('resize', resize);\n resizeObserver.disconnect();\n };\n }, []);\n\n return (\n <canvas\n ref={canvasRef}\n data-darkreader-ignore\n className=\"absolute inset-0 z-0 bg-black pointer-events-none\"\n />\n );\n}\n","import { useEffect, useSyncExternalStore } from 'react';\nimport { colorForSprite } from './characters';\nimport { debug } from './debug';\n\n/**\n * A person's colour — their chat name, their ring in the roster, the ready\n * check and the buffer rings. With an avatar picture it is the picture's\n * average colour; otherwise it is their character's colour, which was itself\n * picked off the portrait the same way.\n *\n * The picture is read through a canvas, so it is loaded once more with\n * `crossOrigin=\"anonymous\"`. Discord and Steam both answer\n * `Access-Control-Allow-Origin: *`; a host that does not taints the canvas,\n * and that person keeps their character's colour. One read per URL per page,\n * cached, failures included.\n */\n\n/** Lightness bounds: a black or white picture must still read as a name on a card. */\nconst MIN_LIGHTNESS = 0.3;\nconst MAX_LIGHTNESS = 0.82;\n/** The canvas the picture is averaged on. Small on purpose: an average needs no detail. */\nconst SAMPLE_SIZE = 24;\n/** Below this alpha a pixel is background, not picture. */\nconst MIN_ALPHA = 32;\n\n/**\n * The alpha-weighted mean of RGBA pixels as `#rrggbb`, lightness clamped to\n * the readable band. Null when no pixel is opaque enough to count.\n */\nexport function averageColor(pixels: ArrayLike<number>): string | null {\n let r = 0, g = 0, b = 0, weight = 0;\n for (let i = 0; i + 3 < pixels.length; i += 4) {\n const a = pixels[i + 3];\n if (a < MIN_ALPHA) continue;\n r += pixels[i] * a;\n g += pixels[i + 1] * a;\n b += pixels[i + 2] * a;\n weight += a;\n }\n if (weight === 0) return null;\n return clampLightness(r / weight, g / weight, b / weight);\n}\n\nfunction clampLightness(r: number, g: number, b: number): string {\n const [h, s, l] = rgbToHsl(r / 255, g / 255, b / 255);\n const clamped = Math.min(MAX_LIGHTNESS, Math.max(MIN_LIGHTNESS, l));\n const [r2, g2, b2] = hslToRgb(h, s, clamped);\n const hex = (v: number) => Math.round(v * 255).toString(16).padStart(2, '0');\n return `#${hex(r2)}${hex(g2)}${hex(b2)}`;\n}\n\nfunction rgbToHsl(r: number, g: number, b: number): [number, number, number] {\n const max = Math.max(r, g, b), min = Math.min(r, g, b);\n const l = (max + min) / 2;\n if (max === min) return [0, 0, l];\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n let h: number;\n if (max === r) h = (g - b) / d + (g < b ? 6 : 0);\n else if (max === g) h = (b - r) / d + 2;\n else h = (r - g) / d + 4;\n return [h / 6, s, l];\n}\n\nfunction hslToRgb(h: number, s: number, l: number): [number, number, number] {\n if (s === 0) return [l, l, l];\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n const channel = (t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n return [channel(h + 1 / 3), channel(h), channel(h - 1 / 3)];\n}\n\n/** url → colour once read; null when it could not be (no CORS, failed load). */\nconst colors = new Map<string, string | null>();\nconst pending = new Set<string>();\nconst listeners = new Set<() => void>();\n\nfunction notify(): void {\n for (const l of listeners) l();\n}\n\nfunction readPicture(url: string): void {\n if (colors.has(url) || pending.has(url)) return;\n if (typeof Image === 'undefined' || typeof document === 'undefined') return;\n pending.add(url);\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.referrerPolicy = 'no-referrer';\n const settle = (color: string | null) => {\n pending.delete(url);\n colors.set(url, color);\n notify();\n };\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = SAMPLE_SIZE;\n canvas.height = SAMPLE_SIZE;\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n if (!ctx) { settle(null); return; }\n ctx.drawImage(img, 0, 0, SAMPLE_SIZE, SAMPLE_SIZE);\n settle(averageColor(ctx.getImageData(0, 0, SAMPLE_SIZE, SAMPLE_SIZE).data));\n } catch (err: unknown) {\n // A tainted canvas: the host sent no CORS header. The character's colour stands.\n debug('avatar', 'picture colour unreadable', { url, error: err instanceof Error ? err.message : String(err) });\n settle(null);\n }\n };\n img.onerror = () => settle(null);\n img.src = url;\n}\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\n/** The colour for someone with this character and (optional) picture, as far\n * as is known now: until the picture has been read, the character's. */\nexport function personColor(sprite: string | null | undefined, url: string | undefined): string {\n if (url) {\n const read = colors.get(url);\n if (read) return read;\n }\n return colorForSprite(sprite);\n}\n\n/** {@link personColor}, re-rendering once the picture's colour has been read. */\nexport function usePersonColor(sprite: string | null | undefined, url: string | undefined): string {\n useEffect(() => { if (url) readPicture(url); }, [url]);\n return useSyncExternalStore(subscribe, () => personColor(sprite, url), () => colorForSprite(sprite));\n}\n","import { useState, type CSSProperties, type ReactNode } from 'react';\nimport { spriteUrlFor } from '../lib/characters';\n\ninterface Props {\n /** The person's character: the portrait, and the fallback for `url`. */\n sprite: string | null | undefined;\n /** Their avatar picture (presence `avatar_url`), preferred when present. */\n url?: string;\n alt?: string;\n className: string;\n style?: CSSProperties;\n /** Shown when there is neither a picture nor a character. */\n fallback: ReactNode;\n}\n\n/**\n * Who someone is, as a picture: their avatar picture (Discord, Steam, an\n * upload) when they have one, else their character portrait.\n *\n * The picture is a third-party URL loaded by the browser alone — no referrer,\n * no CORS mode (it is never read back, so it needs none) — and one that fails\n * falls back to the portrait for as long as that URL stays the same. Games\n * never use this: their piece is always the character.\n */\nexport default function AvatarImage({ sprite, url, alt = '', className, style, fallback }: Props) {\n const [failedUrl, setFailedUrl] = useState<string | null>(null);\n if (url && url !== failedUrl) {\n return (\n <img\n src={url}\n alt={alt}\n referrerPolicy=\"no-referrer\"\n className={className}\n style={style}\n draggable={false}\n onError={() => setFailedUrl(url)}\n />\n );\n }\n const portrait = spriteUrlFor(sprite);\n if (!portrait) return <>{fallback}</>;\n return <img src={portrait} alt={alt} crossOrigin=\"anonymous\" className={className} style={style} draggable={false} />;\n}\n","/**\n * Inside the hadoku Android app (hadoku-mobile)?\n *\n * The app is a WebView over the live site; it appends `HadokuApp/<version>`\n * to the WebView's user agent. Its one native screen, the offline Library\n * (saved episodes, and downloading them from this catalog), has no button of\n * its own in the app: the lobby links to it. The link is a URL the app\n * intercepts and never loads, so it is rendered only where it works.\n */\n\n/** Intercepted by the app's MainActivity, which opens the native Library. */\nexport const HADOKU_APP_LIBRARY_URL = 'hadoku://library';\n\nexport function isHadokuApp(userAgent: string | undefined = typeof navigator !== 'undefined' ? navigator.userAgent : undefined): boolean {\n return userAgent !== undefined && /(^|\\s)HadokuApp\\/\\S/.test(userAgent);\n}\n","import { useEffect, useState } from 'react';\nimport StarfieldCanvas from '../components/StarfieldCanvas';\nimport { Link } from 'react-router-dom';\nimport { useConfig, getRuntimeServerOrigin } from '../lib/config';\nimport { error, warn, debug, isDebugEnabled } from '../lib/debug';\nimport { usePersonColor } from '../lib/pictureColor';\nimport AvatarImage from '../components/AvatarImage';\nimport { HADOKU_APP_LIBRARY_URL, isHadokuApp } from '../lib/hadokuApp';\n\ninterface RoomUser {\n name: string;\n sprite_id: string | null;\n /** Their avatar picture (Discord, Steam, uploaded), when not the character. */\n avatar_url?: string;\n}\n\ninterface RoomEntry {\n room_id: string;\n viewer_key: string;\n leader_key?: string; // present only for friend-tier-or-above requests (server-side)\n leader_occupied?: boolean; // true when a live leader already holds the room\n description?: string;\n users?: RoomUser[];\n}\n\n/** How often the lobby silently re-polls the room list for live updates. */\nconst ROOMS_POLL_INTERVAL_MS = 5000;\n\n/** Sort rooms by occupancy (most users first), ties broken alphabetically. */\nfunction sortRooms(list: RoomEntry[]): RoomEntry[] {\n return list.slice().sort(\n (a, b) => (b.users?.length ?? 0) - (a.users?.length ?? 0) || a.room_id.localeCompare(b.room_id),\n );\n}\n\n/** Turn a room_id like \"walrus-dune\" into \"Walrus Dune\" */\nfunction formatRoomName(r: RoomEntry): string {\n return r.room_id\n .split('-')\n .map(w => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\n/** One circular avatar (their picture, else their character) with a CSS-only\n * hover tooltip showing the user's display name. Avatars stack via negative margin; the hovered one\n * comes forward via z-index + scale. */\nfunction UserAvatar({ user }: { user: RoomUser }) {\n const ring = usePersonColor(user.sprite_id, user.avatar_url);\n return (\n <span className=\"relative -ml-2 first:ml-0 group/av\">\n <span\n className=\"block h-10 w-10 rounded-full border-2 overflow-hidden bg-bg-card transition-transform duration-150 group-hover/av:scale-110 group-hover/av:z-10 shadow-md\"\n style={{ borderColor: ring }}\n >\n <AvatarImage\n sprite={user.sprite_id}\n url={user.avatar_url}\n alt={user.name}\n className=\"h-full w-full object-cover\"\n fallback={\n <span className=\"flex h-full w-full items-center justify-center text-[13px] font-semibold text-text-secondary\">\n {user.name.slice(0, 1).toUpperCase()}\n </span>\n }\n />\n </span>\n {/* Tooltip — pure CSS hover trigger so each badge has its own state */}\n <span\n role=\"tooltip\"\n className=\"pointer-events-none absolute bottom-full left-1/2 mb-1.5 -translate-x-1/2 whitespace-nowrap rounded-md bg-bg-card/95 backdrop-blur px-2 py-1 text-[11px] font-medium text-text shadow-lg border border-border opacity-0 scale-95 group-hover/av:opacity-100 group-hover/av:scale-100 transition-all duration-150 z-20\"\n >\n {user.name}\n </span>\n </span>\n );\n}\n\nfunction RoomCard({ room }: { room: RoomEntry }) {\n const users = room.users ?? [];\n const count = users.length;\n return (\n <li className=\"flex items-stretch gap-2\">\n <Link\n to={`/room/${encodeURIComponent(room.viewer_key)}`}\n className=\"flex-1 block no-underline rounded-lg border border-border bg-bg-card/40 backdrop-blur-sm px-5 py-4 transition-all duration-150 hover:border-border-light hover:-translate-y-px hover:bg-bg-card/55 focus:outline-none focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/40\"\n >\n <div className=\"flex items-center justify-between gap-4\">\n <div className=\"text-xl font-medium tracking-wide text-text no-underline\">\n {formatRoomName(room)}\n </div>\n {count > 0 && (\n <div className=\"flex shrink-0\">\n {users.map((u, i) => (\n <UserAvatar key={`${u.name}-${i}`} user={u} />\n ))}\n </div>\n )}\n </div>\n </Link>\n {/* Leader shortcut — rendered when /api/rooms returned a leader_key (the\n server includes it for friend tier and above) AND the room isn't\n already led. Hiding it for occupied rooms stops friends from\n accidentally trying to take over an active leader. */}\n {room.leader_key && !room.leader_occupied && (\n <Link\n to={`/room/${encodeURIComponent(room.leader_key)}`}\n title=\"Join as leader\"\n className=\"flex items-center px-4 rounded-lg border border-primary/50 bg-primary/10 text-sm font-medium text-text no-underline transition-all duration-150 hover:bg-primary/20 hover:border-primary hover:-translate-y-px focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\"\n >\n Leader\n </Link>\n )}\n </li>\n );\n}\n\nexport default function Home() {\n const config = useConfig();\n const [rooms, setRooms] = useState<RoomEntry[]>([]);\n const [roomsLoading, setRoomsLoading] = useState(true);\n const [roomsError, setRoomsError] = useState<string | null>(null);\n const [reloadTick, setReloadTick] = useState(0);\n\n // A new origin starts a fresh load, as a Retry does.\n const [roomsOrigin, setRoomsOrigin] = useState(config.serverOrigin);\n if (config.serverOrigin !== roomsOrigin) {\n setRoomsOrigin(config.serverOrigin);\n setRoomsLoading(true);\n setRoomsError(null);\n }\n const retryRooms = () => {\n setRoomsLoading(true);\n setRoomsError(null);\n setReloadTick(n => n + 1);\n };\n\n useEffect(() => {\n const effectId = Math.random().toString(36).slice(2, 8);\n const controller = new AbortController();\n const origin = getRuntimeServerOrigin();\n let retried = false;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let resolved = false;\n\n debug('home', 'rooms-effect: mount', {\n effectId, origin, reloadTick,\n pathname: typeof location !== 'undefined' ? location.pathname : '?',\n });\n\n // Watchdog: if the fetch pipeline doesn't resolve within 10 seconds, log\n // a warn with full state so we can see WHAT's stuck. This is the\n // instrumentation for the 'stuck on Loading rooms forever' bug.\n const watchdogTimer = setTimeout(() => {\n if (resolved) return;\n warn('home', 'rooms-effect: WATCHDOG fired — fetch not resolved after 10s', {\n effectId,\n retried,\n hasRetryTimer: !!retryTimer,\n aborted: controller.signal.aborted,\n pathname: typeof location !== 'undefined' ? location.pathname : '?',\n });\n }, 10_000);\n\n const fetchRooms = (attempt: 1 | 2) => {\n const fetchStartedAt = Date.now();\n debug('home', 'rooms-effect: fetch-start', { effectId, attempt });\n // No auth header — edge-router injects X-User-Key from the session\n // cookie. The server includes each room's leader_key when that key is\n // service tier or above, which drives the \"Leader\" shortcut.\n // Pass ?debug so the server includes machine-named e2e/test rooms when\n // debug mode is on (?debug=true, window.__WP_DEBUG__, or stored flag).\n fetch(`${origin}/api/rooms${isDebugEnabled() ? '?debug=1' : ''}`, {\n cache: 'no-store',\n signal: controller.signal,\n })\n .then(res => res.ok ? res.json() : Promise.reject(new Error(`HTTP ${res.status}`)))\n .then(data => {\n const elapsedMs = Date.now() - fetchStartedAt;\n debug('home', 'rooms-effect: fetch-success', {\n effectId, attempt, elapsedMs, roomCount: (data.rooms ?? []).length,\n });\n setRooms(sortRooms(data.rooms || []));\n setRoomsError(null);\n setRoomsLoading(false);\n resolved = true;\n clearTimeout(watchdogTimer);\n })\n .catch((err: unknown) => {\n const elapsedMs = Date.now() - fetchStartedAt;\n const message = err instanceof Error ? err.message : undefined;\n if (err instanceof Error && err.name === 'AbortError') {\n debug('home', 'rooms-effect: fetch-abort', { effectId, attempt, elapsedMs });\n // AbortError means the effect cleanup aborted us — don't touch\n // state. The NEXT effect run will start fresh. But DO mark as\n // resolved so our watchdog doesn't fire.\n resolved = true;\n clearTimeout(watchdogTimer);\n return;\n }\n // One silent retry — handles cold TCP connections.\n if (!retried) {\n retried = true;\n warn('home', 'rooms-effect: fetch-error, scheduling retry', {\n effectId, attempt, elapsedMs, error: message,\n });\n retryTimer = setTimeout(() => {\n retryTimer = null;\n fetchRooms(2);\n }, 500);\n return;\n }\n error('app', 'Failed to load rooms list', { effectId, error: message, elapsedMs });\n setRoomsError(message ?? 'Network error');\n setRoomsLoading(false);\n resolved = true;\n clearTimeout(watchdogTimer);\n });\n };\n\n fetchRooms(1);\n\n // Live refresh: poll the room list so presence avatars and the Leader /\n // occupied state update without a manual reload (the lobby has no socket\n // connection of its own). Silent — no loading spinner, and a transient poll\n // failure keeps the last-good list.\n const pollTimer = setInterval(() => {\n fetch(`${origin}/api/rooms${isDebugEnabled() ? '?debug=1' : ''}`, {\n cache: 'no-store',\n signal: controller.signal,\n })\n .then(res => (res.ok ? res.json() : null))\n .then(data => { if (data) setRooms(sortRooms(data.rooms || [])); })\n .catch(() => { /* transient — keep last-good list */ });\n }, ROOMS_POLL_INTERVAL_MS);\n\n return () => {\n debug('home', 'rooms-effect: cleanup', {\n effectId, resolved, retried, hasRetryTimer: !!retryTimer,\n });\n controller.abort();\n clearTimeout(watchdogTimer);\n clearInterval(pollTimer);\n if (retryTimer) clearTimeout(retryTimer);\n };\n }, [config.serverOrigin, reloadTick]);\n\n return (\n <div className=\"relative h-full w-full flex flex-col items-center justify-start gap-12 py-24\">\n <StarfieldCanvas />\n <h1 className=\"text-5xl font-bold tracking-[0.08em] text-text z-10\">\n Watch Party\n </h1>\n <div className=\"w-full max-w-md z-10\">\n <h2 className=\"text-xs uppercase tracking-[0.2em] text-text-muted/70 mb-3 px-1\">Rooms</h2>\n {roomsLoading ? (\n <div className=\"text-text-secondary text-sm px-1 py-3 text-center\">Loading rooms…</div>\n ) : roomsError ? (\n <div className=\"bg-bg-card/40 backdrop-blur-sm border border-danger/40 rounded-lg px-4 py-3 text-sm space-y-2\">\n <div className=\"bg-danger-bg text-on-danger-bg px-2 py-1 rounded\">Failed to load rooms: {roomsError}</div>\n <button\n onClick={retryRooms}\n className=\"text-xs text-text-secondary hover:text-text underline cursor-pointer\"\n >\n Retry\n </button>\n </div>\n ) : rooms.length === 0 ? (\n <div className=\"text-text-secondary text-sm px-1 py-3\">No rooms available.</div>\n ) : (\n <>\n <ul className=\"list-none p-0 m-0 space-y-2\">\n {rooms.map(r => (\n <RoomCard key={r.viewer_key} room={r} />\n ))}\n </ul>\n </>\n )}\n </div>\n {/* The hadoku app's offline Library. The app has no bar of its own, so\n this is its way in; the URL works only inside the app. A plain <a>,\n not a router <Link>: the app sees real navigations only. */}\n {isHadokuApp() && (\n <div className=\"w-full max-w-md z-10\">\n <h2 className=\"text-xs uppercase tracking-[0.2em] text-text-muted/70 mb-3 px-1\">On this phone</h2>\n <a\n href={HADOKU_APP_LIBRARY_URL}\n className=\"block no-underline rounded-lg border border-border bg-bg-card/40 backdrop-blur-sm px-5 py-4 transition-all duration-150 hover:border-border-light hover:-translate-y-px hover:bg-bg-card/55 focus:outline-none focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/40\"\n >\n <div className=\"text-xl font-medium tracking-wide text-text\">Library</div>\n <div className=\"text-sm text-text-secondary\">Saved episodes, for watching offline</div>\n </a>\n </div>\n )}\n </div>\n );\n}\n","import StarfieldCanvas from './StarfieldCanvas';\n\nexport default function APIDownFallback() {\n return (\n <div className=\"fixed inset-0 bg-black\">\n <StarfieldCanvas />\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"text-center\">\n <h1 className=\"text-4xl font-bold text-white mb-4\">\n API is sleeping...\n </h1>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Edge-cacheable fragment delivery — URL construction and the enable decision.\n *\n * Two ways to fetch the same bytes:\n *\n * range GET <base>/output_frag.mp4 Range: bytes=S-E -> 206\n * fragment GET <base>/v/<token>/frag/<n> (no Range header) -> 200\n *\n * The fragment form exists so Cloudflare can cache a ~1MB object instead of failing to cache a\n * 700-800MB one (and dropping the Range on every fill — measured in prod 2026-08-05). The bytes\n * are identical; only the addressing differs. Server side is `media/fragmentRoute.ts`, and\n * `fragment-route.realmedia.test.ts` proves byte-identity against the real library.\n *\n * This module is deliberately pure. Getting a URL wrong here does not throw — it fetches a\n * *valid-looking* wrong range and appends plausible garbage to a SourceBuffer, which is\n * undetectable client-side and surfaces later as the corrupt-fragment / structural-gap failures\n * this codebase has spent months on. So the URL math lives in one tested place rather than\n * inline in FragmentManager.\n *\n * DEFAULT OFF. See `isFragmentDeliveryEnabled`.\n */\n\nimport {\n resolveDeliveryArm, normalizeFragmentDeliveryFlag, DEFAULT_FRAGMENT_DELIVERY_FLAG,\n type FragmentDeliveryFlag as FragmentDeliveryFlagT, type DeliveryArm,\n} from '@watchparty/shared';\nimport { debug, warn } from './debug';\nimport { readStored, writeStored, readStoredFlag } from './browserStorage';\n\nexport const FRAGMENT_DELIVERY_FLAG = 'watchparty_fragment_delivery';\n\n/** Everything needed to address one FragmentManager's media via the fragment route. */\nexport interface DeliveryConfig {\n /** Leaf base, no trailing slash: `<origin>/media/<mediaId>` */\n baseUrl: string;\n /** Full 64-hex SHA-256 of output_frag.mp4, from index.json. */\n token: string;\n /** Present for audio FragmentManagers only; identifies the track in the index. */\n trackId?: string;\n}\n\n/** `init`, or a zero-based fragment index. */\nexport type DeliveryTarget = 'init' | number;\n\nconst TOKEN_RE = /^[0-9a-f]{64}$/;\nconst TRACK_ID_RE = /^[A-Za-z0-9_.-]+$/;\n\n/**\n * Is the config usable for fragment-route requests?\n *\n * Mirrors the server's route regex (`fragmentRoute.ts` ROUTE / resolveTarget). A config that\n * fails here can only ever produce 404s, so we keep using Range instead — never a broken URL.\n */\nexport function isDeliveryConfigValid(cfg: DeliveryConfig | null | undefined): cfg is DeliveryConfig {\n if (!cfg) return false;\n if (!cfg.baseUrl || cfg.baseUrl.endsWith('/')) return false;\n // Full digest only. A truncated token would reintroduce a collision path on the one value\n // whose wrongness means a YEAR of an edge serving wrong bytes under `immutable`.\n if (!TOKEN_RE.test(cfg.token)) return false;\n if (cfg.trackId !== undefined && !TRACK_ID_RE.test(cfg.trackId)) return false;\n return true;\n}\n\n/**\n * Build the fragment-route URL, or null when this config/target cannot be addressed.\n *\n * Null is always safe: the caller falls back to a Range request for the same bytes.\n */\nexport function buildFragmentUrl(cfg: DeliveryConfig | null | undefined, target: DeliveryTarget): string | null {\n if (!isDeliveryConfigValid(cfg)) return null;\n let tail: string;\n if (target === 'init') {\n tail = 'init';\n } else {\n // Fragment indices are array positions in index.json. A non-integer or negative index would\n // 404 server-side, but building it at all means a bug upstream — refuse instead.\n if (!Number.isInteger(target) || target < 0) return null;\n tail = `frag/${target}`;\n }\n const prefix = cfg.trackId ? `audio/${cfg.trackId}/` : '';\n return `${cfg.baseUrl}/v/${cfg.token}/${prefix}${tail}`;\n}\n\n/** Local override from `?fragmentDelivery=0|1`, or null when the URL says nothing. */\nexport function readDeliveryOverride(): boolean | null {\n if (typeof window === 'undefined') return null;\n try {\n const q = new URLSearchParams(window.location.search).get('fragmentDelivery');\n if (q === '1' || q === 'true') return true;\n if (q === '0' || q === 'false') return false;\n } catch { /* no location */ }\n return readStoredFlag(FRAGMENT_DELIVERY_FLAG);\n}\n\n// ── Server-controlled rollout ────────────────────────────────────────────────\n//\n// The operator flips this from `POST /api/flags/fragment-delivery` (service-tier) with no\n// deploy, and can run `ab` to split one room between both delivery paths at once. See\n// packages/shared/src/fragmentDeliveryFlag.ts for why the split is per-client and deterministic.\n//\n// Until the flag is fetched we resolve OFF. That is the safe direction: a client that starts\n// before the answer arrives uses the delivery path that has always worked.\n\nlet serverFlag: FragmentDeliveryFlagT = { ...DEFAULT_FRAGMENT_DELIVERY_FLAG };\nlet resolvedArm: DeliveryArm | null = null;\n/** True once something that ACTS on the arm has read it (i.e. FragmentManager). */\nlet armPinned = false;\n\nexport const DELIVERY_CLIENT_ID_KEY = 'watchparty_delivery_client_id';\n\n/**\n * Stable per-browser id used ONLY for A/B bucketing.\n *\n * Deliberately not the socket id. That is what `me.clientId` holds, and it is reassigned on\n * every reconnect — bucketing on it would let a viewer flip delivery paths mid-party on a\n * transient disconnect, which both breaks the \"never change path mid-episode\" invariant and\n * turns the A/B comparison into noise (the same person contributing samples to both arms).\n * It is also unavailable at join time, when the arm has to be reported.\n *\n * Persisted so a viewer stays in one arm across reloads and across sessions, which is what\n * makes a percentage rollout mean anything. Not an identity or a tracking id: it is a random\n * value with no server-side meaning, read by nothing except this bucketing.\n */\nexport function deliveryClientId(): string {\n const existing = readStored(DELIVERY_CLIENT_ID_KEY);\n if (existing) return existing;\n const fresh = (globalThis.crypto?.randomUUID?.() ?? `d${Math.random().toString(36).slice(2)}`);\n // An id we could not persist is worse than none: it would put this client in\n // a DIFFERENT arm on every reload, feeding samples to both. Empty id =>\n // resolveDeliveryArm keeps it out of the experiment entirely, which is the\n // safe direction.\n return writeStored(DELIVERY_CLIENT_ID_KEY, fresh) ? fresh : '';\n}\n\n/**\n * Store the flag fetched from the server.\n *\n * Clears a provisional arm, but never a PINNED one.\n *\n * The distinction is the whole reason this exists. `/api/flags` is fetched during app boot and\n * lands after the socket join, so an arm resolved at join time is decided against the default\n * (off) — which on 2026-08-08 made an `ab`/50 rollout produce 0 of 5 clients in the fragment\n * arm. Every client had pinned `range` milliseconds before learning the flag. So a resolution\n * made purely for reporting stays provisional and is recomputed when the flag arrives.\n *\n * Once FragmentManager has actually read the arm (isFragmentDeliveryEnabled), it is pinned and\n * a later flag change cannot move it — that upholds the invariant that a client never switches\n * delivery path mid-episode. Media loads seconds after boot, long after the flag lands, so in\n * practice the pin happens on the correct value.\n */\nexport function setServerDeliveryFlag(raw: unknown): void {\n serverFlag = normalizeFragmentDeliveryFlag(raw);\n if (!armPinned) resolvedArm = null;\n}\n\nexport function getServerDeliveryFlag(): FragmentDeliveryFlagT {\n return { ...serverFlag };\n}\n\n/**\n * Which arm is this client in? Memoised for the session.\n *\n * Memoisation is load-bearing, not an optimisation: an in-flight media load must not change\n * delivery path halfway through because an operator moved the flag. The arm is fixed for the\n * session and a change takes effect on the next page load.\n */\nexport function resolveSessionArm(): DeliveryArm {\n if (resolvedArm === null) {\n resolvedArm = resolveDeliveryArm(serverFlag, deliveryClientId(), readDeliveryOverride());\n }\n return resolvedArm;\n}\n\n/**\n * Fetch the rollout flag. Idempotent, safe to call more than once, never throws.\n *\n * Deliberately NOT tied to any React effect's AbortController. It was, chained onto the\n * app's health-check effect, and `if (controller.signal.aborted) return` then discarded the\n * flag whenever that effect cleaned up before the response landed — a pure race. Two\n * consecutive 8-viewer DO runs on 2026-08-08 disagreed completely because of it: one put 5 of\n * 7 clients in the fragment arm, the next 0 of 6, with the same flag and the same build.\n *\n * A rollout flag is not tied to a component's lifetime. It is a tiny idempotent GET whose only\n * job is to land before media loads (seconds later), so it gets one retry and no cancellation.\n */\nlet flagFetchStarted = false;\nexport async function loadServerDeliveryFlag(origin: string): Promise<void> {\n if (flagFetchStarted) return;\n flagFetchStarted = true;\n for (let attempt = 0; attempt < 2; attempt++) {\n try {\n const res = await fetch(`${origin}/api/flags`, { cache: 'no-store' });\n if (res.ok) {\n const body = await res.json();\n setServerDeliveryFlag(body?.fragment_delivery);\n debug('app', 'Delivery flag loaded', { ...getServerDeliveryFlag(), attempt });\n return;\n }\n } catch { /* fall through to the retry */ }\n if (attempt === 0) await new Promise((r) => setTimeout(r, 500));\n }\n // Both attempts failed — stay on the default (range), which is the path that always works.\n warn('app', 'Delivery flag fetch failed; staying on the default delivery path');\n}\n\n/** Test seam — drop the memoised arm. */\nexport function resetSessionArm(): void { resolvedArm = null; armPinned = false; flagFetchStarted = false; }\n\n/**\n * The arm for this session, for telemetry. Safe to call at join time — the bucketing id is a\n * persisted per-browser value, not the socket id, so it exists before the socket does.\n */\nexport function currentDeliveryArm(): DeliveryArm {\n return resolveSessionArm(); // provisional until something pins it — see setServerDeliveryFlag\n}\n\n/**\n * Is fragment delivery active for this session?\n *\n * **Off unless the server says otherwise.** As of 2026-08-07 Cloudflare returns\n * `cf-cache-status: DYNAMIC` for these URLs (extensionless paths are not cached by default),\n * and the route sits ahead of the Range gate in `priorityQueue.ts` so it consumes no\n * `MAX_CONCURRENT_MEDIA` slot and is never sorted by `X-Buffer-Ahead-Ms`. Enabled today that is\n * strictly worse than Range: no edge cache AND no fairness queue.\n */\nexport function isFragmentDeliveryEnabled(): boolean {\n const arm = resolveSessionArm();\n // Reading it to ACT on it fixes it for the session.\n armPinned = true;\n return arm === 'fragment';\n}\n","import { useSyncExternalStore } from 'react';\nimport { DEFAULT_GAME_CATALOG, GameCatalogSchema } from '@watchparty/shared';\nimport type { GameEntry } from '@wolffm/rooms-protocol';\nimport { debug, errorFields, warn } from './debug';\n\n/**\n * The room's game list, fetched from `GET /api/games` (the server's `GAMES`\n * config). Until it lands — or if it never does — the room has the default\n * list, so Bomberman behaves exactly as it did when the list was hardcoded.\n *\n * Typed as the protocol's `GameEntry`: assigning the zod output to it is the\n * compile-time check that `@watchparty/shared`'s schema and\n * `@wolffm/rooms-protocol`'s type have not drifted apart.\n */\nlet games: readonly GameEntry[] = DEFAULT_GAME_CATALOG;\nconst listeners = new Set<() => void>();\n\nfunction setGames(next: readonly GameEntry[]): void {\n games = next;\n for (const l of listeners) l();\n}\n\n/** Validate a `/api/games` body. A bad body keeps the current list. */\nexport function applyGameCatalog(body: unknown): boolean {\n const parsed = GameCatalogSchema.safeParse((body as { games?: unknown } | null)?.games);\n if (!parsed.success) {\n warn('game', 'Game catalog rejected; keeping the current list', { issues: parsed.error.issues.length });\n return false;\n }\n const next: readonly GameEntry[] = parsed.data;\n setGames(next);\n return true;\n}\n\nlet fetchStarted = false;\n/** Fetch the catalog once per page. Idempotent, never throws. */\nexport async function loadGameCatalog(origin: string): Promise<void> {\n if (fetchStarted) return;\n fetchStarted = true;\n try {\n const res = await fetch(`${origin}/api/games`, { cache: 'no-store' });\n if (!res.ok) {\n warn('game', 'Game catalog fetch failed; using the default list', { status: res.status });\n return;\n }\n if (applyGameCatalog(await res.json())) {\n debug('game', 'Game catalog loaded', { games: games.map((g) => g.id) });\n }\n } catch (e: unknown) {\n warn('game', 'Game catalog fetch failed; using the default list', errorFields(e));\n }\n}\n\nexport function getGameCatalog(): readonly GameEntry[] {\n return games;\n}\n\nfunction subscribe(l: () => void): () => void {\n listeners.add(l);\n return () => { listeners.delete(l); };\n}\n\nexport function useGameCatalog(): readonly GameEntry[] {\n return useSyncExternalStore(subscribe, getGameCatalog);\n}\n\n/** Test seam. */\nexport function resetGameCatalog(): void {\n fetchStarted = false;\n setGames(DEFAULT_GAME_CATALOG);\n}\n","import React from 'react';\n\n/**\n * Wraps React.lazy with a single auto-reload on chunk load failure.\n *\n * When we deploy a new UI bundle, any browser that loaded the old entry\n * chunk holds stale references to the old lazy chunk filenames (those\n * filenames have content hashes like `AdminPanel-DaIaL0mU.js`). When the\n * user triggers a lazy import, the old filename 404s and React throws\n * \"error loading dynamically imported module.\"\n *\n * Recovery: reload once (sessionStorage gate prevents a reload loop on a\n * legitimately broken deploy) and let the browser pick up the current\n * entry chunk, which references the new lazy chunk hashes.\n */\nexport function lazyWithRetry<P extends object>(\n importer: () => Promise<{ default: React.ComponentType<P> }>,\n): React.LazyExoticComponent<React.ComponentType<P>> {\n return React.lazy(async () => {\n try {\n return await importer();\n } catch (err) {\n const msg = String((err as Error)?.message ?? err);\n const isChunkError = /dynamically imported module|ChunkLoadError|Loading chunk/i.test(msg);\n if (!isChunkError) throw err;\n const flag = 'watchparty-chunk-reload';\n if (sessionStorage.getItem(flag)) throw err; // already retried once\n sessionStorage.setItem(flag, String(Date.now()));\n window.location.reload();\n // Return a never-resolving promise so React doesn't surface the error\n // while the page is tearing down for reload.\n return new Promise<{ default: React.ComponentType<P> }>(() => {});\n }\n });\n}\n","import { getUserType } from './auth';\n\n/**\n * Public room IDs that bypass the friend-auth gate. Leader URLs append a\n * hex suffix to the room id, so we match `<id>` exactly OR `<id>-<hex>`.\n *\n * Single entry today: `demo-room` is the showcase room anyone can join\n * without a friend cookie. Per-room exemption is intentional — keeps the\n * exemption list visible at a single source-of-truth grep instead of\n * scattered through the auth flow.\n */\nconst PUBLIC_ROOM_IDS = ['demo-room'];\n\nfunction isPublicRoom(roomKey: string | undefined): boolean {\n if (!roomKey) return false;\n return PUBLIC_ROOM_IDS.some(id => roomKey === id || roomKey.startsWith(id + '-'));\n}\n\n/**\n * Decide whether this navigation needs to bounce through the hadoku.me\n * /auth page. The gate is purely client-side per the agreed design:\n * server-side enforcement on socket join is a follow-up, not in scope.\n *\n * Only the prod host (`hadoku.me`) gates — dev/staging/standalone hosts\n * have no `/auth` page anyway, so we'd just 404 the redirect.\n *\n * Returns the absolute URL to redirect to, or null when the request is\n * allowed through.\n */\nexport function shouldRedirectToAuth(opts: {\n roomKey?: string;\n hostname: string;\n pathname: string;\n search: string;\n /** When true, the gate fires regardless of roomKey — used by the\n * standalone `/editor` route which has no room context but is still\n * friend-tier-only. */\n requireAuth?: boolean;\n}): string | null {\n const onProdHost = opts.hostname === 'hadoku.me';\n if (!onProdHost) return null;\n if (opts.requireAuth) {\n if (getUserType() !== 'public') return null;\n const returnPath = opts.pathname + (opts.search || '');\n return `/auth?return=${encodeURIComponent(returnPath)}`;\n }\n // Lobby (no roomKey) stays public — visitors can see the room list.\n if (!opts.roomKey) return null;\n if (isPublicRoom(opts.roomKey)) return null;\n if (getUserType() !== 'public') return null;\n const returnPath = opts.pathname + (opts.search || '');\n return `/auth?return=${encodeURIComponent(returnPath)}`;\n}\n","import { HadokuThemeRoot } from '@wolffm/themes';\nimport React, { useEffect, useState } from 'react';\nimport { useLocation, useParams } from 'react-router-dom';\nimport Toasts from './components/Toasts';\nimport { CHARACTER_ORDER, spriteUrlFor } from './lib/characters';\nimport Home from './routes/Home';\nimport APIDownFallback from './components/APIDownFallback';\nimport { ConfigContext, DEFAULT_CONFIG, getServerOrigin, type WatchpartyConfig } from './lib/config';\nimport { debug, error, errorFields } from './lib/debug';\nimport { loadServerDeliveryFlag } from './lib/fragmentDelivery';\nimport { loadGameCatalog } from './lib/gameCatalog';\nimport { HEALTH_ENDPOINT } from '@watchparty/shared';\nimport { lazyWithRetry } from './lib/lazyWithRetry';\nimport { shouldRedirectToAuth } from './lib/authGate';\n\nconst Room = lazyWithRetry(() => import('./routes/Room'));\n\nfunction RoomFallback() {\n return (\n <div className=\"flex-1 flex items-center justify-center bg-black\">\n <div className=\"text-text-secondary text-sm\">Loading room...</div>\n </div>\n );\n}\n\nfunction RouteBody() {\n const loc = useLocation();\n const params = useParams<{ roomKey?: string }>();\n\n // Friend-auth gate: public users entering a non-demo room get bounced\n // to hadoku.me/auth. Server-side enforcement is intentionally out of\n // scope — this is purely a UX redirect. The cookie + edge-router\n // injectSessionKey are the actual security boundary.\n const redirect = shouldRedirectToAuth({\n roomKey: params.roomKey,\n hostname: window.location.hostname,\n pathname: window.location.pathname,\n search: window.location.search,\n });\n if (redirect) {\n window.location.replace(redirect);\n return null;\n }\n\n // If we have a roomKey param, show Room directly\n if (params.roomKey) {\n return (\n <React.Suspense fallback={<RoomFallback />}>\n <Room />\n </React.Suspense>\n );\n }\n\n // Otherwise show Home\n if (loc.pathname === '/' || loc.pathname === '') {\n return <Home />;\n }\n\n // Fallback for room paths without params (shouldn't happen with proper routing)\n if (loc.pathname.startsWith('/room')) {\n return (\n <React.Suspense fallback={<RoomFallback />}>\n <Room />\n </React.Suspense>\n );\n }\n\n return <div className=\"p-6\">Not Found</div>;\n}\n\nexport type AppProps = {\n serverOrigin?: string;\n defaultRoomKey?: string;\n /** Hadoku session metadata, passed from mf-loader after whoami resolves. */\n userType?: 'admin' | 'wife' | 'service' | 'friend' | 'member' | 'public';\n /** The key registry's userId, or null. Never the session id (#151). */\n userId?: string | null;\n /** Theme from mf-loader runtimeProps; restored from localStorage as fallback. */\n theme?: string;\n /** Override the chat-image CDN read base. Optional: the default already\n * points at the live CDN, so the host page does not have to pass it. */\n cdnBase?: string;\n};\n\nexport default function App(props: AppProps) {\n const [apiDown, setApiDown] = useState(false);\n\n // Merge props with defaults\n const config: WatchpartyConfig = {\n serverOrigin: props.serverOrigin || DEFAULT_CONFIG.serverOrigin,\n defaultRoomKey: props.defaultRoomKey || DEFAULT_CONFIG.defaultRoomKey,\n cdnBase: props.cdnBase || DEFAULT_CONFIG.cdnBase,\n };\n const origin = getServerOrigin(config);\n\n // Check API health on mount (non-blocking — routes render immediately)\n useEffect(() => {\n const controller = new AbortController();\n async function checkHealth() {\n const url = origin + HEALTH_ENDPOINT;\n debug('app', 'Checking API health', { url });\n try {\n const res = await fetch(url, {\n cache: 'no-store',\n signal: controller.signal,\n });\n if (controller.signal.aborted) return;\n if (res.ok) {\n debug('app', 'API health check passed');\n // Rollout flag. Fire-and-forget, and NOT wired to `controller` — see\n // loadServerDeliveryFlag. Tying it to this effect's abort signal made it a race that\n // silently disabled the whole rollout for an entire DO fleet.\n void loadServerDeliveryFlag(origin);\n // Same lifetime rule: the game list outlives this effect.\n void loadGameCatalog(origin);\n } else {\n error('app', 'API health check failed', { status: res.status });\n setApiDown(true);\n }\n } catch (err) {\n if ((err as Error)?.name === 'AbortError') return; // Cleanup abort — not a real error\n error('app', 'API unreachable', { url, error: err });\n setApiDown(true);\n }\n }\n // checkHealth catches its own failures; nothing reaches the promise.\n void checkHealth();\n return () => controller.abort();\n }, [origin]);\n\n // Auto-retry health check when API is down\n useEffect(() => {\n if (!apiDown) return;\n async function recheckHealth() {\n const url = origin + HEALTH_ENDPOINT;\n try {\n const res = await fetch(url, {\n cache: 'no-store',\n signal: AbortSignal.timeout(5000)\n });\n if (res.ok) {\n debug('app', 'API recovery health check passed');\n setApiDown(false);\n }\n } catch (e: unknown) {\n debug('app', 'API recovery health check still failing', errorFields(e));\n }\n }\n const interval = setInterval(() => { void recheckHealth(); }, 15_000);\n return () => clearInterval(interval);\n }, [apiDown, origin]);\n\n // Preload sprites after page load\n useEffect(() => {\n function preloadAll() {\n debug('app', 'Preloading character sprites', { count: CHARACTER_ORDER.length });\n for (const c of CHARACTER_ORDER) {\n const url = spriteUrlFor(c);\n if (!url) continue;\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.decoding = 'async';\n img.loading = 'eager';\n img.src = url;\n }\n }\n function schedule() {\n if ('requestIdleCallback' in window) {\n window.requestIdleCallback(preloadAll, { timeout: 2000 });\n } else {\n setTimeout(preloadAll, 600);\n }\n }\n if (document.readyState === 'complete') {\n schedule();\n } else {\n window.addEventListener('load', schedule, { once: true });\n }\n }, []);\n\n if (apiDown) {\n return <APIDownFallback />;\n }\n\n return (\n // HadokuThemeRoot must sit above everything that reads the theme —\n // <HadokuThemePicker> in ChatPanel throws without it, by design, so a\n // missing provider is a mount-time error rather than a silently wrong\n // theme. It also applies data-theme, which this app previously did through\n // its own useTheme() call.\n <HadokuThemeRoot>\n <ConfigContext.Provider value={config}>\n <div className=\"h-screen flex flex-col bg-bg\">\n <main className=\"flex-1 w-full overflow-hidden min-h-0 flex flex-col\">\n <RouteBody />\n </main>\n <Toasts />\n </div>\n </ConfigContext.Provider>\n </HadokuThemeRoot>\n );\n}\n","import type { RouteObject } from 'react-router-dom';\nimport { createBrowserRouter } from 'react-router-dom';\nimport App, { type AppProps } from './App';\n\nexport interface CreateWatchpartyRouterOptions {\n basename?: string;\n appProps?: AppProps;\n}\n\nexport function createWatchpartyRouter(\n { basename = '/watchparty', appProps }: CreateWatchpartyRouterOptions = {},\n) {\n const resolvedAppProps = appProps ?? ({});\n const routes: RouteObject[] = [\n { path: '/', element: <App {...resolvedAppProps} /> },\n { path: '/room/:roomKey', element: <App {...resolvedAppProps} /> },\n { path: '/:roomKey', element: <App {...resolvedAppProps} /> },\n ];\n\n return createBrowserRouter(routes, { basename });\n}\n","import { DEVICE_ID_KEY, getDeviceId } from '@wolffm/prefs-client';\nimport { readStored } from './browserStorage';\nimport { debug } from './debug';\n\n/**\n * The browser-persisted device id, reported on join so the server can derive a\n * `dev:`-tier participant identity for a client with no friend key.\n *\n * ## Why this id and not a new one\n *\n * `@wolffm/prefs-client` already owns `hadoku_device_id` — one id per browser,\n * shared across every hadoku microfrontend by design. Minting a\n * watchparty-specific id would give the same physical browser a different\n * identity per app, for no gain: the id is opaque, carries no privileges, and\n * the whole point is \"this is the same browser as last time\".\n *\n * `lib/fragmentDelivery.ts` keeps its OWN `watchparty_delivery_client_id`, and\n * that is deliberate rather than an oversight to clean up — it is an A/B\n * bucketing salt, and pointing it at a shared ecosystem id would silently\n * re-bucket every viewer the first time any other hadoku app touched the key.\n * Two ids, two purposes.\n *\n * ## Why there is a synchronous read at all\n *\n * `getDeviceId()` is async (so the SDK can swap in Capacitor storage), but the\n * join payload is assembled synchronously and a join that waits on I/O is a\n * join that races the socket. So: read localStorage directly for the common\n * case — a returning browser already has the key — and use the async path only\n * to MINT one, priming the cache for the next join.\n *\n * Reading `DEVICE_ID_KEY` ourselves is not reaching into the SDK's internals;\n * the package exports that constant precisely so consumers can.\n *\n * ## The unresolved case is a normal outcome, not an error\n *\n * A brand-new browser, or one with storage blocked (private mode, blocked site\n * data), yields `undefined`. The server then derives an `eph:` identity — the\n * pre-existing behaviour, where a name lasts as long as the socket. It must\n * never block or delay the join: an anonymous viewer losing their display name\n * on reload is a small thing, and not joining at all is not.\n */\n\nlet cached: string | undefined;\n\n/** Synchronous read of an id this browser already holds. */\nfunction storedDeviceId(): string | undefined {\n return readStored(DEVICE_ID_KEY) || undefined;\n}\n\n/**\n * Kick off a mint if this browser has no id yet. Fire-and-forget: callers get\n * the id from `cachedDeviceId()` when it is there, and the ephemeral tier when\n * it isn't. Call it as early as possible so the mint is done before join.\n */\nexport function primeDeviceId(): void {\n if (cached) return;\n const stored = storedDeviceId();\n if (stored) {\n cached = stored;\n return;\n }\n void getDeviceId()\n .then((id) => {\n if (id) cached = id;\n })\n .catch(() => {\n // Storage refused the write. Nothing to recover: the ephemeral tier is\n // the honest answer, and swallowing this is the whole point — a device\n // id is an optimisation, never a requirement for joining a room.\n debug('identity', 'device id unavailable — joining without one');\n });\n}\n\n/**\n * The device id, if this browser has one *right now*. Never blocks, never\n * mints. Returns undefined on a first-ever visit whose mint has not landed.\n */\nexport function cachedDeviceId(): string | undefined {\n return (cached ??= storedDeviceId());\n}\n\n/** Test seam: drop the memoised value so a spec can re-read storage. */\nexport function resetDeviceIdCacheForTests(): void {\n cached = undefined;\n}\n","const PACKET_TYPES = Object.create(null); // no Map = no polyfill\nPACKET_TYPES[\"open\"] = \"0\";\nPACKET_TYPES[\"close\"] = \"1\";\nPACKET_TYPES[\"ping\"] = \"2\";\nPACKET_TYPES[\"pong\"] = \"3\";\nPACKET_TYPES[\"message\"] = \"4\";\nPACKET_TYPES[\"upgrade\"] = \"5\";\nPACKET_TYPES[\"noop\"] = \"6\";\nconst PACKET_TYPES_REVERSE = Object.create(null);\nObject.keys(PACKET_TYPES).forEach((key) => {\n PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key;\n});\nconst ERROR_PACKET = { type: \"error\", data: \"parser error\" };\nexport { PACKET_TYPES, PACKET_TYPES_REVERSE, ERROR_PACKET };\n","import { PACKET_TYPES } from \"./commons.js\";\nconst withNativeBlob = typeof Blob === \"function\" ||\n (typeof Blob !== \"undefined\" &&\n Object.prototype.toString.call(Blob) === \"[object BlobConstructor]\");\nconst withNativeArrayBuffer = typeof ArrayBuffer === \"function\";\n// ArrayBuffer.isView method is not defined in IE10\nconst isView = (obj) => {\n return typeof ArrayBuffer.isView === \"function\"\n ? ArrayBuffer.isView(obj)\n : obj && obj.buffer instanceof ArrayBuffer;\n};\nconst encodePacket = ({ type, data }, supportsBinary, callback) => {\n if (withNativeBlob && data instanceof Blob) {\n if (supportsBinary) {\n return callback(data);\n }\n else {\n return encodeBlobAsBase64(data, callback);\n }\n }\n else if (withNativeArrayBuffer &&\n (data instanceof ArrayBuffer || isView(data))) {\n if (supportsBinary) {\n return callback(data);\n }\n else {\n return encodeBlobAsBase64(new Blob([data]), callback);\n }\n }\n // plain string\n return callback(PACKET_TYPES[type] + (data || \"\"));\n};\nconst encodeBlobAsBase64 = (data, callback) => {\n const fileReader = new FileReader();\n fileReader.onload = function () {\n const content = fileReader.result.split(\",\")[1];\n callback(\"b\" + (content || \"\"));\n };\n return fileReader.readAsDataURL(data);\n};\nfunction toArray(data) {\n if (data instanceof Uint8Array) {\n return data;\n }\n else if (data instanceof ArrayBuffer) {\n return new Uint8Array(data);\n }\n else {\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n }\n}\nlet TEXT_ENCODER;\nexport function encodePacketToBinary(packet, callback) {\n if (withNativeBlob && packet.data instanceof Blob) {\n return packet.data.arrayBuffer().then(toArray).then(callback);\n }\n else if (withNativeArrayBuffer &&\n (packet.data instanceof ArrayBuffer || isView(packet.data))) {\n return callback(toArray(packet.data));\n }\n encodePacket(packet, false, (encoded) => {\n if (!TEXT_ENCODER) {\n TEXT_ENCODER = new TextEncoder();\n }\n callback(TEXT_ENCODER.encode(encoded));\n });\n}\nexport { encodePacket };\n","// imported from https://github.com/socketio/base64-arraybuffer\nconst chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nconst lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (let i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n}\nexport const encode = (arraybuffer) => {\n let bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';\n for (i = 0; i < len; i += 3) {\n base64 += chars[bytes[i] >> 2];\n base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];\n base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];\n base64 += chars[bytes[i + 2] & 63];\n }\n if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + '=';\n }\n else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + '==';\n }\n return base64;\n};\nexport const decode = (base64) => {\n let bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;\n if (base64[base64.length - 1] === '=') {\n bufferLength--;\n if (base64[base64.length - 2] === '=') {\n bufferLength--;\n }\n }\n const arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);\n for (i = 0; i < len; i += 4) {\n encoded1 = lookup[base64.charCodeAt(i)];\n encoded2 = lookup[base64.charCodeAt(i + 1)];\n encoded3 = lookup[base64.charCodeAt(i + 2)];\n encoded4 = lookup[base64.charCodeAt(i + 3)];\n bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n }\n return arraybuffer;\n};\n","import { ERROR_PACKET, PACKET_TYPES_REVERSE, } from \"./commons.js\";\nimport { decode } from \"./contrib/base64-arraybuffer.js\";\nconst withNativeArrayBuffer = typeof ArrayBuffer === \"function\";\nexport const decodePacket = (encodedPacket, binaryType) => {\n if (typeof encodedPacket !== \"string\") {\n return {\n type: \"message\",\n data: mapBinary(encodedPacket, binaryType),\n };\n }\n const type = encodedPacket.charAt(0);\n if (type === \"b\") {\n return {\n type: \"message\",\n data: decodeBase64Packet(encodedPacket.substring(1), binaryType),\n };\n }\n const packetType = PACKET_TYPES_REVERSE[type];\n if (!packetType) {\n return ERROR_PACKET;\n }\n return encodedPacket.length > 1\n ? {\n type: PACKET_TYPES_REVERSE[type],\n data: encodedPacket.substring(1),\n }\n : {\n type: PACKET_TYPES_REVERSE[type],\n };\n};\nconst decodeBase64Packet = (data, binaryType) => {\n if (withNativeArrayBuffer) {\n const decoded = decode(data);\n return mapBinary(decoded, binaryType);\n }\n else {\n return { base64: true, data }; // fallback for old browsers\n }\n};\nconst mapBinary = (data, binaryType) => {\n switch (binaryType) {\n case \"blob\":\n if (data instanceof Blob) {\n // from WebSocket + binaryType \"blob\"\n return data;\n }\n else {\n // from HTTP long-polling or WebTransport\n return new Blob([data]);\n }\n case \"arraybuffer\":\n default:\n if (data instanceof ArrayBuffer) {\n // from HTTP long-polling (base64) or WebSocket + binaryType \"arraybuffer\"\n return data;\n }\n else {\n // from WebTransport (Uint8Array)\n return data.buffer;\n }\n }\n};\n","import { encodePacket, encodePacketToBinary } from \"./encodePacket.js\";\nimport { decodePacket } from \"./decodePacket.js\";\nimport { ERROR_PACKET, } from \"./commons.js\";\nconst SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text\nconst encodePayload = (packets, callback) => {\n // some packets may be added to the array while encoding, so the initial length must be saved\n const length = packets.length;\n const encodedPackets = new Array(length);\n let count = 0;\n packets.forEach((packet, i) => {\n // force base64 encoding for binary packets\n encodePacket(packet, false, (encodedPacket) => {\n encodedPackets[i] = encodedPacket;\n if (++count === length) {\n callback(encodedPackets.join(SEPARATOR));\n }\n });\n });\n};\nconst decodePayload = (encodedPayload, binaryType) => {\n const encodedPackets = encodedPayload.split(SEPARATOR);\n const packets = [];\n for (let i = 0; i < encodedPackets.length; i++) {\n const decodedPacket = decodePacket(encodedPackets[i], binaryType);\n packets.push(decodedPacket);\n if (decodedPacket.type === \"error\") {\n break;\n }\n }\n return packets;\n};\nexport function createPacketEncoderStream() {\n return new TransformStream({\n transform(packet, controller) {\n encodePacketToBinary(packet, (encodedPacket) => {\n const payloadLength = encodedPacket.length;\n let header;\n // inspired by the WebSocket format: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#decoding_payload_length\n if (payloadLength < 126) {\n header = new Uint8Array(1);\n new DataView(header.buffer).setUint8(0, payloadLength);\n }\n else if (payloadLength < 65536) {\n header = new Uint8Array(3);\n const view = new DataView(header.buffer);\n view.setUint8(0, 126);\n view.setUint16(1, payloadLength);\n }\n else {\n header = new Uint8Array(9);\n const view = new DataView(header.buffer);\n view.setUint8(0, 127);\n view.setBigUint64(1, BigInt(payloadLength));\n }\n // first bit indicates whether the payload is plain text (0) or binary (1)\n if (packet.data && typeof packet.data !== \"string\") {\n header[0] |= 0x80;\n }\n controller.enqueue(header);\n controller.enqueue(encodedPacket);\n });\n },\n });\n}\nlet TEXT_DECODER;\nfunction totalLength(chunks) {\n return chunks.reduce((acc, chunk) => acc + chunk.length, 0);\n}\nfunction concatChunks(chunks, size) {\n if (chunks[0].length === size) {\n return chunks.shift();\n }\n const buffer = new Uint8Array(size);\n let j = 0;\n for (let i = 0; i < size; i++) {\n buffer[i] = chunks[0][j++];\n if (j === chunks[0].length) {\n chunks.shift();\n j = 0;\n }\n }\n if (chunks.length && j < chunks[0].length) {\n chunks[0] = chunks[0].slice(j);\n }\n return buffer;\n}\nexport function createPacketDecoderStream(maxPayload, binaryType) {\n if (!TEXT_DECODER) {\n TEXT_DECODER = new TextDecoder();\n }\n const chunks = [];\n let state = 0 /* State.READ_HEADER */;\n let expectedLength = -1;\n let isBinary = false;\n return new TransformStream({\n transform(chunk, controller) {\n chunks.push(chunk);\n while (true) {\n if (state === 0 /* State.READ_HEADER */) {\n if (totalLength(chunks) < 1) {\n break;\n }\n const header = concatChunks(chunks, 1);\n isBinary = (header[0] & 0x80) === 0x80;\n expectedLength = header[0] & 0x7f;\n if (expectedLength < 126) {\n state = 3 /* State.READ_PAYLOAD */;\n }\n else if (expectedLength === 126) {\n state = 1 /* State.READ_EXTENDED_LENGTH_16 */;\n }\n else {\n state = 2 /* State.READ_EXTENDED_LENGTH_64 */;\n }\n }\n else if (state === 1 /* State.READ_EXTENDED_LENGTH_16 */) {\n if (totalLength(chunks) < 2) {\n break;\n }\n const headerArray = concatChunks(chunks, 2);\n expectedLength = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length).getUint16(0);\n state = 3 /* State.READ_PAYLOAD */;\n }\n else if (state === 2 /* State.READ_EXTENDED_LENGTH_64 */) {\n if (totalLength(chunks) < 8) {\n break;\n }\n const headerArray = concatChunks(chunks, 8);\n const view = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length);\n const n = view.getUint32(0);\n if (n > Math.pow(2, 53 - 32) - 1) {\n // the maximum safe integer in JavaScript is 2^53 - 1\n controller.enqueue(ERROR_PACKET);\n break;\n }\n expectedLength = n * Math.pow(2, 32) + view.getUint32(4);\n state = 3 /* State.READ_PAYLOAD */;\n }\n else {\n if (totalLength(chunks) < expectedLength) {\n break;\n }\n const data = concatChunks(chunks, expectedLength);\n controller.enqueue(decodePacket(isBinary ? data : TEXT_DECODER.decode(data), binaryType));\n state = 0 /* State.READ_HEADER */;\n }\n if (expectedLength === 0 || expectedLength > maxPayload) {\n controller.enqueue(ERROR_PACKET);\n break;\n }\n }\n },\n });\n}\nexport const protocol = 4;\nexport { encodePacket, encodePayload, decodePacket, decodePayload, };\n","/**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\nexport function Emitter(obj) {\n if (obj) return mixin(obj);\n}\n\n/**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\nfunction mixin(obj) {\n for (var key in Emitter.prototype) {\n obj[key] = Emitter.prototype[key];\n }\n return obj;\n}\n\n/**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.on =\nEmitter.prototype.addEventListener = function(event, fn){\n this._callbacks = this._callbacks || {};\n (this._callbacks['$' + event] = this._callbacks['$' + event] || [])\n .push(fn);\n return this;\n};\n\n/**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.once = function(event, fn){\n function on() {\n this.off(event, on);\n fn.apply(this, arguments);\n }\n\n on.fn = fn;\n this.on(event, on);\n return this;\n};\n\n/**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.off =\nEmitter.prototype.removeListener =\nEmitter.prototype.removeAllListeners =\nEmitter.prototype.removeEventListener = function(event, fn){\n this._callbacks = this._callbacks || {};\n\n // all\n if (0 == arguments.length) {\n this._callbacks = {};\n return this;\n }\n\n // specific event\n var callbacks = this._callbacks['$' + event];\n if (!callbacks) return this;\n\n // remove all handlers\n if (1 == arguments.length) {\n delete this._callbacks['$' + event];\n return this;\n }\n\n // remove specific handler\n var cb;\n for (var i = 0; i < callbacks.length; i++) {\n cb = callbacks[i];\n if (cb === fn || cb.fn === fn) {\n callbacks.splice(i, 1);\n break;\n }\n }\n\n // Remove event specific arrays for event types that no\n // one is subscribed for to avoid memory leak.\n if (callbacks.length === 0) {\n delete this._callbacks['$' + event];\n }\n\n return this;\n};\n\n/**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\nEmitter.prototype.emit = function(event){\n this._callbacks = this._callbacks || {};\n\n var args = new Array(arguments.length - 1)\n , callbacks = this._callbacks['$' + event];\n\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n\n if (callbacks) {\n callbacks = callbacks.slice(0);\n for (var i = 0, len = callbacks.length; i < len; ++i) {\n callbacks[i].apply(this, args);\n }\n }\n\n return this;\n};\n\n// alias used for reserved events (protected method)\nEmitter.prototype.emitReserved = Emitter.prototype.emit;\n\n/**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\nEmitter.prototype.listeners = function(event){\n this._callbacks = this._callbacks || {};\n return this._callbacks['$' + event] || [];\n};\n\n/**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\nEmitter.prototype.hasListeners = function(event){\n return !! this.listeners(event).length;\n};\n","export const nextTick = (() => {\n const isPromiseAvailable = typeof Promise === \"function\" && typeof Promise.resolve === \"function\";\n if (isPromiseAvailable) {\n return (cb) => Promise.resolve().then(cb);\n }\n else {\n return (cb, setTimeoutFn) => setTimeoutFn(cb, 0);\n }\n})();\nexport const globalThisShim = (() => {\n if (typeof self !== \"undefined\") {\n return self;\n }\n else if (typeof window !== \"undefined\") {\n return window;\n }\n else {\n return Function(\"return this\")();\n }\n})();\nexport const defaultBinaryType = \"arraybuffer\";\nexport function createCookieJar() { }\n","import { globalThisShim as globalThis } from \"./globals.node.js\";\nexport function pick(obj, ...attr) {\n return attr.reduce((acc, k) => {\n if (obj.hasOwnProperty(k)) {\n acc[k] = obj[k];\n }\n return acc;\n }, {});\n}\n// Keep a reference to the real timeout functions so they can be used when overridden\nconst NATIVE_SET_TIMEOUT = globalThis.setTimeout;\nconst NATIVE_CLEAR_TIMEOUT = globalThis.clearTimeout;\nexport function installTimerFunctions(obj, opts) {\n if (opts.useNativeTimers) {\n obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThis);\n obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThis);\n }\n else {\n obj.setTimeoutFn = globalThis.setTimeout.bind(globalThis);\n obj.clearTimeoutFn = globalThis.clearTimeout.bind(globalThis);\n }\n}\n// base64 encoded buffers are about 33% bigger (https://en.wikipedia.org/wiki/Base64)\nconst BASE64_OVERHEAD = 1.33;\n// we could also have used `new Blob([obj]).size`, but it isn't supported in IE9\nexport function byteLength(obj) {\n if (typeof obj === \"string\") {\n return utf8Length(obj);\n }\n // arraybuffer or blob\n return Math.ceil((obj.byteLength || obj.size) * BASE64_OVERHEAD);\n}\nfunction utf8Length(str) {\n let c = 0, length = 0;\n for (let i = 0, l = str.length; i < l; i++) {\n c = str.charCodeAt(i);\n if (c < 0x80) {\n length += 1;\n }\n else if (c < 0x800) {\n length += 2;\n }\n else if (c < 0xd800 || c >= 0xe000) {\n length += 3;\n }\n else {\n i++;\n length += 4;\n }\n }\n return length;\n}\n/**\n * Generates a random 8-characters string.\n */\nexport function randomString() {\n return (Date.now().toString(36).substring(3) +\n Math.random().toString(36).substring(2, 5));\n}\n","// imported from https://github.com/galkn/querystring\n/**\n * Compiles a querystring\n * Returns string representation of the object\n *\n * @param {Object}\n * @api private\n */\nexport function encode(obj) {\n let str = '';\n for (let i in obj) {\n if (obj.hasOwnProperty(i)) {\n if (str.length)\n str += '&';\n str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);\n }\n }\n return str;\n}\n/**\n * Parses a simple querystring into an object\n *\n * @param {String} qs\n * @api private\n */\nexport function decode(qs) {\n let qry = {};\n let pairs = qs.split('&');\n for (let i = 0, l = pairs.length; i < l; i++) {\n let pair = pairs[i].split('=');\n qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);\n }\n return qry;\n}\n","import { decodePacket } from \"engine.io-parser\";\nimport { Emitter } from \"@socket.io/component-emitter\";\nimport { installTimerFunctions } from \"./util.js\";\nimport { encode } from \"./contrib/parseqs.js\";\nexport class TransportError extends Error {\n constructor(reason, description, context) {\n super(reason);\n this.description = description;\n this.context = context;\n this.type = \"TransportError\";\n }\n}\nexport class Transport extends Emitter {\n /**\n * Transport abstract constructor.\n *\n * @param {Object} opts - options\n * @protected\n */\n constructor(opts) {\n super();\n this.writable = false;\n installTimerFunctions(this, opts);\n this.opts = opts;\n this.query = opts.query;\n this.socket = opts.socket;\n this.supportsBinary = !opts.forceBase64;\n }\n /**\n * Emits an error.\n *\n * @param {String} reason\n * @param description\n * @param context - the error context\n * @return {Transport} for chaining\n * @protected\n */\n onError(reason, description, context) {\n super.emitReserved(\"error\", new TransportError(reason, description, context));\n return this;\n }\n /**\n * Opens the transport.\n */\n open() {\n this.readyState = \"opening\";\n this.doOpen();\n return this;\n }\n /**\n * Closes the transport.\n */\n close() {\n if (this.readyState === \"opening\" || this.readyState === \"open\") {\n this.doClose();\n this.onClose();\n }\n return this;\n }\n /**\n * Sends multiple packets.\n *\n * @param {Array} packets\n */\n send(packets) {\n if (this.readyState === \"open\") {\n this.write(packets);\n }\n else {\n // this might happen if the transport was silently closed in the beforeunload event handler\n }\n }\n /**\n * Called upon open\n *\n * @protected\n */\n onOpen() {\n this.readyState = \"open\";\n this.writable = true;\n super.emitReserved(\"open\");\n }\n /**\n * Called with data.\n *\n * @param {String} data\n * @protected\n */\n onData(data) {\n const packet = decodePacket(data, this.socket.binaryType);\n this.onPacket(packet);\n }\n /**\n * Called with a decoded packet.\n *\n * @protected\n */\n onPacket(packet) {\n super.emitReserved(\"packet\", packet);\n }\n /**\n * Called upon close.\n *\n * @protected\n */\n onClose(details) {\n this.readyState = \"closed\";\n super.emitReserved(\"close\", details);\n }\n /**\n * Pauses the transport, in order not to lose packets during an upgrade.\n *\n * @param onPause\n */\n pause(onPause) { }\n createUri(schema, query = {}) {\n return (schema +\n \"://\" +\n this._hostname() +\n this._port() +\n this.opts.path +\n this._query(query));\n }\n _hostname() {\n const hostname = this.opts.hostname;\n return hostname.indexOf(\":\") === -1 ? hostname : \"[\" + hostname + \"]\";\n }\n _port() {\n if (this.opts.port &&\n ((this.opts.secure && Number(this.opts.port !== 443)) ||\n (!this.opts.secure && Number(this.opts.port) !== 80))) {\n return \":\" + this.opts.port;\n }\n else {\n return \"\";\n }\n }\n _query(query) {\n const encodedQuery = encode(query);\n return encodedQuery.length ? \"?\" + encodedQuery : \"\";\n }\n}\n","import { Transport } from \"../transport.js\";\nimport { randomString } from \"../util.js\";\nimport { encodePayload, decodePayload } from \"engine.io-parser\";\nexport class Polling extends Transport {\n constructor() {\n super(...arguments);\n this._polling = false;\n }\n get name() {\n return \"polling\";\n }\n /**\n * Opens the socket (triggers polling). We write a PING message to determine\n * when the transport is open.\n *\n * @protected\n */\n doOpen() {\n this._poll();\n }\n /**\n * Pauses polling.\n *\n * @param {Function} onPause - callback upon buffers are flushed and transport is paused\n * @package\n */\n pause(onPause) {\n this.readyState = \"pausing\";\n const pause = () => {\n this.readyState = \"paused\";\n onPause();\n };\n if (this._polling || !this.writable) {\n let total = 0;\n if (this._polling) {\n total++;\n this.once(\"pollComplete\", function () {\n --total || pause();\n });\n }\n if (!this.writable) {\n total++;\n this.once(\"drain\", function () {\n --total || pause();\n });\n }\n }\n else {\n pause();\n }\n }\n /**\n * Starts polling cycle.\n *\n * @private\n */\n _poll() {\n this._polling = true;\n this.doPoll();\n this.emitReserved(\"poll\");\n }\n /**\n * Overloads onData to detect payloads.\n *\n * @protected\n */\n onData(data) {\n const callback = (packet) => {\n // if its the first message we consider the transport open\n if (\"opening\" === this.readyState && packet.type === \"open\") {\n this.onOpen();\n }\n // if its a close packet, we close the ongoing requests\n if (\"close\" === packet.type) {\n this.onClose({ description: \"transport closed by the server\" });\n return false;\n }\n // otherwise bypass onData and handle the message\n this.onPacket(packet);\n };\n // decode payload\n decodePayload(data, this.socket.binaryType).forEach(callback);\n // if an event did not trigger closing\n if (\"closed\" !== this.readyState) {\n // if we got data we're not polling\n this._polling = false;\n this.emitReserved(\"pollComplete\");\n if (\"open\" === this.readyState) {\n this._poll();\n }\n else {\n }\n }\n }\n /**\n * For polling, send a close packet.\n *\n * @protected\n */\n doClose() {\n const close = () => {\n this.write([{ type: \"close\" }]);\n };\n if (\"open\" === this.readyState) {\n close();\n }\n else {\n // in case we're trying to close while\n // handshaking is in progress (GH-164)\n this.once(\"open\", close);\n }\n }\n /**\n * Writes a packets payload.\n *\n * @param {Array} packets - data packets\n * @protected\n */\n write(packets) {\n this.writable = false;\n encodePayload(packets, (data) => {\n this.doWrite(data, () => {\n this.writable = true;\n this.emitReserved(\"drain\");\n });\n });\n }\n /**\n * Generates uri for connection.\n *\n * @private\n */\n uri() {\n const schema = this.opts.secure ? \"https\" : \"http\";\n const query = this.query || {};\n // cache busting is forced\n if (false !== this.opts.timestampRequests) {\n query[this.opts.timestampParam] = randomString();\n }\n if (!this.supportsBinary && !query.sid) {\n query.b64 = 1;\n }\n return this.createUri(schema, query);\n }\n}\n","// imported from https://github.com/component/has-cors\nlet value = false;\ntry {\n value = typeof XMLHttpRequest !== 'undefined' &&\n 'withCredentials' in new XMLHttpRequest();\n}\ncatch (err) {\n // if XMLHttp support is disabled in IE then it will throw\n // when trying to create\n}\nexport const hasCORS = value;\n","import { Polling } from \"./polling.js\";\nimport { Emitter } from \"@socket.io/component-emitter\";\nimport { installTimerFunctions, pick } from \"../util.js\";\nimport { globalThisShim as globalThis } from \"../globals.node.js\";\nimport { hasCORS } from \"../contrib/has-cors.js\";\nfunction empty() { }\nexport class BaseXHR extends Polling {\n /**\n * XHR Polling constructor.\n *\n * @param {Object} opts\n * @package\n */\n constructor(opts) {\n super(opts);\n if (typeof location !== \"undefined\") {\n const isSSL = \"https:\" === location.protocol;\n let port = location.port;\n // some user agents have empty `location.port`\n if (!port) {\n port = isSSL ? \"443\" : \"80\";\n }\n this.xd =\n (typeof location !== \"undefined\" &&\n opts.hostname !== location.hostname) ||\n port !== opts.port;\n }\n }\n /**\n * Sends data.\n *\n * @param {String} data to send.\n * @param {Function} called upon flush.\n * @private\n */\n doWrite(data, fn) {\n const req = this.request({\n method: \"POST\",\n data: data,\n });\n req.on(\"success\", fn);\n req.on(\"error\", (xhrStatus, context) => {\n this.onError(\"xhr post error\", xhrStatus, context);\n });\n }\n /**\n * Starts a poll cycle.\n *\n * @private\n */\n doPoll() {\n const req = this.request();\n req.on(\"data\", this.onData.bind(this));\n req.on(\"error\", (xhrStatus, context) => {\n this.onError(\"xhr poll error\", xhrStatus, context);\n });\n this.pollXhr = req;\n }\n}\nexport class Request extends Emitter {\n /**\n * Request constructor\n *\n * @param {Object} options\n * @package\n */\n constructor(createRequest, uri, opts) {\n super();\n this.createRequest = createRequest;\n installTimerFunctions(this, opts);\n this._opts = opts;\n this._method = opts.method || \"GET\";\n this._uri = uri;\n this._data = undefined !== opts.data ? opts.data : null;\n this._create();\n }\n /**\n * Creates the XHR object and sends the request.\n *\n * @private\n */\n _create() {\n var _a;\n const opts = pick(this._opts, \"agent\", \"pfx\", \"key\", \"passphrase\", \"cert\", \"ca\", \"ciphers\", \"rejectUnauthorized\", \"autoUnref\");\n opts.xdomain = !!this._opts.xd;\n const xhr = (this._xhr = this.createRequest(opts));\n try {\n xhr.open(this._method, this._uri, true);\n try {\n if (this._opts.extraHeaders) {\n // @ts-ignore\n xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);\n for (let i in this._opts.extraHeaders) {\n if (this._opts.extraHeaders.hasOwnProperty(i)) {\n xhr.setRequestHeader(i, this._opts.extraHeaders[i]);\n }\n }\n }\n }\n catch (e) { }\n if (\"POST\" === this._method) {\n try {\n xhr.setRequestHeader(\"Content-type\", \"text/plain;charset=UTF-8\");\n }\n catch (e) { }\n }\n try {\n xhr.setRequestHeader(\"Accept\", \"*/*\");\n }\n catch (e) { }\n (_a = this._opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr);\n // ie6 check\n if (\"withCredentials\" in xhr) {\n xhr.withCredentials = this._opts.withCredentials;\n }\n if (this._opts.requestTimeout) {\n xhr.timeout = this._opts.requestTimeout;\n }\n xhr.onreadystatechange = () => {\n var _a;\n if (xhr.readyState === 3) {\n (_a = this._opts.cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(\n // @ts-ignore\n xhr.getResponseHeader(\"set-cookie\"));\n }\n if (4 !== xhr.readyState)\n return;\n if (200 === xhr.status || 1223 === xhr.status) {\n this._onLoad();\n }\n else {\n // make sure the `error` event handler that's user-set\n // does not throw in the same tick and gets caught here\n this.setTimeoutFn(() => {\n this._onError(typeof xhr.status === \"number\" ? xhr.status : 0);\n }, 0);\n }\n };\n xhr.send(this._data);\n }\n catch (e) {\n // Need to defer since .create() is called directly from the constructor\n // and thus the 'error' event can only be only bound *after* this exception\n // occurs. Therefore, also, we cannot throw here at all.\n this.setTimeoutFn(() => {\n this._onError(e);\n }, 0);\n return;\n }\n if (typeof document !== \"undefined\") {\n this._index = Request.requestsCount++;\n Request.requests[this._index] = this;\n }\n }\n /**\n * Called upon error.\n *\n * @private\n */\n _onError(err) {\n this.emitReserved(\"error\", err, this._xhr);\n this._cleanup(true);\n }\n /**\n * Cleans up house.\n *\n * @private\n */\n _cleanup(fromError) {\n if (\"undefined\" === typeof this._xhr || null === this._xhr) {\n return;\n }\n this._xhr.onreadystatechange = empty;\n if (fromError) {\n try {\n this._xhr.abort();\n }\n catch (e) { }\n }\n if (typeof document !== \"undefined\") {\n delete Request.requests[this._index];\n }\n this._xhr = null;\n }\n /**\n * Called upon load.\n *\n * @private\n */\n _onLoad() {\n const data = this._xhr.responseText;\n if (data !== null) {\n this.emitReserved(\"data\", data);\n this.emitReserved(\"success\");\n this._cleanup();\n }\n }\n /**\n * Aborts the request.\n *\n * @package\n */\n abort() {\n this._cleanup();\n }\n}\nRequest.requestsCount = 0;\nRequest.requests = {};\n/**\n * Aborts pending requests when unloading the window. This is needed to prevent\n * memory leaks (e.g. when using IE) and to ensure that no spurious error is\n * emitted.\n */\nif (typeof document !== \"undefined\") {\n // @ts-ignore\n if (typeof attachEvent === \"function\") {\n // @ts-ignore\n attachEvent(\"onunload\", unloadHandler);\n }\n else if (typeof addEventListener === \"function\") {\n const terminationEvent = \"onpagehide\" in globalThis ? \"pagehide\" : \"unload\";\n addEventListener(terminationEvent, unloadHandler, false);\n }\n}\nfunction unloadHandler() {\n for (let i in Request.requests) {\n if (Request.requests.hasOwnProperty(i)) {\n Request.requests[i].abort();\n }\n }\n}\nconst hasXHR2 = (function () {\n const xhr = newRequest({\n xdomain: false,\n });\n return xhr && xhr.responseType !== null;\n})();\n/**\n * HTTP long-polling based on the built-in `XMLHttpRequest` object.\n *\n * Usage: browser\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest\n */\nexport class XHR extends BaseXHR {\n constructor(opts) {\n super(opts);\n const forceBase64 = opts && opts.forceBase64;\n this.supportsBinary = hasXHR2 && !forceBase64;\n }\n request(opts = {}) {\n Object.assign(opts, { xd: this.xd }, this.opts);\n return new Request(newRequest, this.uri(), opts);\n }\n}\nfunction newRequest(opts) {\n const xdomain = opts.xdomain;\n // XMLHttpRequest can be disabled on IE\n try {\n if (\"undefined\" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {\n return new XMLHttpRequest();\n }\n }\n catch (e) { }\n if (!xdomain) {\n try {\n return new globalThis[[\"Active\"].concat(\"Object\").join(\"X\")](\"Microsoft.XMLHTTP\");\n }\n catch (e) { }\n }\n}\n","import { Transport } from \"../transport.js\";\nimport { pick, randomString } from \"../util.js\";\nimport { encodePacket } from \"engine.io-parser\";\nimport { globalThisShim as globalThis, nextTick } from \"../globals.node.js\";\n// detect ReactNative environment\nconst isReactNative = typeof navigator !== \"undefined\" &&\n typeof navigator.product === \"string\" &&\n navigator.product.toLowerCase() === \"reactnative\";\nexport class BaseWS extends Transport {\n get name() {\n return \"websocket\";\n }\n doOpen() {\n const uri = this.uri();\n const protocols = this.opts.protocols;\n // React Native only supports the 'headers' option, and will print a warning if anything else is passed\n const opts = isReactNative\n ? {}\n : pick(this.opts, \"agent\", \"perMessageDeflate\", \"pfx\", \"key\", \"passphrase\", \"cert\", \"ca\", \"ciphers\", \"rejectUnauthorized\", \"localAddress\", \"protocolVersion\", \"origin\", \"maxPayload\", \"family\", \"checkServerIdentity\");\n if (this.opts.extraHeaders) {\n opts.headers = this.opts.extraHeaders;\n }\n try {\n this.ws = this.createSocket(uri, protocols, opts);\n }\n catch (err) {\n return this.emitReserved(\"error\", err);\n }\n this.ws.binaryType = this.socket.binaryType;\n this.addEventListeners();\n }\n /**\n * Adds event listeners to the socket\n *\n * @private\n */\n addEventListeners() {\n this.ws.onopen = () => {\n if (this.opts.autoUnref) {\n this.ws._socket.unref();\n }\n this.onOpen();\n };\n this.ws.onclose = (closeEvent) => this.onClose({\n description: \"websocket connection closed\",\n context: closeEvent,\n });\n this.ws.onmessage = (ev) => this.onData(ev.data);\n this.ws.onerror = (e) => this.onError(\"websocket error\", e);\n }\n write(packets) {\n this.writable = false;\n // encodePacket efficient as it uses WS framing\n // no need for encodePayload\n for (let i = 0; i < packets.length; i++) {\n const packet = packets[i];\n const lastPacket = i === packets.length - 1;\n encodePacket(packet, this.supportsBinary, (data) => {\n // Sometimes the websocket has already been closed but the browser didn't\n // have a chance of informing us about it yet, in that case send will\n // throw an error\n try {\n this.doWrite(packet, data);\n }\n catch (e) {\n }\n if (lastPacket) {\n // fake drain\n // defer to next tick to allow Socket to clear writeBuffer\n nextTick(() => {\n this.writable = true;\n this.emitReserved(\"drain\");\n }, this.setTimeoutFn);\n }\n });\n }\n }\n doClose() {\n if (typeof this.ws !== \"undefined\") {\n this.ws.onerror = () => { };\n this.ws.close();\n this.ws = null;\n }\n }\n /**\n * Generates uri for connection.\n *\n * @private\n */\n uri() {\n const schema = this.opts.secure ? \"wss\" : \"ws\";\n const query = this.query || {};\n // append timestamp to URI\n if (this.opts.timestampRequests) {\n query[this.opts.timestampParam] = randomString();\n }\n // communicate binary support capabilities\n if (!this.supportsBinary) {\n query.b64 = 1;\n }\n return this.createUri(schema, query);\n }\n}\nconst WebSocketCtor = globalThis.WebSocket || globalThis.MozWebSocket;\n/**\n * WebSocket transport based on the built-in `WebSocket` object.\n *\n * Usage: browser, Node.js (since v21), Deno, Bun\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket\n * @see https://caniuse.com/mdn-api_websocket\n * @see https://nodejs.org/api/globals.html#websocket\n */\nexport class WS extends BaseWS {\n createSocket(uri, protocols, opts) {\n return !isReactNative\n ? protocols\n ? new WebSocketCtor(uri, protocols)\n : new WebSocketCtor(uri)\n : new WebSocketCtor(uri, protocols, opts);\n }\n doWrite(_packet, data) {\n this.ws.send(data);\n }\n}\n","import { Transport } from \"../transport.js\";\nimport { nextTick } from \"../globals.node.js\";\nimport { createPacketDecoderStream, createPacketEncoderStream, } from \"engine.io-parser\";\n/**\n * WebTransport transport based on the built-in `WebTransport` object.\n *\n * Usage: browser, Node.js (with the `@fails-components/webtransport` package)\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/WebTransport\n * @see https://caniuse.com/webtransport\n */\nexport class WT extends Transport {\n get name() {\n return \"webtransport\";\n }\n doOpen() {\n try {\n // @ts-ignore\n this._transport = new WebTransport(this.createUri(\"https\"), this.opts.transportOptions[this.name]);\n }\n catch (err) {\n return this.emitReserved(\"error\", err);\n }\n this._transport.closed\n .then(() => {\n this.onClose();\n })\n .catch((err) => {\n this.onError(\"webtransport error\", err);\n });\n // note: we could have used async/await, but that would require some additional polyfills\n this._transport.ready.then(() => {\n this._transport.createBidirectionalStream().then((stream) => {\n const decoderStream = createPacketDecoderStream(Number.MAX_SAFE_INTEGER, this.socket.binaryType);\n const reader = stream.readable.pipeThrough(decoderStream).getReader();\n const encoderStream = createPacketEncoderStream();\n encoderStream.readable.pipeTo(stream.writable);\n this._writer = encoderStream.writable.getWriter();\n const read = () => {\n reader\n .read()\n .then(({ done, value }) => {\n if (done) {\n return;\n }\n this.onPacket(value);\n read();\n })\n .catch((err) => {\n });\n };\n read();\n const packet = { type: \"open\" };\n if (this.query.sid) {\n packet.data = `{\"sid\":\"${this.query.sid}\"}`;\n }\n this._writer.write(packet).then(() => this.onOpen());\n });\n });\n }\n write(packets) {\n this.writable = false;\n for (let i = 0; i < packets.length; i++) {\n const packet = packets[i];\n const lastPacket = i === packets.length - 1;\n this._writer.write(packet).then(() => {\n if (lastPacket) {\n nextTick(() => {\n this.writable = true;\n this.emitReserved(\"drain\");\n }, this.setTimeoutFn);\n }\n });\n }\n }\n doClose() {\n var _a;\n (_a = this._transport) === null || _a === void 0 ? void 0 : _a.close();\n }\n}\n","import { XHR } from \"./polling-xhr.node.js\";\nimport { WS } from \"./websocket.node.js\";\nimport { WT } from \"./webtransport.js\";\nexport const transports = {\n websocket: WS,\n webtransport: WT,\n polling: XHR,\n};\n","// imported from https://github.com/galkn/parseuri\n/**\n * Parses a URI\n *\n * Note: we could also have used the built-in URL object, but it isn't supported on all platforms.\n *\n * See:\n * - https://developer.mozilla.org/en-US/docs/Web/API/URL\n * - https://caniuse.com/url\n * - https://www.rfc-editor.org/rfc/rfc3986#appendix-B\n *\n * History of the parse() method:\n * - first commit: https://github.com/socketio/socket.io-client/commit/4ee1d5d94b3906a9c052b459f1a818b15f38f91c\n * - export into its own module: https://github.com/socketio/engine.io-client/commit/de2c561e4564efeb78f1bdb1ba39ef81b2822cb3\n * - reimport: https://github.com/socketio/engine.io-client/commit/df32277c3f6d622eec5ed09f493cae3f3391d242\n *\n * @author Steven Levithan <stevenlevithan.com> (MIT license)\n * @api private\n */\nconst re = /^(?:(?![^:@\\/?#]+:[^:@\\/]*@)(http|https|ws|wss):\\/\\/)?((?:(([^:@\\/?#]*)(?::([^:@\\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/;\nconst parts = [\n 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'\n];\nexport function parse(str) {\n if (str.length > 8000) {\n throw \"URI too long\";\n }\n const src = str, b = str.indexOf('['), e = str.indexOf(']');\n if (b != -1 && e != -1) {\n str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);\n }\n let m = re.exec(str || ''), uri = {}, i = 14;\n while (i--) {\n uri[parts[i]] = m[i] || '';\n }\n if (b != -1 && e != -1) {\n uri.source = src;\n uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');\n uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');\n uri.ipv6uri = true;\n }\n uri.pathNames = pathNames(uri, uri['path']);\n uri.queryKey = queryKey(uri, uri['query']);\n return uri;\n}\nfunction pathNames(obj, path) {\n const regx = /\\/{2,9}/g, names = path.replace(regx, \"/\").split(\"/\");\n if (path.slice(0, 1) == '/' || path.length === 0) {\n names.splice(0, 1);\n }\n if (path.slice(-1) == '/') {\n names.splice(names.length - 1, 1);\n }\n return names;\n}\nfunction queryKey(uri, query) {\n const data = {};\n query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {\n if ($1) {\n data[$1] = $2;\n }\n });\n return data;\n}\n","import { transports as DEFAULT_TRANSPORTS } from \"./transports/index.js\";\nimport { installTimerFunctions, byteLength } from \"./util.js\";\nimport { decode } from \"./contrib/parseqs.js\";\nimport { parse } from \"./contrib/parseuri.js\";\nimport { Emitter } from \"@socket.io/component-emitter\";\nimport { protocol } from \"engine.io-parser\";\nimport { createCookieJar, defaultBinaryType, nextTick, } from \"./globals.node.js\";\nconst withEventListeners = typeof addEventListener === \"function\" &&\n typeof removeEventListener === \"function\";\nconst OFFLINE_EVENT_LISTENERS = [];\nif (withEventListeners) {\n // within a ServiceWorker, any event handler for the 'offline' event must be added on the initial evaluation of the\n // script, so we create one single event listener here which will forward the event to the socket instances\n addEventListener(\"offline\", () => {\n OFFLINE_EVENT_LISTENERS.forEach((listener) => listener());\n }, false);\n}\n/**\n * This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established\n * with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.\n *\n * This class comes without upgrade mechanism, which means that it will keep the first low-level transport that\n * successfully establishes the connection.\n *\n * In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.\n *\n * @example\n * import { SocketWithoutUpgrade, WebSocket } from \"engine.io-client\";\n *\n * const socket = new SocketWithoutUpgrade({\n * transports: [WebSocket]\n * });\n *\n * socket.on(\"open\", () => {\n * socket.send(\"hello\");\n * });\n *\n * @see SocketWithUpgrade\n * @see Socket\n */\nexport class SocketWithoutUpgrade extends Emitter {\n /**\n * Socket constructor.\n *\n * @param {String|Object} uri - uri or options\n * @param {Object} opts - options\n */\n constructor(uri, opts) {\n super();\n this.binaryType = defaultBinaryType;\n this.writeBuffer = [];\n this._prevBufferLen = 0;\n this._pingInterval = -1;\n this._pingTimeout = -1;\n this._maxPayload = -1;\n /**\n * The expiration timestamp of the {@link _pingTimeoutTimer} object is tracked, in case the timer is throttled and the\n * callback is not fired on time. This can happen for example when a laptop is suspended or when a phone is locked.\n */\n this._pingTimeoutTime = Infinity;\n if (uri && \"object\" === typeof uri) {\n opts = uri;\n uri = null;\n }\n if (uri) {\n const parsedUri = parse(uri);\n opts.hostname = parsedUri.host;\n opts.secure =\n parsedUri.protocol === \"https\" || parsedUri.protocol === \"wss\";\n opts.port = parsedUri.port;\n if (parsedUri.query)\n opts.query = parsedUri.query;\n }\n else if (opts.host) {\n opts.hostname = parse(opts.host).host;\n }\n installTimerFunctions(this, opts);\n this.secure =\n null != opts.secure\n ? opts.secure\n : typeof location !== \"undefined\" && \"https:\" === location.protocol;\n if (opts.hostname && !opts.port) {\n // if no port is specified manually, use the protocol default\n opts.port = this.secure ? \"443\" : \"80\";\n }\n this.hostname =\n opts.hostname ||\n (typeof location !== \"undefined\" ? location.hostname : \"localhost\");\n this.port =\n opts.port ||\n (typeof location !== \"undefined\" && location.port\n ? location.port\n : this.secure\n ? \"443\"\n : \"80\");\n this.transports = [];\n this._transportsByName = {};\n opts.transports.forEach((t) => {\n const transportName = t.prototype.name;\n this.transports.push(transportName);\n this._transportsByName[transportName] = t;\n });\n this.opts = Object.assign({\n path: \"/engine.io\",\n agent: false,\n withCredentials: false,\n upgrade: true,\n timestampParam: \"t\",\n rememberUpgrade: false,\n addTrailingSlash: true,\n rejectUnauthorized: true,\n perMessageDeflate: {\n threshold: 1024,\n },\n transportOptions: {},\n closeOnBeforeunload: false,\n }, opts);\n this.opts.path =\n this.opts.path.replace(/\\/$/, \"\") +\n (this.opts.addTrailingSlash ? \"/\" : \"\");\n if (typeof this.opts.query === \"string\") {\n this.opts.query = decode(this.opts.query);\n }\n if (withEventListeners) {\n if (this.opts.closeOnBeforeunload) {\n // Firefox closes the connection when the \"beforeunload\" event is emitted but not Chrome. This event listener\n // ensures every browser behaves the same (no \"disconnect\" event at the Socket.IO level when the page is\n // closed/reloaded)\n this._beforeunloadEventListener = () => {\n if (this.transport) {\n // silently close the transport\n this.transport.removeAllListeners();\n this.transport.close();\n }\n };\n addEventListener(\"beforeunload\", this._beforeunloadEventListener, false);\n }\n if (this.hostname !== \"localhost\") {\n this._offlineEventListener = () => {\n this._onClose(\"transport close\", {\n description: \"network connection lost\",\n });\n };\n OFFLINE_EVENT_LISTENERS.push(this._offlineEventListener);\n }\n }\n if (this.opts.withCredentials) {\n this._cookieJar = createCookieJar();\n }\n this._open();\n }\n /**\n * Creates transport of the given type.\n *\n * @param {String} name - transport name\n * @return {Transport}\n * @private\n */\n createTransport(name) {\n const query = Object.assign({}, this.opts.query);\n // append engine.io protocol identifier\n query.EIO = protocol;\n // transport name\n query.transport = name;\n // session id if we already have one\n if (this.id)\n query.sid = this.id;\n const opts = Object.assign({}, this.opts, {\n query,\n socket: this,\n hostname: this.hostname,\n secure: this.secure,\n port: this.port,\n }, this.opts.transportOptions[name]);\n return new this._transportsByName[name](opts);\n }\n /**\n * Initializes transport to use and starts probe.\n *\n * @private\n */\n _open() {\n if (this.transports.length === 0) {\n // Emit error on next tick so it can be listened to\n this.setTimeoutFn(() => {\n this.emitReserved(\"error\", \"No transports available\");\n }, 0);\n return;\n }\n const transportName = this.opts.rememberUpgrade &&\n SocketWithoutUpgrade.priorWebsocketSuccess &&\n this.transports.indexOf(\"websocket\") !== -1\n ? \"websocket\"\n : this.transports[0];\n this.readyState = \"opening\";\n const transport = this.createTransport(transportName);\n transport.open();\n this.setTransport(transport);\n }\n /**\n * Sets the current transport. Disables the existing one (if any).\n *\n * @private\n */\n setTransport(transport) {\n if (this.transport) {\n this.transport.removeAllListeners();\n }\n // set up transport\n this.transport = transport;\n // set up transport listeners\n transport\n .on(\"drain\", this._onDrain.bind(this))\n .on(\"packet\", this._onPacket.bind(this))\n .on(\"error\", this._onError.bind(this))\n .on(\"close\", (reason) => this._onClose(\"transport close\", reason));\n }\n /**\n * Called when connection is deemed open.\n *\n * @private\n */\n onOpen() {\n this.readyState = \"open\";\n SocketWithoutUpgrade.priorWebsocketSuccess =\n \"websocket\" === this.transport.name;\n this.emitReserved(\"open\");\n this.flush();\n }\n /**\n * Handles a packet.\n *\n * @private\n */\n _onPacket(packet) {\n if (\"opening\" === this.readyState ||\n \"open\" === this.readyState ||\n \"closing\" === this.readyState) {\n this.emitReserved(\"packet\", packet);\n // Socket is live - any packet counts\n this.emitReserved(\"heartbeat\");\n switch (packet.type) {\n case \"open\":\n this.onHandshake(JSON.parse(packet.data));\n break;\n case \"ping\":\n this._sendPacket(\"pong\");\n this.emitReserved(\"ping\");\n this.emitReserved(\"pong\");\n this._resetPingTimeout();\n break;\n case \"error\":\n const err = new Error(\"server error\");\n // @ts-ignore\n err.code = packet.data;\n this._onError(err);\n break;\n case \"message\":\n this.emitReserved(\"data\", packet.data);\n this.emitReserved(\"message\", packet.data);\n break;\n }\n }\n else {\n }\n }\n /**\n * Called upon handshake completion.\n *\n * @param {Object} data - handshake obj\n * @private\n */\n onHandshake(data) {\n this.emitReserved(\"handshake\", data);\n this.id = data.sid;\n this.transport.query.sid = data.sid;\n this._pingInterval = data.pingInterval;\n this._pingTimeout = data.pingTimeout;\n this._maxPayload = data.maxPayload;\n this.onOpen();\n // In case open handler closes socket\n if (\"closed\" === this.readyState)\n return;\n this._resetPingTimeout();\n }\n /**\n * Sets and resets ping timeout timer based on server pings.\n *\n * @private\n */\n _resetPingTimeout() {\n this.clearTimeoutFn(this._pingTimeoutTimer);\n const delay = this._pingInterval + this._pingTimeout;\n this._pingTimeoutTime = Date.now() + delay;\n this._pingTimeoutTimer = this.setTimeoutFn(() => {\n this._onClose(\"ping timeout\");\n }, delay);\n if (this.opts.autoUnref) {\n this._pingTimeoutTimer.unref();\n }\n }\n /**\n * Called on `drain` event\n *\n * @private\n */\n _onDrain() {\n this.writeBuffer.splice(0, this._prevBufferLen);\n // setting prevBufferLen = 0 is very important\n // for example, when upgrading, upgrade packet is sent over,\n // and a nonzero prevBufferLen could cause problems on `drain`\n this._prevBufferLen = 0;\n if (0 === this.writeBuffer.length) {\n this.emitReserved(\"drain\");\n }\n else {\n this.flush();\n }\n }\n /**\n * Flush write buffers.\n *\n * @private\n */\n flush() {\n if (\"closed\" !== this.readyState &&\n this.transport.writable &&\n !this.upgrading &&\n this.writeBuffer.length) {\n const packets = this._getWritablePackets();\n this.transport.send(packets);\n // keep track of current length of writeBuffer\n // splice writeBuffer and callbackBuffer on `drain`\n this._prevBufferLen = packets.length;\n this.emitReserved(\"flush\");\n }\n }\n /**\n * Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP\n * long-polling)\n *\n * @private\n */\n _getWritablePackets() {\n const shouldCheckPayloadSize = this._maxPayload &&\n this.transport.name === \"polling\" &&\n this.writeBuffer.length > 1;\n if (!shouldCheckPayloadSize) {\n return this.writeBuffer;\n }\n let payloadSize = 1; // first packet type\n for (let i = 0; i < this.writeBuffer.length; i++) {\n const data = this.writeBuffer[i].data;\n if (data) {\n payloadSize += byteLength(data);\n }\n if (i > 0 && payloadSize > this._maxPayload) {\n return this.writeBuffer.slice(0, i);\n }\n payloadSize += 2; // separator + packet type\n }\n return this.writeBuffer;\n }\n /**\n * Checks whether the heartbeat timer has expired but the socket has not yet been notified.\n *\n * Note: this method is private for now because it does not really fit the WebSocket API, but if we put it in the\n * `write()` method then the message would not be buffered by the Socket.IO client.\n *\n * @return {boolean}\n * @private\n */\n /* private */ _hasPingExpired() {\n if (!this._pingTimeoutTime)\n return true;\n const hasExpired = Date.now() > this._pingTimeoutTime;\n if (hasExpired) {\n this._pingTimeoutTime = 0;\n nextTick(() => {\n this._onClose(\"ping timeout\");\n }, this.setTimeoutFn);\n }\n return hasExpired;\n }\n /**\n * Sends a message.\n *\n * @param {String} msg - message.\n * @param {Object} options.\n * @param {Function} fn - callback function.\n * @return {Socket} for chaining.\n */\n write(msg, options, fn) {\n this._sendPacket(\"message\", msg, options, fn);\n return this;\n }\n /**\n * Sends a message. Alias of {@link Socket#write}.\n *\n * @param {String} msg - message.\n * @param {Object} options.\n * @param {Function} fn - callback function.\n * @return {Socket} for chaining.\n */\n send(msg, options, fn) {\n this._sendPacket(\"message\", msg, options, fn);\n return this;\n }\n /**\n * Sends a packet.\n *\n * @param {String} type: packet type.\n * @param {String} data.\n * @param {Object} options.\n * @param {Function} fn - callback function.\n * @private\n */\n _sendPacket(type, data, options, fn) {\n if (\"function\" === typeof data) {\n fn = data;\n data = undefined;\n }\n if (\"function\" === typeof options) {\n fn = options;\n options = null;\n }\n if (\"closing\" === this.readyState || \"closed\" === this.readyState) {\n return;\n }\n options = options || {};\n options.compress = false !== options.compress;\n const packet = {\n type: type,\n data: data,\n options: options,\n };\n this.emitReserved(\"packetCreate\", packet);\n this.writeBuffer.push(packet);\n if (fn)\n this.once(\"flush\", fn);\n this.flush();\n }\n /**\n * Closes the connection.\n */\n close() {\n const close = () => {\n this._onClose(\"forced close\");\n this.transport.close();\n };\n const cleanupAndClose = () => {\n this.off(\"upgrade\", cleanupAndClose);\n this.off(\"upgradeError\", cleanupAndClose);\n close();\n };\n const waitForUpgrade = () => {\n // wait for upgrade to finish since we can't send packets while pausing a transport\n this.once(\"upgrade\", cleanupAndClose);\n this.once(\"upgradeError\", cleanupAndClose);\n };\n if (\"opening\" === this.readyState || \"open\" === this.readyState) {\n this.readyState = \"closing\";\n if (this.writeBuffer.length) {\n this.once(\"drain\", () => {\n if (this.upgrading) {\n waitForUpgrade();\n }\n else {\n close();\n }\n });\n }\n else if (this.upgrading) {\n waitForUpgrade();\n }\n else {\n close();\n }\n }\n return this;\n }\n /**\n * Called upon transport error\n *\n * @private\n */\n _onError(err) {\n SocketWithoutUpgrade.priorWebsocketSuccess = false;\n if (this.opts.tryAllTransports &&\n this.transports.length > 1 &&\n this.readyState === \"opening\") {\n this.transports.shift();\n return this._open();\n }\n this.emitReserved(\"error\", err);\n this._onClose(\"transport error\", err);\n }\n /**\n * Called upon transport close.\n *\n * @private\n */\n _onClose(reason, description) {\n if (\"opening\" === this.readyState ||\n \"open\" === this.readyState ||\n \"closing\" === this.readyState) {\n // clear timers\n this.clearTimeoutFn(this._pingTimeoutTimer);\n // stop event from firing again for transport\n this.transport.removeAllListeners(\"close\");\n // ensure transport won't stay open\n this.transport.close();\n // ignore further transport communication\n this.transport.removeAllListeners();\n if (withEventListeners) {\n if (this._beforeunloadEventListener) {\n removeEventListener(\"beforeunload\", this._beforeunloadEventListener, false);\n }\n if (this._offlineEventListener) {\n const i = OFFLINE_EVENT_LISTENERS.indexOf(this._offlineEventListener);\n if (i !== -1) {\n OFFLINE_EVENT_LISTENERS.splice(i, 1);\n }\n }\n }\n // set ready state\n this.readyState = \"closed\";\n // clear session id\n this.id = null;\n // emit close event\n this.emitReserved(\"close\", reason, description);\n // clean buffers after, so users can still\n // grab the buffers on `close` event\n this.writeBuffer = [];\n this._prevBufferLen = 0;\n }\n }\n}\nSocketWithoutUpgrade.protocol = protocol;\n/**\n * This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established\n * with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.\n *\n * This class comes with an upgrade mechanism, which means that once the connection is established with the first\n * low-level transport, it will try to upgrade to a better transport.\n *\n * In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.\n *\n * @example\n * import { SocketWithUpgrade, WebSocket } from \"engine.io-client\";\n *\n * const socket = new SocketWithUpgrade({\n * transports: [WebSocket]\n * });\n *\n * socket.on(\"open\", () => {\n * socket.send(\"hello\");\n * });\n *\n * @see SocketWithoutUpgrade\n * @see Socket\n */\nexport class SocketWithUpgrade extends SocketWithoutUpgrade {\n constructor() {\n super(...arguments);\n this._upgrades = [];\n }\n onOpen() {\n super.onOpen();\n if (\"open\" === this.readyState && this.opts.upgrade) {\n for (let i = 0; i < this._upgrades.length; i++) {\n this._probe(this._upgrades[i]);\n }\n }\n }\n /**\n * Probes a transport.\n *\n * @param {String} name - transport name\n * @private\n */\n _probe(name) {\n let transport = this.createTransport(name);\n let failed = false;\n SocketWithoutUpgrade.priorWebsocketSuccess = false;\n const onTransportOpen = () => {\n if (failed)\n return;\n transport.send([{ type: \"ping\", data: \"probe\" }]);\n transport.once(\"packet\", (msg) => {\n if (failed)\n return;\n if (\"pong\" === msg.type && \"probe\" === msg.data) {\n this.upgrading = true;\n this.emitReserved(\"upgrading\", transport);\n if (!transport)\n return;\n SocketWithoutUpgrade.priorWebsocketSuccess =\n \"websocket\" === transport.name;\n this.transport.pause(() => {\n if (failed)\n return;\n if (\"closed\" === this.readyState)\n return;\n cleanup();\n this.setTransport(transport);\n transport.send([{ type: \"upgrade\" }]);\n this.emitReserved(\"upgrade\", transport);\n transport = null;\n this.upgrading = false;\n this.flush();\n });\n }\n else {\n const err = new Error(\"probe error\");\n // @ts-ignore\n err.transport = transport.name;\n this.emitReserved(\"upgradeError\", err);\n }\n });\n };\n function freezeTransport() {\n if (failed)\n return;\n // Any callback called by transport should be ignored since now\n failed = true;\n cleanup();\n transport.close();\n transport = null;\n }\n // Handle any error that happens while probing\n const onerror = (err) => {\n const error = new Error(\"probe error: \" + err);\n // @ts-ignore\n error.transport = transport.name;\n freezeTransport();\n this.emitReserved(\"upgradeError\", error);\n };\n function onTransportClose() {\n onerror(\"transport closed\");\n }\n // When the socket is closed while we're probing\n function onclose() {\n onerror(\"socket closed\");\n }\n // When the socket is upgraded while we're probing\n function onupgrade(to) {\n if (transport && to.name !== transport.name) {\n freezeTransport();\n }\n }\n // Remove all listeners on the transport and on self\n const cleanup = () => {\n transport.removeListener(\"open\", onTransportOpen);\n transport.removeListener(\"error\", onerror);\n transport.removeListener(\"close\", onTransportClose);\n this.off(\"close\", onclose);\n this.off(\"upgrading\", onupgrade);\n };\n transport.once(\"open\", onTransportOpen);\n transport.once(\"error\", onerror);\n transport.once(\"close\", onTransportClose);\n this.once(\"close\", onclose);\n this.once(\"upgrading\", onupgrade);\n if (this._upgrades.indexOf(\"webtransport\") !== -1 &&\n name !== \"webtransport\") {\n // favor WebTransport\n this.setTimeoutFn(() => {\n if (!failed) {\n transport.open();\n }\n }, 200);\n }\n else {\n transport.open();\n }\n }\n onHandshake(data) {\n this._upgrades = this._filterUpgrades(data.upgrades);\n super.onHandshake(data);\n }\n /**\n * Filters upgrades, returning only those matching client transports.\n *\n * @param {Array} upgrades - server upgrades\n * @private\n */\n _filterUpgrades(upgrades) {\n const filteredUpgrades = [];\n for (let i = 0; i < upgrades.length; i++) {\n if (~this.transports.indexOf(upgrades[i]))\n filteredUpgrades.push(upgrades[i]);\n }\n return filteredUpgrades;\n }\n}\n/**\n * This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established\n * with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.\n *\n * This class comes with an upgrade mechanism, which means that once the connection is established with the first\n * low-level transport, it will try to upgrade to a better transport.\n *\n * @example\n * import { Socket } from \"engine.io-client\";\n *\n * const socket = new Socket();\n *\n * socket.on(\"open\", () => {\n * socket.send(\"hello\");\n * });\n *\n * @see SocketWithoutUpgrade\n * @see SocketWithUpgrade\n */\nexport class Socket extends SocketWithUpgrade {\n constructor(uri, opts = {}) {\n const o = typeof uri === \"object\" ? uri : opts;\n if (!o.transports ||\n (o.transports && typeof o.transports[0] === \"string\")) {\n o.transports = (o.transports || [\"polling\", \"websocket\", \"webtransport\"])\n .map((transportName) => DEFAULT_TRANSPORTS[transportName])\n .filter((t) => !!t);\n }\n super(uri, o);\n }\n}\n","import { parse } from \"engine.io-client\";\n/**\n * URL parser.\n *\n * @param uri - url\n * @param path - the request path of the connection\n * @param loc - An object meant to mimic window.location.\n * Defaults to window.location.\n * @public\n */\nexport function url(uri, path = \"\", loc) {\n let obj = uri;\n // default to window.location\n loc = loc || (typeof location !== \"undefined\" && location);\n if (null == uri)\n uri = loc.protocol + \"//\" + loc.host;\n // relative path support\n if (typeof uri === \"string\") {\n if (\"/\" === uri.charAt(0)) {\n if (\"/\" === uri.charAt(1)) {\n uri = loc.protocol + uri;\n }\n else {\n uri = loc.host + uri;\n }\n }\n if (!/^(https?|wss?):\\/\\//.test(uri)) {\n if (\"undefined\" !== typeof loc) {\n uri = loc.protocol + \"//\" + uri;\n }\n else {\n uri = \"https://\" + uri;\n }\n }\n // parse\n obj = parse(uri);\n }\n // make sure we treat `localhost:80` and `localhost` equally\n if (!obj.port) {\n if (/^(http|ws)$/.test(obj.protocol)) {\n obj.port = \"80\";\n }\n else if (/^(http|ws)s$/.test(obj.protocol)) {\n obj.port = \"443\";\n }\n }\n obj.path = obj.path || \"/\";\n const ipv6 = obj.host.indexOf(\":\") !== -1;\n const host = ipv6 ? \"[\" + obj.host + \"]\" : obj.host;\n // define unique id\n obj.id = obj.protocol + \"://\" + host + \":\" + obj.port + path;\n // define href\n obj.href =\n obj.protocol +\n \"://\" +\n host +\n (loc && loc.port === obj.port ? \"\" : \":\" + obj.port);\n return obj;\n}\n","const withNativeArrayBuffer = typeof ArrayBuffer === \"function\";\nconst isView = (obj) => {\n return typeof ArrayBuffer.isView === \"function\"\n ? ArrayBuffer.isView(obj)\n : obj.buffer instanceof ArrayBuffer;\n};\nconst toString = Object.prototype.toString;\nconst withNativeBlob = typeof Blob === \"function\" ||\n (typeof Blob !== \"undefined\" &&\n toString.call(Blob) === \"[object BlobConstructor]\");\nconst withNativeFile = typeof File === \"function\" ||\n (typeof File !== \"undefined\" &&\n toString.call(File) === \"[object FileConstructor]\");\n/**\n * Returns true if obj is a Buffer, an ArrayBuffer, a Blob or a File.\n *\n * @private\n */\nexport function isBinary(obj) {\n return ((withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj))) ||\n (withNativeBlob && obj instanceof Blob) ||\n (withNativeFile && obj instanceof File));\n}\nexport function hasBinary(obj, toJSON) {\n if (!obj || typeof obj !== \"object\") {\n return false;\n }\n if (Array.isArray(obj)) {\n for (let i = 0, l = obj.length; i < l; i++) {\n if (hasBinary(obj[i])) {\n return true;\n }\n }\n return false;\n }\n if (isBinary(obj)) {\n return true;\n }\n if (obj.toJSON &&\n typeof obj.toJSON === \"function\" &&\n arguments.length === 1) {\n return hasBinary(obj.toJSON(), true);\n }\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) {\n return true;\n }\n }\n return false;\n}\n","import { isBinary } from \"./is-binary.js\";\n/**\n * Replaces every Buffer | ArrayBuffer | Blob | File in packet with a numbered placeholder.\n *\n * @param {Object} packet - socket.io event packet\n * @return {Object} with deconstructed packet and list of buffers\n * @public\n */\nexport function deconstructPacket(packet) {\n const buffers = [];\n const packetData = packet.data;\n const pack = packet;\n pack.data = _deconstructPacket(packetData, buffers);\n pack.attachments = buffers.length; // number of binary 'attachments'\n return { packet: pack, buffers: buffers };\n}\nfunction _deconstructPacket(data, buffers) {\n if (!data)\n return data;\n if (isBinary(data)) {\n const placeholder = { _placeholder: true, num: buffers.length };\n buffers.push(data);\n return placeholder;\n }\n else if (Array.isArray(data)) {\n const newData = new Array(data.length);\n for (let i = 0; i < data.length; i++) {\n newData[i] = _deconstructPacket(data[i], buffers);\n }\n return newData;\n }\n else if (typeof data === \"object\" && !(data instanceof Date)) {\n const newData = {};\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n newData[key] = _deconstructPacket(data[key], buffers);\n }\n }\n return newData;\n }\n return data;\n}\n/**\n * Reconstructs a binary packet from its placeholder packet and buffers\n *\n * @param {Object} packet - event packet with placeholders\n * @param {Array} buffers - binary buffers to put in placeholder positions\n * @return {Object} reconstructed packet\n * @public\n */\nexport function reconstructPacket(packet, buffers) {\n packet.data = _reconstructPacket(packet.data, buffers);\n delete packet.attachments; // no longer useful\n return packet;\n}\nfunction _reconstructPacket(data, buffers) {\n if (!data)\n return data;\n if (data && data._placeholder === true) {\n const isIndexValid = typeof data.num === \"number\" &&\n data.num >= 0 &&\n data.num < buffers.length;\n if (isIndexValid) {\n return buffers[data.num]; // appropriate buffer (should be natural order anyway)\n }\n else {\n throw new Error(\"illegal attachments\");\n }\n }\n else if (Array.isArray(data)) {\n for (let i = 0; i < data.length; i++) {\n data[i] = _reconstructPacket(data[i], buffers);\n }\n }\n else if (typeof data === \"object\") {\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n data[key] = _reconstructPacket(data[key], buffers);\n }\n }\n }\n return data;\n}\n","import { Emitter } from \"@socket.io/component-emitter\";\nimport { deconstructPacket, reconstructPacket } from \"./binary.js\";\nimport { isBinary, hasBinary } from \"./is-binary.js\";\n/**\n * These strings must not be used as event names, as they have a special meaning.\n */\nconst RESERVED_EVENTS = [\n \"connect\",\n \"connect_error\",\n \"disconnect\",\n \"disconnecting\",\n \"newListener\",\n \"removeListener\", // used by the Node.js EventEmitter\n];\n/**\n * Protocol version.\n *\n * @public\n */\nexport const protocol = 5;\nexport var PacketType;\n(function (PacketType) {\n PacketType[PacketType[\"CONNECT\"] = 0] = \"CONNECT\";\n PacketType[PacketType[\"DISCONNECT\"] = 1] = \"DISCONNECT\";\n PacketType[PacketType[\"EVENT\"] = 2] = \"EVENT\";\n PacketType[PacketType[\"ACK\"] = 3] = \"ACK\";\n PacketType[PacketType[\"CONNECT_ERROR\"] = 4] = \"CONNECT_ERROR\";\n PacketType[PacketType[\"BINARY_EVENT\"] = 5] = \"BINARY_EVENT\";\n PacketType[PacketType[\"BINARY_ACK\"] = 6] = \"BINARY_ACK\";\n})(PacketType || (PacketType = {}));\n/**\n * A socket.io Encoder instance\n */\nexport class Encoder {\n /**\n * Encoder constructor\n *\n * @param {function} replacer - custom replacer to pass down to JSON.parse\n */\n constructor(replacer) {\n this.replacer = replacer;\n }\n /**\n * Encode a packet as a single string if non-binary, or as a\n * buffer sequence, depending on packet type.\n *\n * @param {Object} obj - packet object\n */\n encode(obj) {\n if (obj.type === PacketType.EVENT || obj.type === PacketType.ACK) {\n if (hasBinary(obj)) {\n return this.encodeAsBinary({\n type: obj.type === PacketType.EVENT\n ? PacketType.BINARY_EVENT\n : PacketType.BINARY_ACK,\n nsp: obj.nsp,\n data: obj.data,\n id: obj.id,\n });\n }\n }\n return [this.encodeAsString(obj)];\n }\n /**\n * Encode packet as string.\n */\n encodeAsString(obj) {\n // first is type\n let str = \"\" + obj.type;\n // attachments if we have them\n if (obj.type === PacketType.BINARY_EVENT ||\n obj.type === PacketType.BINARY_ACK) {\n str += obj.attachments + \"-\";\n }\n // if we have a namespace other than `/`\n // we append it followed by a comma `,`\n if (obj.nsp && \"/\" !== obj.nsp) {\n str += obj.nsp + \",\";\n }\n // immediately followed by the id\n if (null != obj.id) {\n str += obj.id;\n }\n // json data\n if (null != obj.data) {\n str += JSON.stringify(obj.data, this.replacer);\n }\n return str;\n }\n /**\n * Encode packet as 'buffer sequence' by removing blobs, and\n * deconstructing packet into object with placeholders and\n * a list of buffers.\n */\n encodeAsBinary(obj) {\n const deconstruction = deconstructPacket(obj);\n const pack = this.encodeAsString(deconstruction.packet);\n const buffers = deconstruction.buffers;\n buffers.unshift(pack); // add packet info to beginning of data list\n return buffers; // write all the buffers\n }\n}\n// see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript\nfunction isObject(value) {\n return Object.prototype.toString.call(value) === \"[object Object]\";\n}\n/**\n * A socket.io Decoder instance\n *\n * @return {Object} decoder\n */\nexport class Decoder extends Emitter {\n /**\n * Decoder constructor\n *\n * @param {function} reviver - custom reviver to pass down to JSON.stringify\n */\n constructor(reviver) {\n super();\n this.reviver = reviver;\n }\n /**\n * Decodes an encoded packet string into packet JSON.\n *\n * @param {String} obj - encoded packet\n */\n add(obj) {\n let packet;\n if (typeof obj === \"string\") {\n if (this.reconstructor) {\n throw new Error(\"got plaintext data when reconstructing a packet\");\n }\n packet = this.decodeString(obj);\n const isBinaryEvent = packet.type === PacketType.BINARY_EVENT;\n if (isBinaryEvent || packet.type === PacketType.BINARY_ACK) {\n packet.type = isBinaryEvent ? PacketType.EVENT : PacketType.ACK;\n // binary packet's json\n this.reconstructor = new BinaryReconstructor(packet);\n // no attachments, labeled binary but no binary data to follow\n if (packet.attachments === 0) {\n super.emitReserved(\"decoded\", packet);\n }\n }\n else {\n // non-binary full packet\n super.emitReserved(\"decoded\", packet);\n }\n }\n else if (isBinary(obj) || obj.base64) {\n // raw binary data\n if (!this.reconstructor) {\n throw new Error(\"got binary data when not reconstructing a packet\");\n }\n else {\n packet = this.reconstructor.takeBinaryData(obj);\n if (packet) {\n // received final buffer\n this.reconstructor = null;\n super.emitReserved(\"decoded\", packet);\n }\n }\n }\n else {\n throw new Error(\"Unknown type: \" + obj);\n }\n }\n /**\n * Decode a packet String (JSON data)\n *\n * @param {String} str\n * @return {Object} packet\n */\n decodeString(str) {\n let i = 0;\n // look up type\n const p = {\n type: Number(str.charAt(0)),\n };\n if (PacketType[p.type] === undefined) {\n throw new Error(\"unknown packet type \" + p.type);\n }\n // look up attachments if type binary\n if (p.type === PacketType.BINARY_EVENT ||\n p.type === PacketType.BINARY_ACK) {\n const start = i + 1;\n while (str.charAt(++i) !== \"-\" && i != str.length) { }\n const buf = str.substring(start, i);\n if (buf != Number(buf) || str.charAt(i) !== \"-\") {\n throw new Error(\"Illegal attachments\");\n }\n p.attachments = Number(buf);\n }\n // look up namespace (if any)\n if (\"/\" === str.charAt(i + 1)) {\n const start = i + 1;\n while (++i) {\n const c = str.charAt(i);\n if (\",\" === c)\n break;\n if (i === str.length)\n break;\n }\n p.nsp = str.substring(start, i);\n }\n else {\n p.nsp = \"/\";\n }\n // look up id\n const next = str.charAt(i + 1);\n if (\"\" !== next && Number(next) == next) {\n const start = i + 1;\n while (++i) {\n const c = str.charAt(i);\n if (null == c || Number(c) != c) {\n --i;\n break;\n }\n if (i === str.length)\n break;\n }\n p.id = Number(str.substring(start, i + 1));\n }\n // look up json data\n if (str.charAt(++i)) {\n const payload = this.tryParse(str.substr(i));\n if (Decoder.isPayloadValid(p.type, payload)) {\n p.data = payload;\n }\n else {\n throw new Error(\"invalid payload\");\n }\n }\n return p;\n }\n tryParse(str) {\n try {\n return JSON.parse(str, this.reviver);\n }\n catch (e) {\n return false;\n }\n }\n static isPayloadValid(type, payload) {\n switch (type) {\n case PacketType.CONNECT:\n return isObject(payload);\n case PacketType.DISCONNECT:\n return payload === undefined;\n case PacketType.CONNECT_ERROR:\n return typeof payload === \"string\" || isObject(payload);\n case PacketType.EVENT:\n case PacketType.BINARY_EVENT:\n return (Array.isArray(payload) &&\n (typeof payload[0] === \"number\" ||\n (typeof payload[0] === \"string\" &&\n RESERVED_EVENTS.indexOf(payload[0]) === -1)));\n case PacketType.ACK:\n case PacketType.BINARY_ACK:\n return Array.isArray(payload);\n }\n }\n /**\n * Deallocates a parser's resources\n */\n destroy() {\n if (this.reconstructor) {\n this.reconstructor.finishedReconstruction();\n this.reconstructor = null;\n }\n }\n}\n/**\n * A manager of a binary event's 'buffer sequence'. Should\n * be constructed whenever a packet of type BINARY_EVENT is\n * decoded.\n *\n * @param {Object} packet\n * @return {BinaryReconstructor} initialized reconstructor\n */\nclass BinaryReconstructor {\n constructor(packet) {\n this.packet = packet;\n this.buffers = [];\n this.reconPack = packet;\n }\n /**\n * Method to be called when binary data received from connection\n * after a BINARY_EVENT packet.\n *\n * @param {Buffer | ArrayBuffer} binData - the raw binary data received\n * @return {null | Object} returns null if more binary data is expected or\n * a reconstructed packet object if all buffers have been received.\n */\n takeBinaryData(binData) {\n this.buffers.push(binData);\n if (this.buffers.length === this.reconPack.attachments) {\n // done with buffer list\n const packet = reconstructPacket(this.reconPack, this.buffers);\n this.finishedReconstruction();\n return packet;\n }\n return null;\n }\n /**\n * Cleans up binary packet reconstruction variables.\n */\n finishedReconstruction() {\n this.reconPack = null;\n this.buffers = [];\n }\n}\n","export function on(obj, ev, fn) {\n obj.on(ev, fn);\n return function subDestroy() {\n obj.off(ev, fn);\n };\n}\n","import { PacketType } from \"socket.io-parser\";\nimport { on } from \"./on.js\";\nimport { Emitter, } from \"@socket.io/component-emitter\";\n/**\n * Internal events.\n * These events can't be emitted by the user.\n */\nconst RESERVED_EVENTS = Object.freeze({\n connect: 1,\n connect_error: 1,\n disconnect: 1,\n disconnecting: 1,\n // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener\n newListener: 1,\n removeListener: 1,\n});\n/**\n * A Socket is the fundamental class for interacting with the server.\n *\n * A Socket belongs to a certain Namespace (by default /) and uses an underlying {@link Manager} to communicate.\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"connect\", () => {\n * console.log(\"connected\");\n * });\n *\n * // send an event to the server\n * socket.emit(\"foo\", \"bar\");\n *\n * socket.on(\"foobar\", () => {\n * // an event was received from the server\n * });\n *\n * // upon disconnection\n * socket.on(\"disconnect\", (reason) => {\n * console.log(`disconnected due to ${reason}`);\n * });\n */\nexport class Socket extends Emitter {\n /**\n * `Socket` constructor.\n */\n constructor(io, nsp, opts) {\n super();\n /**\n * Whether the socket is currently connected to the server.\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"connect\", () => {\n * console.log(socket.connected); // true\n * });\n *\n * socket.on(\"disconnect\", () => {\n * console.log(socket.connected); // false\n * });\n */\n this.connected = false;\n /**\n * Whether the connection state was recovered after a temporary disconnection. In that case, any missed packets will\n * be transmitted by the server.\n */\n this.recovered = false;\n /**\n * Buffer for packets received before the CONNECT packet\n */\n this.receiveBuffer = [];\n /**\n * Buffer for packets that will be sent once the socket is connected\n */\n this.sendBuffer = [];\n /**\n * The queue of packets to be sent with retry in case of failure.\n *\n * Packets are sent one by one, each waiting for the server acknowledgement, in order to guarantee the delivery order.\n * @private\n */\n this._queue = [];\n /**\n * A sequence to generate the ID of the {@link QueuedPacket}.\n * @private\n */\n this._queueSeq = 0;\n this.ids = 0;\n /**\n * A map containing acknowledgement handlers.\n *\n * The `withError` attribute is used to differentiate handlers that accept an error as first argument:\n *\n * - `socket.emit(\"test\", (err, value) => { ... })` with `ackTimeout` option\n * - `socket.timeout(5000).emit(\"test\", (err, value) => { ... })`\n * - `const value = await socket.emitWithAck(\"test\")`\n *\n * From those that don't:\n *\n * - `socket.emit(\"test\", (value) => { ... });`\n *\n * In the first case, the handlers will be called with an error when:\n *\n * - the timeout is reached\n * - the socket gets disconnected\n *\n * In the second case, the handlers will be simply discarded upon disconnection, since the client will never receive\n * an acknowledgement from the server.\n *\n * @private\n */\n this.acks = {};\n this.flags = {};\n this.io = io;\n this.nsp = nsp;\n if (opts && opts.auth) {\n this.auth = opts.auth;\n }\n this._opts = Object.assign({}, opts);\n if (this.io._autoConnect)\n this.open();\n }\n /**\n * Whether the socket is currently disconnected\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"connect\", () => {\n * console.log(socket.disconnected); // false\n * });\n *\n * socket.on(\"disconnect\", () => {\n * console.log(socket.disconnected); // true\n * });\n */\n get disconnected() {\n return !this.connected;\n }\n /**\n * Subscribe to open, close and packet events\n *\n * @private\n */\n subEvents() {\n if (this.subs)\n return;\n const io = this.io;\n this.subs = [\n on(io, \"open\", this.onopen.bind(this)),\n on(io, \"packet\", this.onpacket.bind(this)),\n on(io, \"error\", this.onerror.bind(this)),\n on(io, \"close\", this.onclose.bind(this)),\n ];\n }\n /**\n * Whether the Socket will try to reconnect when its Manager connects or reconnects.\n *\n * @example\n * const socket = io();\n *\n * console.log(socket.active); // true\n *\n * socket.on(\"disconnect\", (reason) => {\n * if (reason === \"io server disconnect\") {\n * // the disconnection was initiated by the server, you need to manually reconnect\n * console.log(socket.active); // false\n * }\n * // else the socket will automatically try to reconnect\n * console.log(socket.active); // true\n * });\n */\n get active() {\n return !!this.subs;\n }\n /**\n * \"Opens\" the socket.\n *\n * @example\n * const socket = io({\n * autoConnect: false\n * });\n *\n * socket.connect();\n */\n connect() {\n if (this.connected)\n return this;\n this.subEvents();\n if (!this.io[\"_reconnecting\"])\n this.io.open(); // ensure open\n if (\"open\" === this.io._readyState)\n this.onopen();\n return this;\n }\n /**\n * Alias for {@link connect()}.\n */\n open() {\n return this.connect();\n }\n /**\n * Sends a `message` event.\n *\n * This method mimics the WebSocket.send() method.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send\n *\n * @example\n * socket.send(\"hello\");\n *\n * // this is equivalent to\n * socket.emit(\"message\", \"hello\");\n *\n * @return self\n */\n send(...args) {\n args.unshift(\"message\");\n this.emit.apply(this, args);\n return this;\n }\n /**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @example\n * socket.emit(\"hello\", \"world\");\n *\n * // all serializable datastructures are supported (no need to call JSON.stringify)\n * socket.emit(\"hello\", 1, \"2\", { 3: [\"4\"], 5: Uint8Array.from([6]) });\n *\n * // with an acknowledgement from the server\n * socket.emit(\"hello\", \"world\", (val) => {\n * // ...\n * });\n *\n * @return self\n */\n emit(ev, ...args) {\n var _a, _b, _c;\n if (RESERVED_EVENTS.hasOwnProperty(ev)) {\n throw new Error('\"' + ev.toString() + '\" is a reserved event name');\n }\n args.unshift(ev);\n if (this._opts.retries && !this.flags.fromQueue && !this.flags.volatile) {\n this._addToQueue(args);\n return this;\n }\n const packet = {\n type: PacketType.EVENT,\n data: args,\n };\n packet.options = {};\n packet.options.compress = this.flags.compress !== false;\n // event ack callback\n if (\"function\" === typeof args[args.length - 1]) {\n const id = this.ids++;\n const ack = args.pop();\n this._registerAckCallback(id, ack);\n packet.id = id;\n }\n const isTransportWritable = (_b = (_a = this.io.engine) === null || _a === void 0 ? void 0 : _a.transport) === null || _b === void 0 ? void 0 : _b.writable;\n const isConnected = this.connected && !((_c = this.io.engine) === null || _c === void 0 ? void 0 : _c._hasPingExpired());\n const discardPacket = this.flags.volatile && !isTransportWritable;\n if (discardPacket) {\n }\n else if (isConnected) {\n this.notifyOutgoingListeners(packet);\n this.packet(packet);\n }\n else {\n this.sendBuffer.push(packet);\n }\n this.flags = {};\n return this;\n }\n /**\n * @private\n */\n _registerAckCallback(id, ack) {\n var _a;\n const timeout = (_a = this.flags.timeout) !== null && _a !== void 0 ? _a : this._opts.ackTimeout;\n if (timeout === undefined) {\n this.acks[id] = ack;\n return;\n }\n // @ts-ignore\n const timer = this.io.setTimeoutFn(() => {\n delete this.acks[id];\n for (let i = 0; i < this.sendBuffer.length; i++) {\n if (this.sendBuffer[i].id === id) {\n this.sendBuffer.splice(i, 1);\n }\n }\n ack.call(this, new Error(\"operation has timed out\"));\n }, timeout);\n const fn = (...args) => {\n // @ts-ignore\n this.io.clearTimeoutFn(timer);\n ack.apply(this, args);\n };\n fn.withError = true;\n this.acks[id] = fn;\n }\n /**\n * Emits an event and waits for an acknowledgement\n *\n * @example\n * // without timeout\n * const response = await socket.emitWithAck(\"hello\", \"world\");\n *\n * // with a specific timeout\n * try {\n * const response = await socket.timeout(1000).emitWithAck(\"hello\", \"world\");\n * } catch (err) {\n * // the server did not acknowledge the event in the given delay\n * }\n *\n * @return a Promise that will be fulfilled when the server acknowledges the event\n */\n emitWithAck(ev, ...args) {\n return new Promise((resolve, reject) => {\n const fn = (arg1, arg2) => {\n return arg1 ? reject(arg1) : resolve(arg2);\n };\n fn.withError = true;\n args.push(fn);\n this.emit(ev, ...args);\n });\n }\n /**\n * Add the packet to the queue.\n * @param args\n * @private\n */\n _addToQueue(args) {\n let ack;\n if (typeof args[args.length - 1] === \"function\") {\n ack = args.pop();\n }\n const packet = {\n id: this._queueSeq++,\n tryCount: 0,\n pending: false,\n args,\n flags: Object.assign({ fromQueue: true }, this.flags),\n };\n args.push((err, ...responseArgs) => {\n if (packet !== this._queue[0]) {\n }\n const hasError = err !== null;\n if (hasError) {\n if (packet.tryCount > this._opts.retries) {\n this._queue.shift();\n if (ack) {\n ack(err);\n }\n }\n }\n else {\n this._queue.shift();\n if (ack) {\n ack(null, ...responseArgs);\n }\n }\n packet.pending = false;\n return this._drainQueue();\n });\n this._queue.push(packet);\n this._drainQueue();\n }\n /**\n * Send the first packet of the queue, and wait for an acknowledgement from the server.\n * @param force - whether to resend a packet that has not been acknowledged yet\n *\n * @private\n */\n _drainQueue(force = false) {\n if (!this.connected || this._queue.length === 0) {\n return;\n }\n const packet = this._queue[0];\n if (packet.pending && !force) {\n return;\n }\n packet.pending = true;\n packet.tryCount++;\n this.flags = packet.flags;\n this.emit.apply(this, packet.args);\n }\n /**\n * Sends a packet.\n *\n * @param packet\n * @private\n */\n packet(packet) {\n packet.nsp = this.nsp;\n this.io._packet(packet);\n }\n /**\n * Called upon engine `open`.\n *\n * @private\n */\n onopen() {\n if (typeof this.auth == \"function\") {\n this.auth((data) => {\n this._sendConnectPacket(data);\n });\n }\n else {\n this._sendConnectPacket(this.auth);\n }\n }\n /**\n * Sends a CONNECT packet to initiate the Socket.IO session.\n *\n * @param data\n * @private\n */\n _sendConnectPacket(data) {\n this.packet({\n type: PacketType.CONNECT,\n data: this._pid\n ? Object.assign({ pid: this._pid, offset: this._lastOffset }, data)\n : data,\n });\n }\n /**\n * Called upon engine or manager `error`.\n *\n * @param err\n * @private\n */\n onerror(err) {\n if (!this.connected) {\n this.emitReserved(\"connect_error\", err);\n }\n }\n /**\n * Called upon engine `close`.\n *\n * @param reason\n * @param description\n * @private\n */\n onclose(reason, description) {\n this.connected = false;\n delete this.id;\n this.emitReserved(\"disconnect\", reason, description);\n this._clearAcks();\n }\n /**\n * Clears the acknowledgement handlers upon disconnection, since the client will never receive an acknowledgement from\n * the server.\n *\n * @private\n */\n _clearAcks() {\n Object.keys(this.acks).forEach((id) => {\n const isBuffered = this.sendBuffer.some((packet) => String(packet.id) === id);\n if (!isBuffered) {\n // note: handlers that do not accept an error as first argument are ignored here\n const ack = this.acks[id];\n delete this.acks[id];\n if (ack.withError) {\n ack.call(this, new Error(\"socket has been disconnected\"));\n }\n }\n });\n }\n /**\n * Called with socket packet.\n *\n * @param packet\n * @private\n */\n onpacket(packet) {\n const sameNamespace = packet.nsp === this.nsp;\n if (!sameNamespace)\n return;\n switch (packet.type) {\n case PacketType.CONNECT:\n if (packet.data && packet.data.sid) {\n this.onconnect(packet.data.sid, packet.data.pid);\n }\n else {\n this.emitReserved(\"connect_error\", new Error(\"It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)\"));\n }\n break;\n case PacketType.EVENT:\n case PacketType.BINARY_EVENT:\n this.onevent(packet);\n break;\n case PacketType.ACK:\n case PacketType.BINARY_ACK:\n this.onack(packet);\n break;\n case PacketType.DISCONNECT:\n this.ondisconnect();\n break;\n case PacketType.CONNECT_ERROR:\n this.destroy();\n const err = new Error(packet.data.message);\n // @ts-ignore\n err.data = packet.data.data;\n this.emitReserved(\"connect_error\", err);\n break;\n }\n }\n /**\n * Called upon a server event.\n *\n * @param packet\n * @private\n */\n onevent(packet) {\n const args = packet.data || [];\n if (null != packet.id) {\n args.push(this.ack(packet.id));\n }\n if (this.connected) {\n this.emitEvent(args);\n }\n else {\n this.receiveBuffer.push(Object.freeze(args));\n }\n }\n emitEvent(args) {\n if (this._anyListeners && this._anyListeners.length) {\n const listeners = this._anyListeners.slice();\n for (const listener of listeners) {\n listener.apply(this, args);\n }\n }\n super.emit.apply(this, args);\n if (this._pid && args.length && typeof args[args.length - 1] === \"string\") {\n this._lastOffset = args[args.length - 1];\n }\n }\n /**\n * Produces an ack callback to emit with an event.\n *\n * @private\n */\n ack(id) {\n const self = this;\n let sent = false;\n return function (...args) {\n // prevent double callbacks\n if (sent)\n return;\n sent = true;\n self.packet({\n type: PacketType.ACK,\n id: id,\n data: args,\n });\n };\n }\n /**\n * Called upon a server acknowledgement.\n *\n * @param packet\n * @private\n */\n onack(packet) {\n const ack = this.acks[packet.id];\n if (typeof ack !== \"function\") {\n return;\n }\n delete this.acks[packet.id];\n // @ts-ignore FIXME ack is incorrectly inferred as 'never'\n if (ack.withError) {\n packet.data.unshift(null);\n }\n // @ts-ignore\n ack.apply(this, packet.data);\n }\n /**\n * Called upon server connect.\n *\n * @private\n */\n onconnect(id, pid) {\n this.id = id;\n this.recovered = pid && this._pid === pid;\n this._pid = pid; // defined only if connection state recovery is enabled\n this.connected = true;\n this.emitBuffered();\n this._drainQueue(true);\n this.emitReserved(\"connect\");\n }\n /**\n * Emit buffered events (received and emitted).\n *\n * @private\n */\n emitBuffered() {\n this.receiveBuffer.forEach((args) => this.emitEvent(args));\n this.receiveBuffer = [];\n this.sendBuffer.forEach((packet) => {\n this.notifyOutgoingListeners(packet);\n this.packet(packet);\n });\n this.sendBuffer = [];\n }\n /**\n * Called upon server disconnect.\n *\n * @private\n */\n ondisconnect() {\n this.destroy();\n this.onclose(\"io server disconnect\");\n }\n /**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @private\n */\n destroy() {\n if (this.subs) {\n // clean subscriptions to avoid reconnections\n this.subs.forEach((subDestroy) => subDestroy());\n this.subs = undefined;\n }\n this.io[\"_destroy\"](this);\n }\n /**\n * Disconnects the socket manually. In that case, the socket will not try to reconnect.\n *\n * If this is the last active Socket instance of the {@link Manager}, the low-level connection will be closed.\n *\n * @example\n * const socket = io();\n *\n * socket.on(\"disconnect\", (reason) => {\n * // console.log(reason); prints \"io client disconnect\"\n * });\n *\n * socket.disconnect();\n *\n * @return self\n */\n disconnect() {\n if (this.connected) {\n this.packet({ type: PacketType.DISCONNECT });\n }\n // remove socket from pool\n this.destroy();\n if (this.connected) {\n // fire events\n this.onclose(\"io client disconnect\");\n }\n return this;\n }\n /**\n * Alias for {@link disconnect()}.\n *\n * @return self\n */\n close() {\n return this.disconnect();\n }\n /**\n * Sets the compress flag.\n *\n * @example\n * socket.compress(false).emit(\"hello\");\n *\n * @param compress - if `true`, compresses the sending data\n * @return self\n */\n compress(compress) {\n this.flags.compress = compress;\n return this;\n }\n /**\n * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not\n * ready to send messages.\n *\n * @example\n * socket.volatile.emit(\"hello\"); // the server may or may not receive it\n *\n * @returns self\n */\n get volatile() {\n this.flags.volatile = true;\n return this;\n }\n /**\n * Sets a modifier for a subsequent event emission that the callback will be called with an error when the\n * given number of milliseconds have elapsed without an acknowledgement from the server:\n *\n * @example\n * socket.timeout(5000).emit(\"my-event\", (err) => {\n * if (err) {\n * // the server did not acknowledge the event in the given delay\n * }\n * });\n *\n * @returns self\n */\n timeout(timeout) {\n this.flags.timeout = timeout;\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback.\n *\n * @example\n * socket.onAny((event, ...args) => {\n * console.log(`got ${event}`);\n * });\n *\n * @param listener\n */\n onAny(listener) {\n this._anyListeners = this._anyListeners || [];\n this._anyListeners.push(listener);\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback. The listener is added to the beginning of the listeners array.\n *\n * @example\n * socket.prependAny((event, ...args) => {\n * console.log(`got event ${event}`);\n * });\n *\n * @param listener\n */\n prependAny(listener) {\n this._anyListeners = this._anyListeners || [];\n this._anyListeners.unshift(listener);\n return this;\n }\n /**\n * Removes the listener that will be fired when any event is emitted.\n *\n * @example\n * const catchAllListener = (event, ...args) => {\n * console.log(`got event ${event}`);\n * }\n *\n * socket.onAny(catchAllListener);\n *\n * // remove a specific listener\n * socket.offAny(catchAllListener);\n *\n * // or remove all listeners\n * socket.offAny();\n *\n * @param listener\n */\n offAny(listener) {\n if (!this._anyListeners) {\n return this;\n }\n if (listener) {\n const listeners = this._anyListeners;\n for (let i = 0; i < listeners.length; i++) {\n if (listener === listeners[i]) {\n listeners.splice(i, 1);\n return this;\n }\n }\n }\n else {\n this._anyListeners = [];\n }\n return this;\n }\n /**\n * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,\n * e.g. to remove listeners.\n */\n listenersAny() {\n return this._anyListeners || [];\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback.\n *\n * Note: acknowledgements sent to the server are not included.\n *\n * @example\n * socket.onAnyOutgoing((event, ...args) => {\n * console.log(`sent event ${event}`);\n * });\n *\n * @param listener\n */\n onAnyOutgoing(listener) {\n this._anyOutgoingListeners = this._anyOutgoingListeners || [];\n this._anyOutgoingListeners.push(listener);\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback. The listener is added to the beginning of the listeners array.\n *\n * Note: acknowledgements sent to the server are not included.\n *\n * @example\n * socket.prependAnyOutgoing((event, ...args) => {\n * console.log(`sent event ${event}`);\n * });\n *\n * @param listener\n */\n prependAnyOutgoing(listener) {\n this._anyOutgoingListeners = this._anyOutgoingListeners || [];\n this._anyOutgoingListeners.unshift(listener);\n return this;\n }\n /**\n * Removes the listener that will be fired when any event is emitted.\n *\n * @example\n * const catchAllListener = (event, ...args) => {\n * console.log(`sent event ${event}`);\n * }\n *\n * socket.onAnyOutgoing(catchAllListener);\n *\n * // remove a specific listener\n * socket.offAnyOutgoing(catchAllListener);\n *\n * // or remove all listeners\n * socket.offAnyOutgoing();\n *\n * @param [listener] - the catch-all listener (optional)\n */\n offAnyOutgoing(listener) {\n if (!this._anyOutgoingListeners) {\n return this;\n }\n if (listener) {\n const listeners = this._anyOutgoingListeners;\n for (let i = 0; i < listeners.length; i++) {\n if (listener === listeners[i]) {\n listeners.splice(i, 1);\n return this;\n }\n }\n }\n else {\n this._anyOutgoingListeners = [];\n }\n return this;\n }\n /**\n * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,\n * e.g. to remove listeners.\n */\n listenersAnyOutgoing() {\n return this._anyOutgoingListeners || [];\n }\n /**\n * Notify the listeners for each packet sent\n *\n * @param packet\n *\n * @private\n */\n notifyOutgoingListeners(packet) {\n if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) {\n const listeners = this._anyOutgoingListeners.slice();\n for (const listener of listeners) {\n listener.apply(this, packet.data);\n }\n }\n }\n}\n","/**\n * Initialize backoff timer with `opts`.\n *\n * - `min` initial timeout in milliseconds [100]\n * - `max` max timeout [10000]\n * - `jitter` [0]\n * - `factor` [2]\n *\n * @param {Object} opts\n * @api public\n */\nexport function Backoff(opts) {\n opts = opts || {};\n this.ms = opts.min || 100;\n this.max = opts.max || 10000;\n this.factor = opts.factor || 2;\n this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;\n this.attempts = 0;\n}\n/**\n * Return the backoff duration.\n *\n * @return {Number}\n * @api public\n */\nBackoff.prototype.duration = function () {\n var ms = this.ms * Math.pow(this.factor, this.attempts++);\n if (this.jitter) {\n var rand = Math.random();\n var deviation = Math.floor(rand * this.jitter * ms);\n ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;\n }\n return Math.min(ms, this.max) | 0;\n};\n/**\n * Reset the number of attempts.\n *\n * @api public\n */\nBackoff.prototype.reset = function () {\n this.attempts = 0;\n};\n/**\n * Set the minimum duration\n *\n * @api public\n */\nBackoff.prototype.setMin = function (min) {\n this.ms = min;\n};\n/**\n * Set the maximum duration\n *\n * @api public\n */\nBackoff.prototype.setMax = function (max) {\n this.max = max;\n};\n/**\n * Set the jitter\n *\n * @api public\n */\nBackoff.prototype.setJitter = function (jitter) {\n this.jitter = jitter;\n};\n","import { Socket as Engine, installTimerFunctions, nextTick, } from \"engine.io-client\";\nimport { Socket } from \"./socket.js\";\nimport * as parser from \"socket.io-parser\";\nimport { on } from \"./on.js\";\nimport { Backoff } from \"./contrib/backo2.js\";\nimport { Emitter, } from \"@socket.io/component-emitter\";\nexport class Manager extends Emitter {\n constructor(uri, opts) {\n var _a;\n super();\n this.nsps = {};\n this.subs = [];\n if (uri && \"object\" === typeof uri) {\n opts = uri;\n uri = undefined;\n }\n opts = opts || {};\n opts.path = opts.path || \"/socket.io\";\n this.opts = opts;\n installTimerFunctions(this, opts);\n this.reconnection(opts.reconnection !== false);\n this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);\n this.reconnectionDelay(opts.reconnectionDelay || 1000);\n this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);\n this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5);\n this.backoff = new Backoff({\n min: this.reconnectionDelay(),\n max: this.reconnectionDelayMax(),\n jitter: this.randomizationFactor(),\n });\n this.timeout(null == opts.timeout ? 20000 : opts.timeout);\n this._readyState = \"closed\";\n this.uri = uri;\n const _parser = opts.parser || parser;\n this.encoder = new _parser.Encoder();\n this.decoder = new _parser.Decoder();\n this._autoConnect = opts.autoConnect !== false;\n if (this._autoConnect)\n this.open();\n }\n reconnection(v) {\n if (!arguments.length)\n return this._reconnection;\n this._reconnection = !!v;\n if (!v) {\n this.skipReconnect = true;\n }\n return this;\n }\n reconnectionAttempts(v) {\n if (v === undefined)\n return this._reconnectionAttempts;\n this._reconnectionAttempts = v;\n return this;\n }\n reconnectionDelay(v) {\n var _a;\n if (v === undefined)\n return this._reconnectionDelay;\n this._reconnectionDelay = v;\n (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMin(v);\n return this;\n }\n randomizationFactor(v) {\n var _a;\n if (v === undefined)\n return this._randomizationFactor;\n this._randomizationFactor = v;\n (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setJitter(v);\n return this;\n }\n reconnectionDelayMax(v) {\n var _a;\n if (v === undefined)\n return this._reconnectionDelayMax;\n this._reconnectionDelayMax = v;\n (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMax(v);\n return this;\n }\n timeout(v) {\n if (!arguments.length)\n return this._timeout;\n this._timeout = v;\n return this;\n }\n /**\n * Starts trying to reconnect if reconnection is enabled and we have not\n * started reconnecting yet\n *\n * @private\n */\n maybeReconnectOnOpen() {\n // Only try to reconnect if it's the first time we're connecting\n if (!this._reconnecting &&\n this._reconnection &&\n this.backoff.attempts === 0) {\n // keeps reconnection from firing twice for the same reconnection loop\n this.reconnect();\n }\n }\n /**\n * Sets the current transport `socket`.\n *\n * @param {Function} fn - optional, callback\n * @return self\n * @public\n */\n open(fn) {\n if (~this._readyState.indexOf(\"open\"))\n return this;\n this.engine = new Engine(this.uri, this.opts);\n const socket = this.engine;\n const self = this;\n this._readyState = \"opening\";\n this.skipReconnect = false;\n // emit `open`\n const openSubDestroy = on(socket, \"open\", function () {\n self.onopen();\n fn && fn();\n });\n const onError = (err) => {\n this.cleanup();\n this._readyState = \"closed\";\n this.emitReserved(\"error\", err);\n if (fn) {\n fn(err);\n }\n else {\n // Only do this if there is no fn to handle the error\n this.maybeReconnectOnOpen();\n }\n };\n // emit `error`\n const errorSub = on(socket, \"error\", onError);\n if (false !== this._timeout) {\n const timeout = this._timeout;\n // set timer\n const timer = this.setTimeoutFn(() => {\n openSubDestroy();\n onError(new Error(\"timeout\"));\n socket.close();\n }, timeout);\n if (this.opts.autoUnref) {\n timer.unref();\n }\n this.subs.push(() => {\n this.clearTimeoutFn(timer);\n });\n }\n this.subs.push(openSubDestroy);\n this.subs.push(errorSub);\n return this;\n }\n /**\n * Alias for open()\n *\n * @return self\n * @public\n */\n connect(fn) {\n return this.open(fn);\n }\n /**\n * Called upon transport open.\n *\n * @private\n */\n onopen() {\n // clear old subs\n this.cleanup();\n // mark as open\n this._readyState = \"open\";\n this.emitReserved(\"open\");\n // add new subs\n const socket = this.engine;\n this.subs.push(on(socket, \"ping\", this.onping.bind(this)), on(socket, \"data\", this.ondata.bind(this)), on(socket, \"error\", this.onerror.bind(this)), on(socket, \"close\", this.onclose.bind(this)), \n // @ts-ignore\n on(this.decoder, \"decoded\", this.ondecoded.bind(this)));\n }\n /**\n * Called upon a ping.\n *\n * @private\n */\n onping() {\n this.emitReserved(\"ping\");\n }\n /**\n * Called with data.\n *\n * @private\n */\n ondata(data) {\n try {\n this.decoder.add(data);\n }\n catch (e) {\n this.onclose(\"parse error\", e);\n }\n }\n /**\n * Called when parser fully decodes a packet.\n *\n * @private\n */\n ondecoded(packet) {\n // the nextTick call prevents an exception in a user-provided event listener from triggering a disconnection due to a \"parse error\"\n nextTick(() => {\n this.emitReserved(\"packet\", packet);\n }, this.setTimeoutFn);\n }\n /**\n * Called upon socket error.\n *\n * @private\n */\n onerror(err) {\n this.emitReserved(\"error\", err);\n }\n /**\n * Creates a new socket for the given `nsp`.\n *\n * @return {Socket}\n * @public\n */\n socket(nsp, opts) {\n let socket = this.nsps[nsp];\n if (!socket) {\n socket = new Socket(this, nsp, opts);\n this.nsps[nsp] = socket;\n }\n else if (this._autoConnect && !socket.active) {\n socket.connect();\n }\n return socket;\n }\n /**\n * Called upon a socket close.\n *\n * @param socket\n * @private\n */\n _destroy(socket) {\n const nsps = Object.keys(this.nsps);\n for (const nsp of nsps) {\n const socket = this.nsps[nsp];\n if (socket.active) {\n return;\n }\n }\n this._close();\n }\n /**\n * Writes a packet.\n *\n * @param packet\n * @private\n */\n _packet(packet) {\n const encodedPackets = this.encoder.encode(packet);\n for (let i = 0; i < encodedPackets.length; i++) {\n this.engine.write(encodedPackets[i], packet.options);\n }\n }\n /**\n * Clean up transport subscriptions and packet buffer.\n *\n * @private\n */\n cleanup() {\n this.subs.forEach((subDestroy) => subDestroy());\n this.subs.length = 0;\n this.decoder.destroy();\n }\n /**\n * Close the current socket.\n *\n * @private\n */\n _close() {\n this.skipReconnect = true;\n this._reconnecting = false;\n this.onclose(\"forced close\");\n }\n /**\n * Alias for close()\n *\n * @private\n */\n disconnect() {\n return this._close();\n }\n /**\n * Called when:\n *\n * - the low-level engine is closed\n * - the parser encountered a badly formatted packet\n * - all sockets are disconnected\n *\n * @private\n */\n onclose(reason, description) {\n var _a;\n this.cleanup();\n (_a = this.engine) === null || _a === void 0 ? void 0 : _a.close();\n this.backoff.reset();\n this._readyState = \"closed\";\n this.emitReserved(\"close\", reason, description);\n if (this._reconnection && !this.skipReconnect) {\n this.reconnect();\n }\n }\n /**\n * Attempt a reconnection.\n *\n * @private\n */\n reconnect() {\n if (this._reconnecting || this.skipReconnect)\n return this;\n const self = this;\n if (this.backoff.attempts >= this._reconnectionAttempts) {\n this.backoff.reset();\n this.emitReserved(\"reconnect_failed\");\n this._reconnecting = false;\n }\n else {\n const delay = this.backoff.duration();\n this._reconnecting = true;\n const timer = this.setTimeoutFn(() => {\n if (self.skipReconnect)\n return;\n this.emitReserved(\"reconnect_attempt\", self.backoff.attempts);\n // check again for the case socket closed in above events\n if (self.skipReconnect)\n return;\n self.open((err) => {\n if (err) {\n self._reconnecting = false;\n self.reconnect();\n this.emitReserved(\"reconnect_error\", err);\n }\n else {\n self.onreconnect();\n }\n });\n }, delay);\n if (this.opts.autoUnref) {\n timer.unref();\n }\n this.subs.push(() => {\n this.clearTimeoutFn(timer);\n });\n }\n }\n /**\n * Called upon successful reconnect.\n *\n * @private\n */\n onreconnect() {\n const attempt = this.backoff.attempts;\n this._reconnecting = false;\n this.backoff.reset();\n this.emitReserved(\"reconnect\", attempt);\n }\n}\n","import { url } from \"./url.js\";\nimport { Manager } from \"./manager.js\";\nimport { Socket } from \"./socket.js\";\n/**\n * Managers cache.\n */\nconst cache = {};\nfunction lookup(uri, opts) {\n if (typeof uri === \"object\") {\n opts = uri;\n uri = undefined;\n }\n opts = opts || {};\n const parsed = url(uri, opts.path || \"/socket.io\");\n const source = parsed.source;\n const id = parsed.id;\n const path = parsed.path;\n const sameNamespace = cache[id] && path in cache[id][\"nsps\"];\n const newConnection = opts.forceNew ||\n opts[\"force new connection\"] ||\n false === opts.multiplex ||\n sameNamespace;\n let io;\n if (newConnection) {\n io = new Manager(source, opts);\n }\n else {\n if (!cache[id]) {\n cache[id] = new Manager(source, opts);\n }\n io = cache[id];\n }\n if (parsed.query && !opts.query) {\n opts.query = parsed.queryKey;\n }\n return io.socket(parsed.path, opts);\n}\n// so that \"lookup\" can be used both as a function (e.g. `io(...)`) and as a\n// namespace (e.g. `io.connect(...)`), for backward compatibility\nObject.assign(lookup, {\n Manager,\n Socket,\n io: lookup,\n connect: lookup,\n});\n/**\n * Protocol version.\n *\n * @public\n */\nexport { protocol } from \"socket.io-parser\";\n/**\n * Expose constructors for standalone build.\n *\n * @public\n */\nexport { Manager, Socket, lookup as io, lookup as connect, lookup as default, };\nexport { Fetch, NodeXHR, XHR, NodeWebSocket, WebSocket, WebTransport, } from \"engine.io-client\";\n","import { FRAGMENT_MP4_FILENAME } from '@watchparty/shared';\nimport { getRuntimeServerOrigin } from './config';\n\n/** Derive the fMP4 and index URLs for a given mediaId. Single source of truth used by Room and usePlaylistPreBuffer. */\nexport function resolveMediaUrls(mediaId: string): { mediaUrl: string; indexUrl: string } {\n const origin = getRuntimeServerOrigin();\n const root = `${origin}/media/${mediaId}`.replace(/\\\\/g, '/');\n return { mediaUrl: `${root}/${FRAGMENT_MP4_FILENAME}`, indexUrl: `${root}/index.json` };\n}\n\n/** Resolve a media-relative asset path (e.g. a playlist poster/cover) to a full URL. */\nexport function resolveMediaAsset(relPath: string): string {\n const origin = getRuntimeServerOrigin();\n return `${origin}/media/${relPath}`.replace(/\\\\/g, '/');\n}\n\n/**\n * The card image for one playlist/tierlist entry.\n *\n * An explicit `thumbnail` always wins — that is what flat-layout ingest writes\n * into playlist.json, and it may point anywhere. Everything else falls back to\n * `<mediaId>/poster.jpg`, which is the SAME convention that ingest's\n * `copy_poster` already uses; `scripts/fetch-posters.py` fills it in for the\n * entries ingest never covered (subfolder-layout clips, and anime SERIES, which\n * have no video of their own to grab a frame from).\n *\n * Deriving it by convention rather than writing paths into every playlist.json\n * means a poster appears the moment the file exists — no manifest to re-emit,\n * and no migration for the playlists that already ship a thumbnail. A missing\n * file is a 404 the caller hides, which is exactly the blank tile it replaced.\n */\nexport function resolveCardImage(mediaId: string, thumbnail?: string): string {\n return resolveMediaAsset(thumbnail ?? `${mediaId}/poster.jpg`);\n}\n","/**\n * Client for the global tierlist.\n *\n * HTTP, not socket events: the board is not room state, so it must be readable\n * from anywhere — including before a room socket exists. The only socket\n * involvement is the `tierlist_updated` ping that tells this client to re-fetch\n * (see `wireTierlist` in socket.ts).\n */\nimport { getRuntimeServerOrigin } from './config';\nimport { resolveCardImage } from './mediaUrls';\nimport { useAppStore } from './store';\nimport { debug, warn, errorFields } from './debug';\nimport type { TTierlistSnapshotOut, TTier } from '@watchparty/shared';\n\nfunction url(path: string): string {\n return `${getRuntimeServerOrigin()}${path}`.replace(/\\\\/g, '/');\n}\n\n/**\n * Pull the board.\n *\n * `adoptDraft` decides whether the fetched `myBoard` replaces what is on screen.\n * True when this client opens the board or saves its own; false for a refresh\n * caused by someone ELSE saving — their result must land live, but overwriting\n * a draft mid-drag would move cards under the user's hands.\n */\nexport async function refreshTierlist(adoptDraft: boolean): Promise<TTierlistSnapshotOut | null> {\n try {\n const res = await fetch(url('/api/tierlist'));\n if (!res.ok) {\n warn('tierlist', 'Board fetch failed', { status: res.status });\n return null;\n }\n const snap = (await res.json()) as TTierlistSnapshotOut;\n useAppStore.getState().setTierlistSnapshot(snap, adoptDraft);\n debug('tierlist', 'Board loaded', {\n items: snap.items.length, voters: snap.voterCount, placed: snap.placed.length,\n });\n return snap;\n } catch (err: unknown) {\n warn('tierlist', 'Board fetch threw', errorFields(err));\n return null;\n }\n}\n\n/**\n * Pull the poster images into the browser cache.\n *\n * Called on INTENT — hovering or focusing the toolbar button — not on mount.\n * The board is ~7 images of ~50KB; fetching them for everyone who never opens\n * it would put ~400KB in front of the media fetches during a load, and this\n * codebase has a long history of exactly that kind of opportunistic prefetch\n * starving playback (see usePlaylistPreBuffer). Intent-triggered costs nothing\n * until someone reaches for it, and by the time the click lands the images are\n * already cached, so the board opens populated instead of filling in.\n *\n * Fire-and-forget and idempotent: the browser dedupes in-flight requests for\n * the same URL, so repeated hovers cost nothing.\n */\nlet warmed = false;\nexport function warmTierlistPosters(): void {\n if (warmed || typeof Image === 'undefined') return;\n const snap = useAppStore.getState().tierlist;\n if (!snap || snap.items.length === 0) return; // nothing known yet; the mount fetch will land first\n warmed = true;\n for (const item of snap.items) {\n const img = new Image();\n img.decoding = 'async';\n img.src = resolveCardImage(item.id, item.thumbnail);\n }\n debug('tierlist', 'Warming posters', { count: snap.items.length });\n}\n\n/**\n * Publish this client's draft.\n *\n * The response is the freshly-recomputed board, so the saver sees their own\n * effect without waiting for the broadcast to come back around. Everyone else\n * is updated by the `tierlist_updated` ping the server emits.\n */\nexport async function saveTierlist(\n board: Partial<Record<TTier, string[]>>,\n): Promise<boolean> {\n const store = useAppStore.getState();\n store.setTierlistSaving(true);\n try {\n // Only the board: the server names a voter by their account and draws their\n // character from prefs-api, so nothing about the person travels with it.\n const res = await fetch(url('/api/tierlist/me'), {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ board }),\n });\n if (!res.ok) {\n warn('tierlist', 'Save rejected', { status: res.status });\n return false;\n }\n const snap = (await res.json()) as TTierlistSnapshotOut;\n useAppStore.getState().setTierlistSnapshot(snap, true);\n return true;\n } catch (err: unknown) {\n warn('tierlist', 'Save threw', errorFields(err));\n return false;\n } finally {\n useAppStore.getState().setTierlistSaving(false);\n }\n}\n","import { CHARACTER_ORDER, displayNameFor, isCharacterName } from './characters';\nimport { useAppStore } from './store';\nimport { debug, warn } from './debug';\n\n/**\n * The server refused our sprite (`conflict / sprite_taken`): take the next free\n * character and ask for it.\n *\n * Two rules, both because this retry is AUTOMATIC, not a choice the person made:\n * - a custom name is kept. Only a missing or character-default name takes the\n * new character's default;\n * - the result is NOT saved. This used to write `user`-scope prefs, so one\n * retry on a second browser rewrote the account's saved name and sprite\n * everywhere. Nothing in watchparty saves an identity now: the character is\n * chosen in the fleet settings popout (lib/avatar.ts).\n *\n * Returns the payload to emit, or null when no character is free.\n */\nexport function retryTakenSprite(): { name: string; sprite: string } | null {\n const st = useAppStore.getState();\n const used = new Set(Object.values(st.roster).map(r => r.sprite).filter(Boolean));\n const free = CHARACTER_ORDER.find(c => !used.has(c));\n if (!free) {\n warn('socket', 'sprite_taken: no available sprites to retry with');\n return null;\n }\n const keepName = !!st.name && !isCharacterName(st.name);\n const name = keepName ? st.name : displayNameFor(free);\n debug('socket', 'sprite_taken: retrying with next available', { from: st.sprite, to: free, name, keptCustomName: keepName });\n st.setSessionIdentity(name, free);\n return { name, sprite: free };\n}\n\n/**\n * Whether a `sprite_taken` refusal is already settled, so retrying would only\n * ask for a sprite nobody needs: there is no seat for us in the roster yet\n * (the first presence brings the server's pick), or the seat's sprite is the\n * one we hold.\n */\nexport function isStaleSpriteRefusal(myClientId: string | undefined): boolean {\n const st = useAppStore.getState();\n const seat = myClientId ? st.roster[myClientId] : undefined;\n return !seat || (!!seat.sprite && seat.sprite === st.sprite);\n}\n","// src/constants.ts\nvar PREFS_API_BASE = \"https://hadoku.me/prefs\";\n\n// src/avatar-contract.ts\nvar AVATAR_SOURCES = [\"sprite\", \"discord\", \"steam\", \"upload\"];\nvar LINK_PROVIDERS = [\"discord\", \"steam\"];\nvar LINK_MESSAGE_TYPE = \"hadoku-avatar-link\";\nvar RESOLVE_MAX_IDS = 100;\nvar SPRITE_ID_PATTERN = /^[a-z][a-z0-9-]{0,31}$/;\nvar LINK_CALLBACK_PATH = \"/account/link/callback\";\n\n// src/avatar.ts\nvar LINK_WINDOW_NAME = \"hadoku-avatar-link\";\nvar LINK_POPUP_MARK = \"hadoku-avatar-link-popup\";\nfunction markPopup(on) {\n try {\n if (on) sessionStorage.setItem(LINK_POPUP_MARK, \"1\");\n else sessionStorage.removeItem(LINK_POPUP_MARK);\n } catch {\n }\n}\nvar AvatarError = class extends Error {\n constructor(status, message) {\n super(message);\n this.status = status;\n this.name = \"AvatarError\";\n }\n status;\n};\nasync function readJson(res) {\n if (!res.ok) {\n const body = await res.json().catch(() => null);\n throw new AvatarError(res.status, body?.message ?? `HTTP ${res.status}`);\n }\n return await res.json();\n}\nfunction createAvatarClient(opts = {}) {\n const base = `${opts.baseUrl ?? PREFS_API_BASE}/api/v1/_avatar`;\n const f = opts.fetch ?? fetch;\n const call = (path, init = {}) => f(`${base}${path}`, { credentials: \"include\", ...init }).then(readJson);\n const send = (path, method, body) => call(path, {\n method,\n ...body === void 0 ? {} : { headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify(body) }\n });\n const getSettings = () => call(\"\");\n async function linkInPopup(provider) {\n markPopup(true);\n const popup = window.open(\"about:blank\", LINK_WINDOW_NAME, \"popup,width=520,height=760\");\n markPopup(false);\n if (!popup)\n throw new AvatarError(0, \"The sign-in window was blocked: allow pop-ups for hadoku.me\");\n let authorizeUrl;\n try {\n ({ authorizeUrl } = await send(`/link/${provider}`, \"POST\", {}));\n } catch (err) {\n popup.close();\n throw err;\n }\n popup.location.href = authorizeUrl;\n return new Promise((resolve, reject) => {\n const channel = new BroadcastChannel(LINK_MESSAGE_TYPE);\n let settled = false;\n const finish = (failure) => {\n if (settled) return;\n settled = true;\n channel.close();\n clearInterval(closedPoll);\n clearTimeout(giveUp);\n if (failure) reject(new AvatarError(400, failure));\n else getSettings().then(resolve, reject);\n };\n channel.onmessage = (e) => {\n if (e.data?.type !== LINK_MESSAGE_TYPE) return;\n finish(e.data.ok ? void 0 : e.data.error);\n };\n const closedPoll = setInterval(() => {\n if (!popup.closed) return;\n clearInterval(closedPoll);\n setTimeout(() => finish(), 1500);\n }, 500);\n const giveUp = setTimeout(() => finish(), 10 * 60 * 1e3);\n });\n }\n return {\n /** The caller's settings, including the resolved avatar. */\n get: getSettings,\n /** Pick a source. 409 when it is not available (not linked, nothing uploaded). */\n choose: (source) => send(\"\", \"PUT\", { source }),\n /** Set the source, the character, or both in one write. */\n update: (u) => send(\"\", \"PUT\", u),\n /**\n * Begin linking. Navigate the browser to the returned URL; the provider\n * returns it to hadoku.me/account/link/callback, which completes the link.\n * Call this only from the user's own click: nothing is fetched from\n * Discord or Steam before they ask.\n */\n startLink: (provider) => send(`/link/${provider}`, \"POST\", {}),\n /**\n * Link in a popup, so the page never navigates. Call it straight from the\n * click handler: the window is opened before the first await, which is\n * what popup blockers allow. Resolves with fresh settings once the popup\n * reports back or is closed (closing is not an error: the settings say\n * whether the link landed). Rejects only when the popup could not open\n * or the link could not start.\n */\n linkInPopup: (provider) => linkInPopup(provider),\n /** Finish a link from the callback page's query string (`location.search`). */\n completeLink: (query) => send(\"/link/complete\", \"POST\", { query: query.replace(/^\\?/, \"\") }),\n /** Delete the linked id and its cached avatar URL. */\n unlink: (provider) => send(`/link/${provider}`, \"DELETE\"),\n /** Upload an image (PNG, JPEG, WebP or GIF). It is re-encoded and becomes the chosen source. */\n upload: (image) => call(\"/upload\", { method: \"POST\", body: image }),\n removeUpload: () => send(\"/upload\", \"DELETE\")\n };\n}\nasync function resolveAvatars(opts, userIds) {\n const f = opts.fetch ?? fetch;\n const url = `${opts.baseUrl ?? PREFS_API_BASE}/api/v1/_avatar/resolve`;\n const unique = [...new Set(userIds)];\n const out = {};\n for (let i = 0; i < unique.length; i += RESOLVE_MAX_IDS) {\n const res = await f(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", \"X-User-Key\": opts.serviceKey },\n body: JSON.stringify({ userIds: unique.slice(i, i + RESOLVE_MAX_IDS) })\n });\n Object.assign(out, (await readJson(res)).avatars);\n }\n return out;\n}\nexport {\n AVATAR_SOURCES,\n AvatarError,\n LINK_CALLBACK_PATH,\n LINK_MESSAGE_TYPE,\n LINK_POPUP_MARK,\n LINK_PROVIDERS,\n RESOLVE_MAX_IDS,\n SPRITE_ID_PATTERN,\n createAvatarClient,\n resolveAvatars\n};\n","/**\n * The person's avatar, as hadoku_site's prefs-api resolves it.\n *\n * A person picks their CHARACTER and their PICTURE (Discord, Steam, an upload,\n * or the character itself) at the top level, in the fleet settings popout\n * (`ConnectedSettings` → `AvatarPicker`, @wolffm/task-ui-components). Watchparty\n * has no picker of its own and no longer reads or writes the `sprite` field of\n * its prefs row: prefs-api falls back to that field for someone who never chose\n * at the top level, so it stays in the schema, but only prefs-api reads it.\n *\n * - The character is REQUESTED at join (`fetchRequestedSprite`, awaited by the\n * pre-join wait) and live whenever the popout changes it (`AVATAR_EVENT`).\n * The room still decides: a taken character falls back as it always has.\n * - The picture is never read here. The server resolves each participant's by\n * registry userId and sends it in presence (`avatar_url`, apps/server\n * `rooms/avatars.ts`), so a person sees everyone's, not only their own.\n */\nimport { createAvatarClient, AvatarError, type AvatarSettings } from '@wolffm/prefs-client/avatar';\nimport { useAppStore } from './store';\nimport { displayNameFor, isCharacterId, isCharacterName } from './characters';\nimport { debug, warn, errorFields } from './debug';\n\n/**\n * The settings popout's window event, `detail: AvatarSettings`, fired after\n * every change the person makes. @wolffm/task-ui-components exports it as\n * `AVATAR_EVENT` from 4.22.3, which is not on the registry yet (4.22.1 is\n * installed) — and the room chrome must never import that package anyway (a\n * game host need not install it), so the value is spelled here.\n */\nexport const AVATAR_EVENT = 'hadoku:avatar';\n\n/** The character a person asked for: their top-level pick, else the one\n * prefs-api resolved (it falls back to the old watchparty pref). */\nexport function requestedSpriteOf(settings: Pick<AvatarSettings, 'sprite' | 'avatar'> | null | undefined): string | null {\n const id = settings?.sprite ?? settings?.avatar?.sprite ?? null;\n return isCharacterId(id) ? id : null;\n}\n\n/**\n * The signed-in person's requested character, or null. Never throws.\n *\n * Normal answers, logged at debug: a signed-out visitor's 401/403 (they keep\n * today's auto-assign), and a 404 — an origin with no prefs-api mounted, which\n * is the local dev/E2E server and any non-hadoku host of the room chrome.\n * Anything else is a fault worth a warn, and still resolves null: no answer\n * from prefs-api must never block or break a join.\n */\nexport async function fetchRequestedSprite(opts: { baseUrl?: string; fetch?: typeof fetch } = {}): Promise<string | null> {\n const f = opts.fetch ?? (typeof fetch === 'undefined' ? undefined : fetch);\n const origin = typeof window === 'undefined' ? undefined : window.location?.origin;\n const baseUrl = opts.baseUrl ?? (origin ? `${origin}/prefs` : undefined);\n if (!f || !baseUrl) return null;\n try {\n const settings = await createAvatarClient({ baseUrl, fetch: f }).get();\n const sprite = requestedSpriteOf(settings);\n debug('avatar', 'Requested character from prefs-api', { sprite });\n return sprite;\n } catch (err: unknown) {\n if (err instanceof AvatarError && (err.status === 401 || err.status === 403 || err.status === 404)) {\n debug('avatar', 'No avatar settings here (signed out, or no prefs-api on this origin)', { status: err.status });\n } else {\n warn('avatar', 'Avatar settings read failed — keeping the auto-assigned character', {\n status: err instanceof AvatarError ? err.status : undefined, ...errorFields(err),\n });\n }\n return null;\n }\n}\n\n/**\n * Make `sprite` the identity this tab asks for. A SESSION identity: nothing is\n * saved — the choice lives in prefs-api. The name follows the character only\n * when it is a character name; a registry name or a host-offered one stays.\n * Returns whether anything changed.\n */\nexport function adoptRequestedSprite(sprite: string | null): boolean {\n if (!sprite) return false;\n const st = useAppStore.getState();\n if (st.sprite === sprite) return false;\n const registryNamed = !!(st.me.clientId && st.roster[st.me.clientId]?.registryName);\n // An empty name stays empty, so ensureAutoIdentity derives it at join.\n const name = registryNamed || !st.name || !isCharacterName(st.name) ? st.name : displayNameFor(sprite);\n st.setSessionIdentity(name, sprite);\n return true;\n}\n\n/** Call `onChange` for every settings-popout avatar change; returns the unsubscribe.\n * A no-op where there is no window (the chrome mounts under jsdom/happy-dom\n * in consumers' tests, and the UI's own tests run in node). */\nexport function listenForAvatarChanges(\n onChange: (settings: AvatarSettings) => void,\n target: EventTarget | undefined = typeof window === 'undefined' ? undefined : window,\n): () => void {\n if (!target) return () => {};\n const handler = (e: Event) => {\n const detail = (e as CustomEvent<AvatarSettings | undefined>).detail;\n if (!detail || typeof detail !== 'object') return;\n onChange(detail);\n };\n target.addEventListener(AVATAR_EVENT, handler);\n return () => target.removeEventListener(AVATAR_EVENT, handler);\n}\n","/**\n * How is this app framed?\n *\n * Watchparty is reachable two ways that are INDISTINGUISHABLE in every log we\n * currently write:\n *\n * 1. Direct — `https://hadoku.me/watchparty/...` as a top-level document.\n * 2. From the hadoku.me home page — the shell mounts a scene iframe, and the\n * scene mounts watchparty in a second iframe inside it (depth 2).\n *\n * `client_url` is read from the app's OWN window, so it is byte-identical in\n * both cases (`https://hadoku.me/watchparty/room/...`). During the 2026-08-04\n * investigation that made \"did this viewer enter from the home page?\"\n * unfalsifiable from logs — the hypothesis could be neither confirmed nor\n * refuted, only argued about. This closes that gap: `framed`/`depth` go out\n * with `join` and land in the `session_open` record.\n *\n * Cross-origin safe: reading `window.parent`/`window.top` and comparing\n * WindowProxy identity is permitted across origins (only reaching *into* their\n * document is blocked). The walk is still wrapped defensively — a telemetry\n * field must never be able to break a join.\n */\n\nexport interface EmbedContext {\n /** True when this document is not the top-level window. */\n framed: boolean;\n /** Nesting depth: 0 = top-level, 1 = one iframe, 2 = the home-page path. */\n depth: number;\n}\n\n/** Hard cap on the parent walk, so a malformed/cyclic frame tree can't hang join. */\nconst MAX_FRAME_DEPTH = 10;\n\nexport function describeEmbedding(win: Window | undefined = typeof window !== 'undefined' ? window : undefined): EmbedContext {\n if (!win) return { framed: false, depth: 0 };\n try {\n let depth = 0;\n let w: Window = win;\n while (w !== w.parent && depth < MAX_FRAME_DEPTH) {\n depth++;\n w = w.parent;\n }\n // `top` can read as null in exotic/detached cases; fall back to the walk.\n const framed = win.top ? win.top !== win.self : depth > 0;\n return { framed, depth };\n } catch {\n // Never let telemetry break the join path.\n return { framed: false, depth: 0 };\n }\n}\n","/**\n * Reconnect and resync — the CONTRACT, not the transport.\n *\n * A client that drops and returns has three problems, and they are separable:\n * did it miss anything (sequence), is it even talking to the same room\n * incarnation (epoch), and does the server still agree about who it is\n * (identity). The rules for all three live here, pure and dependency-free, so\n * both ends agree on them and either end can test them without a socket.\n *\n * **The implementations deliberately stay where they are.** Watchparty's socket\n * lifecycle is in `apps/ui/src/lib/socket.ts` and is not extracted; a second\n * consumer whose client is a cross-origin iframe relaying over `postMessage`\n * has a different transport entirely. What both need to agree on is the RULES,\n * which is this file.\n *\n * ## What watchparty actually stamps today — read this before binding\n *\n * `CoreRoomState.lastEventSeq` is incremented **only for playback control\n * events** (`ws/control.ts`), and it reaches clients in the `snapshot` and\n * `control_ack` payloads. Chat, presence, health and game envelopes carry no\n * sequence at all. So `classifySeq` is a rule this package *guarantees*, not a\n * behaviour watchparty currently exercises end to end — an app that wants gap\n * detection stamps `SeqCursor` on its own envelopes and runs the classifier.\n *\n * That distinction was stated wrongly once (an earlier version of the\n * extraction reply claimed \"every envelope carries seq\"), so it is spelled out\n * here rather than left to be inferred.\n */\n/**\n * Classify an incoming event against the last one applied.\n *\n * `last === null` means nothing has been applied yet, which is 'ok' rather than\n * a gap: a client joining mid-stream has missed everything by definition, and\n * its snapshot — not a resync request — is what establishes the baseline.\n *\n * **Sequence numbers are NEVER compared across epochs.** A restarted server\n * counting from 1 while the client holds 500 would otherwise read as a flood\n * of duplicates and the client would sit there discarding live events forever.\n * The epoch check therefore comes first, before any arithmetic.\n */\nexport function classifySeq(last, incoming) {\n if (last === null)\n return 'ok';\n if (incoming.epoch !== last.epoch)\n return 'epoch-change';\n if (incoming.seq === last.seq + 1)\n return 'ok';\n if (incoming.seq <= last.seq)\n return 'duplicate';\n return 'gap';\n}\n/** How many events a gap skipped. 0 when the verdict is not 'gap'. */\nexport function missedCount(last, incoming) {\n if (last === null || incoming.epoch !== last.epoch)\n return 0;\n return Math.max(0, incoming.seq - last.seq - 1);\n}\n/**\n * Does this verdict require the client to ask the server for state?\n *\n * A helper rather than a comparison at each call site, because the answer is\n * NOT \"anything that isn't ok\": a duplicate must not trigger a resync. Under\n * any retransmit, duplicates arrive in bursts, and resyncing on each one turns\n * a harmless replay into a request storm against the server that is already\n * struggling enough to be retransmitting.\n */\nexport function needsResync(verdict) {\n return verdict === 'gap' || verdict === 'epoch-change';\n}\n/**\n * Should the client re-assert its local identity to the server?\n *\n * On each snapshot a client compares its own name/avatar against the server's\n * roster entry FOR ITSELF and emits an identity update only for the fields that\n * actually disagree, so later snapshots are no-ops.\n *\n * **Read `serverEntry` from the ROSTER, not from the snapshot.** Watchparty's\n * snapshot carries seven fields and has never included a roster; a caller that\n * looked itself up there got `undefined` permanently, both guards collapsed to\n * local state alone, and every client with a saved identity re-emitted on\n * every snapshot — including the room-wide ones. That bug survived a long time\n * because broken and correct agree on the FIRST snapshot after join and\n * diverge only afterwards.\n *\n * `serverEntry === undefined` still means \"assert\": that is the genuine\n * first-snapshot case, where the client cannot know the server's view.\n *\n * Known quirk, preserved deliberately: an empty server name does not trigger a\n * name assert, because an empty string is not a default name under any sane\n * `isDefaultName`. Widening that is a separate decision with a different blast\n * radius.\n *\n * @param isDefaultName recognises an auto-assigned name; a local name that is\n * still a default is not worth asserting.\n * @returns the fields to emit, or null when nothing differs.\n */\nexport function resolveIdentityReassert(local, serverEntry, isDefaultName) {\n const wantsName = !!local.name &&\n !isDefaultName(local.name) &&\n (!serverEntry || isDefaultName(serverEntry.name || ''));\n const wantsAvatar = !!local.avatarId && (!serverEntry || serverEntry.avatarId !== local.avatarId);\n if (!wantsName && !wantsAvatar)\n return null;\n const out = {};\n if (wantsName)\n out.name = local.name;\n if (wantsAvatar)\n out.avatarId = local.avatarId;\n return out;\n}\n","import { removeStored } from './browserStorage';\nimport { STORAGE_KEYS } from './storageKeys';\n\n/**\n * Forget this browser's stored ballot for a playlist. Called when the leader\n * removes us from the results (`playlist_votes_cleared`). The ballot is kept in\n * localStorage and RE-SENT whenever the playlist loads (PlaylistPanel's restore\n * effect), so clearing only the server's copy would be undone by the next\n * reload. Returns how many entries were removed.\n */\nexport function clearStoredVotes(playlist: { id: string; videos: ReadonlyArray<{ mediaId: string }> }, owner: string): number {\n let removed = 0;\n for (const video of playlist.videos) {\n const key = STORAGE_KEYS.voteKey(owner, playlist.id, video.mediaId);\n if (globalThis.localStorage?.getItem(key) != null) removed++;\n removeStored(key);\n }\n return removed;\n}\n","/**\n * Client-side liveness of the socket, judged by time_pong replies.\n *\n * The browser only learns a connection died when something closes it. A\n * connection that goes quiet without closing — half-open, or stalled somewhere\n * upstream — keeps `socket.connected === true` indefinitely: engine.io's own\n * timeout is pingInterval + SOCKET_PING_TIMEOUT_MS, over five minutes here.\n * mistral-bluff 2026-10-20 had both kinds: four IPv4 viewers' sockets were cut\n * and reconnected on their own, while an IPv6 viewer's sat silent for 96s on\n * the same socket and recovered only when the network did.\n *\n * Rule: a ping unanswered for PONG_DEAD_AFTER_MS of AWAKE time means the\n * socket is dead, and the caller replaces it. \"Awake\" matters — a frozen or\n * throttled background page stops running timers, so a long gap between two\n * ticks is the page sleeping, not the network failing. Such a gap restarts the\n * clock instead of counting toward it.\n *\n * No timer of its own: it is evaluated on the existing time-ping tick.\n */\n\n/** Pings go out every DEFAULT_CLIENT_TIME_PING_INTERVAL_MS (5s); four of them unanswered. */\nexport const PONG_DEAD_AFTER_MS = 20_000;\n/** A tick this late after the previous one means the page was asleep. */\nexport const SLEEP_GAP_MS = 10_000;\n\nexport interface Liveness {\n /** When the oldest ping with no pong since was sent; null when all answered. */\n unansweredSince: number | null;\n lastPongAt: number | null;\n lastTickAt: number | null;\n}\n\nexport function createLiveness(): Liveness {\n return { unansweredSince: null, lastPongAt: null, lastTickAt: null };\n}\n\nexport function notePong(l: Liveness, now: number): void {\n l.lastPongAt = now;\n l.unansweredSince = null;\n}\n\n/**\n * Called on each ping tick, before the ping is sent. Returns true when the\n * socket should be treated as dead.\n */\nexport function tick(l: Liveness, now: number, connected: boolean): boolean {\n const slept = l.lastTickAt !== null && now - l.lastTickAt > SLEEP_GAP_MS;\n l.lastTickAt = now;\n if (!connected) {\n l.unansweredSince = null;\n return false;\n }\n if (slept) {\n l.unansweredSince = now;\n return false;\n }\n if (l.unansweredSince === null) {\n l.unansweredSince = now;\n return false;\n }\n return now - l.unansweredSince > PONG_DEAD_AFTER_MS;\n}\n\n/** ms since the last pong, for the health report; undefined before the first. */\nexport function pongAge(l: Liveness, now: number): number | undefined {\n return l.lastPongAt === null ? undefined : Math.max(0, now - l.lastPongAt);\n}\n","import type { Socket } from 'socket.io-client';\nimport { io } from 'socket.io-client';\nimport { DEFAULT_UI_PORT, DEFAULT_HTTP_PORT, DEFAULT_WS_PATH, PLAYLIST_EVENTS, TIERLIST_EVENTS, READY_EVENTS, CORE_EVENTS, GAME_EVENTS, DEFAULT_CLIENT_TIME_PING_INTERVAL_MS } from '@watchparty/shared';\nimport { isChatImageKey, DEFAULT_CHAT_MAX_IMAGES } from '@watchparty/shared';\nimport type { TVoteValue, TChatImage } from '@watchparty/shared';\nimport type { RosterUser, ChatMessage } from './store';\nimport { useAppStore } from './store';\nimport { refreshTierlist } from './tierlistApi';\nimport { getRuntimeConfig } from './config';\nimport { displayNameFor, isCharacterName } from './characters';\nimport { debug, warn, error, setLogRoomContext } from './debug';\nimport { isStaleSpriteRefusal, retryTakenSprite } from './spriteRetry';\nimport { adoptRequestedSprite } from './avatar';\nimport { describeEmbedding } from './embedContext';\nimport { currentDeliveryArm } from './fragmentDelivery';\nimport { cachedDeviceId } from './deviceId';\nimport { resolveIdentityReassert } from '@wolffm/rooms-protocol';\nimport type {\n SnapshotPayload, ControlBroadcastPayload, ControlAckPayload, TimePongPayload,\n ReadyStatePayload, PresencePayload, ChatBroadcastPayload, ChatHistoryPayload,\n PlaylistStatePayload, PlaylistVoteProgressPayload, PlaylistResultsPayload, PlaylistVotesClearedPayload,\n ReadyCheckStatePayload, GameActivePayload, HealthSnapshotPayload,\n BufferStatusPayload, ErrorPayload,\n} from './wireEvents';\nimport { registerDebugGlobal } from './debugGlobals';\nimport { clearStoredVotes } from './playlistVotes';\nimport { voteOwnerScope } from './auth';\nimport { createLiveness, notePong, tick as livenessTick, pongAge } from './connectionLiveness';\n\nlet socket: Socket | null = null;\nlet timePingInflight: { ts: number } | null = null;\nlet timePingInterval: ReturnType<typeof setInterval> | null = null;\nlet timePingTimeout: ReturnType<typeof setTimeout> | null = null;\nlet lastJoinPayload: { room_key: string; name?: string; sprite?: string | null; embed?: { framed: boolean; depth: number }; device_id?: string; tab_id: string } | null = null;\n/** One per page load, sent on the join and every rejoin, so the server can tell\n * this tab reconnecting from a second tab and retire the old connection. */\nconst TAB_ID = makeTabId();\nconst liveness = createLiveness();\n/** How the previous connection ended, reported on the next rejoin. */\nlet lastDisconnect: { reason: string; at: number } | null = null;\n/** Set just before the pong watchdog closes the transport, so the rejoin says why. */\nlet pendingDisconnectCause: string | null = null;\nlet reconnectCount = 0;\n/** The identity the latest join (or rejoin) carried — what the server has\n * already been asked for, so the first snapshot never asks again. */\nlet joinedIdentity: { name?: string; sprite?: string | null } | null = null;\n/** True while this module sets an identity it is about to emit itself, so the\n * store-change reassert below does not send a second copy of it. */\nlet identityEmitInHand = false;\n/** Set when the server said our wanted sprite is held by this account's other connection; cleared per connect. */\nlet spriteHeldByOwnOtherConnection = false;\nlet hasConnectedOnce = false; // Distinguishes initial connect from reconnects\nlet lastReadyMediaId: string | null = null; // Tracks last client_ready so it can be re-emitted on reconnect\n\ninterface JoinOpts {\n room_key: string;\n name?: string;\n sprite?: string | null;\n}\n\nexport function connectAndJoin(opts: JoinOpts): Socket {\n const s = getSocket();\n const state = useAppStore.getState();\n // If we already have a clientId and roster contains it, avoid duplicate join.\n if (state.me.clientId && state.roster[state.me.clientId]) {\n if (opts.name || opts.sprite) {\n debug('socket', 'Identity update (already joined)', { name: opts.name, sprite: opts.sprite });\n s.emit(CORE_EVENTS.IDENTITY_UPDATE, { name: opts.name, sprite: opts.sprite });\n }\n return s;\n }\n const payload = sanitizeJoin(opts);\n lastJoinPayload = payload; // Store for reconnection\n joinedIdentity = { name: payload.name, sprite: payload.sprite };\n if (s.connected) {\n debug('socket', 'Emitting join', payload);\n s.emit(CORE_EVENTS.JOIN, payload);\n } else {\n s.once('connect', () => { debug('socket', 'Emitting join', payload); s.emit(CORE_EVENTS.JOIN, payload); });\n }\n return s;\n}\n\nfunction sanitizeJoin(o: JoinOpts) {\n return {\n room_key: o.room_key,\n name: o.name,\n sprite: o.sprite,\n // Entry-path telemetry — see lib/embedContext.ts. Sent on every join AND\n // rejoin (lastJoinPayload carries it), so a reconnect keeps the attribution.\n embed: describeEmbedding(),\n delivery_arm: currentDeliveryArm(),\n // Identity tier input — see lib/deviceId.ts. Sent on every join AND rejoin\n // (lastJoinPayload carries it) so a reconnect lands on the same\n // ParticipantId rather than minting a new person.\n device_id: cachedDeviceId(),\n tab_id: TAB_ID,\n };\n}\n\nfunction makeTabId(): string {\n const c = globalThis.crypto;\n if (c && typeof c.randomUUID === 'function') return c.randomUUID();\n const bytes = new Uint8Array(16);\n if (c && typeof c.getRandomValues === 'function') c.getRandomValues(bytes);\n else for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);\n return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n}\n\n/** ms since this connection's last time_pong, for the health report. */\nexport function currentPongAgeMs(): number | undefined {\n return pongAge(liveness, Date.now());\n}\n\nexport function getSocket(): Socket {\n if (!socket) {\n const config = getRuntimeConfig();\n let origin = config.serverOrigin || '/';\n if (origin === '/' && typeof window !== 'undefined') {\n const loc = window.location;\n if ((loc.hostname === 'localhost' || loc.hostname === '127.0.0.1') && loc.port === String(DEFAULT_UI_PORT)) {\n origin = `${loc.protocol}//${loc.hostname}:${DEFAULT_HTTP_PORT}`;\n debug('socket', 'Using dev fallback origin', { origin });\n }\n }\n // Strip any path from the origin - socket.io treats URL paths as namespaces\n const socketOrigin = new URL(origin.startsWith('http') ? origin : `${window.location.origin}${origin}`).origin;\n socket = io(socketOrigin, { path: DEFAULT_WS_PATH, transports: ['websocket', 'polling'] });\n debug('socket', 'Socket initialized', { origin });\n\n // E2E handle — published only when the host opts in (lib/debugGlobals.ts).\n registerDebugGlobal('__SOCKET__', socket);\n\n // Start time ping loop immediately when socket is created.\n // This must live here (not in wireCoreHandlers) so that cleanupTimers() + getSocket()\n // restarts the interval correctly. wireCoreHandlers is called once at creation time\n // but not on reconnect, so placing the interval there would leave it dead after cleanup.\n if (timePingTimeout) { clearTimeout(timePingTimeout); timePingTimeout = null; }\n timePingInflight = null;\n timePingInterval = setInterval(() => {\n if (livenessTick(liveness, Date.now(), !!socket?.connected)) {\n // Half-open or stalled upstream: nothing will ever close it for us.\n // Closing the transport hands it to socket.io's reconnect, and the\n // rejoin's tab id lets the server retire the old row at once.\n warn('socket', 'PONG-WATCHDOG no time_pong for 20s — replacing the connection', {\n sid: socket?.id, lastPongAgeMs: pongAge(liveness, Date.now()) ?? null,\n });\n pendingDisconnectCause = 'pong-watchdog';\n liveness.unansweredSince = null;\n socket?.io.engine?.close();\n return;\n }\n initiateTimePing();\n }, DEFAULT_CLIENT_TIME_PING_INTERVAL_MS);\n\n socket.on('connect', () => {\n spriteHeldByOwnOtherConnection = false;\n const sid = socket?.id;\n debug('socket', 'Connected', { id: sid, isReconnect: hasConnectedOnce });\n if (sid) {\n try {\n useAppStore.getState().ensureMe(sid);\n // Reset client sequence on (re)connect to match server's fresh connection state\n // Server starts with lastClientSeq=0, so we need nextClientSeq=1\n useAppStore.setState(s => ({ me: { ...s.me, nextClientSeq: 1 } }));\n debug('socket', 'Reset client sequence for new connection');\n } catch (e) {\n error('socket', 'Failed to initialize store on connect', { error: (e as Error).message, sid });\n }\n }\n // Re-join on reconnect only — initial join is handled by connectAndJoin()\n if (hasConnectedOnce && lastJoinPayload) {\n const st = useAppStore.getState();\n reconnectCount += 1;\n const rejoinPayload = {\n ...lastJoinPayload, name: st.name, sprite: st.sprite,\n reconnect: {\n count: reconnectCount,\n reason: (lastDisconnect?.reason ?? 'unknown').slice(0, 64),\n offline_ms: lastDisconnect ? Math.max(0, Date.now() - lastDisconnect.at) : 0,\n },\n };\n const readyMediaId = lastReadyMediaId;\n debug('socket', 'Re-emitting join after reconnect', { room_key: rejoinPayload.room_key, name: rejoinPayload.name, sprite: rejoinPayload.sprite });\n // Wire snapshot ack BEFORE emitting join so we never miss the response.\n // The server emits `snapshot` once per successful join — we use it as\n // the join-ack. Re-emitting client_ready before snapshot arrives loses\n // the event server-side because the new socket isn't yet in the room\n // (Bug 2 follow-up: the previous fix race-condition'd by re-emitting\n // client_ready unconditionally; this version waits.)\n if (readyMediaId) {\n let resolved = false;\n const onSnapshot = () => {\n if (resolved) return;\n resolved = true;\n socket!.off(CORE_EVENTS.SNAPSHOT, onSnapshot);\n socket!.emit(CORE_EVENTS.CLIENT_READY, { media_id: readyMediaId });\n debug('socket', 'Re-emitted client_ready after reconnect snapshot', { mediaId: readyMediaId });\n };\n socket!.on(CORE_EVENTS.SNAPSHOT, onSnapshot);\n setTimeout(() => {\n if (resolved) return;\n resolved = true;\n socket!.off(CORE_EVENTS.SNAPSHOT, onSnapshot);\n warn('socket', 'client_ready re-emit timed out waiting for snapshot', { mediaId: readyMediaId });\n }, 10_000);\n }\n joinedIdentity = { name: rejoinPayload.name, sprite: rejoinPayload.sprite };\n socket!.emit(CORE_EVENTS.JOIN, rejoinPayload);\n // Abort any stale in-flight fetches from the previous connection.\n // On socket.io reconnect the FragmentManager carries over pending\n // fetch indices from the old session which block new fetches at\n // lower indices indefinitely (until their 60-90s adaptive timeouts\n // expire). Clearing them here lets prefetch restart immediately.\n // Notify MediaPlayer via event rather than reaching into __FRAGMENT_MANAGER__\n // directly. MediaPlayer owns the FM; socket should not depend on the window global.\n window.dispatchEvent(new CustomEvent('watchparty:socket-reconnect'));\n } else if (hasConnectedOnce) {\n warn('socket', 'Reconnected — no join payload, not re-joining any room');\n }\n hasConnectedOnce = true;\n });\n socket.on('disconnect', (reason) => {\n setLogRoomContext(null);\n lastDisconnect = { reason: pendingDisconnectCause ?? reason, at: Date.now() };\n pendingDisconnectCause = null;\n debug('socket', 'Disconnected', { reason });\n });\n socket.on('connect_error', (err) => error('socket', 'Connection error', { message: err?.message }));\n socket.on('reconnect_attempt', (n) => warn('socket', 'Reconnect attempt', { attempt: n }));\n socket.on('reconnect_failed', () => error('socket', 'Reconnect failed'));\n wireCoreHandlers(socket);\n }\n return socket;\n}\n\n// --- Helpers ---\n\nfunction isServerPlaying(payload: { play_state?: string; playing?: boolean }): boolean {\n return payload.play_state === 'playing' || payload.playing === true;\n}\n\nfunction normalizeChatMessage(m: ChatBroadcastPayload, seqFallback?: number): ChatMessage {\n return {\n id: String(m.id ?? m.server_seq ?? seqFallback ?? `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`),\n clientId: m.client_id,\n author: typeof m.author === 'string' ? m.author : undefined,\n name: m.name || 'Anon',\n sprite: m.sprite ?? null,\n text: m.text || '',\n ts: m.ts || Date.now(),\n // Attachments arrive from other clients, so the key shape is re-checked\n // here at the boundary rather than trusted at render time. A malformed\n // entry is dropped, not rendered and not allowed near an <img src>.\n images: Array.isArray(m.images)\n ? m.images\n .filter((im: unknown): im is TChatImage =>\n !!im && isChatImageKey((im as TChatImage).key))\n .slice(0, DEFAULT_CHAT_MAX_IMAGES)\n : undefined,\n isSystem: m.isSystem || false,\n systemType: m.systemType,\n };\n}\n\n// --- Domain-split wire functions ---\n\nfunction wireSync(s: Socket): void {\n // snapshot\n s.on(CORE_EVENTS.SNAPSHOT, (payload: SnapshotPayload) => {\n // First snapshot = join confirmed. Ask which game is open, so a late\n // joiner mounts it without waiting for the next leader broadcast.\n // Idempotent on later snapshots.\n s.emit(GAME_EVENTS.SYNC);\n // NOTE: the snapshot carries no roster and no client_id — `buildSnapshot`\n // emits exactly seven fields (room_id, play_state, playhead_ms, leader_id,\n // media_id, server_seq, server_ts). Anything roster-shaped must come from the store,\n // which the `presence` handler maintains.\n // Server sends play_state: 'playing'|'paused', convert to boolean\n useAppStore.getState().applySnapshot({\n roomId: payload.room_id ?? null,\n mediaId: payload.media_id ?? null,\n playheadMs: payload.playhead_ms || 0,\n playing: isServerPlaying(payload),\n serverSeq: payload.server_seq || 0,\n leaderId: payload.leader_id || null,\n });\n // No auto identity assignment here: with no roster in the snapshot,\n // ensureAutoIdentity() would always pick the first character (sage) and\n // send an identity_update the server accepts for name but rejects for\n // sprite, leaving duplicate names across clients. `presence` arrives right\n // after with the full roster and its handler owns that correction.\n if (!useAppStore.getState().name) {\n debug('socket', 'Deferring identity to presence event (snapshot carries no roster)');\n }\n\n // Reassert local identity (name + sprite) on the first snapshot after\n // join. Two motivations:\n // 1. Custom NAME — replaces the old 40ms postJoinIdentity setTimeout.\n // 2. Saved SPRITE — when /api/me/prefs resolves AFTER Room.tsx fires\n // connectAndJoin (the typical fresh-device case: SPA bundle on a\n // direct /room/{key} link), the join payload sends the auto-\n // assigned sprite. rehydrateFromPrefs then updates the LOCAL store\n // to the saved sprite, but joinedRef pins the join — without this\n // reassert, other clients keep seeing the auto-assigned sprite\n // forever. Bug 1 from the 2026-05-20 cedar-ridge retrospective\n // (Coz + LittleMiss with wrong avatars).\n // Each field is gated independently: only emit it if the local store has a\n // non-default value AND the server's roster entry for us still shows a\n // different value, so once the server reflects us later snapshots are\n // no-ops. That entry comes from the STORE roster (maintained by the\n // `presence` handler) — it used to be looked up in `payload.users`, which\n // the snapshot has never carried, so the lookup was permanently undefined\n // and every client with a saved identity re-emitted on every snapshot.\n // Rule + regression tests: @wolffm/rooms-protocol resync.ts.\n const stAfter = useAppStore.getState();\n const myClientId = socket?.id;\n const myEntry = myClientId ? stAfter.roster[myClientId] : undefined;\n // The rule lives in @wolffm/rooms-protocol (resync.ts) so both ends of the\n // room layer agree on it. It speaks `avatarId`; the store and the WIRE both\n // say `sprite`, so the mapping happens here at the edge rather than\n // spreading watchparty's vocabulary into the package.\n // Before the first presence there is no roster entry, and the server's\n // view of us is what the join just carried: asserting that again only\n // repeats a request it has already answered (with a sprite_taken, when\n // the joined sprite was held — which used to start a retry cascade into\n // identity.rate_limit). Only what changed SINCE the join is asserted.\n const known = myEntry ?? joinedIdentity;\n const idResult = resolveIdentityReassert(\n { name: stAfter.name, avatarId: stAfter.sprite },\n known ? { name: known.name, avatarId: known.sprite ?? null } : undefined,\n // A join that carried no name counts as a default one, so a name that\n // landed after the join (prefs) is still asserted.\n (n) => n === '' || isCharacterName(n),\n );\n if (idResult) {\n const idPayload = {\n ...(idResult.name !== undefined ? { name: idResult.name } : {}),\n ...(idResult.avatarId !== undefined && !spriteHeldByOwnOtherConnection ? { sprite: idResult.avatarId } : {}),\n };\n if (Object.keys(idPayload).length > 0) {\n debug('socket', 'Identity update on snapshot', idPayload);\n s.emit(CORE_EVENTS.IDENTITY_UPDATE, idPayload);\n }\n }\n\n debug('socket', 'Received snapshot', {\n mediaId: payload.media_id ?? null,\n playheadMs: payload.playhead_ms || 0,\n playing: isServerPlaying(payload),\n leaderId: payload.leader_id || null,\n serverSeq: payload.server_seq || 0,\n rosterSize: Object.keys(stAfter.roster).length,\n });\n\n // Set room context for client log correlation with server session logs\n if (lastJoinPayload?.room_key && socket?.id) {\n setLogRoomContext({ room_key: lastJoinPayload.room_key, client_id: socket.id });\n }\n });\n\n // control broadcasts (simplified before MSE): { server_seq, playhead_ms, playing, leader_id? }\n s.on(CORE_EVENTS.CONTROL_BROADCAST, (msg: ControlBroadcastPayload) => {\n const state = useAppStore.getState();\n // If media_id present and changed, promote it into snapshot + reset readiness gate\n if (Object.prototype.hasOwnProperty.call(msg, 'media_id')) {\n const newMediaId = msg.media_id ?? null;\n if (state.snapshot.mediaId !== newMediaId) {\n state.applySnapshot({ mediaId: newMediaId });\n // Reset readiness (server will emit fresh ready_state after clients append)\n if (newMediaId) state.setReadiness({ mediaId: newMediaId, ready: false, readyCount: 0, total: 0 });\n // Bump generation so the seek effect re-fires even when playheadMs doesn't\n // change (e.g. 0 → 0 on same-media reload). Only bump on actual media\n // changes — bumping on every play/pause/seek broadcast (which all include\n // media_id) disables the DEFAULT_DRIFT_SOFT_MS deduplication guard in\n // usePlaybackSync, causing cascading seek preemptions on multi-viewer seeks.\n state.bumpLoadGeneration();\n }\n }\n // Server sends play_state: 'playing'|'paused', convert to boolean\n state.updateControlState({\n playheadMs: msg.playhead_ms,\n playing: isServerPlaying(msg),\n serverSeq: msg.server_seq,\n leaderId: msg.leader_id ?? state.snapshot.leaderId\n });\n debug('socket', 'Control broadcast received', {\n kind: msg.kind, serverSeq: msg.server_seq, playheadMs: msg.playhead_ms,\n playState: msg.play_state, mediaId: msg.media_id,\n });\n });\n\n // control ack (map client_seq -> server_seq)\n s.on(CORE_EVENTS.CONTROL_ACK, (ack: ControlAckPayload) => {\n if (typeof ack?.client_seq === 'number' && typeof ack?.server_seq === 'number') {\n debug('socket', 'Control ack received', ack);\n }\n });\n\n // time_pong: server response to our time_ping { server_ts, client_sent_ts }\n s.on(CORE_EVENTS.TIME_PONG, (p: TimePongPayload) => {\n // Any pong proves the connection carries traffic — even one too late for\n // an RTT sample.\n notePong(liveness, Date.now());\n if (timePingInflight && timePingInflight.ts) {\n const rtt = Date.now() - timePingInflight.ts;\n useAppStore.getState().addRttSample(rtt, p?.server_ts, timePingInflight.ts);\n timePingInflight = null;\n if (timePingTimeout) { clearTimeout(timePingTimeout); timePingTimeout = null; }\n debug('socket', 'Time sync RTT', { rtt, offset: useAppStore.getState().drift.offsetMs });\n }\n });\n\n // ready_state: server-authoritative readiness broadcast\n s.on(CORE_EVENTS.READY_STATE, (payload: ReadyStatePayload) => {\n if (!payload) return;\n const mediaId = payload.media_id ?? null;\n const readyCount = typeof payload.ready_count === 'number' ? payload.ready_count : 0;\n const total = typeof payload.total === 'number' ? payload.total : 0;\n const ready = payload.ready === true;\n useAppStore.getState().setReadiness({ mediaId, ready, readyCount, total });\n debug('socket', 'Ready state received', { mediaId, readyCount, total, ready });\n });\n}\n\nfunction wirePresence(s: Socket): void {\n s.on(CORE_EVENTS.PRESENCE, (ev: PresencePayload) => {\n if (!ev) return;\n // Server currently emits { users: [...] }\n if (Array.isArray(ev.users)) {\n const roster: Record<string, RosterUser> = {};\n for (const u of ev.users) {\n roster[u.client_id] = {\n clientId: u.client_id,\n ...(u.author ? { author: u.author } : {}),\n name: u.name || 'Anon',\n sprite: u.sprite_id ?? u.sprite ?? null,\n isLeader: u.is_leader,\n ...(u.registry_name ? { registryName: true } : {}),\n ...(u.avatar_url ? { avatarUrl: u.avatar_url } : {}),\n };\n }\n // Server is authoritative for sprite assignments - update local state to match\n const st = useAppStore.getState();\n const myId = socket?.id;\n const mine = myId ? roster[myId] : undefined;\n if (mine?.registryName) {\n // The server named us from the key registry: that IS our name, and it\n // never takes ours instead (ws/join.ts). Adopt it, and the sprite with\n // it. The roster goes in FIRST so the store-change re-assert below sees\n // the server already agreeing and stays quiet.\n useAppStore.setState({ roster });\n if (mine.name !== st.name || (mine.sprite && mine.sprite !== st.sprite)) {\n debug('socket', 'Adopting registry name', { from: st.name, to: mine.name });\n useAppStore.getState().setSessionIdentity(mine.name, mine.sprite ?? st.sprite);\n }\n } else if (myId && roster[myId]) {\n const serverName = roster[myId].name;\n const serverSprite = roster[myId].sprite;\n // Keep roster display name in sync with local custom name\n if (st.name && !isCharacterName(st.name)) {\n roster[myId].name = st.name; // user chose a custom name\n }\n // The roster goes in FIRST, as in the registry branch: the store-change\n // reassert then sees the server agreeing with the sprite adopted below\n // and stays quiet, instead of sending it straight back.\n useAppStore.setState({ roster });\n // Server is authoritative for sprite (prevents duplicates), but name is user-owned.\n // If the server reassigned our sprite (e.g., another user took ours during disconnect),\n // accept the new sprite but preserve a custom name the user set.\n if (serverSprite && serverSprite !== st.sprite) {\n const hasCustomName = st.name && !isCharacterName(st.name);\n // Use the display name for the newly-assigned sprite, not the server's\n // stale name (which may still reflect the old sprite's default name).\n // Custom names are always preserved.\n const nameToUse = hasCustomName ? st.name : displayNameFor(serverSprite);\n debug('socket', 'Server reassigned sprite', { from: st.sprite, to: serverSprite, newName: nameToUse, preservingCustomName: hasCustomName });\n useAppStore.getState().setSessionIdentity(nameToUse, serverSprite);\n // Re-assert the name so other clients see it immediately — unless the\n // server already shows it.\n if (nameToUse !== serverName) s.emit(CORE_EVENTS.IDENTITY_UPDATE, { name: nameToUse });\n }\n }\n }\n debug('socket', 'Received presence update', ev);\n // If we still have no identity after presence, attempt assignment\n const stFinal = useAppStore.getState();\n if (!stFinal.name) {\n stFinal.ensureAutoIdentity?.();\n const st3 = useAppStore.getState();\n if (st3.name) {\n debug('socket', 'Auto-assigned identity on presence', { name: st3.name, sprite: st3.sprite });\n s.emit(CORE_EVENTS.IDENTITY_UPDATE, { name: st3.name, sprite: st3.sprite || undefined });\n }\n }\n });\n}\n\nfunction wireChat(s: Socket): void {\n // chat_broadcast: { id, client_id, text, name, sprite, ts, isSystem?, systemType? }\n s.on(CORE_EVENTS.CHAT_BROADCAST, (m: ChatBroadcastPayload) => {\n const chatMsg = normalizeChatMessage(m, m.server_seq);\n useAppStore.getState().appendChat(chatMsg);\n debug('chat', 'Message received', chatMsg);\n });\n\n // chat_history: { messages: [...] } - sent on join\n s.on(CORE_EVENTS.CHAT_HISTORY, (data: ChatHistoryPayload) => {\n if (!data?.messages || !Array.isArray(data.messages)) return;\n const messages: ChatMessage[] = data.messages.map((m) => normalizeChatMessage(m));\n useAppStore.getState().setChat(messages);\n debug('chat', 'History loaded', { count: messages.length });\n });\n}\n\nfunction wirePlaylist(s: Socket): void {\n s.on(PLAYLIST_EVENTS.STATE, (payload: PlaylistStatePayload) => {\n useAppStore.getState().applyPlaylistState({\n playlist: payload?.playlist ?? null,\n activeIndex: payload?.activeIndex ?? null,\n myVotes: payload?.myVotes ?? {},\n });\n debug('playlist', 'Playlist state received', { playlistId: payload?.playlist?.id ?? null, activeIndex: payload?.activeIndex, myVoteCount: Object.keys(payload?.myVotes || {}).length });\n });\n\n s.on(PLAYLIST_EVENTS.VOTE_PROGRESS, (payload: PlaylistVoteProgressPayload) => {\n useAppStore.getState().setVoteProgress(payload?.progress ?? []);\n debug('playlist', 'Vote progress', { progressCount: payload?.progress?.length });\n });\n\n s.on(PLAYLIST_EVENTS.RESULTS, (payload: PlaylistResultsPayload) => {\n useAppStore.getState().setPlaylistResults(payload ?? null);\n debug('playlist', 'Results received', { playlistId: payload?.playlist?.id, update: payload?.update === true });\n });\n\n // The leader removed us from the results: drop the ballot here too, or the\n // restore effect re-sends it on the next playlist load.\n // On rejoin this arrives BEFORE playlist_state, so the store may not know the\n // playlist yet — clear from the ids in the payload, never from the store.\n s.on(PLAYLIST_EVENTS.VOTES_CLEARED, (payload: PlaylistVotesClearedPayload) => {\n if (!payload?.playlistId || !Array.isArray(payload.mediaIds)) return;\n const removed = clearStoredVotes(\n { id: payload.playlistId, videos: payload.mediaIds.map(mediaId => ({ mediaId })) },\n voteOwnerScope(),\n );\n const st = useAppStore.getState();\n if (st.playlist?.id === payload.playlistId) {\n st.applyPlaylistState({ playlist: st.playlist, activeIndex: st.activePlaylistIndex, myVotes: {} });\n }\n debug('playlist', 'Votes cleared by leader', { playlistId: payload.playlistId, removed });\n });\n}\n\nfunction wireTierlist(s: Socket): void {\n // A \"go re-fetch\" ping, not a payload. The shared board is identical for\n // everyone but `myBoard` is not, so one broadcast cannot serve both — each\n // client pulls its own view. `adoptDraft: false` because this fires when\n // SOMEONE ELSE saved: their result must land live, but replacing this\n // client's draft would yank cards out from under a drag in progress.\n s.on(TIERLIST_EVENTS.UPDATED, () => {\n debug('tierlist', 'Someone saved — refreshing the board');\n void refreshTierlist(false);\n });\n}\n\nfunction wireReadyCheck(s: Socket): void {\n // Server-authoritative state: { active: boolean, ready: clientId[] }.\n // Client never derives this locally — every transition is a broadcast.\n s.on(READY_EVENTS.STATE, (payload: ReadyCheckStatePayload) => {\n if (!payload || typeof payload.active !== 'boolean') return;\n const ready = Array.isArray(payload.ready) ? payload.ready.filter((x: unknown) => typeof x === 'string') : [];\n useAppStore.getState().setReadyCheckState({ active: payload.active, ready });\n debug('ready-check', 'State received', { active: payload.active, readyCount: ready.length });\n });\n}\n\n/** Leader-only emit — opens a fresh ready check. Server validates role. */\nexport function emitReadyCheckStart(): void {\n socket?.emit(READY_EVENTS.START, {});\n}\n\n/** Any-client emit — toggles current user's ready flag. */\nexport function emitReadyCheckToggle(ready: boolean): void {\n socket?.emit(READY_EVENTS.TOGGLE, { ready });\n}\n\n// ---- Waiting-room game ---------------------------------------------------\n\nfunction wireGame(s: Socket): void {\n // The game open in the room (null = none). Every game is a bundle that\n // talks to its own server; the room only says which one to mount.\n s.on(GAME_EVENTS.ACTIVE, (payload: GameActivePayload) => {\n const gameId = typeof payload?.gameId === 'string' ? payload.gameId : null;\n useAppStore.getState().setActiveGameId(gameId);\n debug('game', 'game_active', { gameId });\n });\n}\n\n/** Leader-only emit: open a game for the whole room, or close it with null.\n * Server broadcasts game_active back to everyone. */\nexport function emitGameSelect(gameId: string | null): void {\n socket?.emit(GAME_EVENTS.SELECT, { gameId });\n}\n\nfunction wireHealth(s: Socket): void {\n // health_snapshot: aggregated client health (leader only)\n s.on(CORE_EVENTS.HEALTH_SNAPSHOT, (payload: HealthSnapshotPayload) => {\n useAppStore.getState().setHealthSnapshot(payload);\n });\n // buffer_status: lightweight buffer data broadcast to all clients in room\n s.on(CORE_EVENTS.BUFFER_STATUS, (payload: BufferStatusPayload) => {\n useAppStore.getState().setBufferStatus(payload);\n });\n}\n\nfunction wireCoreHandlers(s: Socket): void {\n wireSync(s);\n wirePresence(s);\n wireChat(s);\n wireHealth(s);\n wirePlaylist(s);\n wireTierlist(s);\n wireReadyCheck(s);\n wireGame(s);\n\n // error: { code, message? }\n s.on(CORE_EVENTS.ERROR, (e: ErrorPayload) => {\n const code = e?.code || 'error/unknown';\n\n // Sprite conflict: silently retry with next available sprite from roster.\n // This fires when identity_update requests a sprite that's already claimed.\n // The refusal's other reason: the sprite is held by ANOTHER CONNECTION OF THE SAME\n // ACCOUNT (a second browser). Accept what the server gave us; re-asking is what\n // tripped sprite_taken in the first place.\n if (code === 'conflict' && e?.message === 'sprite_held_by_you') {\n spriteHeldByOwnOtherConnection = true;\n debug('socket', 'sprite held by this account\\'s other connection: keeping the server-assigned sprite');\n return;\n }\n if (code === 'conflict' && e?.message === 'sprite_taken') {\n // A refusal can be stale. Until the first presence we have no seat to\n // compare against — the presence itself brings the server's pick, which\n // the handler above adopts. And once our sprite matches the server's,\n // the refusal answered an earlier ask the server has since settled.\n // Retrying in either case asked for a sprite nobody needed, drew a fresh\n // refusal, and cascaded into identity.rate_limit.\n if (isStaleSpriteRefusal(socket?.id)) {\n debug('socket', 'sprite_taken: stale, the server already has our sprite');\n return;\n }\n // The retry emits its own payload; the store-change reassert must not\n // send the new sprite a second time.\n identityEmitInHand = true;\n let retry: ReturnType<typeof retryTakenSprite>;\n try {\n retry = retryTakenSprite();\n } finally {\n identityEmitInHand = false;\n }\n if (retry) s.emit(CORE_EVENTS.IDENTITY_UPDATE, retry);\n return;\n }\n\n const map: Record<string, string> = {\n 'control/forbidden': 'You are not the leader.',\n 'control/stale_seq': 'Stale control sequence.',\n 'control/seq_gap': 'Control sequence gap detected.',\n 'rate/limited': 'Rate limited. Slow down.',\n 'payload/too_large': 'Payload too large.',\n 'room/full': 'Room is full.',\n 'auth/invalid_key': 'Invalid room key.',\n 'auth/leader_occupied': 'A leader is already connected to this room.',\n 'auth/friend_required': 'Sign in to join this room.',\n 'origin_block': 'Origin not allowed.',\n 'conflict': 'Character is already taken by another user.',\n 'recap/no_media': 'Load an episode first.',\n 'recap/no_previous': 'This is the first episode of the season — nothing to recap.',\n 'recap/not_episode': 'Recaps are only available for episodes.',\n 'recap/not_found': 'No recap available for the previous episode.'\n };\n const message = map[code] || code;\n // recap/* are informational outcomes of a command the user ran, not\n // faults: \"this is the first episode\" is an answer, and an error toast\n // (plus an error-level log) overstates it.\n if (code.startsWith('recap/')) {\n debug('socket', `recap unavailable: ${message}`, { code });\n useAppStore.getState().pushToast('info', message);\n return;\n }\n // An access refusal the UI shows (auth/*: invalid key, leader occupied,\n // friend required) is an expected outcome of a room visit, not a client\n // fault — it fires in normal use (a stale link, a signed-out visitor)\n // and in tests that deliberately provoke it (room-chrome's unprovisioned-\n // room-without-a-friend-key case). Logging it at error() forwards to the\n // server at pino ERROR, which scripts/e2e.js's summary.txt error count\n // fails the WHOLE SUITE on (test-runner.js: serverErrors !== 0) — outside\n // and unfiltered by the per-test/per-suite warn allowlist, which only\n // ever sees warn-level entries. Every other server error code keeps\n // logging at error(); only auth/* is downgraded (2026-10-01, board H7).\n const logRefusal = code.startsWith('auth/') ? warn : error;\n logRefusal('socket', `Server error: ${message}`, { code, raw: e });\n useAppStore.getState().pushToast('error', message);\n });\n}\n\n// outbound helpers\nexport function sendChat(text: string, images?: TChatImage[]) {\n // `images` is omitted rather than sent as [] so a text-only message is the\n // exact payload it was before attachments existed.\n getSocket().emit(CORE_EVENTS.CHAT_SEND, images?.length ? { text, images } : { text });\n}\n\nfunction initiateTimePing() {\n if (timePingInflight) return; // wait for prior\n timePingInflight = { ts: Date.now() };\n getSocket().emit(CORE_EVENTS.TIME_PING, {});\n // Clear inflight after 10s if pong never arrives, so future pings aren't blocked forever\n timePingTimeout = setTimeout(() => {\n if (timePingInflight) {\n debug('socket', 'Time ping timed out after 10s, clearing inflight');\n timePingInflight = null;\n }\n timePingTimeout = null;\n }, 10_000);\n}\n\n/**\n * The fleet settings popout changed this person's avatar (`hadoku:avatar`,\n * lib/avatar.ts). `sprite` is the character they now ask for, or null.\n *\n * Not joined yet: the identity is adopted and the join carries it. Joined: ONE\n * identity_update, carrying the new character (the room's uniqueness rules\n * still decide; a taken one falls back exactly as a join's does) and\n * `avatar: true`, which makes the server re-read the picture fresh — so a\n * picture-only change, with the same character, reaches the room too.\n */\nexport function sendAvatarChange(sprite: string | null): void {\n const before = useAppStore.getState();\n const myId = before.me.clientId;\n if (!myId || !before.roster[myId]) {\n adoptRequestedSprite(sprite);\n debug('socket', 'Avatar change before join: the join will carry it', { sprite });\n return;\n }\n // This module emits the change itself; the store-change reassert must not\n // send a second copy of it.\n identityEmitInHand = true;\n try {\n adoptRequestedSprite(sprite);\n } finally {\n identityEmitInHand = false;\n }\n const after = useAppStore.getState();\n const payload: { name?: string; sprite?: string; avatar: true } = { avatar: true };\n if (after.sprite && after.sprite !== before.sprite) payload.sprite = after.sprite;\n // A character name follows the character; a registry name never changes here.\n if (after.name && after.name !== before.name) payload.name = after.name;\n debug('socket', 'Sending avatar change', payload);\n getSocket().emit(CORE_EVENTS.IDENTITY_UPDATE, payload);\n}\n\nexport function sendIdentityUpdate(name?: string, sprite?: string | null) {\n const payload: { name?: string; sprite?: string } = {};\n if (name) payload.name = name;\n if (sprite) payload.sprite = sprite;\n if (!payload.name && !payload.sprite) return;\n debug('socket', 'Sending identity update', payload);\n getSocket().emit(CORE_EVENTS.IDENTITY_UPDATE, payload);\n}\n\n// Identity-reassert subscription: when the local store's name or sprite\n// changes AFTER we've joined a room, push the change to the server so\n// other clients' rosters update. Without this, a fresh-device direct\n// /room/{key} link races:\n// - Room.tsx fires connectAndJoin BEFORE syncFromServerIfFirstLoad\n// resolves (the prefs fetch is async, the join is sync-from-mount).\n// - Server auto-assigns a sprite; presence broadcasts it to everyone.\n// - Later, /api/me/prefs lands; rehydrateFromPrefs sets local sprite\n// to the saved one. But joinedRef in Room.tsx is now true — no\n// re-join fires, and the snapshot reassert handler can't help\n// because no new snapshot lands (it's only pushed on server events).\n// Bug 1 from the 2026-05-20 cedar-ridge retrospective.\n//\n// Guards: only emit if we're actually joined (me.clientId is in our own\n// roster, set by applySnapshot post-join) AND the new value differs from\n// the server roster's view of us (avoids emitting on the join's own\n// snapshot-applied update). Idempotent server-side anyway.\nlet _lastReasserted = { name: '', sprite: '' as string | null };\nuseAppStore.subscribe((state, prev) => {\n if (state.name === prev.name && state.sprite === prev.sprite) return;\n if (identityEmitInHand) return;\n const myId = state.me.clientId;\n if (!myId) return;\n const myEntry = state.roster[myId];\n if (!myEntry) return; // not yet joined\n const wantsName = !!state.name\n && !isCharacterName(state.name)\n && state.name !== _lastReasserted.name\n && (isCharacterName(myEntry.name || '') || myEntry.name !== state.name);\n const wantsSprite = !!state.sprite\n && state.sprite !== _lastReasserted.sprite\n && myEntry.sprite !== state.sprite;\n if (!wantsName && !wantsSprite) return;\n const payload: { name?: string; sprite?: string } = {};\n if (wantsName) { payload.name = state.name; _lastReasserted.name = state.name; }\n if (wantsSprite) { payload.sprite = state.sprite!; _lastReasserted.sprite = state.sprite!; }\n debug('socket', 'Identity reassert (store change)', payload);\n if (socket?.connected) {\n socket.emit(CORE_EVENTS.IDENTITY_UPDATE, payload);\n } else {\n // Buffered emit fires once connected.\n getSocket().emit(CORE_EVENTS.IDENTITY_UPDATE, payload);\n }\n});\n\n/** Clear time-sync timers. Call on navigation/unmount to prevent leaked intervals. */\nfunction cleanupTimers() {\n if (timePingInterval) { clearInterval(timePingInterval); timePingInterval = null; }\n if (timePingTimeout) { clearTimeout(timePingTimeout); timePingTimeout = null; }\n timePingInflight = null;\n liveness.unansweredSince = null;\n liveness.lastTickAt = null;\n}\n\n/** Clear stored join payload. Call on intentional disconnect to prevent auto-rejoin. */\nfunction clearJoinState(): void {\n debug('socket', 'clearJoinState called', { hadPayload: lastJoinPayload !== null, room_key: lastJoinPayload?.room_key });\n lastJoinPayload = null;\n hasConnectedOnce = false;\n lastReadyMediaId = null;\n}\n\n/**\n * Leave the current room: clear join state, stop timers, disconnect the\n * socket, and reset room-session store state.\n *\n * The disconnect is the important part — without it the socket stays open,\n * the server keeps counting us in the room's presence, and the Home page\n * (which reads /api/rooms) shows our avatar until a manual refresh. Nulling\n * the socket + resetting `me`/`roster` also ensures a later re-join emits a\n * fresh `join` rather than tripping connectAndJoin's \"already joined\" guard.\n */\nexport function leaveRoom(): void {\n debug('socket', 'leaveRoom called', { room_key: lastJoinPayload?.room_key });\n clearJoinState();\n cleanupTimers();\n if (socket) {\n socket.disconnect();\n socket = null;\n }\n useAppStore.setState({\n me: { clientId: null, nextClientSeq: 1 },\n roster: {},\n snapshot: { roomId: null, mediaId: null, playheadMs: 0, playing: false, serverSeq: 0, leaderId: null },\n chat: [],\n playlist: null,\n activePlaylistIndex: null,\n myVotes: {},\n voteProgress: [],\n playlistResults: null,\n readiness: { mediaId: null, ready: false, readyCount: 0, total: 0 },\n readyCheck: { active: false, ready: [] },\n activeGameId: null,\n });\n}\n\n// ── Playlist outbound emitters ──────────────────────────────────────────────\n\nexport function emitPlaylistLoad(playlistId: string): void {\n debug('playlist', 'Emitting playlist_load', { playlistId });\n getSocket().emit(PLAYLIST_EVENTS.LOAD, { playlistId });\n}\n\nexport function emitPlaylistSelect(index: number): void {\n debug('playlist', 'Emitting playlist_select', { index });\n getSocket().emit(PLAYLIST_EVENTS.SELECT, { index });\n}\n\nexport function emitVoteUpdate(playlistId: string, mediaId: string, vote: TVoteValue): void {\n debug('playlist', 'Emitting playlist_vote_update', { playlistId, mediaId, vote });\n getSocket().emit(PLAYLIST_EVENTS.VOTE_UPDATE, { playlistId, mediaId, vote });\n}\n\n/**\n * Ask the server to broadcast the previous episode's recap to the room.\n *\n * The server owns the whole decision — which episode is \"previous\", whether a\n * recap was prebuilt, and the rendering — because it is the only side that can\n * see the media tree. The client just asks. Failures come back as a normal\n * socket `error` with a recap/* code.\n */\nexport function emitRecapRequest(): void {\n debug('chat', 'Emitting recap_request');\n getSocket().emit('recap_request');\n}\n\nexport function emitRevealRequest(): void {\n debug('playlist', 'Emitting playlist_reveal_request');\n getSocket().emit(PLAYLIST_EVENTS.REVEAL_REQUEST, {});\n}\n\n/** Leader: remove one voter (a key of the results' `votes`) from the reveal. */\nexport function emitVoteRemove(voterKey: string): void {\n debug('playlist', 'Emitting playlist_vote_remove', { voterKey });\n getSocket().emit(PLAYLIST_EVENTS.VOTE_REMOVE, { voterKey });\n}\n\n\n\n/**\n * Emit client_ready and remember the mediaId so it can be re-emitted on reconnect.\n * Call this instead of getSocket().emit('client_ready', ...) directly.\n * On reconnect, the server loses the ready state for the old socket ID.\n * Re-emitting ensures the readiness count is restored without requiring a full re-init.\n */\nexport function emitClientReady(mediaId: string): void {\n lastReadyMediaId = mediaId;\n getSocket().emit(CORE_EVENTS.CLIENT_READY, { media_id: mediaId });\n debug('socket', 'client_ready emitted', { mediaId });\n}\n","import React from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport { RouterProvider } from 'react-router-dom';\nimport type { AppProps } from './App';\nimport { createWatchpartyRouter } from './router';\nimport { setRuntimeConfig } from './lib/config';\nimport { loadDisplayNames } from './lib/characters';\nimport { error as logError, warn as logWarn, debug as logDebug, errorFields } from './lib/debug';\nimport { loadPreferences, syncFromServerIfFirstLoad } from './lib/preferences';\nimport { setAuth, loadWhoami, getUserId, getPrefsCacheUserId } from './lib/auth';\nimport { primeDeviceId } from './lib/deviceId';\nimport { useAppStore } from './lib/store';\nimport { leaveRoom } from './lib/socket'; // also installs the module-level identity-reassert subscriber\nimport { exposeDebugGlobals } from './lib/debugGlobals';\nimport { saveTheme, THEMES, type Theme } from '@wolffm/themes';\nimport '@wolffm/themes/style.css';\n// Icon sizing + accent tiles, unlayered next to style.css (THEME_USAGE_GUIDE).\nimport '@wolffm/themes/icons.css';\nimport './styles.css';\n\nexport type { AppProps } from './App';\nexport { createWatchpartyRouter } from './router';\nexport type { CreateWatchpartyRouterOptions } from './router';\n\nexport type WatchpartyMountProps = AppProps & {\n basename?: string;\n strictMode?: boolean;\n};\n\ntype MountedInstance = {\n root: Root;\n};\n\n/** The mount element, carrying its instance so a re-mount or unmount finds it. */\ntype MountTarget = HTMLElement & { __watchparty?: MountedInstance };\n\nfunction injectPreconnect(origin: string) {\n if (!origin || origin === '/') return;\n if (document.querySelector(`link[rel=\"preconnect\"][href=\"${origin}\"]`)) return;\n const link = document.createElement('link');\n link.rel = 'preconnect';\n link.href = origin;\n link.crossOrigin = 'anonymous';\n document.head.appendChild(link);\n}\n\nfunction render(el: HTMLElement, routerContent: React.ReactElement, strictMode: boolean) {\n const root = createRoot(el);\n const element = strictMode ? (\n <React.StrictMode>{routerContent}</React.StrictMode>\n ) : (\n routerContent\n );\n root.render(element);\n return root;\n}\n\n// The page-wide rejection logger. Held so `unmount()` can remove it: a host\n// that unmounts watchparty (hadoku_site on a route change away from it) must\n// not keep a watchparty listener on its window.\nlet unhandledRejectionHandler: ((event: PromiseRejectionEvent) => void) | null = null;\nlet uncaughtErrorHandler: ((event: ErrorEvent) => void) | null = null;\n\n/** Where this bundle was loaded from; an uncaught error is ours only if thrown from under it. */\nconst BUNDLE_DIR = import.meta.url.replace(/[^/]*$/, '');\n\n/**\n * Uncaught SYNCHRONOUS errors were not forwarded at all — only promise\n * rejections were — so a throw inside an interval (the health reporter, the\n * time-ping tick) left nothing in the session log but the silence it caused.\n *\n * Only errors thrown from this bundle are ours: on hadoku.me the window's\n * `error` event also fires for the host shell and every other app on the page.\n * The ResizeObserver \"loop\" notices are a browser report, not a fault.\n */\nfunction isOurUncaughtError(event: ErrorEvent): boolean {\n if (!event.filename || !event.filename.startsWith(BUNDLE_DIR)) return false;\n return !/^ResizeObserver loop/.test(event.message ?? '');\n}\n\nexport function mount(el: MountTarget, props: WatchpartyMountProps = {}) {\n const { basename, strictMode = import.meta.env.DEV, ...appProps } = props;\n\n // The whole-app entry owns the page, and every E2E spec drives it through\n // the `window.__*` handles — so it publishes them. The embeddable\n // `RoomChrome` does not (lib/debugGlobals.ts).\n exposeDebugGlobals();\n\n // Set runtime config for non-component code (socket, catalog, etc.)\n setRuntimeConfig({\n serverOrigin: appProps.serverOrigin,\n defaultRoomKey: appProps.defaultRoomKey,\n cdnBase: appProps.cdnBase,\n });\n\n // Mint the browser device id if this browser has none, so the join payload\n // can carry it (lib/deviceId.ts). Started here — the earliest point in boot\n // — because the join assembles synchronously and must never wait on it: a\n // client whose mint hasn't landed joins at the ephemeral tier instead.\n primeDeviceId();\n\n // Stash auth identity for non-component code (socket, fetch wrappers).\n // mf-loader pre-resolves the hadoku_session cookie and passes these as\n // mount props; userType defaults to 'public' when absent.\n setAuth({\n userType: appProps.userType,\n userId: appProps.userId,\n });\n // Re-read preferences now that setAuth has wired in the real userId.\n // The store's module-top-level loadPreferences() ran with userId='public'\n // (default before setAuth), so authed users' prefs in the user-keyed slot\n // were never loaded — causing the wipe-to-defaults on every reload.\n // Runs synchronously before React mounts so users never see the flash of\n // default state.\n useAppStore.getState().rehydrateFromPrefs();\n\n // Boot beacon: ALWAYS fires a warn-level log with the current pref state\n // so server.jsonl can confirm \"yes this user is running the new bundle\".\n // If this log doesn't appear for a session, the browser is serving cached\n // old code that doesn't have the SDK migration. Snapshot fields:\n // uid — getUserId() at the moment we emit (post-setAuth)\n // bundleHas — pref/storage facts that only the new code touches\n // storeName/Sprite — what the store ended up with after rehydrate\n // 2026-05-26 added during the cedar-ridge Frieren regression investigation.\n try {\n const uid = getUserId() || 'public';\n const sdkUid = getPrefsCacheUserId();\n const ls = typeof localStorage !== 'undefined' ? localStorage : null;\n const legacyAnon = ls?.getItem('watchparty_preferences');\n const legacyKeyed = ls && uid !== 'public' ? ls.getItem(`watchparty_preferences:${uid}`) : null;\n const sdkTheme = sdkUid ? ls?.getItem(`prefs-cache:${sdkUid}:portfolio`) : null;\n const sdkApp = sdkUid ? ls?.getItem(`prefs-cache:${sdkUid}:watchparty`) : null;\n const st = useAppStore.getState();\n // debug, not warn. This beacon was added 2026-05-26 as temporary\n // instrumentation for the cedar-ridge prefs investigation; that concluded\n // and is now locked in by five dedicated prefs regression specs\n // (prefs-persistence / -cross-user / -anon-to-authed / -legacy-migration,\n // bug1-sprite-prefs-race). Left at warn it fired on EVERY boot of EVERY\n // client forever — noise in production session logs, and it failed ~30 E2E\n // tests via the unexpected-warning gate. Per the log-level policy, routine\n // \"this is what happened\" events are debug; warn is for real problems.\n // debug still forwards to the server when reportLogs=true, so the\n // diagnostic remains available in E2E without polluting prod.\n logDebug('boot', 'prefs.beacon', {\n uid,\n sdkUid,\n legacyAnonBytes: legacyAnon?.length ?? 0,\n legacyKeyedBytes: legacyKeyed?.length ?? 0,\n sdkThemeBytes: sdkTheme?.length ?? 0,\n sdkAppBytes: sdkApp?.length ?? 0,\n storeName: st.name,\n storeSprite: st.sprite,\n });\n } catch (e) {\n logWarn('boot', 'prefs.beacon.threw', { err: (e as Error)?.message });\n }\n // Fire-and-forget whoami to populate display name. Cookie auto-included.\n loadWhoami().catch((e: unknown) => logWarn('boot', 'whoami threw', errorFields(e)));\n // Cross-device pref prefill: on this user's first load per device, pull\n // their last-used prefs from the server. Async + idempotent — re-hydrate\n // the store if anything merged in. No-op for anonymous users or if\n // already synced. Failures are silent (logged warn) and will retry next\n // session.\n syncFromServerIfFirstLoad().then((merged) => {\n if (merged) useAppStore.getState().rehydrateFromPrefs();\n // socket.ts subscribes to name/sprite changes and re-asserts to the\n // server whenever they drift from the server roster. The rehydrate\n // above is what triggers that in the fresh-device case (Bug 1).\n }).catch((e: unknown) => logWarn('boot', 'prefs sync threw', errorFields(e)));\n\n // Register global unhandled rejection handler once\n if (!unhandledRejectionHandler) {\n unhandledRejectionHandler = (event) => {\n logError('app', 'Unhandled promise rejection', { reason: String(event.reason) });\n };\n window.addEventListener('unhandledrejection', unhandledRejectionHandler);\n }\n if (!uncaughtErrorHandler) {\n uncaughtErrorHandler = (event) => {\n if (!isOurUncaughtError(event)) return;\n logError('app', 'Uncaught error', {\n message: event.message,\n source: `${event.filename.slice(BUNDLE_DIR.length)}:${event.lineno}:${event.colno}`,\n stack: event.error instanceof Error ? event.error.stack?.slice(0, 1500) : undefined,\n });\n };\n window.addEventListener('error', uncaughtErrorHandler);\n }\n\n // Early preconnect to server origin for faster API/socket/sprite fetches\n if (appProps.serverOrigin) {\n injectPreconnect(appProps.serverOrigin);\n }\n\n // Restore persisted theme before first render. Two storage layers stack on\n // hadoku.me page loads: a blocking inline script in Base.astro reads\n // sessionStorage['hadoku-theme'] BEFORE our bundle runs and applies the\n // theme to the DOM (or falls back to prefers-color-scheme: dark when empty).\n // Our authoritative store is localStorage (survives tab close), so call\n // saveTheme which mirrors localStorage → sessionStorage + DOM. That keeps\n // the inline script in sync on the next cold-tab load — without this,\n // every fresh tab flashes the OS-default dark theme until our bundle\n // takes over.\n const savedTheme = loadPreferences().theme;\n if (savedTheme && (THEMES as readonly string[]).includes(savedTheme)) {\n saveTheme(savedTheme as Theme);\n }\n\n // Kick off display names fetch (non-blocking, optional file)\n loadDisplayNames().catch((e: unknown) => logWarn('boot', 'display names load threw', errorFields(e)));\n\n el.__watchparty?.root.unmount();\n const router = createWatchpartyRouter({\n basename,\n appProps: appProps,\n });\n const root = render(el, <RouterProvider router={router} />, strictMode);\n const instance: MountedInstance = { root };\n el.__watchparty = instance;\n return router;\n}\n\n/**\n * Tear down a `mount()`: the React root, the room, the socket and the\n * page-wide listener. Unmounting the React root alone left the socket\n * connected — the server kept the viewer in the room's presence and every\n * other client kept seeing them — for as long as the host page lived.\n */\nexport function unmount(el: MountTarget) {\n const instance = el.__watchparty;\n if (!instance) return;\n instance.root.unmount();\n delete el.__watchparty;\n leaveRoom();\n if (unhandledRejectionHandler) {\n window.removeEventListener('unhandledrejection', unhandledRejectionHandler);\n unhandledRejectionHandler = null;\n }\n if (uncaughtErrorHandler) {\n window.removeEventListener('error', uncaughtErrorHandler);\n uncaughtErrorHandler = null;\n }\n}\n"],"names":["__typeError","msg","__accessCheck","obj","member","__privateGet","getter","__privateAdd","value","PopStateEventType","createBrowserHistory","options","createBrowserLocation","window2","globalHistory","pathname","search","hash","createLocation","createBrowserHref","to","createPath","getUrlBasedHistory","invariant","message","warning","cond","createKey","getHistoryState","location","index","current","state","key","parsePath","path","parsedPath","hashIndex","searchIndex","getLocation","createHref2","validateLocation","v5Compat","action","listener","getIndex","handlePop","nextIndex","delta","history","push","historyState","url","error","replace2","createURL","createBrowserURLImpl","fn","n","isAbsolute","base","href","_map","RouterContextProvider","init","context","unsupportedLazyRouteObjectKeys","isUnsupportedLazyRouteObjectKey","unsupportedLazyRouteFunctionKeys","isUnsupportedLazyRouteFunctionKey","isIndexRoute","route","convertRoutesToDataRoutes","routes","mapRouteProperties2","parentPath","manifest","allowInPlaceMutations","treePath","id","indexRoute","mergeRouteUpdates","pathOrLayoutRoute","updates","matchRoutes","locationArg","basename","matchRoutesImpl","allowPartial","stripBasename","branches","flattenRoutes","rankRouteBranches","matches","i","decoded","decodePath","matchRouteBranch","convertRouteMatchToUiMatch","match","loaderData","params","parentsMeta","_hasParentOptionalSegments","flattenRoute","hasParentOptionalSegments","relativePath","meta","joinPaths","routesMeta","computeScore","exploded","explodeOptionalSegments","segments","first","rest","isOptional","required","restExploded","result","subpath","a","b","compareIndexes","paramRe","dynamicSegmentValue","indexRouteValue","emptySegmentValue","staticSegmentValue","splatPenalty","isSplat","s","initialScore","score","segment","branch","matchedParams","matchedPathname","end","remainingPathname","matchPath","normalizePathname","pattern","matcher","compiledParams","compilePath","pathnameBase","captureGroups","memo2","paramName","splatValue","caseSensitive","regexpSource","_","v","startIndex","nextChar","prependBasename","ABSOLUTE_URL_REGEX","isAbsoluteUrl","resolvePath","fromPathname","toPathname","oldPathname","resolvePathname","normalizeSearch","normalizeHash","getInvalidPathError","char","field","dest","getPathContributingMatches","getResolveToMatches","pathMatches","idx","resolveTo","toArg","routePathnames","locationPathname","isPathRelative","isEmptyPath","from","routePathnameIndex","toSegments","hasExplicitTrailingSlash","hasCurrentTrailingSlash","paths","ErrorResponseImpl","status","statusText","data2","internal","isRouteErrorResponse","getRoutePattern","m","isBrowser","parseToInfo","_to","absoluteURL","isExternal","currentUrl","targetUrl","UninstrumentedSymbol","getRouteInstrumentationUpdates","fns","aggregated","keys","instrumented","wrapImpl","lazyObject","lazyFn","instrumentations","handler","original","args","getHandlerInfo","middleware","instrumentClientSideRouter","router","navigate","instrumentedNavigate","opts","getRouterInfo","fetch2","instrumentedFetch","impls","getInfo","recurseRight","info","impl","handlerPromise","callHandler","e","request","unstable_pattern","getReadonlyRequest","getReadonlyContext","isPlainObject","frozen","ctx","objectProtoNames","thing","proto","validMutationMethodsArr","validMutationMethods","validRequestMethodsArr","validRequestMethods","redirectStatusCodes","redirectPreserveMethodStatusCodes","IDLE_NAVIGATION","IDLE_FETCHER","IDLE_BLOCKER","defaultMapRouteProperties","TRANSITIONS_STORAGE_KEY","ResetLoaderDataSymbol","createRouter","routerWindow","isBrowser3","hydrationRouteProperties2","_mapRouteProperties","dataRoutes","inFlightDataRoutes","dataStrategyImpl","defaultDataStrategyWithMiddleware","future","unlistenHistory","subscribers","savedScrollPositions2","getScrollRestorationKey2","getScrollPosition","initialScrollRestored","initialMatches","initialMatchesIsFOW","initialErrors","initialized","getInternalRouterError","getShortCircuitMatches","checkFogOfWar","routeHasLoaderOrMiddleware","errors","shouldLoadRouteOnHydration","fogOfWar","pendingAction","pendingPopstateNavigationDfd","pendingPreventScrollReset","pendingNavigationController","pendingViewTransitionEnabled","appliedViewTransitions","removePageHideEventListener","isUninterruptedRevalidation","isRevalidationRequired","cancelledFetcherLoads","fetchControllers","incrementingLoadId","pendingNavigationLoadId","fetchReloadIds","fetchRedirectIds","fetchLoadMatches","activeFetchers","fetchersQueuedForDeletion","blockerFunctions","unblockBlockerHistoryUpdate","pendingRevalidationDfd","initialize","historyAction","blockerKey","shouldBlockNavigation","nextHistoryUpdatePromise","resolve","updateBlocker","blockers","updateState","startNavigation","restoreAppliedTransitions","_saveAppliedTransitions","persistAppliedTransitions","dispose","deleteFetcher","deleteBlocker","subscribe","newState","matchRoute","unmountedFetchers","mountedFetchers","fetcher","subscriber","completeNavigation","flushSync","isActionReload","isMutationMethod","actionData","mergeLoaderData","k","restoreScrollPosition","getSavedScrollPosition","preventScrollReset","viewTransitionOpts","priorPaths","toPaths","createDeferred","promise","normalizedPath","normalizeTo","submission","normalizeNavigateOptions","currentLocation","nextLocation","userReplace","revalidate","interruptActiveLoads","saveScrollPosition","routesToUse","loadingNavigation","isHashChangeOnly","notFoundMatches","handleNavigational404","createClientSideRequest","scopedContext","pendingActionResult","findNearestBoundary","actionResult","handleAction","routeId","isErrorResult","getLoadingNavigation","shortCircuited","updatedMatches","handleLoaders","getActionDataForCommit","isFogOfWar","initialHydration","navigation","getSubmittingNavigation","discoverResult","discoverRoutes","matches2","boundaryId","actionMatch","getTargetMatch","dsMatches","getTargetedDataStrategyMatches","results","callDataStrategy","isRedirectResult","normalizeRedirectLocation","startRedirectNavigation","boundaryMatch","overrideNavigation","fetcherSubmission","callSiteDefaultShouldRevalidate","activeSubmission","getSubmissionFromNavigation","shouldUpdateNavigationState","getUpdatedActionData","revalidatingFetchers","getMatchesToLoad","updatedFetchers2","markFetchRedirectsDone","getUpdatedRevalidatingFetchers","rf","abortFetcher","abortPendingFetchRevalidations","f","loaderResults","fetcherResults","callLoadersAndMaybeResolveData","redirect2","findRedirect","processLoaderData","updatedFetchers","didAbortFetchLoads","abortStaleFetchLoads","shouldUpdateFetchers","revalidatingFetcher","getLoadingFetcher","setFetcherError","handleFetcherAction","handleFetcherLoader","requestMatches","existingFetcher","updateFetcherState","getSubmittingFetcher","abortController","fetchRequest","originatingLoadId","fetchMatches","actionResults","match2","getDoneFetcher","revalidationRequest","loadId","loadFetcher","staleKey","existingFetcher2","r","doneFetcher","isNavigation","redirectLocation","isDocumentReload","redirectNavigationType","formMethod","formAction","formEncType","fetcherKey","dataResults","callDataStrategyImpl","isRedirectDataStrategyResult","response","normalizeRelativeRoutingRedirectResponse","convertDataStrategyResultToDataResult","fetchersToLoad","loaderResultsPromise","fetcherResultsPromise","acc","getFetcher","resetFetcher","queueFetcherForDeletion","count","reason","controller","markFetchersDone","doneKeys","landedId","yeetedKeys","getBlocker","blocker","newBlocker","entries","blockerFunction","enableScrollRestoration","positions","getPosition","getKey","y","getScrollKey","signal","partialMatches","isNonHMR","localManifest","children","patchRoutesImpl","newMatches","newPartialMatches","compareMatches","_internalSetRoutes","newRoutes","patchRoutes","unstable_allowElementMutations","isSubmissionNavigation","fromRouteId","relative","contextualMatches","activeRouteMatch","nakedIndex","hasNakedIndexQuery","indexValues","qs","isFetcher","isValidMethod","getInvalidBodyError","stripHashFromPath","text","name","json","searchParams","formData","convertFormDataToSearchParams","convertSearchParamsToFormData","lazyRoutePropertiesToSkip","hasPatchRoutesOnNavigation","nextUrl","maxIdx","actionStatus","shouldSkipRevalidation","baseShouldRevalidateArgs","forceShouldLoad","isNewLoader","getDataStrategyMatch","defaultShouldRevalidate","isNewRouteInstance","shouldRevalidateArgs","shouldLoad","shouldRevalidateLoader","isMidInitialLoad","fetcherMatches","fetcherMatch","fetchController","fetcherDsMatches","hasData","hasError","currentLoaderData","currentMatch","isNew","isMissingData","currentPath","loaderMatch","arg","routeChoice","allowElementMutations","childrenToPatch","uniqueChildren","existingChildren","newRoute","existingRoute","existingRoute2","isSameRoute","existingRouteTyped","newRouteTyped","aChild","bChild","lazyRoutePropertyCache","loadLazyRouteProperty","routeToUpdate","cache","cachedPromise","propertyPromise","isUnsupported","isStaticallyDefined","lazyRouteFunctionCache","loadLazyRoute","type","lazyRoutePromise2","lazyRoute","routeUpdates","lazyRouteProperty","lazyValue","lazyKeys","lazyPropertyPromises","lazyHandlerPromise","lazyRoutePromise","defaultDataStrategy","matchesToLoad","keyedResults","runClientMiddlewarePipeline","runMiddlewarePipeline","isRedirectResponse","isDataStrategyResults","errorHandler","nextResult","maxBoundaryIdx","boundaryRouteId","processResult","isResult","tuples","callRouteMiddleware","middlewares","tuple","next","getDataStrategyMatchLazyPromises","lazyMiddlewarePromise","lazyRoutePromises","isUsingNewApi","_lazyPromises","handlerOverride","lazy","loader","isMiddlewareOnlyRoute","callLoaderOrAction","targetMatch","isStaticHandler","dataStrategyArgs","cb","typedDataStrategyArgs","onReject","isAction","runHandler","reject","abortPromise","actualHandler","handlerError","handler2","parseResponseBody","contentType","dataStrategyResult","isResponse","isDataWithResponseInit","dataWithResponseInitToErrorResponse","trimmedMatches","historyInstance","invalidProtocols","normalizedLocation","isSameBasename","processRouteLoaderData","skipLoaderErrorBubbling","statusCode","foundError","loaderHeaders","pendingError","newLoaderData","mergedLoaderData","merged","method","errorMessage","isDataStrategyResult","isRedirectStatusCode","_window","transitions","sessionPositions","res","rej","val","DataRouterContext","React","DataRouterStateContext","RSCRouterContext","useIsRSCRouterContext","ViewTransitionContext","FetchersContext","AwaitContext","NavigationContext","LocationContext","RouteContext","RouteErrorContext","ERROR_DIGEST_BASE","ERROR_DIGEST_REDIRECT","ERROR_DIGEST_ROUTE_ERROR_RESPONSE","decodeRedirectErrorDigest","digest","parsed","decodeRouteErrorResponseDigest","useHref","useInRouterContext","navigator","React2","useResolvedPath","joinedPathname","useLocation","navigateEffectWarning","useIsomorphicLayoutEffect","useNavigate","isDataRoute","useNavigateStable","useNavigateUnstable","dataRouterContext","routePathnamesJson","activeRef","useParams","routeMatch","useRoutesImpl","dataRouterState","onError","parentMatches","parentParams","parentPathname","parentPathnameBase","parentRoute","warningOnce","locationFromContext","parentSegments","_renderMatches","DefaultErrorComponent","useRouteError","stack","lightgrey","preStyles","codeStyles","devInfo","defaultErrorElement","RenderErrorBoundary","props","errorInfo","RSCErrorHandler","errorRedirectHandledMap","existingRedirect","redirectPromise","RenderedRoute","routeContext","onErrorHandler","renderedMatches","errorIndex","renderFallback","fallbackIndex","errors2","needsToRunLoader","outlet","shouldRenderHydrateFallback","errorElement","hydrateFallbackElement","getChildren","getDataRouterConsoleError","hookName","useDataRouterContext","useDataRouterState","useRouteContext","useCurrentRouteId","thisRoute","useRouteId","alreadyWarned","alreadyWarned2","warnOnce","condition","USE_OPTIMISTIC","useOptimisticImpl","React3","stableUseOptimisticSetter","useOptimisticSafe","mapRouteProperties","hydrationRouteProperties","Deferred","RouterProvider","reactDomFlushSyncImpl","unstable_useTransitions","_state","setStateImpl","setOptimisticState","pendingState","setPendingState","vtContext","setVtContext","renderDfd","setRenderDfd","transition","setTransition","interruption","setInterruption","fetcherData","setState","deletedFetchers","newErrors","isViewTransitionAvailable","getOptimisticRouterState","t","renderPromise","transition2","state2","Router","MemoizedDataRoutes","currentState","DataRoutes","basenameProp","locationProp","navigationType","staticProp","navigationContext","locationContext","trailingPathname","defaultMethod","defaultEncType","isHtmlElement","object","isButtonElement","isFormElement","isInputElement","isModifiedEvent","event","shouldProcessLinkClick","target","_formDataSupportsSubmitter","isFormDataSubmitterSupported","supportedFormEncTypes","getFormEncType","encType","getFormSubmissionInfo","body","attr","form","prefix","invariant2","singleFetchUrl","reqUrl","trailingSlashAware","extension","loadRouteModule","routeModulesCache","routeModule","isHtmlLinkDescriptor","getKeyedPrefetchLinks","routeModules","links","mod","dedupeLinkDescriptors","link","getNewMatchesForLinks","page","nextMatches","currentMatches","mode","matchPathChanged","manifestRoute","getModuleLinkHrefs","includeHydrateFallback","dedupeHrefs","hrefs","sortKeys","sorted","descriptors","preloads","set","deduped","descriptor","useDataRouterContext2","React8","useDataRouterStateContext","FrameworkContext","useFrameworkContext","usePrefetchBehavior","prefetch","theirElementProps","frameworkContext","maybePrefetch","setMaybePrefetch","shouldPrefetch","setShouldPrefetch","onFocus","onBlur","onMouseEnter","onMouseLeave","onTouchStart","ref","callback","entry","observer","setIntent","cancelIntent","composeEventHandlers","theirHandler","ourHandler","PrefetchPageLinks","linkProps","PrefetchPageLinksImpl","useKeyedPrefetchLinks","keyedPrefetchLinks","setKeyedPrefetchLinks","interrupted","newMatchesForData","newMatchesForAssets","dataHrefs","routesParams","foundOptOutRoute","m2","moduleHrefs","mergeRefs","refs","isBrowser2","createBrowserRouter","parseHydrationData","deserializeErrors","serialized","ErrorConstructor","ABSOLUTE_URL_REGEX2","Link","React10","onClick","discover","reloadDocument","viewTransition","unstable_defaultShouldRevalidate","forwardedRef","prefetchRef","prefetchHandlers","internalOnClick","useLinkClickHandler","handleClick","NavLink","ariaCurrentProp","classNameProp","styleProp","routerState","isTransitioning","useViewTransitionState","nextLocationPathname","endSlashPosition","isActive","isPending","renderProps","ariaCurrent","className","style","Form","onSubmit","submit","useSubmit","useFormAction","submitHandler","submitter","submitMethod","doSubmit","getDataRouterConsoleError2","useDataRouterContext3","replaceProp","doNavigate","fetcherId","getUniqueFetcherId","currentRouteId","routerFetch","routerNavigate","nextPath","RouterProvider2","ReactDOM","createStoreImpl","createState","listeners","partial","replace","nextState","previousState","getState","api","initialState","createStore","identity","useStore","selector","slice","createImpl","useBoundStore","create","DEFAULT_CDN_BASE","CHAT_IMAGE_KEY_RE","isChatImageKey","DEFAULT_HTTP_PORT","DEFAULT_UI_PORT","DEFAULT_DRIFT_SOFT_MS","DEFAULT_WS_PATH","DEFAULT_CHAT_MAX_LENGTH","DEFAULT_CHAT_COOLDOWN_MS","DEFAULT_CHAT_MAX_IMAGES","DEFAULT_HEALTH_BROADCAST_INTERVAL_MS","_env","Tier","z","TIER_ORDER","MAX_IMAGE_DIMENSION","MAX_IMAGE_TITLE_LENGTH","CORE_EVENTS","ControlKind","EmbedContext","ChatImage","d","SystemMessageType","HealthReport","ClientHealth","BufferClient","VoteValue","PlaylistVideo","PlaylistType","PlaylistConfig","PlaylistVoteProgressItem","PLAYLIST_EVENTS","TierlistItem","TierlistBoard","TierlistPlacedOut","TIERLIST_EVENTS","READY_EVENTS","GAME_EVENTS","CHARACTER_SETS","ENTRIES","CHARACTER_ORDER","c","CHARACTER_COLORS","CHARACTER_ART_REV","portraitPath","rev","isCharacterId","sprite","MAX_CONCURRENT_JOBS","BUFFER_AHEAD_MS","INITIAL_BUFFER_MS","CRITICAL_BUFFER_MS","LOW_BUFFER_MS","LEADER_STALL_PAUSE_THRESHOLD_MS","STABLE_GAP_DWELL_MS","DEFAULT_PREFETCH_INTERVAL_MS","DEFAULT_BUFFER_GATE_TIMEOUT_MS","INIT_DIGEST_TRACK_COUNT","INIT_RETRY_DELAY_MS","MAX_INIT_FETCH_RETRIES","END_OF_STREAM_RETRY_INTERVAL_MS","MAX_FETCH_ERROR_CYCLES","ERROR_RESET_AGE_MS","APPEND_HOLD_MAX_MS","BACKGROUND_FETCH_PRIORITY_MS","DEFAULT_CLIENT_TIME_PING_INTERVAL_MS","FRAGMENT_MP4_FILENAME","HEALTH_ENDPOINT","DEFAULT_FRAGMENT_DELIVERY_FLAG","FRAGMENT_DELIVERY_MODES","isFragmentDeliveryMode","normalizeFragmentDeliveryFlag","raw","o","percent","hashClientId","clientId","h","resolveDeliveryArm","flag","override","SubmissionKind","SubmissionState","SUBMISSION_TRANSITIONS","Submission","SUBMISSION_SOURCE_MAX_CHARS","SUBMISSION_TITLE_MAX_CHARS","SUBMISSION_SERIES_MAX_CHARS","GAME_ID_RE","PROBE_ORIGIN","isSameOriginPath","SameOriginPath","GameEntryBase","GameEntrySchema","GameCatalogSchema","games","g","DEFAULT_GAME_CATALOG","ShowSource","ShowResult","VideoResult","SEARCH_MIN_QUERY","SEARCH_MAX_QUERY","MAX_BYTES","ACCEPTED_IMAGE_TYPES","ACCEPTED_AUDIO_TYPES","AUDIO_TYPE_ALIASES","kindOfType","DEFAULT_SEARCH_LIMIT","SEARCH_DEBOUNCE_MS","CdnError","retryAfterSeconds","parseRetryAfter","header","now","trimmed","seconds","at","reasonForStatus","errorFromResponse","DEFAULT_UPLOAD_PATH","KEY_PATTERN","preflight","file","kind","max","normalizeItem","createCdnClient","cdnBase","uploadPath","doFetch","err","uploadOptions","basePath","catalogueOptions","defaultSurface","searchOptions","query","useOptions","surface","filesFromClipboard","clipboardData","kinds","accept","isAccepted","fromFiles","item","filesFromDrop","dataTransfer","measureImage","creator","bitmap","dims","cached","setChatMediaConfig","config","getChatMediaCdnBase","getCdnClient","resolveChatImageUrl","DEFAULT_CONFIG","runtimeConfig","setRuntimeConfig","filtered","getRuntimeConfig","ConfigContext","createContext","useConfig","useContext","getServerOrigin","getRuntimeServerOrigin","STORAGE_KEYS","owner","playlistId","mediaId","storage","readStored","writeStored","storedKeys","removeStored","readStoredFlag","registry","exposed","registerDebugGlobal","publish","exposeDebugGlobals","logHistory","MAX_HISTORY","logQueue","logFlushTimeout","LOG_FLUSH_DELAY","LOG_FLUSH_DELAY_FAST","currentRoomContext","setLogRoomContext","isReportAllEnabled","isDebugEnabled","stored","getAllowedCategories","categories","formatTime","addToHistory","styles","safeStringify","data","_log","level","consoleFn","alwaysReport","alwaysShow","category","queueLogForServer","allowed","time","suffix","debug","warn","getLogHistory","clearLogHistory","enableDebug","disableDebug","MAX_DATA_SIZE","MAX_BATCH_SIZE","truncateData","truncated","vStr","beaconLog","origin","loc","flushLogsToServer","batch","prepared","chunk","chunkSize","entrySize","errorFields","delay","colorForSprite","spriteUrlFor","displayNames","loadPromise","loadDisplayNames","displayNameFor","isCharacterName","lower","dn","getPrefsCacheUserId","setAuth","input","getUserType","TIER_RANK","tierAtLeast","tier","minimum","isPrivileged","getUserId","voteOwnerScope","loadWhoami","WatchpartyPrefsSchema","watchpartyPrefs","createPrefsClient","THEME_KEYS","sdkCacheKey","appId","uid","identityPendingUnresolved","readSdkCache","stripRetiredNameFromCaches","rewritten","sdkRow","legacyRow","LEGACY_PREFIX","blob","_retired","latestThemeBlob","latestAppBlob","legacyMergedFor","loadPreferences","cacheTheme","cacheApp","themeBlob","appBlob","legacy","readLegacy","anonWritesThisLoad","isAnonymousNow","savePref","themePrefs","syncInFlight","subscribedOnce","syncFromServerIfFirstLoad","writeThrough","rehydrate","themeFromServer","appFromServer","useAppStore","store","themeKeyPost","appKeyPost","sdkThemePost","sdkAppPost","migrateLegacyIfNeeded","legacyKey","deleteLegacy","sdkHasTheme","sdkHasApp","themePatch","appPatch","themeKeys","appKeys","writeFailureWarned","env","CHAT_WIDTH_DEFAULT_PX","CHAT_WIDTH_MIN_PX","CHAT_WIDTH_MAX_PX","clampChatWidth","px","frameWidth","savedPrefs","get","usedSprites","snap","rosterUpdates","u","leaderId","newPlayheadMs","copy","messages","newVal","width","rtt","serverTime","clientSendTs","rtts","offsetMs","clientMid","volume","muted","lang","enabled","snapshot","progress","open","saving","adoptDraft","prev","itemId","row","without","gameId","mount","probed","prefs","tab","Toasts","toasts","pop","useEffect","timers","jsx","STAR_COUNT","StarfieldCanvas","canvasRef","useRef","starsRef","canvas","resize","parent","rect","resizeObserver","creationCounter","biasForIndex","makeStar","x","initial","creationIndex","bias","ultraRare","rare","colorRare","tri","min","u1","u2","sizeBase","sizeVariance","size","alpha","speedBase","speedScale","speed","normAlpha","normSize","cw","ch","twinkleAmount","twinkleEnabled","dimFloor","startVal","targetVal","duration","speedNorm","MIN_SEC","spanSec","exp","floorLift","lifeMsTotal","frameId","lastTime","MAX_DELTA_MS","drawCurvedBottomRect","bottomR","w","x0","y0","x1","y1","updateAlpha","dt","baseDur","jitter","p","eased","micro","updateColor","colors","cycle","c0","c1","rCol","gCol","bCol","render","deltaMs","OFFSCREEN_BUFFER","norm","scaled","newStar","baseAlphaRaw","FADE_MS","lifeFade","baseAlpha","starFillStyle","enhanced","len","ti","tp","linear","fade","scale","drawSize","headLeft","headTop","over","glowSize","MIN_LIGHTNESS","MAX_LIGHTNESS","SAMPLE_SIZE","MIN_ALPHA","averageColor","pixels","weight","clampLightness","l","rgbToHsl","clamped","r2","g2","b2","hslToRgb","hex","q","channel","pending","notify","readPicture","img","settle","color","personColor","read","usePersonColor","useSyncExternalStore","AvatarImage","alt","fallback","failedUrl","setFailedUrl","useState","portrait","Fragment","HADOKU_APP_LIBRARY_URL","isHadokuApp","userAgent","ROOMS_POLL_INTERVAL_MS","sortRooms","list","formatRoomName","UserAvatar","user","ring","jsxs","RoomCard","room","users","Home","rooms","setRooms","roomsLoading","setRoomsLoading","roomsError","setRoomsError","reloadTick","setReloadTick","roomsOrigin","setRoomsOrigin","retryRooms","effectId","retried","retryTimer","resolved","watchdogTimer","fetchRooms","attempt","fetchStartedAt","elapsedMs","pollTimer","APIDownFallback","FRAGMENT_DELIVERY_FLAG","TOKEN_RE","TRACK_ID_RE","isDeliveryConfigValid","cfg","buildFragmentUrl","tail","readDeliveryOverride","serverFlag","resolvedArm","armPinned","DELIVERY_CLIENT_ID_KEY","deliveryClientId","existing","fresh","setServerDeliveryFlag","getServerDeliveryFlag","resolveSessionArm","flagFetchStarted","loadServerDeliveryFlag","currentDeliveryArm","isFragmentDeliveryEnabled","arm","setGames","applyGameCatalog","fetchStarted","loadGameCatalog","getGameCatalog","useGameCatalog","lazyWithRetry","importer","PUBLIC_ROOM_IDS","isPublicRoom","roomKey","shouldRedirectToAuth","returnPath","Room","RoomFallback","RouteBody","redirect","App","apiDown","setApiDown","checkHealth","recheckHealth","interval","preloadAll","schedule","HadokuThemeRoot","createWatchpartyRouter","appProps","resolvedAppProps","storedDeviceId","DEVICE_ID_KEY","primeDeviceId","getDeviceId","cachedDeviceId","PACKET_TYPES","PACKET_TYPES_REVERSE","ERROR_PACKET","withNativeBlob","withNativeArrayBuffer","isView","encodePacket","supportsBinary","encodeBlobAsBase64","fileReader","content","toArray","TEXT_ENCODER","encodePacketToBinary","packet","encoded","chars","lookup","decode","base64","bufferLength","encoded1","encoded2","encoded3","encoded4","arraybuffer","bytes","decodePacket","encodedPacket","binaryType","mapBinary","decodeBase64Packet","SEPARATOR","encodePayload","packets","length","encodedPackets","decodePayload","encodedPayload","decodedPacket","createPacketEncoderStream","payloadLength","view","TEXT_DECODER","totalLength","chunks","concatChunks","buffer","j","createPacketDecoderStream","maxPayload","expectedLength","isBinary","headerArray","protocol","Emitter","mixin","on","callbacks","nextTick","setTimeoutFn","globalThisShim","defaultBinaryType","pick","NATIVE_SET_TIMEOUT","globalThis","NATIVE_CLEAR_TIMEOUT","installTimerFunctions","BASE64_OVERHEAD","byteLength","utf8Length","str","randomString","encode","qry","pairs","pair","TransportError","description","Transport","details","onPause","schema","hostname","encodedQuery","Polling","pause","total","close","hasCORS","empty","BaseXHR","isSSL","port","req","xhrStatus","Request","createRequest","uri","_a","xhr","fromError","unloadHandler","terminationEvent","hasXHR2","newRequest","XHR","forceBase64","xdomain","isReactNative","BaseWS","protocols","closeEvent","ev","lastPacket","WebSocketCtor","WS","_packet","WT","stream","decoderStream","reader","encoderStream","done","transports","re","parts","parse","src","pathNames","queryKey","regx","names","$0","$1","$2","withEventListeners","OFFLINE_EVENT_LISTENERS","SocketWithoutUpgrade","parsedUri","transportName","transport","payloadSize","hasExpired","cleanupAndClose","waitForUpgrade","SocketWithUpgrade","failed","onTransportOpen","cleanup","freezeTransport","onerror","onTransportClose","onclose","onupgrade","upgrades","filteredUpgrades","DEFAULT_TRANSPORTS","host","toString","withNativeFile","hasBinary","toJSON","deconstructPacket","buffers","packetData","pack","_deconstructPacket","placeholder","newData","reconstructPacket","_reconstructPacket","RESERVED_EVENTS","PacketType","Encoder","replacer","deconstruction","isObject","Decoder","reviver","isBinaryEvent","BinaryReconstructor","start","buf","payload","binData","Socket","io","nsp","_b","_c","ack","isTransportWritable","isConnected","timeout","timer","arg1","arg2","responseArgs","force","self","sent","pid","subDestroy","compress","Backoff","ms","rand","deviation","Manager","_parser","parser","Engine","socket","openSubDestroy","errorSub","nsps","source","sameNamespace","newConnection","resolveMediaUrls","root","resolveMediaAsset","relPath","resolveCardImage","thumbnail","refreshTierlist","warmed","warmTierlistPosters","saveTierlist","board","retryTakenSprite","st","used","free","keepName","isStaleSpriteRefusal","myClientId","seat","PREFS_API_BASE","LINK_MESSAGE_TYPE","LINK_WINDOW_NAME","LINK_POPUP_MARK","markPopup","AvatarError","readJson","createAvatarClient","call","send","getSettings","linkInPopup","provider","popup","authorizeUrl","settled","finish","failure","closedPoll","giveUp","image","AVATAR_EVENT","requestedSpriteOf","settings","fetchRequestedSprite","baseUrl","adoptRequestedSprite","listenForAvatarChanges","onChange","detail","MAX_FRAME_DEPTH","describeEmbedding","win","depth","resolveIdentityReassert","local","serverEntry","isDefaultName","wantsName","wantsAvatar","out","clearStoredVotes","playlist","removed","video","PONG_DEAD_AFTER_MS","SLEEP_GAP_MS","createLiveness","notePong","tick","connected","slept","pongAge","timePingInflight","timePingInterval","timePingTimeout","lastJoinPayload","TAB_ID","makeTabId","liveness","lastDisconnect","pendingDisconnectCause","reconnectCount","joinedIdentity","identityEmitInHand","spriteHeldByOwnOtherConnection","hasConnectedOnce","lastReadyMediaId","connectAndJoin","getSocket","sanitizeJoin","currentPongAgeMs","socketOrigin","livenessTick","initiateTimePing","sid","rejoinPayload","readyMediaId","onSnapshot","wireCoreHandlers","isServerPlaying","normalizeChatMessage","seqFallback","im","wireSync","stAfter","known","idResult","idPayload","newMediaId","readyCount","ready","wirePresence","roster","myId","mine","serverName","serverSprite","hasCustomName","nameToUse","stFinal","st3","wireChat","chatMsg","wirePlaylist","wireTierlist","wireReadyCheck","emitReadyCheckStart","emitReadyCheckToggle","wireGame","emitGameSelect","wireHealth","code","retry","sendChat","images","sendAvatarChange","before","after","sendIdentityUpdate","_lastReasserted","myEntry","wantsSprite","cleanupTimers","clearJoinState","leaveRoom","emitPlaylistLoad","emitPlaylistSelect","emitVoteUpdate","vote","emitRecapRequest","emitRevealRequest","emitVoteRemove","voterKey","emitClientReady","injectPreconnect","el","routerContent","strictMode","createRoot","element","unhandledRejectionHandler","uncaughtErrorHandler","BUNDLE_DIR","isOurUncaughtError","sdkUid","ls","legacyAnon","legacyKeyed","sdkTheme","sdkApp","logDebug","logWarn","logError","savedTheme","THEMES","saveTheme","instance","unmount"],"mappings":";;;;;;;;AAUA,IAAIA,KAAc,CAACC,MAAQ;AACzB,QAAM,UAAUA,CAAG;AACrB,GACIC,KAAgB,CAACC,GAAKC,GAAQH,MAAQG,EAAO,IAAID,CAAG,KAAKH,GAAY,YAAYC,CAAG,GACpFI,KAAe,CAACF,GAAKC,GAAQE,OAAYJ,GAAcC,GAAKC,GAAQ,yBAAyB,GAAGE,IAASA,EAAO,KAAKH,CAAG,IAAIC,EAAO,IAAID,CAAG,IAC1II,KAAe,CAACJ,GAAKC,GAAQI,MAAUJ,EAAO,IAAID,CAAG,IAAIH,GAAY,mDAAmD,IAAII,aAAkB,UAAUA,EAAO,IAAID,CAAG,IAAIC,EAAO,IAAID,GAAKK,CAAK,GAS/LC,KAAoB;AAiGxB,SAASC,GAAqBC,IAAU,IAAI;AAC1C,WAASC,EAAsBC,GAASC,GAAe;AACrD,QAAI,EAAE,UAAAC,GAAU,QAAAC,GAAQ,MAAAC,EAAA,IAASJ,EAAQ;AACzC,WAAOK;AAAA,MACL;AAAA,MACA,EAAE,UAAAH,GAAU,QAAAC,GAAQ,MAAAC,EAAA;AAAA;AAAA,MAEpBH,EAAc,SAASA,EAAc,MAAM,OAAO;AAAA,MAClDA,EAAc,SAASA,EAAc,MAAM,OAAO;AAAA,IAAA;AAAA,EAEtD;AACA,WAASK,EAAkBN,GAASO,GAAI;AACtC,WAAO,OAAOA,KAAO,WAAWA,IAAKC,GAAWD,CAAE;AAAA,EACpD;AACA,SAAOE;AAAA,IACLV;AAAA,IACAO;AAAA,IACA;AAAA,IACAR;AAAA,EAAA;AAEJ;AA4CA,SAASY,EAAUf,GAAOgB,GAAS;AACjC,MAAIhB,MAAU,MAASA,MAAU,QAAQ,OAAOA,IAAU;AACxD,UAAM,IAAI,MAAMgB,CAAO;AAE3B;AACA,SAASC,GAAQC,GAAMF,GAAS;AAC9B,MAAI,CAACE,GAAM;AACT,IAAI,OAAO,UAAY,OAAa,QAAQ,KAAKF,CAAO;AACxD,QAAI;AACF,YAAM,IAAI,MAAMA,CAAO;AAAA,IACzB,QAAY;AAAA,IACZ;AAAA,EACF;AACF;AACA,SAASG,KAAY;AACnB,SAAO,KAAK,SAAS,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE;AACnD;AACA,SAASC,GAAgBC,GAAUC,GAAO;AACxC,SAAO;AAAA,IACL,KAAKD,EAAS;AAAA,IACd,KAAKA,EAAS;AAAA,IACd,KAAKC;AAAA,EAAA;AAET;AACA,SAASZ,GAAea,GAASX,GAAIY,IAAQ,MAAMC,GAAK;AAatD,SAZe;AAAA,IACb,UAAU,OAAOF,KAAY,WAAWA,IAAUA,EAAQ;AAAA,IAC1D,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,GAAG,OAAOX,KAAO,WAAWc,GAAUd,CAAE,IAAIA;AAAA,IAC5C,OAAAY;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,KAAKZ,KAAMA,EAAG,OAAOa,KAAON,GAAA;AAAA,EAAU;AAG1C;AACA,SAASN,GAAW;AAAA,EAClB,UAAAN,IAAW;AAAA,EACX,QAAAC,IAAS;AAAA,EACT,MAAAC,IAAO;AACT,GAAG;AACD,SAAID,KAAUA,MAAW,QACvBD,KAAYC,EAAO,OAAO,CAAC,MAAM,MAAMA,IAAS,MAAMA,IACpDC,KAAQA,MAAS,QACnBF,KAAYE,EAAK,OAAO,CAAC,MAAM,MAAMA,IAAO,MAAMA,IAC7CF;AACT;AACA,SAASmB,GAAUC,GAAM;AACvB,MAAIC,IAAa,CAAA;AACjB,MAAID,GAAM;AACR,QAAIE,IAAYF,EAAK,QAAQ,GAAG;AAChC,IAAIE,KAAa,MACfD,EAAW,OAAOD,EAAK,UAAUE,CAAS,GAC1CF,IAAOA,EAAK,UAAU,GAAGE,CAAS;AAEpC,QAAIC,IAAcH,EAAK,QAAQ,GAAG;AAClC,IAAIG,KAAe,MACjBF,EAAW,SAASD,EAAK,UAAUG,CAAW,GAC9CH,IAAOA,EAAK,UAAU,GAAGG,CAAW,IAElCH,MACFC,EAAW,WAAWD;AAAA,EAE1B;AACA,SAAOC;AACT;AACA,SAASd,GAAmBiB,GAAaC,GAAaC,GAAkB9B,IAAU,CAAA,GAAI;AACpF,MAAI,EAAE,QAAQE,IAAU,SAAS,aAAa,UAAA6B,IAAW,OAAU/B,GAC/DG,IAAgBD,EAAQ,SACxB8B,IAAS,OACTC,IAAW,MACXd,IAAQe,EAAA;AACZ,EAAIf,KAAS,SACXA,IAAQ,GACRhB,EAAc,aAAa,EAAE,GAAGA,EAAc,OAAO,KAAKgB,EAAA,GAAS,EAAE;AAEvE,WAASe,IAAW;AAElB,YADY/B,EAAc,SAAS,EAAE,KAAK,KAAA,GAC7B;AAAA,EACf;AACA,WAASgC,IAAY;AACnB,IAAAH,IAAS;AACT,QAAII,IAAYF,EAAA,GACZG,IAAQD,KAAa,OAAO,OAAOA,IAAYjB;AACnD,IAAAA,IAAQiB,GACJH,KACFA,EAAS,EAAE,QAAAD,GAAQ,UAAUM,EAAQ,UAAU,OAAAD,GAAO;AAAA,EAE1D;AACA,WAASE,EAAK9B,GAAIY,GAAO;AACvB,IAAAW,IAAS;AACT,QAAId,IAAWX,GAAe+B,EAAQ,UAAU7B,GAAIY,CAAK;AAEzD,IAAAF,IAAQe,MAAa;AACrB,QAAIM,IAAevB,GAAgBC,GAAUC,CAAK,GAC9CsB,IAAMH,EAAQ,WAAWpB,CAAQ;AACrC,QAAI;AACF,MAAAf,EAAc,UAAUqC,GAAc,IAAIC,CAAG;AAAA,IAC/C,SAASC,GAAO;AACd,UAAIA,aAAiB,gBAAgBA,EAAM,SAAS;AAClD,cAAMA;AAER,MAAAxC,EAAQ,SAAS,OAAOuC,CAAG;AAAA,IAC7B;AACA,IAAIV,KAAYE,KACdA,EAAS,EAAE,QAAAD,GAAQ,UAAUM,EAAQ,UAAU,OAAO,GAAG;AAAA,EAE7D;AACA,WAASK,EAASlC,GAAIY,GAAO;AAC3B,IAAAW,IAAS;AACT,QAAId,IAAWX,GAAe+B,EAAQ,UAAU7B,GAAIY,CAAK;AAEzD,IAAAF,IAAQe,EAAA;AACR,QAAIM,IAAevB,GAAgBC,GAAUC,CAAK,GAC9CsB,IAAMH,EAAQ,WAAWpB,CAAQ;AACrC,IAAAf,EAAc,aAAaqC,GAAc,IAAIC,CAAG,GAC5CV,KAAYE,KACdA,EAAS,EAAE,QAAAD,GAAQ,UAAUM,EAAQ,UAAU,OAAO,GAAG;AAAA,EAE7D;AACA,WAASM,EAAUnC,GAAI;AACrB,WAAOoC,GAAqBpC,CAAE;AAAA,EAChC;AACA,MAAI6B,IAAU;AAAA,IACZ,IAAI,SAAS;AACX,aAAON;AAAA,IACT;AAAA,IACA,IAAI,WAAW;AACb,aAAOJ,EAAY1B,GAASC,CAAa;AAAA,IAC3C;AAAA,IACA,OAAO2C,GAAI;AACT,UAAIb;AACF,cAAM,IAAI,MAAM,4CAA4C;AAE9D,aAAA/B,EAAQ,iBAAiBJ,IAAmBqC,CAAS,GACrDF,IAAWa,GACJ,MAAM;AACX,QAAA5C,EAAQ,oBAAoBJ,IAAmBqC,CAAS,GACxDF,IAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,WAAWxB,GAAI;AACb,aAAOoB,EAAY3B,GAASO,CAAE;AAAA,IAChC;AAAA,IACA,WAAAmC;AAAA,IACA,eAAenC,GAAI;AACjB,UAAIgC,IAAMG,EAAUnC,CAAE;AACtB,aAAO;AAAA,QACL,UAAUgC,EAAI;AAAA,QACd,QAAQA,EAAI;AAAA,QACZ,MAAMA,EAAI;AAAA,MAAA;AAAA,IAEd;AAAA,IACA,MAAAF;AAAA,IACA,SAASI;AAAA,IACT,GAAGI,GAAG;AACJ,aAAO5C,EAAc,GAAG4C,CAAC;AAAA,IAC3B;AAAA,EAAA;AAEF,SAAOT;AACT;AACA,SAASO,GAAqBpC,GAAIuC,IAAa,IAAO;AACpD,MAAIC,IAAO;AACX,EAAI,OAAO,SAAW,QACpBA,IAAO,OAAO,SAAS,WAAW,SAAS,OAAO,SAAS,SAAS,OAAO,SAAS,OAEtFrC,EAAUqC,GAAM,0DAA0D;AAC1E,MAAIC,IAAO,OAAOzC,KAAO,WAAWA,IAAKC,GAAWD,CAAE;AACtD,SAAAyC,IAAOA,EAAK,QAAQ,MAAM,KAAK,GAC3B,CAACF,KAAcE,EAAK,WAAW,IAAI,MACrCA,IAAOD,IAAOC,IAET,IAAI,IAAIA,GAAMD,CAAI;AAC3B;AAMA,IAAIE,IACAC,KAAwB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,EAKhC,YAAYC,GAAM;AAEhB,QADAzD,GAAa,MAAMuD,IAAsB,oBAAI,IAAA,CAAK,GAC9CE;AACF,eAAS,CAACC,GAASzD,CAAK,KAAKwD;AAC3B,aAAK,IAAIC,GAASzD,CAAK;AAAA,EAG7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IAAIyD,GAAS;AACX,QAAI5D,GAAa,MAAMyD,EAAI,EAAE,IAAIG,CAAO;AACtC,aAAO5D,GAAa,MAAMyD,EAAI,EAAE,IAAIG,CAAO;AAE7C,QAAIA,EAAQ,iBAAiB;AAC3B,aAAOA,EAAQ;AAEjB,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IAAIA,GAASzD,GAAO;AAClB,IAAAH,GAAa,MAAMyD,EAAI,EAAE,IAAIG,GAASzD,CAAK;AAAA,EAC7C;AACF;AACAsD,yBAAW,QAAA;AACX,IAAII,yBAAqD,IAAI;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,SAASC,GAAgClC,GAAK;AAC5C,SAAOiC,GAA+B;AAAA,IACpCjC;AAAA,EAAA;AAEJ;AACA,IAAImC,yBAAuD,IAAI;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,SAASC,GAAkCpC,GAAK;AAC9C,SAAOmC,GAAiC;AAAA,IACtCnC;AAAA,EAAA;AAEJ;AACA,SAASqC,GAAaC,GAAO;AAC3B,SAAOA,EAAM,UAAU;AACzB;AACA,SAASC,GAA0BC,GAAQC,GAAqBC,IAAa,CAAA,GAAIC,IAAW,CAAA,GAAIC,IAAwB,IAAO;AAC7H,SAAOJ,EAAO,IAAI,CAACF,GAAOzC,MAAU;AAClC,QAAIgD,IAAW,CAAC,GAAGH,GAAY,OAAO7C,CAAK,CAAC,GACxCiD,IAAK,OAAOR,EAAM,MAAO,WAAWA,EAAM,KAAKO,EAAS,KAAK,GAAG;AASpE,QARAvD;AAAA,MACEgD,EAAM,UAAU,MAAQ,CAACA,EAAM;AAAA,MAC/B;AAAA,IAAA,GAEFhD;AAAA,MACEsD,KAAyB,CAACD,EAASG,CAAE;AAAA,MACrC,qCAAqCA,CAAE;AAAA,IAAA,GAErCT,GAAaC,CAAK,GAAG;AACvB,UAAIS,IAAa;AAAA,QACf,GAAGT;AAAA,QACH,IAAAQ;AAAA,MAAA;AAEF,aAAAH,EAASG,CAAE,IAAIE;AAAA,QACbD;AAAA,QACAN,EAAoBM,CAAU;AAAA,MAAA,GAEzBA;AAAA,IACT,OAAO;AACL,UAAIE,IAAoB;AAAA,QACtB,GAAGX;AAAA,QACH,IAAAQ;AAAA,QACA,UAAU;AAAA,MAAA;AAEZ,aAAAH,EAASG,CAAE,IAAIE;AAAA,QACbC;AAAA,QACAR,EAAoBQ,CAAiB;AAAA,MAAA,GAEnCX,EAAM,aACRW,EAAkB,WAAWV;AAAA,QAC3BD,EAAM;AAAA,QACNG;AAAA,QACAI;AAAA,QACAF;AAAA,QACAC;AAAA,MAAA,IAGGK;AAAA,IACT;AAAA,EACF,CAAC;AACH;AACA,SAASD,GAAkBV,GAAOY,GAAS;AACzC,SAAO,OAAO,OAAOZ,GAAO;AAAA,IAC1B,GAAGY;AAAA,IACH,GAAG,OAAOA,EAAQ,QAAS,YAAYA,EAAQ,QAAQ,OAAO;AAAA,MAC5D,MAAM;AAAA,QACJ,GAAGZ,EAAM;AAAA,QACT,GAAGY,EAAQ;AAAA,MAAA;AAAA,IACb,IACE,CAAA;AAAA,EAAC,CACN;AACH;AACA,SAASC,GAAYX,GAAQY,GAAaC,IAAW,KAAK;AACxD,SAAOC,GAAgBd,GAAQY,GAAaC,GAAU,EAAK;AAC7D;AACA,SAASC,GAAgBd,GAAQY,GAAaC,GAAUE,GAAc;AACpE,MAAI3D,IAAW,OAAOwD,KAAgB,WAAWnD,GAAUmD,CAAW,IAAIA,GACtEtE,IAAW0E,GAAc5D,EAAS,YAAY,KAAKyD,CAAQ;AAC/D,MAAIvE,KAAY;AACd,WAAO;AAET,MAAI2E,IAAWC,GAAclB,CAAM;AACnC,EAAAmB,GAAkBF,CAAQ;AAC1B,MAAIG,IAAU;AACd,WAASC,IAAI,GAAGD,KAAW,QAAQC,IAAIJ,EAAS,QAAQ,EAAEI,GAAG;AAC3D,QAAIC,IAAUC,GAAWjF,CAAQ;AACjC,IAAA8E,IAAUI;AAAA,MACRP,EAASI,CAAC;AAAA,MACVC;AAAA,MACAP;AAAA,IAAA;AAAA,EAEJ;AACA,SAAOK;AACT;AACA,SAASK,GAA2BC,GAAOC,GAAY;AACrD,MAAI,EAAE,OAAA7B,GAAO,UAAAxD,GAAU,QAAAsF,EAAA,IAAWF;AAClC,SAAO;AAAA,IACL,IAAI5B,EAAM;AAAA,IACV,UAAAxD;AAAA,IACA,QAAAsF;AAAA,IACA,MAAMD,EAAW7B,EAAM,EAAE;AAAA,IACzB,YAAY6B,EAAW7B,EAAM,EAAE;AAAA,IAC/B,QAAQA,EAAM;AAAA,EAAA;AAElB;AACA,SAASoB,GAAclB,GAAQiB,IAAW,IAAIY,IAAc,CAAA,GAAI3B,IAAa,IAAI4B,IAA6B,IAAO;AACnH,MAAIC,IAAe,CAACjC,GAAOzC,GAAO2E,IAA4BF,GAA4BG,MAAiB;AACzG,QAAIC,IAAO;AAAA,MACT,cAAcD,MAAiB,SAASnC,EAAM,QAAQ,KAAKmC;AAAA,MAC3D,eAAenC,EAAM,kBAAkB;AAAA,MACvC,eAAezC;AAAA,MACf,OAAAyC;AAAA,IAAA;AAEF,QAAIoC,EAAK,aAAa,WAAW,GAAG,GAAG;AACrC,UAAI,CAACA,EAAK,aAAa,WAAWhC,CAAU,KAAK8B;AAC/C;AAEF,MAAAlF;AAAA,QACEoF,EAAK,aAAa,WAAWhC,CAAU;AAAA,QACvC,wBAAwBgC,EAAK,YAAY,wBAAwBhC,CAAU;AAAA,MAAA,GAE7EgC,EAAK,eAAeA,EAAK,aAAa,MAAMhC,EAAW,MAAM;AAAA,IAC/D;AACA,QAAIxC,IAAOyE,GAAU,CAACjC,GAAYgC,EAAK,YAAY,CAAC,GAChDE,IAAaP,EAAY,OAAOK,CAAI;AAgBxC,IAfIpC,EAAM,YAAYA,EAAM,SAAS,SAAS,MAC5ChD;AAAA;AAAA;AAAA,MAGEgD,EAAM,UAAU;AAAA,MAChB,4FAA4FpC,CAAI;AAAA,IAAA,GAElGwD;AAAA,MACEpB,EAAM;AAAA,MACNmB;AAAA,MACAmB;AAAA,MACA1E;AAAA,MACAsE;AAAA,IAAA,IAGA,EAAAlC,EAAM,QAAQ,QAAQ,CAACA,EAAM,UAGjCmB,EAAS,KAAK;AAAA,MACZ,MAAAvD;AAAA,MACA,OAAO2E,GAAa3E,GAAMoC,EAAM,KAAK;AAAA,MACrC,YAAAsC;AAAA,IAAA,CACD;AAAA,EACH;AACA,SAAApC,EAAO,QAAQ,CAACF,GAAOzC,MAAU;AAC/B,QAAIyC,EAAM,SAAS,MAAM,CAACA,EAAM,MAAM,SAAS,GAAG;AAChD,MAAAiC,EAAajC,GAAOzC,CAAK;AAAA;AAEzB,eAASiF,KAAYC,GAAwBzC,EAAM,IAAI;AACrD,QAAAiC,EAAajC,GAAOzC,GAAO,IAAMiF,CAAQ;AAAA,EAG/C,CAAC,GACMrB;AACT;AACA,SAASsB,GAAwB7E,GAAM;AACrC,MAAI8E,IAAW9E,EAAK,MAAM,GAAG;AAC7B,MAAI8E,EAAS,WAAW,EAAG,QAAO,CAAA;AAClC,MAAI,CAACC,GAAO,GAAGC,CAAI,IAAIF,GACnBG,IAAaF,EAAM,SAAS,GAAG,GAC/BG,IAAWH,EAAM,QAAQ,OAAO,EAAE;AACtC,MAAIC,EAAK,WAAW;AAClB,WAAOC,IAAa,CAACC,GAAU,EAAE,IAAI,CAACA,CAAQ;AAEhD,MAAIC,IAAeN,GAAwBG,EAAK,KAAK,GAAG,CAAC,GACrDI,IAAS,CAAA;AACb,SAAAA,EAAO;AAAA,IACL,GAAGD,EAAa;AAAA,MACd,CAACE,MAAYA,MAAY,KAAKH,IAAW,CAACA,GAAUG,CAAO,EAAE,KAAK,GAAG;AAAA,IAAA;AAAA,EACvE,GAEEJ,KACFG,EAAO,KAAK,GAAGD,CAAY,GAEtBC,EAAO;AAAA,IACZ,CAACR,MAAa5E,EAAK,WAAW,GAAG,KAAK4E,MAAa,KAAK,MAAMA;AAAA,EAAA;AAElE;AACA,SAASnB,GAAkBF,GAAU;AACnC,EAAAA,EAAS;AAAA,IACP,CAAC+B,GAAGC,MAAMD,EAAE,UAAUC,EAAE,QAAQA,EAAE,QAAQD,EAAE,QAAQE;AAAA,MAClDF,EAAE,WAAW,IAAI,CAACd,MAASA,EAAK,aAAa;AAAA,MAC7Ce,EAAE,WAAW,IAAI,CAACf,MAASA,EAAK,aAAa;AAAA,IAAA;AAAA,EAC/C;AAEJ;AACA,IAAIiB,KAAU,aACVC,KAAsB,GACtBC,KAAkB,GAClBC,KAAoB,GACpBC,KAAqB,IACrBC,KAAe,IACfC,KAAU,CAACC,MAAMA,MAAM;AAC3B,SAASrB,GAAa3E,GAAML,GAAO;AACjC,MAAImF,IAAW9E,EAAK,MAAM,GAAG,GACzBiG,IAAenB,EAAS;AAC5B,SAAIA,EAAS,KAAKiB,EAAO,MACvBE,KAAgBH,KAEdnG,MACFsG,KAAgBN,KAEXb,EAAS,OAAO,CAACkB,MAAM,CAACD,GAAQC,CAAC,CAAC,EAAE;AAAA,IACzC,CAACE,GAAOC,MAAYD,KAAST,GAAQ,KAAKU,CAAO,IAAIT,KAAsBS,MAAY,KAAKP,KAAoBC;AAAA,IAChHI;AAAA,EAAA;AAEJ;AACA,SAAST,GAAeF,GAAGC,GAAG;AAE5B,SADeD,EAAE,WAAWC,EAAE,UAAUD,EAAE,MAAM,GAAG,EAAE,EAAE,MAAM,CAAC,GAAG3B,MAAM,MAAM4B,EAAE5B,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAM/E2B,EAAEA,EAAE,SAAS,CAAC,IAAIC,EAAEA,EAAE,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA,IAIhC;AAAA;AAEJ;AACA,SAASzB,GAAiBsC,GAAQxH,GAAUyE,IAAe,IAAO;AAChE,MAAI,EAAE,YAAAqB,MAAe0B,GACjBC,IAAgB,CAAA,GAChBC,IAAkB,KAClB5C,IAAU,CAAA;AACd,WAASC,IAAI,GAAGA,IAAIe,EAAW,QAAQ,EAAEf,GAAG;AAC1C,QAAIa,IAAOE,EAAWf,CAAC,GACnB4C,IAAM5C,MAAMe,EAAW,SAAS,GAChC8B,IAAoBF,MAAoB,MAAM1H,IAAWA,EAAS,MAAM0H,EAAgB,MAAM,KAAK,KACnGtC,IAAQyC;AAAA,MACV,EAAE,MAAMjC,EAAK,cAAc,eAAeA,EAAK,eAAe,KAAA+B,EAAA;AAAA,MAC9DC;AAAA,IAAA,GAEEpE,IAAQoC,EAAK;AAWjB,QAVI,CAACR,KAASuC,KAAOlD,KAAgB,CAACqB,EAAWA,EAAW,SAAS,CAAC,EAAE,MAAM,UAC5EV,IAAQyC;AAAA,MACN;AAAA,QACE,MAAMjC,EAAK;AAAA,QACX,eAAeA,EAAK;AAAA,QACpB,KAAK;AAAA,MAAA;AAAA,MAEPgC;AAAA,IAAA,IAGA,CAACxC;AACH,aAAO;AAET,WAAO,OAAOqC,GAAerC,EAAM,MAAM,GACzCN,EAAQ,KAAK;AAAA;AAAA,MAEX,QAAQ2C;AAAA,MACR,UAAU5B,GAAU,CAAC6B,GAAiBtC,EAAM,QAAQ,CAAC;AAAA,MACrD,cAAc0C;AAAA,QACZjC,GAAU,CAAC6B,GAAiBtC,EAAM,YAAY,CAAC;AAAA,MAAA;AAAA,MAEjD,OAAA5B;AAAA,IAAA,CACD,GACG4B,EAAM,iBAAiB,QACzBsC,IAAkB7B,GAAU,CAAC6B,GAAiBtC,EAAM,YAAY,CAAC;AAAA,EAErE;AACA,SAAON;AACT;AA6BA,SAAS+C,GAAUE,GAAS/H,GAAU;AACpC,EAAI,OAAO+H,KAAY,aACrBA,IAAU,EAAE,MAAMA,GAAS,eAAe,IAAO,KAAK,GAAA;AAExD,MAAI,CAACC,GAASC,CAAc,IAAIC;AAAA,IAC9BH,EAAQ;AAAA,IACRA,EAAQ;AAAA,IACRA,EAAQ;AAAA,EAAA,GAEN3C,IAAQpF,EAAS,MAAMgI,CAAO;AAClC,MAAI,CAAC5C,EAAO,QAAO;AACnB,MAAIsC,IAAkBtC,EAAM,CAAC,GACzB+C,IAAeT,EAAgB,QAAQ,WAAW,IAAI,GACtDU,IAAgBhD,EAAM,MAAM,CAAC;AAiBjC,SAAO;AAAA,IACL,QAjBW6C,EAAe;AAAA,MAC1B,CAACI,GAAO,EAAE,WAAAC,GAAW,YAAAjC,EAAA,GAActF,MAAU;AAC3C,YAAIuH,MAAc,KAAK;AACrB,cAAIC,IAAaH,EAAcrH,CAAK,KAAK;AACzC,UAAAoH,IAAeT,EAAgB,MAAM,GAAGA,EAAgB,SAASa,EAAW,MAAM,EAAE,QAAQ,WAAW,IAAI;AAAA,QAC7G;AACA,cAAM9I,IAAQ2I,EAAcrH,CAAK;AACjC,eAAIsF,KAAc,CAAC5G,IACjB4I,EAAMC,CAAS,IAAI,SAEnBD,EAAMC,CAAS,KAAK7I,KAAS,IAAI,QAAQ,QAAQ,GAAG,GAE/C4I;AAAA,MACT;AAAA,MACA,CAAA;AAAA,IAAC;AAAA,IAID,UAAUX;AAAA,IACV,cAAAS;AAAA,IACA,SAAAJ;AAAA,EAAA;AAEJ;AACA,SAASG,GAAY9G,GAAMoH,IAAgB,IAAOb,IAAM,IAAM;AAC5D,EAAAjH;AAAA,IACEU,MAAS,OAAO,CAACA,EAAK,SAAS,GAAG,KAAKA,EAAK,SAAS,IAAI;AAAA,IACzD,eAAeA,CAAI,oCAAoCA,EAAK,QAAQ,OAAO,IAAI,CAAC,yIAAyIA,EAAK,QAAQ,OAAO,IAAI,CAAC;AAAA,EAAA;AAEpP,MAAIkE,IAAS,CAAA,GACTmD,IAAe,MAAMrH,EAAK,QAAQ,WAAW,EAAE,EAAE,QAAQ,QAAQ,GAAG,EAAE,QAAQ,sBAAsB,MAAM,EAAE;AAAA,IAC9G;AAAA,IACA,CAACsH,GAAGJ,GAAWjC,OACbf,EAAO,KAAK,EAAE,WAAAgD,GAAW,YAAYjC,KAAc,MAAM,GAClDA,IAAa,iBAAiB;AAAA,EACvC,EACA,QAAQ,uBAAuB,UAAU;AAC3C,SAAIjF,EAAK,SAAS,GAAG,KACnBkE,EAAO,KAAK,EAAE,WAAW,IAAA,CAAK,GAC9BmD,KAAgBrH,MAAS,OAAOA,MAAS,OAAO,UAAU,uBACjDuG,IACTc,KAAgB,UACPrH,MAAS,MAAMA,MAAS,QACjCqH,KAAgB,kBAIX,CADO,IAAI,OAAOA,GAAcD,IAAgB,SAAS,GAAG,GAClDlD,CAAM;AACzB;AACA,SAASL,GAAWxF,GAAO;AACzB,MAAI;AACF,WAAOA,EAAM,MAAM,GAAG,EAAE,IAAI,CAACkJ,MAAM,mBAAmBA,CAAC,EAAE,QAAQ,OAAO,KAAK,CAAC,EAAE,KAAK,GAAG;AAAA,EAC1F,SAASrG,GAAO;AACd,WAAA5B;AAAA,MACE;AAAA,MACA,iBAAiBjB,CAAK,iHAAiH6C,CAAK;AAAA,IAAA,GAEvI7C;AAAA,EACT;AACF;AACA,SAASiF,GAAc1E,GAAUuE,GAAU;AACzC,MAAIA,MAAa,IAAK,QAAOvE;AAC7B,MAAI,CAACA,EAAS,YAAA,EAAc,WAAWuE,EAAS,YAAA,CAAa;AAC3D,WAAO;AAET,MAAIqE,IAAarE,EAAS,SAAS,GAAG,IAAIA,EAAS,SAAS,IAAIA,EAAS,QACrEsE,IAAW7I,EAAS,OAAO4I,CAAU;AACzC,SAAIC,KAAYA,MAAa,MACpB,OAEF7I,EAAS,MAAM4I,CAAU,KAAK;AACvC;AACA,SAASE,GAAgB;AAAA,EACvB,UAAAvE;AAAA,EACA,UAAAvE;AACF,GAAG;AACD,SAAOA,MAAa,MAAMuE,IAAWsB,GAAU,CAACtB,GAAUvE,CAAQ,CAAC;AACrE;AACA,IAAI+I,KAAqB,iCACrBC,KAAgB,CAAC3G,MAAQ0G,GAAmB,KAAK1G,CAAG;AACxD,SAAS4G,GAAY5I,GAAI6I,IAAe,KAAK;AAC3C,MAAI;AAAA,IACF,UAAUC;AAAA,IACV,QAAAlJ,IAAS;AAAA,IACT,MAAAC,IAAO;AAAA,EAAA,IACL,OAAOG,KAAO,WAAWc,GAAUd,CAAE,IAAIA,GACzCL;AACJ,MAAImJ;AACF,QAAIH,GAAcG,CAAU;AAC1B,MAAAnJ,IAAWmJ;AAAA,SACN;AACL,UAAIA,EAAW,SAAS,IAAI,GAAG;AAC7B,YAAIC,IAAcD;AAClB,QAAAA,IAAaA,EAAW,QAAQ,UAAU,GAAG,GAC7CzI;AAAA,UACE;AAAA,UACA,+DAA+D0I,CAAW,OAAOD,CAAU;AAAA,QAAA;AAAA,MAE/F;AACA,MAAIA,EAAW,WAAW,GAAG,IAC3BnJ,IAAWqJ,GAAgBF,EAAW,UAAU,CAAC,GAAG,GAAG,IAEvDnJ,IAAWqJ,GAAgBF,GAAYD,CAAY;AAAA,IAEvD;AAAA;AAEA,IAAAlJ,IAAWkJ;AAEb,SAAO;AAAA,IACL,UAAAlJ;AAAA,IACA,QAAQsJ,GAAgBrJ,CAAM;AAAA,IAC9B,MAAMsJ,GAAcrJ,CAAI;AAAA,EAAA;AAE5B;AACA,SAASmJ,GAAgB1D,GAAcuD,GAAc;AACnD,MAAIhD,IAAWgD,EAAa,QAAQ,QAAQ,EAAE,EAAE,MAAM,GAAG;AAEzD,SADuBvD,EAAa,MAAM,GAAG,EAC5B,QAAQ,CAAC4B,MAAY;AACpC,IAAIA,MAAY,OACVrB,EAAS,SAAS,KAAGA,EAAS,IAAA,IACzBqB,MAAY,OACrBrB,EAAS,KAAKqB,CAAO;AAAA,EAEzB,CAAC,GACMrB,EAAS,SAAS,IAAIA,EAAS,KAAK,GAAG,IAAI;AACpD;AACA,SAASsD,GAAoBC,GAAMC,GAAOC,GAAMvI,GAAM;AACpD,SAAO,qBAAqBqI,CAAI,4CAA4CC,CAAK,aAAa,KAAK;AAAA,IACjGtI;AAAA,EAAA,CACD,0CAA0CuI,CAAI;AACjD;AACA,SAASC,GAA2B9E,GAAS;AAC3C,SAAOA,EAAQ;AAAA,IACb,CAACM,GAAOrE,MAAUA,MAAU,KAAKqE,EAAM,MAAM,QAAQA,EAAM,MAAM,KAAK,SAAS;AAAA,EAAA;AAEnF;AACA,SAASyE,GAAoB/E,GAAS;AACpC,MAAIgF,IAAcF,GAA2B9E,CAAO;AACpD,SAAOgF,EAAY;AAAA,IACjB,CAAC1E,GAAO2E,MAAQA,MAAQD,EAAY,SAAS,IAAI1E,EAAM,WAAWA,EAAM;AAAA,EAAA;AAE5E;AACA,SAAS4E,GAAUC,GAAOC,GAAgBC,GAAkBC,IAAiB,IAAO;AAClF,MAAI/J;AACJ,EAAI,OAAO4J,KAAU,WACnB5J,IAAKc,GAAU8I,CAAK,KAEpB5J,IAAK,EAAE,GAAG4J,EAAA,GACVzJ;AAAA,IACE,CAACH,EAAG,YAAY,CAACA,EAAG,SAAS,SAAS,GAAG;AAAA,IACzCmJ,GAAoB,KAAK,YAAY,UAAUnJ,CAAE;AAAA,EAAA,GAEnDG;AAAA,IACE,CAACH,EAAG,YAAY,CAACA,EAAG,SAAS,SAAS,GAAG;AAAA,IACzCmJ,GAAoB,KAAK,YAAY,QAAQnJ,CAAE;AAAA,EAAA,GAEjDG;AAAA,IACE,CAACH,EAAG,UAAU,CAACA,EAAG,OAAO,SAAS,GAAG;AAAA,IACrCmJ,GAAoB,KAAK,UAAU,QAAQnJ,CAAE;AAAA,EAAA;AAGjD,MAAIgK,IAAcJ,MAAU,MAAM5J,EAAG,aAAa,IAC9C8I,IAAakB,IAAc,MAAMhK,EAAG,UACpCiK;AACJ,MAAInB,KAAc;AAChB,IAAAmB,IAAOH;AAAA,OACF;AACL,QAAII,IAAqBL,EAAe,SAAS;AACjD,QAAI,CAACE,KAAkBjB,EAAW,WAAW,IAAI,GAAG;AAClD,UAAIqB,IAAarB,EAAW,MAAM,GAAG;AACrC,aAAOqB,EAAW,CAAC,MAAM;AACvB,QAAAA,EAAW,MAAA,GACXD,KAAsB;AAExB,MAAAlK,EAAG,WAAWmK,EAAW,KAAK,GAAG;AAAA,IACnC;AACA,IAAAF,IAAOC,KAAsB,IAAIL,EAAeK,CAAkB,IAAI;AAAA,EACxE;AACA,MAAInJ,IAAO6H,GAAY5I,GAAIiK,CAAI,GAC3BG,IAA2BtB,KAAcA,MAAe,OAAOA,EAAW,SAAS,GAAG,GACtFuB,KAA2BL,KAAelB,MAAe,QAAQgB,EAAiB,SAAS,GAAG;AAClG,SAAI,CAAC/I,EAAK,SAAS,SAAS,GAAG,MAAMqJ,KAA4BC,OAC/DtJ,EAAK,YAAY,MAEZA;AACT;AACA,IAAIyE,KAAY,CAAC8E,MAAUA,EAAM,KAAK,GAAG,EAAE,QAAQ,UAAU,GAAG,GAC5D7C,KAAoB,CAAC9H,MAAaA,EAAS,QAAQ,QAAQ,EAAE,EAAE,QAAQ,QAAQ,GAAG,GAClFsJ,KAAkB,CAACrJ,MAAW,CAACA,KAAUA,MAAW,MAAM,KAAKA,EAAO,WAAW,GAAG,IAAIA,IAAS,MAAMA,GACvGsJ,KAAgB,CAACrJ,MAAS,CAACA,KAAQA,MAAS,MAAM,KAAKA,EAAK,WAAW,GAAG,IAAIA,IAAO,MAAMA,GAmC3F0K,KAAoB,MAAM;AAAA,EAC5B,YAAYC,GAAQC,GAAYC,GAAOC,IAAW,IAAO;AACvD,SAAK,SAASH,GACd,KAAK,aAAaC,KAAc,IAChC,KAAK,WAAWE,GACZD,aAAiB,SACnB,KAAK,OAAOA,EAAM,SAAA,GAClB,KAAK,QAAQA,KAEb,KAAK,OAAOA;AAAA,EAEhB;AACF;AACA,SAASE,GAAqB3I,GAAO;AACnC,SAAOA,KAAS,QAAQ,OAAOA,EAAM,UAAW,YAAY,OAAOA,EAAM,cAAe,YAAY,OAAOA,EAAM,YAAa,aAAa,UAAUA;AACvJ;AACA,SAAS4I,GAAgBpG,GAAS;AAChC,SAAOA,EAAQ,IAAI,CAACqG,MAAMA,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,QAAQ,UAAU,GAAG,KAAK;AAC9F;AACA,IAAIC,KAAY,OAAO,SAAW,OAAe,OAAO,OAAO,WAAa,OAAe,OAAO,OAAO,SAAS,gBAAkB;AACpI,SAASC,GAAYC,GAAK/G,GAAU;AAClC,MAAIlE,IAAKiL;AACT,MAAI,OAAOjL,KAAO,YAAY,CAAC0I,GAAmB,KAAK1I,CAAE;AACvD,WAAO;AAAA,MACL,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,IAAAA;AAAA,IAAA;AAGJ,MAAIkL,IAAclL,GACdmL,IAAa;AACjB,MAAIJ;AACF,QAAI;AACF,UAAIK,IAAa,IAAI,IAAI,OAAO,SAAS,IAAI,GACzCC,IAAYrL,EAAG,WAAW,IAAI,IAAI,IAAI,IAAIoL,EAAW,WAAWpL,CAAE,IAAI,IAAI,IAAIA,CAAE,GAChFe,IAAOsD,GAAcgH,EAAU,UAAUnH,CAAQ;AACrD,MAAImH,EAAU,WAAWD,EAAW,UAAUrK,KAAQ,OACpDf,IAAKe,IAAOsK,EAAU,SAASA,EAAU,OAEzCF,IAAa;AAAA,IAEjB,QAAY;AACV,MAAA9K;AAAA,QACE;AAAA,QACA,aAAaL,CAAE;AAAA,MAAA;AAAA,IAEnB;AAEF,SAAO;AAAA,IACL,aAAAkL;AAAA,IACA,YAAAC;AAAA,IACA,IAAAnL;AAAA,EAAA;AAEJ;AAGA,IAAIsL,4BAA8B,gBAAgB;AAClD,SAASC,GAA+BC,GAAKrI,GAAO;AAClD,MAAIsI,IAAa;AAAA,IACf,MAAM,CAAA;AAAA,IACN,eAAe,CAAA;AAAA,IACf,eAAe,CAAA;AAAA,IACf,mBAAmB,CAAA;AAAA,IACnB,YAAY,CAAA;AAAA,IACZ,QAAQ,CAAA;AAAA,IACR,QAAQ,CAAA;AAAA,EAAC;AAEX,EAAAD,EAAI;AAAA,IACF,CAACnJ,MAAOA,EAAG;AAAA,MACT,IAAIc,EAAM;AAAA,MACV,OAAOA,EAAM;AAAA,MACb,MAAMA,EAAM;AAAA,MACZ,WAAWuB,GAAG;AACZ,YAAIgH,IAAO,OAAO,KAAKD,CAAU;AACjC,iBAAS5K,KAAO6K;AACd,UAAIhH,EAAE7D,CAAG,KACP4K,EAAW5K,CAAG,EAAE,KAAK6D,EAAE7D,CAAG,CAAC;AAAA,MAGjC;AAAA,IAAA,CACD;AAAA,EAAA;AAEH,MAAIkD,IAAU,CAAA;AACd,MAAI,OAAOZ,EAAM,QAAS,cAAcsI,EAAW,KAAK,SAAS,GAAG;AAClE,QAAIE,IAAeC,GAASH,EAAW,MAAMtI,EAAM,MAAM,MAAA;AAAA,KAAY;AACrE,IAAIwI,MACF5H,EAAQ,OAAO4H;AAAA,EAEnB;AACA,MAAI,OAAOxI,EAAM,QAAS,UAAU;AAClC,QAAI0I,IAAa1I,EAAM;AACvB,KAAC,cAAc,UAAU,QAAQ,EAAE,QAAQ,CAACtC,MAAQ;AAClD,UAAIiL,IAASD,EAAWhL,CAAG,GACvBkL,IAAmBN,EAAW,QAAQ5K,CAAG,EAAE;AAC/C,UAAI,OAAOiL,KAAW,cAAcC,EAAiB,SAAS,GAAG;AAC/D,YAAIJ,IAAeC,GAASG,GAAkBD,GAAQ,MAAA;AAAA,SAAY;AAClE,QAAIH,MACF5H,EAAQ,OAAO,OAAO,OAAOA,EAAQ,QAAQ,IAAI;AAAA,UAC/C,CAAClD,CAAG,GAAG8K;AAAA,QAAA,CACR;AAAA,MAEL;AAAA,IACF,CAAC;AAAA,EACH;AACA,UAAC,UAAU,QAAQ,EAAE,QAAQ,CAAC9K,MAAQ;AACpC,QAAImL,IAAU7I,EAAMtC,CAAG;AACvB,QAAI,OAAOmL,KAAY,cAAcP,EAAW5K,CAAG,EAAE,SAAS,GAAG;AAC/D,UAAIoL,IAAWD,EAAQV,EAAoB,KAAKU,GAC5CL,IAAeC;AAAA,QACjBH,EAAW5K,CAAG;AAAA,QACdoL;AAAA,QACA,IAAIC,MAASC,GAAeD,EAAK,CAAC,CAAC;AAAA,MAAA;AAErC,MAAIP,MACE9K,MAAQ,YAAYoL,EAAS,YAAY,OAC3CN,EAAa,UAAU,KAEzBA,EAAaL,EAAoB,IAAIW,GACrClI,EAAQlD,CAAG,IAAI8K;AAAA,IAEnB;AAAA,EACF,CAAC,GACGxI,EAAM,cAAcA,EAAM,WAAW,SAAS,KAAKsI,EAAW,WAAW,SAAS,MACpF1H,EAAQ,aAAaZ,EAAM,WAAW,IAAI,CAACiJ,MAAe;AACxD,QAAIH,IAAWG,EAAWd,EAAoB,KAAKc,GAC/CT,IAAeC;AAAA,MACjBH,EAAW;AAAA,MACXQ;AAAA,MACA,IAAIC,MAASC,GAAeD,EAAK,CAAC,CAAC;AAAA,IAAA;AAErC,WAAIP,KACFA,EAAaL,EAAoB,IAAIW,GAC9BN,KAEFS;AAAA,EACT,CAAC,IAEIrI;AACT;AACA,SAASsI,GAA2BC,GAAQd,GAAK;AAC/C,MAAIC,IAAa;AAAA,IACf,UAAU,CAAA;AAAA,IACV,OAAO,CAAA;AAAA,EAAC;AAcV,MAZAD,EAAI;AAAA,IACF,CAACnJ,MAAOA,EAAG;AAAA,MACT,WAAWqC,GAAG;AACZ,YAAIgH,IAAO,OAAO,KAAKhH,CAAC;AACxB,iBAAS7D,KAAO6K;AACd,UAAIhH,EAAE7D,CAAG,KACP4K,EAAW5K,CAAG,EAAE,KAAK6D,EAAE7D,CAAG,CAAC;AAAA,MAGjC;AAAA,IAAA,CACD;AAAA,EAAA,GAEC4K,EAAW,SAAS,SAAS,GAAG;AAClC,QAAIc,IAAWD,EAAO,SAAShB,EAAoB,KAAKgB,EAAO,UAC3DE,IAAuBZ;AAAA,MACzBH,EAAW;AAAA,MACXc;AAAA,MACA,IAAIL,MAAS;AACX,YAAI,CAAClM,GAAIyM,CAAI,IAAIP;AACjB,eAAO;AAAA,UACL,IAAI,OAAOlM,KAAO,YAAY,OAAOA,KAAO,WAAWA,IAAKA,IAAKC,GAAWD,CAAE,IAAI;AAAA,UAClF,GAAG0M,GAAcJ,GAAQG,KAAQ,CAAA,CAAE;AAAA,QAAA;AAAA,MAEvC;AAAA,IAAA;AAEF,IAAID,MACFA,EAAqBlB,EAAoB,IAAIiB,GAC7CD,EAAO,WAAWE;AAAA,EAEtB;AACA,MAAIf,EAAW,MAAM,SAAS,GAAG;AAC/B,QAAIkB,IAASL,EAAO,MAAMhB,EAAoB,KAAKgB,EAAO,OACtDM,IAAoBhB,GAASH,EAAW,OAAOkB,GAAQ,IAAIT,MAAS;AACtE,UAAI,CAACrL,GAAA,EAAO4B,GAAMgK,CAAI,IAAIP;AAC1B,aAAO;AAAA,QACL,MAAMzJ,KAAQ;AAAA,QACd,YAAY5B;AAAA,QACZ,GAAG6L,GAAcJ,GAAQG,KAAQ,CAAA,CAAE;AAAA,MAAA;AAAA,IAEvC,CAAC;AACD,IAAIG,MACFA,EAAkBtB,EAAoB,IAAIqB,GAC1CL,EAAO,QAAQM;AAAA,EAEnB;AACA,SAAON;AACT;AA6BA,SAASV,GAASiB,GAAOb,GAASc,GAAS;AACzC,SAAID,EAAM,WAAW,IACZ,OAEF,UAAUX,MAAS;AACxB,QAAI/F,IAAS,MAAM4G;AAAA,MACjBF;AAAA,MACAC,EAAQ,GAAGZ,CAAI;AAAA,MACf,MAAMF,EAAQ,GAAGE,CAAI;AAAA,MACrBW,EAAM,SAAS;AAAA,IAAA;AAEjB,QAAI1G,EAAO,SAAS;AAClB,YAAMA,EAAO;AAEf,WAAOA,EAAO;AAAA,EAChB;AACF;AACA,eAAe4G,GAAaF,GAAOG,GAAMhB,GAAStL,GAAO;AACvD,MAAIuM,IAAOJ,EAAMnM,CAAK,GAClByF;AACJ,MAAK8G,GAOE;AACL,QAAIC,GACAC,IAAc,aACZD,IACF,QAAQ,MAAM,sDAAsD,IAEpEA,IAAiBH,GAAaF,GAAOG,GAAMhB,GAAStL,IAAQ,CAAC,GAE/DyF,IAAS,MAAM+G,GACf/M,EAAUgG,GAAQ,mBAAmB,GACjCA,EAAO,SAAS,WAAWA,EAAO,iBAAiB,QAC9C,EAAE,QAAQ,SAAS,OAAOA,EAAO,MAAA,IAEnC,EAAE,QAAQ,WAAW,OAAO,OAAA;AAErC,QAAI;AACF,YAAM8G,EAAKE,GAAaH,CAAI;AAAA,IAC9B,SAASI,GAAG;AACV,cAAQ,MAAM,+CAA+CA,CAAC;AAAA,IAChE;AACA,IAAKF,KACH,MAAMC,EAAA,GAER,MAAMD;AAAA,EACR;AA9BE,QAAI;AAEF,MAAA/G,IAAS,EAAE,MAAM,WAAW,OADhB,MAAM6F,EAAA,EACU;AAAA,IAC9B,SAASoB,GAAG;AACV,MAAAjH,IAAS,EAAE,MAAM,SAAS,OAAOiH,EAAA;AAAA,IACnC;AA0BF,SAAIjH,KAGG;AAAA,IACL,MAAM;AAAA,IACN,OAAO,IAAI,MAAM,8CAA8C;AAAA,EAAA;AAEnE;AACA,SAASgG,GAAeD,GAAM;AAC5B,MAAI,EAAE,SAAAmB,GAAS,SAAAxK,GAAS,QAAAoC,GAAQ,kBAAAqI,MAAqBpB;AACrD,SAAO;AAAA,IACL,SAASqB,GAAmBF,CAAO;AAAA,IACnC,QAAQ,EAAE,GAAGpI,EAAA;AAAA,IACb,kBAAAqI;AAAA,IACA,SAASE,GAAmB3K,CAAO;AAAA,EAAA;AAEvC;AACA,SAAS6J,GAAcJ,GAAQG,GAAM;AACnC,SAAO;AAAA,IACL,YAAYxM,GAAWqM,EAAO,MAAM,QAAQ;AAAA,IAC5C,GAAG,gBAAgBG,IAAO,EAAE,YAAYA,EAAK,WAAA,IAAe,CAAA;AAAA,IAC5D,GAAG,iBAAiBA,IAAO,EAAE,aAAaA,EAAK,YAAA,IAAgB,CAAA;AAAA,IAC/D,GAAG,cAAcA,IAAO,EAAE,UAAUA,EAAK,SAAA,IAAa,CAAA;AAAA,IACtD,GAAG,UAAUA,IAAO,EAAE,MAAMA,EAAK,KAAA,IAAS,CAAA;AAAA,EAAC;AAE/C;AACA,SAASc,GAAmBF,GAAS;AACnC,SAAO;AAAA,IACL,QAAQA,EAAQ;AAAA,IAChB,KAAKA,EAAQ;AAAA,IACb,SAAS;AAAA,MACP,KAAK,IAAInB,MAASmB,EAAQ,QAAQ,IAAI,GAAGnB,CAAI;AAAA,IAAA;AAAA,EAC/C;AAEJ;AACA,SAASsB,GAAmB3K,GAAS;AACnC,MAAI4K,GAAc5K,CAAO,GAAG;AAC1B,QAAI6K,IAAS,EAAE,GAAG7K,EAAA;AAClB,kBAAO,OAAO6K,CAAM,GACbA;AAAA,EACT;AACE,WAAO;AAAA,MACL,KAAK,CAACC,MAAQ9K,EAAQ,IAAI8K,CAAG;AAAA,IAAA;AAGnC;AACA,IAAIC,KAAmB,OAAO,oBAAoB,OAAO,SAAS,EAAE,KAAA,EAAO,KAAK,IAAI;AACpF,SAASH,GAAcI,GAAO;AAC5B,MAAIA,MAAU,QAAQ,OAAOA,KAAU;AACrC,WAAO;AAET,QAAMC,IAAQ,OAAO,eAAeD,CAAK;AACzC,SAAOC,MAAU,OAAO,aAAaA,MAAU,QAAQ,OAAO,oBAAoBA,CAAK,EAAE,KAAA,EAAO,KAAK,IAAI,MAAMF;AACjH;AAGA,IAAIG,KAA0B;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GACIC,KAAuB,IAAI;AAAA,EAC7BD;AACF,GACIE,KAAyB;AAAA,EAC3B;AAAA,EACA,GAAGF;AACL,GACIG,KAAsB,IAAI,IAAID,EAAsB,GACpDE,yBAA0C,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC,GACvEC,KAAoD,oBAAI,IAAI,CAAC,KAAK,GAAG,CAAC,GACtEC,KAAkB;AAAA,EACpB,OAAO;AAAA,EACP,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AACR,GACIC,KAAe;AAAA,EACjB,OAAO;AAAA,EACP,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AACR,GACIC,KAAe;AAAA,EACjB,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AACZ,GACIC,KAA4B,CAACrL,OAAW;AAAA,EAC1C,kBAAkB,EAAQA,EAAM;AAClC,IACIsL,KAA0B,4BAC1BC,4BAA+B,iBAAiB;AACpD,SAASC,GAAa/L,GAAM;AAC1B,QAAMgM,IAAehM,EAAK,SAASA,EAAK,SAAS,OAAO,SAAW,MAAc,SAAS,QACpFiM,IAAa,OAAOD,IAAiB,OAAe,OAAOA,EAAa,WAAa,OAAe,OAAOA,EAAa,SAAS,gBAAkB;AACzJ,EAAAzO;AAAA,IACEyC,EAAK,OAAO,SAAS;AAAA,IACrB;AAAA,EAAA;AAEF,MAAIkM,IAA4BlM,EAAK,4BAA4B,CAAA,GAC7DmM,IAAsBnM,EAAK,sBAAsB4L,IACjDlL,IAAsByL;AAC1B,MAAInM,EAAK,2BAA2B;AAClC,QAAImJ,IAAmBnJ,EAAK;AAC5B,IAAAU,IAAsB,CAACH,OACd;AAAA,MACL,GAAG4L,EAAoB5L,CAAK;AAAA,MAC5B,GAAGoI;AAAA,QACDQ,EAAiB,IAAI,CAACrH,MAAMA,EAAE,KAAK,EAAE,OAAO,OAAO;AAAA,QACnDvB;AAAA,MAAA;AAAA,IACF;AAAA,EAGN;AACA,MAAIK,IAAW,CAAA,GACXwL,IAAa5L;AAAA,IACfR,EAAK;AAAA,IACLU;AAAA,IACA;AAAA,IACAE;AAAA,EAAA,GAEEyL,GACA/K,IAAWtB,EAAK,YAAY;AAChC,EAAKsB,EAAS,WAAW,GAAG,MAC1BA,IAAW,IAAIA,CAAQ;AAEzB,MAAIgL,IAAmBtM,EAAK,gBAAgBuM,IACxCC,IAAS;AAAA,IACX,GAAGxM,EAAK;AAAA,EAAA,GAENyM,IAAkB,MAClBC,wBAAkC,IAAA,GAClCC,IAAwB,MACxBC,IAA2B,MAC3BC,IAAoB,MACpBC,IAAwB9M,EAAK,iBAAiB,MAC9C+M,IAAiB3L,GAAYgL,GAAYpM,EAAK,QAAQ,UAAUsB,CAAQ,GACxE0L,IAAsB,IACtBC,IAAgB,MAChBC;AACJ,MAAIH,KAAkB,QAAQ,CAAC/M,EAAK,yBAAyB;AAC3D,QAAIX,IAAQ8N,GAAuB,KAAK;AAAA,MACtC,UAAUnN,EAAK,QAAQ,SAAS;AAAA,IAAA,CACjC,GACG,EAAE,SAAA6B,GAAS,OAAAtB,MAAU6M,GAAuBhB,CAAU;AAC1D,IAAAc,IAAc,IACdH,IAAiBlL,GACjBoL,IAAgB,EAAE,CAAC1M,EAAM,EAAE,GAAGlB,EAAA;AAAA,EAChC,WACM0N,KAAkB,CAAC/M,EAAK,iBACXqN;AAAA,IACbN;AAAA,IACAX;AAAA,IACApM,EAAK,QAAQ,SAAS;AAAA,EAAA,EAEX,WACX+M,IAAiB,OAGhBA;AAYL,QAAWA,EAAe,KAAK,CAAC7E,MAAMA,EAAE,MAAM,IAAI;AAChD,MAAAgF,IAAc;AAAA,aACL,CAACH,EAAe,KAAK,CAAC7E,MAAMoF,GAA2BpF,EAAE,KAAK,CAAC;AACxE,MAAAgF,IAAc;AAAA,SACT;AACL,UAAI9K,IAAapC,EAAK,gBAAgBA,EAAK,cAAc,aAAa,MAClEuN,IAASvN,EAAK,gBAAgBA,EAAK,cAAc,SAAS;AAC9D,UAAIuN,GAAQ;AACV,YAAIzG,IAAMiG,EAAe;AAAA,UACvB,CAAC7E,MAAMqF,EAAOrF,EAAE,MAAM,EAAE,MAAM;AAAA,QAAA;AAEhC,QAAAgF,IAAcH,EAAe,MAAM,GAAGjG,IAAM,CAAC,EAAE;AAAA,UAC7C,CAACoB,MAAM,CAACsF,GAA2BtF,EAAE,OAAO9F,GAAYmL,CAAM;AAAA,QAAA;AAAA,MAElE;AACE,QAAAL,IAAcH,EAAe;AAAA,UAC3B,CAAC7E,MAAM,CAACsF,GAA2BtF,EAAE,OAAO9F,GAAYmL,CAAM;AAAA,QAAA;AAAA,IAGpE;AAAA,OA/BqB;AACnB,IAAAL,IAAc,IACdH,IAAiB,CAAA;AACjB,QAAIU,IAAWJ;AAAA,MACb;AAAA,MACAjB;AAAA,MACApM,EAAK,QAAQ,SAAS;AAAA,IAAA;AAExB,IAAIyN,EAAS,UAAUA,EAAS,YAC9BT,IAAsB,IACtBD,IAAiBU,EAAS;AAAA,EAE9B;AAqBF,MAAI/D,GACA1L,IAAQ;AAAA,IACV,eAAegC,EAAK,QAAQ;AAAA,IAC5B,UAAUA,EAAK,QAAQ;AAAA,IACvB,SAAS+M;AAAA,IACT,aAAAG;AAAA,IACA,YAAYzB;AAAA;AAAA,IAEZ,uBAAuBzL,EAAK,iBAAiB,OAAO,KAAQ;AAAA,IAC5D,oBAAoB;AAAA,IACpB,cAAc;AAAA,IACd,YAAYA,EAAK,iBAAiBA,EAAK,cAAc,cAAc,CAAA;AAAA,IACnE,YAAYA,EAAK,iBAAiBA,EAAK,cAAc,cAAc;AAAA,IACnE,QAAQA,EAAK,iBAAiBA,EAAK,cAAc,UAAUiN;AAAA,IAC3D,8BAA8B,IAAA;AAAA,IAC9B,8BAA8B,IAAA;AAAA,EAAI,GAEhCS,IAAgB,OAChBC,IAA+B,MAC/BC,IAA4B,IAC5BC,GACAC,IAA+B,IAC/BC,yBAA6C,IAAA,GAC7CC,IAA8B,MAC9BC,IAA8B,IAC9BC,KAAyB,IACzBC,yBAA4C,IAAA,GAC5CC,wBAAuC,IAAA,GACvCC,KAAqB,GACrBC,KAA0B,IAC1BC,yBAAqC,IAAA,GACrCC,yBAAuC,IAAA,GACvCC,yBAAuC,IAAA,GACvCC,yBAAqC,IAAA,GACrCC,yBAAgD,IAAA,GAChDC,yBAAuC,IAAA,GACvCC,IACAC,KAAyB;AAC7B,WAASC,KAAa;AA+CpB,QA9CAtC,IAAkBzM,EAAK,QAAQ;AAAA,MAC7B,CAAC,EAAE,QAAQgP,GAAe,UAAAnR,GAAU,OAAAmB,QAAY;AAC9C,YAAI6P,IAA6B;AAC/B,UAAAA,GAAA,GACAA,KAA8B;AAC9B;AAAA,QACF;AACA,QAAApR;AAAA,UACEmR,GAAiB,SAAS,KAAK5P,KAAS;AAAA,UACxC;AAAA,QAAA;AAEF,YAAIiQ,IAAaC,GAAsB;AAAA,UACrC,iBAAiBlR,EAAM;AAAA,UACvB,cAAcH;AAAA,UACd,eAAAmR;AAAA,QAAA,CACD;AACD,YAAIC,KAAcjQ,KAAS,MAAM;AAC/B,cAAImQ,IAA2B,IAAI,QAAQ,CAACC,MAAY;AACtD,YAAAP,KAA8BO;AAAA,UAChC,CAAC;AACD,UAAApP,EAAK,QAAQ,GAAGhB,IAAQ,EAAE,GAC1BqQ,GAAcJ,GAAY;AAAA,YACxB,OAAO;AAAA,YACP,UAAApR;AAAA,YACA,UAAU;AACR,cAAAwR,GAAcJ,GAAY;AAAA,gBACxB,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,OAAO;AAAA,gBACP,UAAApR;AAAA,cAAA,CACD,GACDsR,EAAyB,KAAK,MAAMnP,EAAK,QAAQ,GAAGhB,CAAK,CAAC;AAAA,YAC5D;AAAA,YACA,QAAQ;AACN,kBAAIsQ,IAAW,IAAI,IAAItR,EAAM,QAAQ;AACrC,cAAAsR,EAAS,IAAIL,GAAYtD,EAAY,GACrC4D,GAAY,EAAE,UAAAD,GAAU;AAAA,YAC1B;AAAA,UAAA,CACD,GACD3B,GAA8B,QAAA,GAC9BA,IAA+B;AAC/B;AAAA,QACF;AACA,eAAO6B,GAAgBR,GAAenR,CAAQ;AAAA,MAChD;AAAA,IAAA,GAEEoO,GAAY;AACd,MAAAwD,GAA0BzD,GAAc+B,EAAsB;AAC9D,UAAI2B,IAA0B,MAAMC,GAA0B3D,GAAc+B,EAAsB;AAClG,MAAA/B,EAAa,iBAAiB,YAAY0D,CAAuB,GACjE1B,IAA8B,MAAMhC,EAAa,oBAAoB,YAAY0D,CAAuB;AAAA,IAC1G;AACA,WAAK1R,EAAM,eACTwR,GAAgB,OAAiBxR,EAAM,UAAU;AAAA,MAC/C,kBAAkB;AAAA,IAAA,CACnB,GAEI0L;AAAA,EACT;AACA,WAASkG,KAAU;AACjB,IAAInD,KACFA,EAAA,GAEEuB,KACFA,EAAA,GAEFtB,EAAY,MAAA,GACZmB,KAA+BA,EAA4B,MAAA,GAC3D7P,EAAM,SAAS,QAAQ,CAACyH,GAAGxH,MAAQ4R,GAAc5R,CAAG,CAAC,GACrDD,EAAM,SAAS,QAAQ,CAACyH,GAAGxH,MAAQ6R,GAAc7R,CAAG,CAAC;AAAA,EACvD;AACA,WAAS8R,GAAUtQ,GAAI;AACrB,WAAAiN,EAAY,IAAIjN,CAAE,GACX,MAAMiN,EAAY,OAAOjN,CAAE;AAAA,EACpC;AACA,WAAS8P,GAAYS,GAAUnG,IAAO,IAAI;AACxC,IAAImG,EAAS,YACXA,EAAS,UAAUA,EAAS,QAAQ,IAAI,CAAC9H,MAAM;AAC7C,UAAI3H,IAAQK,EAASsH,EAAE,MAAM,EAAE,GAC3B+H,IAAa/H,EAAE;AACnB,aAAI+H,EAAW,YAAY1P,EAAM,WAAW0P,EAAW,iBAAiB1P,EAAM,gBAAgB0P,EAAW,2BAA2B1P,EAAM,yBACjI;AAAA,QACL,GAAG2H;AAAA,QACH,OAAA3H;AAAA,MAAA,IAGG2H;AAAA,IACT,CAAC,IAEHlK,IAAQ;AAAA,MACN,GAAGA;AAAA,MACH,GAAGgS;AAAA,IAAA;AAEL,QAAIE,IAAoB,CAAA,GACpBC,IAAkB,CAAA;AACtB,IAAAnS,EAAM,SAAS,QAAQ,CAACoS,GAASnS,MAAQ;AACvC,MAAImS,EAAQ,UAAU,WAChBzB,GAA0B,IAAI1Q,CAAG,IACnCiS,EAAkB,KAAKjS,CAAG,IAE1BkS,EAAgB,KAAKlS,CAAG;AAAA,IAG9B,CAAC,GACD0Q,GAA0B,QAAQ,CAAC1Q,MAAQ;AACzC,MAAI,CAACD,EAAM,SAAS,IAAIC,CAAG,KAAK,CAACmQ,EAAiB,IAAInQ,CAAG,KACvDiS,EAAkB,KAAKjS,CAAG;AAAA,IAE9B,CAAC,GACD,CAAC,GAAGyO,CAAW,EAAE;AAAA,MACf,CAAC2D,MAAeA,EAAWrS,GAAO;AAAA,QAChC,iBAAiBkS;AAAA,QACjB,WAAWF,EAAS,UAAU;AAAA,QAC9B,oBAAoBnG,EAAK;AAAA,QACzB,WAAWA,EAAK,cAAc;AAAA,MAAA,CAC/B;AAAA,IAAA,GAEHqG,EAAkB,QAAQ,CAACjS,MAAQ4R,GAAc5R,CAAG,CAAC,GACrDkS,EAAgB,QAAQ,CAAClS,MAAQD,EAAM,SAAS,OAAOC,CAAG,CAAC;AAAA,EAC7D;AACA,WAASqS,GAAmBzS,GAAUmS,GAAU,EAAE,WAAAO,EAAA,IAAc,CAAA,GAAI;AAClE,QAAIC,IAAiBxS,EAAM,cAAc,QAAQA,EAAM,WAAW,cAAc,QAAQyS,GAAiBzS,EAAM,WAAW,UAAU,KAAKA,EAAM,WAAW,UAAU,aAAaH,EAAS,OAAO,gBAAgB,IAC7M6S;AACJ,IAAIV,EAAS,aACP,OAAO,KAAKA,EAAS,UAAU,EAAE,SAAS,IAC5CU,IAAaV,EAAS,aAEtBU,IAAa,OAENF,IACTE,IAAa1S,EAAM,aAEnB0S,IAAa;AAEf,QAAItO,IAAa4N,EAAS,aAAaW;AAAA,MACrC3S,EAAM;AAAA,MACNgS,EAAS;AAAA,MACTA,EAAS,WAAW,CAAA;AAAA,MACpBA,EAAS;AAAA,IAAA,IACPhS,EAAM,YACNsR,IAAWtR,EAAM;AACrB,IAAIsR,EAAS,OAAO,MAClBA,IAAW,IAAI,IAAIA,CAAQ,GAC3BA,EAAS,QAAQ,CAAC7J,GAAGmL,MAAMtB,EAAS,IAAIsB,GAAGjF,EAAY,CAAC;AAE1D,QAAIkF,IAAwB5C,IAA8B,KAAQ6C,GAAuBjT,GAAUmS,EAAS,WAAWhS,EAAM,OAAO,GAChI+S,IAAqBnD,MAA8B,MAAQ5P,EAAM,WAAW,cAAc,QAAQyS,GAAiBzS,EAAM,WAAW,UAAU,KAAKH,EAAS,OAAO,gBAAgB;AACvL,IAAIwO,MACFD,IAAaC,GACbA,IAAqB,SAEnB4B,KACOP,MAAkB,UAClBA,MAAkB,SAC3B1N,EAAK,QAAQ,KAAKnC,GAAUA,EAAS,KAAK,IACjC6P,MAAkB,aAC3B1N,EAAK,QAAQ,QAAQnC,GAAUA,EAAS,KAAK;AAE/C,QAAImT;AACJ,QAAItD,MAAkB,OAAiB;AACrC,UAAIuD,IAAalD,GAAuB,IAAI/P,EAAM,SAAS,QAAQ;AACnE,MAAIiT,KAAcA,EAAW,IAAIpT,EAAS,QAAQ,IAChDmT,IAAqB;AAAA,QACnB,iBAAiBhT,EAAM;AAAA,QACvB,cAAcH;AAAA,MAAA,IAEPkQ,GAAuB,IAAIlQ,EAAS,QAAQ,MACrDmT,IAAqB;AAAA,QACnB,iBAAiBnT;AAAA,QACjB,cAAcG,EAAM;AAAA,MAAA;AAAA,IAG1B,WAAW8P,GAA8B;AACvC,UAAIoD,IAAUnD,GAAuB,IAAI/P,EAAM,SAAS,QAAQ;AAChE,MAAIkT,IACFA,EAAQ,IAAIrT,EAAS,QAAQ,KAE7BqT,IAA0B,oBAAI,IAAI,CAACrT,EAAS,QAAQ,CAAC,GACrDkQ,GAAuB,IAAI/P,EAAM,SAAS,UAAUkT,CAAO,IAE7DF,IAAqB;AAAA,QACnB,iBAAiBhT,EAAM;AAAA,QACvB,cAAcH;AAAA,MAAA;AAAA,IAElB;AACA,IAAA0R;AAAA,MACE;AAAA,QACE,GAAGS;AAAA;AAAA,QAEH,YAAAU;AAAA,QACA,YAAAtO;AAAA,QACA,eAAesL;AAAA,QACf,UAAA7P;AAAA,QACA,aAAa;AAAA,QACb,YAAY4N;AAAA,QACZ,cAAc;AAAA,QACd,uBAAAoF;AAAA,QACA,oBAAAE;AAAA,QACA,UAAAzB;AAAA,MAAA;AAAA,MAEF;AAAA,QACE,oBAAA0B;AAAA,QACA,WAAWT,MAAc;AAAA,MAAA;AAAA,IAC3B,GAEF7C,IAAgB,OAChBE,IAA4B,IAC5BE,IAA+B,IAC/BG,IAA8B,IAC9BC,KAAyB,IACzBP,GAA8B,QAAA,GAC9BA,IAA+B,MAC/BmB,IAAwB,QAAA,GACxBA,KAAyB;AAAA,EAC3B;AACA,iBAAenF,GAASvM,GAAIyM,GAAM;AAGhC,QAFA8D,GAA8B,QAAA,GAC9BA,IAA+B,MAC3B,OAAOvQ,KAAO,UAAU;AAC1B,MAAKuQ,MACHA,IAA+BwD,GAAA;AAEjC,UAAIC,IAAUzD,EAA6B;AAC3C,aAAA3N,EAAK,QAAQ,GAAG5C,CAAE,GACXgU;AAAA,IACT;AACA,QAAIC,IAAiBC;AAAA,MACnBtT,EAAM;AAAA,MACNA,EAAM;AAAA,MACNsD;AAAA,MACAlE;AAAA,MACAyM,GAAM;AAAA,MACNA,GAAM;AAAA,IAAA,GAEJ,EAAE,MAAA1L,GAAM,YAAAoT,GAAY,OAAAlS,EAAA,IAAUmS;AAAA,MAChC;AAAA,MACAH;AAAA,MACAxH;AAAA,IAAA,GAEE4H,IAAkBzT,EAAM,UACxB0T,IAAexU,GAAec,EAAM,UAAUG,GAAM0L,KAAQA,EAAK,KAAK;AAC1E,IAAA6H,IAAe;AAAA,MACb,GAAGA;AAAA,MACH,GAAG1R,EAAK,QAAQ,eAAe0R,CAAY;AAAA,IAAA;AAE7C,QAAIC,IAAc9H,KAAQA,EAAK,WAAW,OAAOA,EAAK,UAAU,QAC5DmF,IAAgB;AACpB,IAAI2C,MAAgB,KAClB3C,IAAgB,YACP2C,MAAgB,MAChBJ,KAAc,QAAQd,GAAiBc,EAAW,UAAU,KAAKA,EAAW,eAAevT,EAAM,SAAS,WAAWA,EAAM,SAAS,WAC7IgR,IAAgB;AAElB,QAAI+B,IAAqBlH,KAAQ,wBAAwBA,IAAOA,EAAK,uBAAuB,KAAO,QAC/F0G,KAAa1G,KAAQA,EAAK,eAAe,IACzCoF,IAAaC,GAAsB;AAAA,MACrC,iBAAAuC;AAAA,MACA,cAAAC;AAAA,MACA,eAAA1C;AAAA,IAAA,CACD;AACD,QAAIC,GAAY;AACd,MAAAI,GAAcJ,GAAY;AAAA,QACxB,OAAO;AAAA,QACP,UAAUyC;AAAA,QACV,UAAU;AACR,UAAArC,GAAcJ,GAAY;AAAA,YACxB,OAAO;AAAA,YACP,SAAS;AAAA,YACT,OAAO;AAAA,YACP,UAAUyC;AAAA,UAAA,CACX,GACD/H,GAASvM,GAAIyM,CAAI;AAAA,QACnB;AAAA,QACA,QAAQ;AACN,cAAIyF,IAAW,IAAI,IAAItR,EAAM,QAAQ;AACrC,UAAAsR,EAAS,IAAIL,GAAYtD,EAAY,GACrC4D,GAAY,EAAE,UAAAD,GAAU;AAAA,QAC1B;AAAA,MAAA,CACD;AACD;AAAA,IACF;AACA,UAAME,GAAgBR,GAAe0C,GAAc;AAAA,MACjD,YAAAH;AAAA;AAAA;AAAA,MAGA,cAAclS;AAAA,MACd,oBAAA0R;AAAA,MACA,SAASlH,KAAQA,EAAK;AAAA,MACtB,sBAAsBA,KAAQA,EAAK;AAAA,MACnC,WAAA0G;AAAA,MACA,iCAAiC1G,KAAQA,EAAK;AAAA,IAAA,CAC/C;AAAA,EACH;AACA,WAAS+H,KAAa;AACpB,IAAK9C,OACHA,KAAyBqC,GAAA,IAE3BU,GAAA,GACAtC,GAAY,EAAE,cAAc,WAAW;AACvC,QAAI6B,IAAUtC,GAAuB;AACrC,WAAI9Q,EAAM,WAAW,UAAU,eACtBoT,IAELpT,EAAM,WAAW,UAAU,UAC7BwR,GAAgBxR,EAAM,eAAeA,EAAM,UAAU;AAAA,MACnD,gCAAgC;AAAA,IAAA,CACjC,GACMoT,MAET5B;AAAA,MACE9B,KAAiB1P,EAAM;AAAA,MACvBA,EAAM,WAAW;AAAA,MACjB;AAAA,QACE,oBAAoBA,EAAM;AAAA;AAAA,QAE1B,sBAAsB8P,MAAiC;AAAA,MAAA;AAAA,IACzD,GAEKsD;AAAA,EACT;AACA,iBAAe5B,GAAgBR,GAAenR,GAAUgM,GAAM;AAC5D,IAAAgE,KAA+BA,EAA4B,MAAA,GAC3DA,IAA8B,MAC9BH,IAAgBsB,GAChBf,KAA+BpE,KAAQA,EAAK,oCAAoC,IAChFiI,GAAmB9T,EAAM,UAAUA,EAAM,OAAO,GAChD4P,KAA6B/D,KAAQA,EAAK,wBAAwB,IAClEiE,KAAgCjE,KAAQA,EAAK,0BAA0B;AACvE,QAAIkI,IAAc1F,KAAsBD,GACpC4F,IAAoBnI,KAAQA,EAAK,oBACjChI,IAAUgI,GAAM,oBAAoB7L,EAAM,WAAWA,EAAM,QAAQ,SAAS,KAAK,CAACgP;AAAA;AAAA,MAEpFhP,EAAM;AAAA,QACJoD,GAAY2Q,GAAalU,GAAUyD,CAAQ,GAC3CiP,KAAa1G,KAAQA,EAAK,eAAe;AAC7C,QAAIhI,KAAW7D,EAAM,eAAe,CAACkQ,MAA0B+D,GAAiBjU,EAAM,UAAUH,CAAQ,KAAK,EAAEgM,KAAQA,EAAK,cAAc4G,GAAiB5G,EAAK,WAAW,UAAU,IAAI;AACvL,MAAAyG,GAAmBzS,GAAU,EAAE,SAAAgE,EAAA,GAAW,EAAE,WAAA0O,GAAW;AACvD;AAAA,IACF;AACA,QAAI9C,IAAWJ,GAAcxL,GAASkQ,GAAalU,EAAS,QAAQ;AAIpE,QAHI4P,EAAS,UAAUA,EAAS,YAC9B5L,IAAU4L,EAAS,UAEjB,CAAC5L,GAAS;AACZ,UAAI,EAAE,OAAAxC,IAAO,iBAAA6S,IAAiB,OAAA3R,GAAA,IAAU4R;AAAA,QACtCtU,EAAS;AAAA,MAAA;AAEX,MAAAyS;AAAA,QACEzS;AAAA,QACA;AAAA,UACE,SAASqU;AAAA,UACT,YAAY,CAAA;AAAA,UACZ,QAAQ;AAAA,YACN,CAAC3R,GAAM,EAAE,GAAGlB;AAAA,UAAA;AAAA,QACd;AAAA,QAEF,EAAE,WAAAkR,EAAA;AAAA,MAAU;AAEd;AAAA,IACF;AACA,IAAA1C,IAA8B,IAAI,gBAAA;AAClC,QAAIpD,IAAU2H;AAAA,MACZpS,EAAK;AAAA,MACLnC;AAAA,MACAgQ,EAA4B;AAAA,MAC5BhE,KAAQA,EAAK;AAAA,IAAA,GAEXwI,IAAgBrS,EAAK,aAAa,MAAMA,EAAK,WAAA,IAAe,IAAID,GAAA,GAChEuS;AACJ,QAAIzI,KAAQA,EAAK;AACf,MAAAyI,IAAsB;AAAA,QACpBC,GAAoB1Q,CAAO,EAAE,MAAM;AAAA,QACnC,EAAE,MAAM,SAAqB,OAAOgI,EAAK,aAAA;AAAA,MAAa;AAAA,aAE/CA,KAAQA,EAAK,cAAc4G,GAAiB5G,EAAK,WAAW,UAAU,GAAG;AAClF,UAAI2I,KAAe,MAAMC;AAAA,QACvBhI;AAAA,QACA5M;AAAA,QACAgM,EAAK;AAAA,QACLhI;AAAA,QACAwQ;AAAA,QACA5E,EAAS;AAAA,QACT5D,KAAQA,EAAK,qBAAqB;AAAA,QAClC,EAAE,SAASA,EAAK,SAAS,WAAA0G,EAAA;AAAA,MAAU;AAErC,UAAIiC,GAAa;AACf;AAEF,UAAIA,GAAa,qBAAqB;AACpC,YAAI,CAACE,IAASnP,EAAM,IAAIiP,GAAa;AACrC,YAAIG,GAAcpP,EAAM,KAAKyE,GAAqBzE,GAAO,KAAK,KAAKA,GAAO,MAAM,WAAW,KAAK;AAC9F,UAAAsK,IAA8B,MAC9ByC,GAAmBzS,GAAU;AAAA,YAC3B,SAAS2U,GAAa;AAAA,YACtB,YAAY,CAAA;AAAA,YACZ,QAAQ;AAAA,cACN,CAACE,EAAO,GAAGnP,GAAO;AAAA,YAAA;AAAA,UACpB,CACD;AACD;AAAA,QACF;AAAA,MACF;AACA,MAAA1B,IAAU2Q,GAAa,WAAW3Q,GAClCyQ,IAAsBE,GAAa,qBACnCR,IAAoBY,GAAqB/U,GAAUgM,EAAK,UAAU,GAClE0G,IAAY,IACZ9C,EAAS,SAAS,IAClBhD,IAAU2H;AAAA,QACRpS,EAAK;AAAA,QACLyK,EAAQ;AAAA,QACRA,EAAQ;AAAA,MAAA;AAAA,IAEZ;AACA,QAAI;AAAA,MACF,gBAAAoI;AAAA,MACA,SAASC;AAAA,MACT,YAAA1Q;AAAA,MACA,QAAAmL;AAAA,IAAA,IACE,MAAMwF;AAAA,MACRtI;AAAA,MACA5M;AAAA,MACAgE;AAAA,MACAwQ;AAAA,MACA5E,EAAS;AAAA,MACTuE;AAAA,MACAnI,KAAQA,EAAK;AAAA,MACbA,KAAQA,EAAK;AAAA,MACbA,KAAQA,EAAK;AAAA,MACbA,KAAQA,EAAK,qBAAqB;AAAA,MAClC0G;AAAA,MACA+B;AAAA,MACAzI,KAAQA,EAAK;AAAA,IAAA;AAEf,IAAIgJ,MAGJhF,IAA8B,MAC9ByC,GAAmBzS,GAAU;AAAA,MAC3B,SAASiV,KAAkBjR;AAAA,MAC3B,GAAGmR,GAAuBV,CAAmB;AAAA,MAC7C,YAAAlQ;AAAA,MACA,QAAAmL;AAAA,IAAA,CACD;AAAA,EACH;AACA,iBAAekF,GAAahI,GAAS5M,GAAU0T,GAAY1P,GAASwQ,GAAeY,GAAYC,GAAkBrJ,IAAO,IAAI;AAC1H,IAAAgI,GAAA;AACA,QAAIsB,IAAaC,GAAwBvV,GAAU0T,CAAU;AAE7D,QADAhC,GAAY,EAAE,YAAA4D,KAAc,EAAE,WAAWtJ,EAAK,cAAc,IAAM,GAC9DoJ,GAAY;AACd,UAAII,IAAiB,MAAMC;AAAA,QACzBzR;AAAA,QACAhE,EAAS;AAAA,QACT4M,EAAQ;AAAA,MAAA;AAEV,UAAI4I,EAAe,SAAS;AAC1B,eAAO,EAAE,gBAAgB,GAAA;AAC3B,UAAWA,EAAe,SAAS,SAAS;AAC1C,YAAIA,EAAe,eAAe,WAAW,GAAG;AAC9C,cAAI,EAAE,SAASE,GAAU,OAAAhT,GAAA,IAAU6M,GAAuBhB,CAAU;AACpE,iBAAO;AAAA,YACL,SAASmH;AAAA,YACT,qBAAqB;AAAA,cACnBhT,GAAM;AAAA,cACN;AAAA,gBACE,MAAM;AAAA,gBACN,OAAO8S,EAAe;AAAA,cAAA;AAAA,YACxB;AAAA,UACF;AAAA,QAEJ;AACA,YAAIG,IAAajB,GAAoBc,EAAe,cAAc,EAAE,MAAM;AAC1E,eAAO;AAAA,UACL,SAASA,EAAe;AAAA,UACxB,qBAAqB;AAAA,YACnBG;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,OAAOH,EAAe;AAAA,YAAA;AAAA,UACxB;AAAA,QACF;AAAA,MAEJ,WAAYA,EAAe;AAezB,QAAAxR,IAAUwR,EAAe;AAAA,WAfS;AAClC,YAAI,EAAE,iBAAAnB,GAAiB,OAAA7S,GAAO,OAAAkB,GAAA,IAAU4R;AAAA,UACtCtU,EAAS;AAAA,QAAA;AAEX,eAAO;AAAA,UACL,SAASqU;AAAA,UACT,qBAAqB;AAAA,YACnB3R,GAAM;AAAA,YACN;AAAA,cACE,MAAM;AAAA,cACN,OAAAlB;AAAA,YAAA;AAAA,UACF;AAAA,QACF;AAAA,MAEJ;AAAA,IAGF;AACA,QAAIkE,GACAkQ,IAAcC,GAAe7R,GAAShE,CAAQ;AAClD,QAAI,CAAC4V,EAAY,MAAM,UAAU,CAACA,EAAY,MAAM;AAClD,MAAAlQ,IAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO4J,GAAuB,KAAK;AAAA,UACjC,QAAQ1C,EAAQ;AAAA,UAChB,UAAU5M,EAAS;AAAA,UACnB,SAAS4V,EAAY,MAAM;AAAA,QAAA,CAC5B;AAAA,MAAA;AAAA,SAEE;AACL,UAAIE,IAAYC;AAAA,QACdlT;AAAA,QACAE;AAAA,QACA6J;AAAA,QACA5I;AAAA,QACA4R;AAAA,QACAP,IAAmB,CAAA,IAAKhH;AAAA,QACxBmG;AAAA,MAAA,GAEEwB,IAAU,MAAMC;AAAA,QAClBrJ;AAAA,QACAkJ;AAAA,QACAtB;AAAA,QACA;AAAA,MAAA;AAGF,UADA9O,IAASsQ,EAAQJ,EAAY,MAAM,EAAE,GACjC,CAAClQ;AACH,iBAASpB,KAASN;AAChB,cAAIgS,EAAQ1R,EAAM,MAAM,EAAE,GAAG;AAC3B,YAAAoB,IAASsQ,EAAQ1R,EAAM,MAAM,EAAE;AAC/B;AAAA,UACF;AAAA;AAGJ,UAAIsI,EAAQ,OAAO;AACjB,eAAO,EAAE,gBAAgB,GAAA;AAAA,IAE7B;AACA,QAAIsJ,GAAiBxQ,CAAM,GAAG;AAC5B,UAAIjE;AACJ,aAAIuK,KAAQA,EAAK,WAAW,OAC1BvK,IAAWuK,EAAK,UAQhBvK,IANgB0U;AAAA,QACdzQ,EAAO,SAAS,QAAQ,IAAI,UAAU;AAAA,QACtC,IAAI,IAAIkH,EAAQ,GAAG;AAAA,QACnBnJ;AAAA,QACAtB,EAAK;AAAA,MAAA,MAEkBhC,EAAM,SAAS,WAAWA,EAAM,SAAS,QAEpE,MAAMiW,GAAwBxJ,GAASlH,GAAQ,IAAM;AAAA,QACnD,YAAAgO;AAAA,QACA,SAASjS;AAAA,MAAA,CACV,GACM,EAAE,gBAAgB,GAAA;AAAA,IAC3B;AACA,QAAIqT,GAAcpP,CAAM,GAAG;AACzB,UAAI2Q,IAAgB3B,GAAoB1Q,GAAS4R,EAAY,MAAM,EAAE;AACrE,cAAK5J,KAAQA,EAAK,aAAa,OAC7B6D,IAAgB,SAEX;AAAA,QACL,SAAA7L;AAAA,QACA,qBAAqB;AAAA,UACnBqS,EAAc,MAAM;AAAA,UACpB3Q;AAAA,UACAkQ,EAAY,MAAM;AAAA,QAAA;AAAA,MACpB;AAAA,IAEJ;AACA,WAAO;AAAA,MACL,SAAA5R;AAAA,MACA,qBAAqB,CAAC4R,EAAY,MAAM,IAAIlQ,CAAM;AAAA,IAAA;AAAA,EAEtD;AACA,iBAAewP,GAActI,GAAS5M,GAAUgE,GAASwQ,GAAeY,GAAYkB,GAAoB5C,GAAY6C,GAAmB9U,GAAU4T,GAAkB3C,GAAW+B,GAAqB+B,GAAiC;AAClO,QAAIrC,IAAoBmC,KAAsBvB,GAAqB/U,GAAU0T,CAAU,GACnF+C,KAAmB/C,KAAc6C,KAAqBG,GAA4BvC,CAAiB,GACnGwC,KAA8B,CAACvG,KAA+B,CAACiF;AACnE,QAAID,GAAY;AACd,UAAIuB,IAA6B;AAC/B,YAAI9D,KAAa+D,GAAqBnC,CAAmB;AACzD,QAAA/C;AAAA,UACE;AAAA,YACE,YAAYyC;AAAA,YACZ,GAAGtB,OAAe,SAAS,EAAE,YAAAA,OAAe,CAAA;AAAA,UAAC;AAAA,UAE/C;AAAA,YACE,WAAAH;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AACA,UAAI8C,IAAiB,MAAMC;AAAA,QACzBzR;AAAA,QACAhE,EAAS;AAAA,QACT4M,EAAQ;AAAA,MAAA;AAEV,UAAI4I,EAAe,SAAS;AAC1B,eAAO,EAAE,gBAAgB,GAAA;AAC3B,UAAWA,EAAe,SAAS,SAAS;AAC1C,YAAIA,EAAe,eAAe,WAAW,GAAG;AAC9C,cAAI,EAAE,SAASE,IAAU,OAAAhT,GAAA,IAAU6M,GAAuBhB,CAAU;AACpE,iBAAO;AAAA,YACL,SAASmH;AAAA,YACT,YAAY,CAAA;AAAA,YACZ,QAAQ;AAAA,cACN,CAAChT,GAAM,EAAE,GAAG8S,EAAe;AAAA,YAAA;AAAA,UAC7B;AAAA,QAEJ;AACA,YAAIG,KAAajB,GAAoBc,EAAe,cAAc,EAAE,MAAM;AAC1E,eAAO;AAAA,UACL,SAASA,EAAe;AAAA,UACxB,YAAY,CAAA;AAAA,UACZ,QAAQ;AAAA,YACN,CAACG,EAAU,GAAGH,EAAe;AAAA,UAAA;AAAA,QAC/B;AAAA,MAEJ,WAAYA,EAAe;AAYzB,QAAAxR,IAAUwR,EAAe;AAAA,WAZS;AAClC,YAAI,EAAE,OAAAhU,IAAO,iBAAA6S,IAAiB,OAAA3R,GAAA,IAAU4R;AAAA,UACtCtU,EAAS;AAAA,QAAA;AAEX,eAAO;AAAA,UACL,SAASqU;AAAA,UACT,YAAY,CAAA;AAAA,UACZ,QAAQ;AAAA,YACN,CAAC3R,GAAM,EAAE,GAAGlB;AAAA,UAAA;AAAA,QACd;AAAA,MAEJ;AAAA,IAGF;AACA,QAAI0S,KAAc1F,KAAsBD,GACpC,EAAE,WAAAuH,IAAW,sBAAAe,GAAA,IAAyBC;AAAA,MACxClK;AAAA,MACA4H;AAAA,MACA3R;AAAA,MACAE;AAAA,MACAZ,EAAK;AAAA,MACLhC;AAAA,MACA6D;AAAA,MACAyS;AAAA,MACAzW;AAAA,MACAqV,IAAmB,CAAA,IAAKhH;AAAA,MACxBgH,MAAqB;AAAA,MACrBhF;AAAA,MACAC;AAAA,MACAQ;AAAA,MACAF;AAAA,MACAD;AAAA,MACAuD;AAAA,MACAzQ;AAAA,MACAtB,EAAK,2BAA2B;AAAA,MAChCsS;AAAA,MACA+B;AAAA,IAAA;AAGF,QADA/F,KAA0B,EAAED,IACxB,CAACrO,EAAK,gBAAgB,CAAC2T,GAAU,KAAK,CAACzL,MAAMA,EAAE,UAAU,KAAK,CAACyL,GAAU;AAAA,MAC3E,CAACzL,MAAMA,EAAE,MAAM,cAAcA,EAAE,MAAM,WAAW,SAAS;AAAA,IAAA,KACtDwM,GAAqB,WAAW,GAAG;AACtC,UAAIE,IAAmBC,GAAA;AACvB,aAAAvE;AAAA,QACEzS;AAAA,QACA;AAAA,UACE,SAAAgE;AAAA,UACA,YAAY,CAAA;AAAA;AAAA,UAEZ,QAAQyQ,KAAuBK,GAAcL,EAAoB,CAAC,CAAC,IAAI,EAAE,CAACA,EAAoB,CAAC,CAAC,GAAGA,EAAoB,CAAC,EAAE,UAAU;AAAA,UACpI,GAAGU,GAAuBV,CAAmB;AAAA,UAC7C,GAAGsC,IAAmB,EAAE,UAAU,IAAI,IAAI5W,EAAM,QAAQ,MAAM,CAAA;AAAA,QAAC;AAAA,QAEjE,EAAE,WAAAuS,EAAA;AAAA,MAAU,GAEP,EAAE,gBAAgB,GAAA;AAAA,IAC3B;AACA,QAAIiE,IAA6B;AAC/B,UAAIrT,IAAU,CAAA;AACd,UAAI,CAAC8R,GAAY;AACf,QAAA9R,EAAQ,aAAa6Q;AACrB,YAAItB,KAAa+D,GAAqBnC,CAAmB;AACzD,QAAI5B,OAAe,WACjBvP,EAAQ,aAAauP;AAAA,MAEzB;AACA,MAAIgE,GAAqB,SAAS,MAChCvT,EAAQ,WAAW2T,GAA+BJ,EAAoB,IAExEnF,GAAYpO,GAAS,EAAE,WAAAoP,GAAW;AAAA,IACpC;AACA,IAAAmE,GAAqB,QAAQ,CAACK,MAAO;AACnC,MAAAC,GAAaD,EAAG,GAAG,GACfA,EAAG,cACL3G,EAAiB,IAAI2G,EAAG,KAAKA,EAAG,UAAU;AAAA,IAE9C,CAAC;AACD,QAAIE,KAAiC,MAAMP,GAAqB,QAAQ,CAACQ,MAAMF,GAAaE,EAAE,GAAG,CAAC;AAClG,IAAIrH,KACFA,EAA4B,OAAO;AAAA,MACjC;AAAA,MACAoH;AAAA,IAAA;AAGJ,QAAI,EAAE,eAAAE,IAAe,gBAAAC,GAAA,IAAmB,MAAMC;AAAA,MAC5C1B;AAAA,MACAe;AAAA,MACAjK;AAAA,MACA4H;AAAA,IAAA;AAEF,QAAI5H,EAAQ,OAAO;AACjB,aAAO,EAAE,gBAAgB,GAAA;AAE3B,IAAIoD,KACFA,EAA4B,OAAO;AAAA,MACjC;AAAA,MACAoH;AAAA,IAAA,GAGJP,GAAqB,QAAQ,CAACK,MAAO3G,EAAiB,OAAO2G,EAAG,GAAG,CAAC;AACpE,QAAIO,KAAYC,GAAaJ,EAAa;AAC1C,QAAIG;AACF,mBAAMrB,GAAwBxJ,GAAS6K,GAAU,QAAQ,IAAM;AAAA,QAC7D,SAAShW;AAAA,MAAA,CACV,GACM,EAAE,gBAAgB,GAAA;AAG3B,QADAgW,KAAYC,GAAaH,EAAc,GACnCE;AACF,aAAA9G,GAAiB,IAAI8G,GAAU,GAAG,GAClC,MAAMrB,GAAwBxJ,GAAS6K,GAAU,QAAQ,IAAM;AAAA,QAC7D,SAAShW;AAAA,MAAA,CACV,GACM,EAAE,gBAAgB,GAAA;AAE3B,QAAI,EAAE,YAAA8C,IAAY,QAAAmL,GAAA,IAAWiI;AAAA,MAC3BxX;AAAA,MACA6D;AAAA,MACAsT;AAAA,MACA7C;AAAA,MACAoC;AAAA,MACAU;AAAA,IAAA;AAEF,IAAIlC,KAAoBlV,EAAM,WAC5BuP,KAAS,EAAE,GAAGvP,EAAM,QAAQ,GAAGuP,GAAA;AAEjC,QAAIkI,KAAkBZ,GAAA,GAClBa,KAAqBC,GAAqBrH,EAAuB,GACjEsH,KAAuBH,MAAmBC,MAAsBhB,GAAqB,SAAS;AAClG,WAAO;AAAA,MACL,SAAA7S;AAAA,MACA,YAAAO;AAAA,MACA,QAAAmL;AAAA,MACA,GAAGqI,KAAuB,EAAE,UAAU,IAAI,IAAI5X,EAAM,QAAQ,MAAM,CAAA;AAAA,IAAC;AAAA,EAEvE;AACA,WAASyW,GAAqBnC,GAAqB;AACjD,QAAIA,KAAuB,CAACK,GAAcL,EAAoB,CAAC,CAAC;AAC9D,aAAO;AAAA,QACL,CAACA,EAAoB,CAAC,CAAC,GAAGA,EAAoB,CAAC,EAAE;AAAA,MAAA;AAErD,QAAWtU,EAAM;AACf,aAAI,OAAO,KAAKA,EAAM,UAAU,EAAE,WAAW,IACpC,OAEAA,EAAM;AAAA,EAGnB;AACA,WAAS8W,GAA+BJ,GAAsB;AAC5D,WAAAA,EAAqB,QAAQ,CAACK,MAAO;AACnC,UAAI3E,IAAUpS,EAAM,SAAS,IAAI+W,EAAG,GAAG,GACnCc,IAAsBC;AAAA,QACxB;AAAA,QACA1F,IAAUA,EAAQ,OAAO;AAAA,MAAA;AAE3B,MAAApS,EAAM,SAAS,IAAI+W,EAAG,KAAKc,CAAmB;AAAA,IAChD,CAAC,GACM,IAAI,IAAI7X,EAAM,QAAQ;AAAA,EAC/B;AACA,iBAAe+L,GAAO9L,GAAKyU,GAAS7S,GAAMgK,GAAM;AAC9C,IAAAmL,GAAa/W,CAAG;AAChB,QAAIsS,KAAa1G,KAAQA,EAAK,eAAe,IACzCkI,IAAc1F,KAAsBD,GACpCiF,IAAiBC;AAAA,MACnBtT,EAAM;AAAA,MACNA,EAAM;AAAA,MACNsD;AAAA,MACAzB;AAAA,MACA6S;AAAA,MACA7I,GAAM;AAAA,IAAA,GAEJhI,IAAUT,GAAY2Q,GAAaV,GAAgB/P,CAAQ,GAC3DmM,IAAWJ,GAAcxL,GAASkQ,GAAaV,CAAc;AAIjE,QAHI5D,EAAS,UAAUA,EAAS,YAC9B5L,IAAU4L,EAAS,UAEjB,CAAC5L,GAAS;AACZ,MAAAkU;AAAA,QACE9X;AAAA,QACAyU;AAAA,QACAvF,GAAuB,KAAK,EAAE,UAAUkE,GAAgB;AAAA,QACxD,EAAE,WAAAd,EAAA;AAAA,MAAU;AAEd;AAAA,IACF;AACA,QAAI,EAAE,MAAApS,GAAM,YAAAoT,GAAY,OAAAlS,EAAA,IAAUmS;AAAA,MAChC;AAAA,MACAH;AAAA,MACAxH;AAAA,IAAA;AAEF,QAAIxK,GAAO;AACT,MAAA0W,GAAgB9X,GAAKyU,GAASrT,GAAO,EAAE,WAAAkR,GAAW;AAClD;AAAA,IACF;AACA,QAAI8B,IAAgBrS,EAAK,aAAa,MAAMA,EAAK,WAAA,IAAe,IAAID,GAAA,GAChEgR,KAAsBlH,KAAQA,EAAK,wBAAwB;AAC/D,QAAI0H,KAAcd,GAAiBc,EAAW,UAAU,GAAG;AACzD,YAAMyE;AAAA,QACJ/X;AAAA,QACAyU;AAAA,QACAvU;AAAA,QACA0D;AAAA,QACAwQ;AAAA,QACA5E,EAAS;AAAA,QACT8C;AAAA,QACAQ;AAAA,QACAQ;AAAA,QACA1H,KAAQA,EAAK;AAAA,MAAA;AAEf;AAAA,IACF;AACA,IAAA4E,GAAiB,IAAIxQ,GAAK,EAAE,SAAAyU,GAAS,MAAAvU,GAAM,GAC3C,MAAM8X;AAAA,MACJhY;AAAA,MACAyU;AAAA,MACAvU;AAAA,MACA0D;AAAA,MACAwQ;AAAA,MACA5E,EAAS;AAAA,MACT8C;AAAA,MACAQ;AAAA,MACAQ;AAAA,IAAA;AAAA,EAEJ;AACA,iBAAeyE,GAAoB/X,GAAKyU,GAASvU,GAAM+X,GAAgB7D,GAAeY,GAAY1C,GAAWQ,GAAoBQ,GAAY8C,GAAiC;AAC5K,IAAAxC,GAAA,GACApD,GAAiB,OAAOxQ,CAAG;AAC3B,QAAIkY,IAAkBnY,EAAM,SAAS,IAAIC,CAAG;AAC5C,IAAAmY,GAAmBnY,GAAKoY,GAAqB9E,GAAY4E,CAAe,GAAG;AAAA,MACzE,WAAA5F;AAAA,IAAA,CACD;AACD,QAAI+F,IAAkB,IAAI,gBAAA,GACtBC,IAAenE;AAAA,MACjBpS,EAAK;AAAA,MACL7B;AAAA,MACAmY,EAAgB;AAAA,MAChB/E;AAAA,IAAA;AAEF,QAAI0B,GAAY;AACd,UAAII,KAAiB,MAAMC;AAAA,QACzB4C;AAAA,QACA,IAAI,IAAIK,EAAa,GAAG,EAAE;AAAA,QAC1BA,EAAa;AAAA,QACbtY;AAAA,MAAA;AAEF,UAAIoV,GAAe,SAAS;AAC1B;AACF,UAAWA,GAAe,SAAS,SAAS;AAC1C,QAAA0C,GAAgB9X,GAAKyU,GAASW,GAAe,OAAO,EAAE,WAAA9C,GAAW;AACjE;AAAA,MACF,WAAY8C,GAAe;AASzB,QAAA6C,IAAiB7C,GAAe;AAAA,WATE;AAClC,QAAA0C;AAAA,UACE9X;AAAA,UACAyU;AAAA,UACAvF,GAAuB,KAAK,EAAE,UAAUhP,GAAM;AAAA,UAC9C,EAAE,WAAAoS,EAAA;AAAA,QAAU;AAEd;AAAA,MACF;AAAA,IAGF;AACA,QAAIpO,IAAQuR,GAAewC,GAAgB/X,CAAI;AAC/C,QAAI,CAACgE,EAAM,MAAM,UAAU,CAACA,EAAM,MAAM,MAAM;AAC5C,UAAI9C,KAAQ8N,GAAuB,KAAK;AAAA,QACtC,QAAQoE,EAAW;AAAA,QACnB,UAAUpT;AAAA,QACV,SAAAuU;AAAA,MAAA,CACD;AACD,MAAAqD,GAAgB9X,GAAKyU,GAASrT,IAAO,EAAE,WAAAkR,GAAW;AAClD;AAAA,IACF;AACA,IAAAnC,EAAiB,IAAInQ,GAAKqY,CAAe;AACzC,QAAIE,KAAoBnI,IACpBoI,KAAe7C;AAAA,MACjBlT;AAAA,MACAE;AAAA,MACA2V;AAAA,MACAL;AAAA,MACA/T;AAAA,MACA+J;AAAA,MACAmG;AAAA,IAAA,GAEEqE,KAAgB,MAAM5C;AAAA,MACxByC;AAAA,MACAE;AAAA,MACApE;AAAA,MACApU;AAAA,IAAA,GAEEuU,KAAekE,GAAcvU,EAAM,MAAM,EAAE;AAC/C,QAAI,CAACqQ;AACH,eAASmE,MAAUF;AACjB,YAAIC,GAAcC,GAAO,MAAM,EAAE,GAAG;AAClC,UAAAnE,KAAekE,GAAcC,GAAO,MAAM,EAAE;AAC5C;AAAA,QACF;AAAA;AAGJ,QAAIJ,EAAa,OAAO,SAAS;AAC/B,MAAInI,EAAiB,IAAInQ,CAAG,MAAMqY,KAChClI,EAAiB,OAAOnQ,CAAG;AAE7B;AAAA,IACF;AACA,QAAI0Q,GAA0B,IAAI1Q,CAAG;AACnC,UAAI8V,GAAiBvB,EAAY,KAAKG,GAAcH,EAAY,GAAG;AACjE,QAAA4D,GAAmBnY,GAAK2Y,GAAe,MAAM,CAAC;AAC9C;AAAA,MACF;AAAA,WACK;AACL,UAAI7C,GAAiBvB,EAAY;AAE/B,YADApE,EAAiB,OAAOnQ,CAAG,GACvBqQ,KAA0BkI,IAAmB;AAC/C,UAAAJ,GAAmBnY,GAAK2Y,GAAe,MAAM,CAAC;AAC9C;AAAA,QACF;AACE,iBAAApI,GAAiB,IAAIvQ,CAAG,GACxBmY,GAAmBnY,GAAK6X,GAAkBvE,CAAU,CAAC,GAC9C0C,GAAwBsC,GAAc/D,IAAc,IAAO;AAAA,YAChE,mBAAmBjB;AAAA,YACnB,oBAAAR;AAAA,UAAA,CACD;AAGL,UAAI4B,GAAcH,EAAY,GAAG;AAC/B,QAAAuD,GAAgB9X,GAAKyU,GAASF,GAAa,KAAK;AAChD;AAAA,MACF;AAAA,IACF;AACA,QAAId,KAAe1T,EAAM,WAAW,YAAYA,EAAM,UAClD6Y,KAAsBzE;AAAA,MACxBpS,EAAK;AAAA,MACL0R;AAAA,MACA4E,EAAgB;AAAA,IAAA,GAEdvE,KAAc1F,KAAsBD,GACpCvK,KAAU7D,EAAM,WAAW,UAAU,SAASoD,GAAY2Q,IAAa/T,EAAM,WAAW,UAAUsD,CAAQ,IAAItD,EAAM;AACxH,IAAAT,EAAUsE,IAAS,8CAA8C;AACjE,QAAIiV,KAAS,EAAEzI;AACf,IAAAE,GAAe,IAAItQ,GAAK6Y,EAAM;AAC9B,QAAIC,KAAcjB,GAAkBvE,GAAYiB,GAAa,IAAI;AACjE,IAAAxU,EAAM,SAAS,IAAIC,GAAK8Y,EAAW;AACnC,QAAI,EAAE,WAAApD,IAAW,sBAAAe,GAAA,IAAyBC;AAAA,MACxCkC;AAAA,MACAxE;AAAA,MACA3R;AAAA,MACAE;AAAA,MACAZ,EAAK;AAAA,MACLhC;AAAA,MACA6D;AAAA,MACA0P;AAAA,MACAG;AAAA,MACAxF;AAAA,MACA;AAAA,MACAgC;AAAA,MACAC;AAAA,MACAQ;AAAA,MACAF;AAAA,MACAD;AAAA,MACAuD;AAAA,MACAzQ;AAAA,MACAtB,EAAK,2BAA2B;AAAA,MAChC,CAACmC,EAAM,MAAM,IAAIqQ,EAAY;AAAA,MAC7B6B;AAAA,IAAA;AAEF,IAAAK,GAAqB,OAAO,CAACK,OAAOA,GAAG,QAAQ9W,CAAG,EAAE,QAAQ,CAAC8W,OAAO;AAClE,UAAIiC,KAAWjC,GAAG,KACdkC,KAAmBjZ,EAAM,SAAS,IAAIgZ,EAAQ,GAC9CnB,KAAsBC;AAAA,QACxB;AAAA,QACAmB,KAAmBA,GAAiB,OAAO;AAAA,MAAA;AAE7C,MAAAjZ,EAAM,SAAS,IAAIgZ,IAAUnB,EAAmB,GAChDb,GAAagC,EAAQ,GACjBjC,GAAG,cACL3G,EAAiB,IAAI4I,IAAUjC,GAAG,UAAU;AAAA,IAEhD,CAAC,GACDxF,GAAY,EAAE,UAAU,IAAI,IAAIvR,EAAM,QAAQ,GAAG;AACjD,QAAIiX,KAAiC,MAAMP,GAAqB,QAAQ,CAACK,OAAOC,GAAaD,GAAG,GAAG,CAAC;AACpG,IAAAuB,EAAgB,OAAO;AAAA,MACrB;AAAA,MACArB;AAAA,IAAA;AAEF,QAAI,EAAE,eAAAE,IAAe,gBAAAC,EAAA,IAAmB,MAAMC;AAAA,MAC5C1B;AAAA,MACAe;AAAA,MACAmC;AAAA,MACAxE;AAAA,IAAA;AAEF,QAAIiE,EAAgB,OAAO;AACzB;AASF,QAPAA,EAAgB,OAAO;AAAA,MACrB;AAAA,MACArB;AAAA,IAAA,GAEF1G,GAAe,OAAOtQ,CAAG,GACzBmQ,EAAiB,OAAOnQ,CAAG,GAC3ByW,GAAqB,QAAQ,CAACwC,OAAM9I,EAAiB,OAAO8I,GAAE,GAAG,CAAC,GAC9DlZ,EAAM,SAAS,IAAIC,CAAG,GAAG;AAC3B,UAAIkZ,KAAcP,GAAepE,GAAa,IAAI;AAClD,MAAAxU,EAAM,SAAS,IAAIC,GAAKkZ,EAAW;AAAA,IACrC;AACA,QAAI7B,KAAYC,GAAaJ,EAAa;AAC1C,QAAIG;AACF,aAAOrB;AAAA,QACL4C;AAAA,QACAvB,GAAU;AAAA,QACV;AAAA,QACA,EAAE,oBAAAvE,EAAA;AAAA,MAAmB;AAIzB,QADAuE,KAAYC,GAAaH,CAAc,GACnCE;AACF,aAAA9G,GAAiB,IAAI8G,GAAU,GAAG,GAC3BrB;AAAA,QACL4C;AAAA,QACAvB,GAAU;AAAA,QACV;AAAA,QACA,EAAE,oBAAAvE,EAAA;AAAA,MAAmB;AAGzB,QAAI,EAAE,YAAA3O,IAAY,QAAAmL,GAAA,IAAWiI;AAAA,MAC3BxX;AAAA,MACA6D;AAAA,MACAsT;AAAA,MACA;AAAA,MACAT;AAAA,MACAU;AAAA,IAAA;AAEF,IAAAO,GAAqBmB,EAAM,GACvB9Y,EAAM,WAAW,UAAU,aAAa8Y,KAASxI,MACnD/Q,EAAUmQ,GAAe,yBAAyB,GAClDG,KAA+BA,EAA4B,MAAA,GAC3DyC,GAAmBtS,EAAM,WAAW,UAAU;AAAA,MAC5C,SAAA6D;AAAA,MACA,YAAAO;AAAA,MACA,QAAAmL;AAAA,MACA,UAAU,IAAI,IAAIvP,EAAM,QAAQ;AAAA,IAAA,CACjC,MAEDuR,GAAY;AAAA,MACV,QAAAhC;AAAA,MACA,YAAYoD;AAAA,QACV3S,EAAM;AAAA,QACNoE;AAAA,QACAP;AAAA,QACA0L;AAAA,MAAA;AAAA,MAEF,UAAU,IAAI,IAAIvP,EAAM,QAAQ;AAAA,IAAA,CACjC,GACDkQ,KAAyB;AAAA,EAE7B;AACA,iBAAe+H,GAAoBhY,GAAKyU,GAASvU,GAAM0D,GAASwQ,GAAeY,GAAY1C,GAAWQ,GAAoBQ,GAAY;AACpI,QAAI4E,IAAkBnY,EAAM,SAAS,IAAIC,CAAG;AAC5C,IAAAmY;AAAA,MACEnY;AAAA,MACA6X;AAAA,QACEvE;AAAA,QACA4E,IAAkBA,EAAgB,OAAO;AAAA,MAAA;AAAA,MAE3C,EAAE,WAAA5F,EAAA;AAAA,IAAU;AAEd,QAAI+F,IAAkB,IAAI,gBAAA,GACtBC,IAAenE;AAAA,MACjBpS,EAAK;AAAA,MACL7B;AAAA,MACAmY,EAAgB;AAAA,IAAA;AAElB,QAAIrD,GAAY;AACd,UAAII,KAAiB,MAAMC;AAAA,QACzBzR;AAAA,QACA,IAAI,IAAI0U,EAAa,GAAG,EAAE;AAAA,QAC1BA,EAAa;AAAA,QACbtY;AAAA,MAAA;AAEF,UAAIoV,GAAe,SAAS;AAC1B;AACF,UAAWA,GAAe,SAAS,SAAS;AAC1C,QAAA0C,GAAgB9X,GAAKyU,GAASW,GAAe,OAAO,EAAE,WAAA9C,GAAW;AACjE;AAAA,MACF,WAAY8C,GAAe;AASzB,QAAAxR,IAAUwR,GAAe;AAAA,WATS;AAClC,QAAA0C;AAAA,UACE9X;AAAA,UACAyU;AAAA,UACAvF,GAAuB,KAAK,EAAE,UAAUhP,GAAM;AAAA,UAC9C,EAAE,WAAAoS,EAAA;AAAA,QAAU;AAEd;AAAA,MACF;AAAA,IAGF;AACA,QAAIpO,IAAQuR,GAAe7R,GAAS1D,CAAI;AACxC,IAAAiQ,EAAiB,IAAInQ,GAAKqY,CAAe;AACzC,QAAIE,IAAoBnI,IACpBsF,KAAYC;AAAA,MACdlT;AAAA,MACAE;AAAA,MACA2V;AAAA,MACA1U;AAAA,MACAM;AAAA,MACA+J;AAAA,MACAmG;AAAA,IAAA,GAQE9O,MANU,MAAMuQ;AAAA,MAClByC;AAAA,MACA5C;AAAA,MACAtB;AAAA,MACApU;AAAA,IAAA,GAEmBkE,EAAM,MAAM,EAAE;AAInC,QAHIiM,EAAiB,IAAInQ,CAAG,MAAMqY,KAChClI,EAAiB,OAAOnQ,CAAG,GAEzB,CAAAsY,EAAa,OAAO,SAGxB;AAAA,UAAI5H,GAA0B,IAAI1Q,CAAG,GAAG;AACtC,QAAAmY,GAAmBnY,GAAK2Y,GAAe,MAAM,CAAC;AAC9C;AAAA,MACF;AACA,UAAI7C,GAAiBxQ,EAAM;AACzB,YAAI+K,KAA0BkI,GAAmB;AAC/C,UAAAJ,GAAmBnY,GAAK2Y,GAAe,MAAM,CAAC;AAC9C;AAAA,QACF,OAAO;AACL,UAAApI,GAAiB,IAAIvQ,CAAG,GACxB,MAAMgW,GAAwBsC,GAAchT,IAAQ,IAAO;AAAA,YACzD,oBAAAwN;AAAA,UAAA,CACD;AACD;AAAA,QACF;AAEF,UAAI4B,GAAcpP,EAAM,GAAG;AACzB,QAAAwS,GAAgB9X,GAAKyU,GAASnP,GAAO,KAAK;AAC1C;AAAA,MACF;AACA,MAAA6S,GAAmBnY,GAAK2Y,GAAerT,GAAO,IAAI,CAAC;AAAA;AAAA,EACrD;AACA,iBAAe0Q,GAAwBxJ,GAAS6K,GAAW8B,GAAc;AAAA,IACvE,YAAA7F;AAAA,IACA,mBAAA6C;AAAA,IACA,oBAAArD;AAAA,IACA,SAASzR;AAAA,EAAA,IACP,IAAI;AACN,IAAK8X,MACHzJ,GAA8B,QAAA,GAC9BA,IAA+B,OAE7B2H,EAAU,SAAS,QAAQ,IAAI,oBAAoB,MACrDpH,KAAyB;AAE3B,QAAIrQ,IAAWyX,EAAU,SAAS,QAAQ,IAAI,UAAU;AACxD,IAAA/X,EAAUM,GAAU,qDAAqD,GACzEA,IAAWmW;AAAA,MACTnW;AAAA,MACA,IAAI,IAAI4M,EAAQ,GAAG;AAAA,MACnBnJ;AAAA,MACAtB,EAAK;AAAA,IAAA;AAEP,QAAIqX,IAAmBna,GAAec,EAAM,UAAUH,GAAU;AAAA,MAC9D,aAAa;AAAA,IAAA,CACd;AACD,QAAIoO,GAAY;AACd,UAAIqL,KAAmB;AACvB,UAAIhC,EAAU,SAAS,QAAQ,IAAI,yBAAyB;AAC1D,QAAAgC,KAAmB;AAAA,eACVvR,GAAclI,CAAQ,GAAG;AAClC,cAAMuB,KAAMI,GAAqB3B,GAAU,EAAI;AAC/C,QAAAyZ;AAAA,QACAlY,GAAI,WAAW4M,EAAa,SAAS;AAAA,QACrCvK,GAAcrC,GAAI,UAAUkC,CAAQ,KAAK;AAAA,MAC3C;AACA,UAAIgW,IAAkB;AACpB,QAAIhY,IACF0M,EAAa,SAAS,QAAQnO,CAAQ,IAEtCmO,EAAa,SAAS,OAAOnO,CAAQ;AAEvC;AAAA,MACF;AAAA,IACF;AACA,IAAAgQ,IAA8B;AAC9B,QAAI0J,IAAyBjY,MAAa,MAAQgW,EAAU,SAAS,QAAQ,IAAI,iBAAiB,IAAI,YAA0B,QAC5H,EAAE,YAAAkC,GAAY,YAAAC,GAAY,aAAAC,EAAA,IAAgB1Z,EAAM;AACpD,IAAI,CAACuT,KAAc,CAAC6C,KAAqBoD,KAAcC,KAAcC,MACnEnG,IAAagD,GAA4BvW,EAAM,UAAU;AAE3D,QAAIsW,IAAmB/C,KAAc6C;AACrC,QAAI5I,GAAkC,IAAI8J,EAAU,SAAS,MAAM,KAAKhB,KAAoB7D,GAAiB6D,EAAiB,UAAU;AACtI,YAAM9E,GAAgB+H,GAAwBF,GAAkB;AAAA,QAC9D,YAAY;AAAA,UACV,GAAG/C;AAAA,UACH,YAAYzW;AAAA,QAAA;AAAA;AAAA,QAGd,oBAAoBkT,KAAsBnD;AAAA,QAC1C,sBAAsBwJ,IAAetJ,IAA+B;AAAA,MAAA,CACrE;AAAA,SACI;AACL,UAAIqG,KAAqBvB;AAAA,QACvByE;AAAA,QACA9F;AAAA,MAAA;AAEF,YAAM/B,GAAgB+H,GAAwBF,GAAkB;AAAA,QAC9D,oBAAAlD;AAAA;AAAA,QAEA,mBAAAC;AAAA;AAAA,QAEA,oBAAoBrD,KAAsBnD;AAAA,QAC1C,sBAAsBwJ,IAAetJ,IAA+B;AAAA,MAAA,CACrE;AAAA,IACH;AAAA,EACF;AACA,iBAAegG,GAAiBrJ,GAAS5I,GAASwQ,GAAesF,GAAY;AAC3E,QAAI9D,GACA+D,IAAc,CAAA;AAClB,QAAI;AACF,MAAA/D,IAAU,MAAMgE;AAAA,QACdvL;AAAA,QACA7B;AAAA,QACA5I;AAAA,QACA8V;AAAA,QACAtF;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,SAAS7H,GAAG;AACV,aAAA3I,EAAQ,OAAO,CAACqG,MAAMA,EAAE,UAAU,EAAE,QAAQ,CAACA,MAAM;AACjD,QAAA0P,EAAY1P,EAAE,MAAM,EAAE,IAAI;AAAA,UACxB,MAAM;AAAA,UACN,OAAOsC;AAAA,QAAA;AAAA,MAEX,CAAC,GACMoN;AAAA,IACT;AACA,QAAInN,EAAQ,OAAO;AACjB,aAAOmN;AAET,QAAI,CAACnH,GAAiBhG,EAAQ,MAAM;AAClC,eAAStI,KAASN,GAAS;AACzB,YAAIgS,EAAQ1R,EAAM,MAAM,EAAE,GAAG,SAAS;AACpC;AAEF,QAAI,CAAC0R,EAAQ,eAAe1R,EAAM,MAAM,EAAE,KAAK,CAACnE,EAAM,WAAW,eAAemE,EAAM,MAAM,EAAE,MAAM,CAACnE,EAAM,UAAU,CAACA,EAAM,OAAO,eAAemE,EAAM,MAAM,EAAE,MAAMA,EAAM,kBAAA,MAC1K0R,EAAQ1R,EAAM,MAAM,EAAE,IAAI;AAAA,UACxB,MAAM;AAAA,UACN,QAAQ,IAAI;AAAA,YACV,kDAAkDA,EAAM,MAAM,EAAE;AAAA,UAAA;AAAA,QAClE;AAAA,MAGN;AAEF,aAAS,CAACuQ,GAASnP,CAAM,KAAK,OAAO,QAAQsQ,CAAO;AAClD,UAAIiE,GAA6BvU,CAAM,GAAG;AACxC,YAAIwU,IAAWxU,EAAO;AACtB,QAAAqU,EAAYlF,CAAO,IAAI;AAAA,UACrB,MAAM;AAAA,UACN,UAAUsF;AAAA,YACRD;AAAA,YACAtN;AAAA,YACAiI;AAAA,YACA7Q;AAAA,YACAP;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AACE,QAAAsW,EAAYlF,CAAO,IAAI,MAAMuF,GAAsC1U,CAAM;AAG7E,WAAOqU;AAAA,EACT;AACA,iBAAevC,GAA+BxT,GAASqW,GAAgBzN,GAAS4H,GAAe;AAC7F,QAAI8F,IAAuBrE;AAAA,MACzBrJ;AAAA,MACA5I;AAAA,MACAwQ;AAAA,MACA;AAAA,IAAA,GAEE+F,IAAwB,QAAQ;AAAA,MAClCF,EAAe,IAAI,OAAOhD,MAAM;AAC9B,YAAIA,EAAE,WAAWA,EAAE,SAASA,EAAE,WAAWA,EAAE,YAAY;AAOrD,cAAI3R,KANU,MAAMuQ;AAAA,YAClBoB,EAAE;AAAA,YACFA,EAAE;AAAA,YACF7C;AAAA,YACA6C,EAAE;AAAA,UAAA,GAEiBA,EAAE,MAAM,MAAM,EAAE;AACrC,iBAAO,EAAE,CAACA,EAAE,GAAG,GAAG3R,EAAA;AAAA,QACpB;AACE,iBAAO,QAAQ,QAAQ;AAAA,YACrB,CAAC2R,EAAE,GAAG,GAAG;AAAA,cACP,MAAM;AAAA,cACN,OAAO/H,GAAuB,KAAK;AAAA,gBACjC,UAAU+H,EAAE;AAAA,cAAA,CACb;AAAA,YAAA;AAAA,UACH,CACD;AAAA,MAEL,CAAC;AAAA,IAAA,GAECC,IAAgB,MAAMgD,GACtB/C,KAAkB,MAAMgD,GAAuB;AAAA,MACjD,CAACC,GAAKnB,MAAM,OAAO,OAAOmB,GAAKnB,CAAC;AAAA,MAChC,CAAA;AAAA,IAAC;AAEH,WAAO;AAAA,MACL,eAAA/B;AAAA,MACA,gBAAAC;AAAA,IAAA;AAAA,EAEJ;AACA,WAASvD,KAAuB;AAC9B,IAAA3D,KAAyB,IACzBO,GAAiB,QAAQ,CAAChJ,GAAGxH,MAAQ;AACnC,MAAImQ,EAAiB,IAAInQ,CAAG,KAC1BkQ,GAAsB,IAAIlQ,CAAG,GAE/B+W,GAAa/W,CAAG;AAAA,IAClB,CAAC;AAAA,EACH;AACA,WAASmY,GAAmBnY,GAAKmS,GAASvG,IAAO,CAAA,GAAI;AACnD,IAAA7L,EAAM,SAAS,IAAIC,GAAKmS,CAAO,GAC/Bb;AAAA,MACE,EAAE,UAAU,IAAI,IAAIvR,EAAM,QAAQ,EAAA;AAAA,MAClC,EAAE,YAAY6L,KAAQA,EAAK,eAAe,GAAA;AAAA,IAAK;AAAA,EAEnD;AACA,WAASkM,GAAgB9X,GAAKyU,GAASrT,GAAOwK,IAAO,CAAA,GAAI;AACvD,QAAIqK,IAAgB3B,GAAoBvU,EAAM,SAAS0U,CAAO;AAC9D,IAAA7C,GAAc5R,CAAG,GACjBsR;AAAA,MACE;AAAA,QACE,QAAQ;AAAA,UACN,CAAC2E,EAAc,MAAM,EAAE,GAAG7U;AAAA,QAAA;AAAA,QAE5B,UAAU,IAAI,IAAIrB,EAAM,QAAQ;AAAA,MAAA;AAAA,MAElC,EAAE,YAAY6L,KAAQA,EAAK,eAAe,GAAA;AAAA,IAAK;AAAA,EAEnD;AACA,WAASyO,GAAWra,GAAK;AACvB,WAAAyQ,GAAe,IAAIzQ,IAAMyQ,GAAe,IAAIzQ,CAAG,KAAK,KAAK,CAAC,GACtD0Q,GAA0B,IAAI1Q,CAAG,KACnC0Q,GAA0B,OAAO1Q,CAAG,GAE/BD,EAAM,SAAS,IAAIC,CAAG,KAAKyN;AAAA,EACpC;AACA,WAAS6M,GAAata,GAAK4L,GAAM;AAC/B,IAAAmL,GAAa/W,GAAK4L,GAAM,MAAM,GAC9BuM,GAAmBnY,GAAK2Y,GAAe,IAAI,CAAC;AAAA,EAC9C;AACA,WAAS/G,GAAc5R,GAAK;AAC1B,QAAImS,IAAUpS,EAAM,SAAS,IAAIC,CAAG;AACpC,IAAImQ,EAAiB,IAAInQ,CAAG,KAAK,EAAEmS,KAAWA,EAAQ,UAAU,aAAa7B,GAAe,IAAItQ,CAAG,MACjG+W,GAAa/W,CAAG,GAElBwQ,GAAiB,OAAOxQ,CAAG,GAC3BsQ,GAAe,OAAOtQ,CAAG,GACzBuQ,GAAiB,OAAOvQ,CAAG,GAC3B0Q,GAA0B,OAAO1Q,CAAG,GACpCkQ,GAAsB,OAAOlQ,CAAG,GAChCD,EAAM,SAAS,OAAOC,CAAG;AAAA,EAC3B;AACA,WAASua,GAAwBva,GAAK;AACpC,QAAIwa,KAAS/J,GAAe,IAAIzQ,CAAG,KAAK,KAAK;AAC7C,IAAIwa,KAAS,KACX/J,GAAe,OAAOzQ,CAAG,GACzB0Q,GAA0B,IAAI1Q,CAAG,KAEjCyQ,GAAe,IAAIzQ,GAAKwa,CAAK,GAE/BlJ,GAAY,EAAE,UAAU,IAAI,IAAIvR,EAAM,QAAQ,GAAG;AAAA,EACnD;AACA,WAASgX,GAAa/W,GAAKya,GAAQ;AACjC,QAAIC,IAAavK,EAAiB,IAAInQ,CAAG;AACzC,IAAI0a,MACFA,EAAW,MAAMD,CAAM,GACvBtK,EAAiB,OAAOnQ,CAAG;AAAA,EAE/B;AACA,WAAS2a,GAAiB9P,GAAM;AAC9B,aAAS7K,KAAO6K,GAAM;AACpB,UAAIsH,IAAUkI,GAAWra,CAAG,GACxBkZ,IAAcP,GAAexG,EAAQ,IAAI;AAC7C,MAAApS,EAAM,SAAS,IAAIC,GAAKkZ,CAAW;AAAA,IACrC;AAAA,EACF;AACA,WAAStC,KAAyB;AAChC,QAAIgE,IAAW,CAAA,GACXpD,IAAkB;AACtB,aAASxX,KAAOuQ,IAAkB;AAChC,UAAI4B,IAAUpS,EAAM,SAAS,IAAIC,CAAG;AACpC,MAAAV,EAAU6S,GAAS,qBAAqBnS,CAAG,EAAE,GACzCmS,EAAQ,UAAU,cACpB5B,GAAiB,OAAOvQ,CAAG,GAC3B4a,EAAS,KAAK5a,CAAG,GACjBwX,IAAkB;AAAA,IAEtB;AACA,WAAAmD,GAAiBC,CAAQ,GAClBpD;AAAA,EACT;AACA,WAASE,GAAqBmD,GAAU;AACtC,QAAIC,IAAa,CAAA;AACjB,aAAS,CAAC9a,GAAK8C,CAAE,KAAKwN;AACpB,UAAIxN,IAAK+X,GAAU;AACjB,YAAI1I,IAAUpS,EAAM,SAAS,IAAIC,CAAG;AACpC,QAAAV,EAAU6S,GAAS,qBAAqBnS,CAAG,EAAE,GACzCmS,EAAQ,UAAU,cACpB4E,GAAa/W,CAAG,GAChBsQ,GAAe,OAAOtQ,CAAG,GACzB8a,EAAW,KAAK9a,CAAG;AAAA,MAEvB;AAEF,WAAA2a,GAAiBG,CAAU,GACpBA,EAAW,SAAS;AAAA,EAC7B;AACA,WAASC,GAAW/a,GAAKwB,GAAI;AAC3B,QAAIwZ,IAAUjb,EAAM,SAAS,IAAIC,CAAG,KAAK0N;AACzC,WAAIiD,GAAiB,IAAI3Q,CAAG,MAAMwB,KAChCmP,GAAiB,IAAI3Q,GAAKwB,CAAE,GAEvBwZ;AAAA,EACT;AACA,WAASnJ,GAAc7R,GAAK;AAC1B,IAAAD,EAAM,SAAS,OAAOC,CAAG,GACzB2Q,GAAiB,OAAO3Q,CAAG;AAAA,EAC7B;AACA,WAASoR,GAAcpR,GAAKib,GAAY;AACtC,QAAID,IAAUjb,EAAM,SAAS,IAAIC,CAAG,KAAK0N;AACzC,IAAApO;AAAA,MACE0b,EAAQ,UAAU,eAAeC,EAAW,UAAU,aAAaD,EAAQ,UAAU,aAAaC,EAAW,UAAU,aAAaD,EAAQ,UAAU,aAAaC,EAAW,UAAU,gBAAgBD,EAAQ,UAAU,aAAaC,EAAW,UAAU,eAAeD,EAAQ,UAAU,gBAAgBC,EAAW,UAAU;AAAA,MAClU,qCAAqCD,EAAQ,KAAK,OAAOC,EAAW,KAAK;AAAA,IAAA;AAE3E,QAAI5J,IAAW,IAAI,IAAItR,EAAM,QAAQ;AACrC,IAAAsR,EAAS,IAAIrR,GAAKib,CAAU,GAC5B3J,GAAY,EAAE,UAAAD,GAAU;AAAA,EAC1B;AACA,WAASJ,GAAsB;AAAA,IAC7B,iBAAAuC;AAAA,IACA,cAAAC;AAAA,IACA,eAAA1C;AAAA,EAAA,GACC;AACD,QAAIJ,GAAiB,SAAS;AAC5B;AAEF,IAAIA,GAAiB,OAAO,KAC1BnR,GAAQ,IAAO,8CAA8C;AAE/D,QAAI0b,IAAU,MAAM,KAAKvK,GAAiB,SAAS,GAC/C,CAACK,GAAYmK,CAAe,IAAID,EAAQA,EAAQ,SAAS,CAAC,GAC1DF,IAAUjb,EAAM,SAAS,IAAIiR,CAAU;AAC3C,QAAI,EAAAgK,KAAWA,EAAQ,UAAU,iBAG7BG,EAAgB,EAAE,iBAAA3H,GAAiB,cAAAC,GAAc,eAAA1C,EAAA,CAAe;AAClE,aAAOC;AAAA,EAEX;AACA,WAASkD,GAAsBpV,GAAU;AACvC,QAAIsC,IAAQ8N,GAAuB,KAAK,EAAE,UAAApQ,GAAU,GAChDgV,IAAc1F,KAAsBD,GACpC,EAAE,SAAAvK,GAAS,OAAAtB,MAAU6M,GAAuB2E,CAAW;AAC3D,WAAO,EAAE,iBAAiBlQ,GAAS,OAAAtB,GAAO,OAAAlB,EAAA;AAAA,EAC5C;AACA,WAASga,GAAwBC,GAAWC,GAAaC,GAAQ;AAI/D,QAHA7M,IAAwB2M,GACxBzM,IAAoB0M,GACpB3M,IAA2B4M,KAAU,MACjC,CAAC1M,KAAyB9O,EAAM,eAAeyN,IAAiB;AAClE,MAAAqB,IAAwB;AACxB,UAAI2M,IAAI3I,GAAuB9S,EAAM,UAAUA,EAAM,OAAO;AAC5D,MAAIyb,KAAK,QACPlK,GAAY,EAAE,uBAAuBkK,GAAG;AAAA,IAE5C;AACA,WAAO,MAAM;AACX,MAAA9M,IAAwB,MACxBE,IAAoB,MACpBD,IAA2B;AAAA,IAC7B;AAAA,EACF;AACA,WAAS8M,GAAa7b,GAAUgE,GAAS;AACvC,WAAI+K,KACQA;AAAA,MACR/O;AAAA,MACAgE,EAAQ,IAAI,CAACqG,MAAMhG,GAA2BgG,GAAGlK,EAAM,UAAU,CAAC;AAAA,IAAA,KAEtDH,EAAS;AAAA,EAG3B;AACA,WAASiU,GAAmBjU,GAAUgE,GAAS;AAC7C,QAAI8K,KAAyBE,GAAmB;AAC9C,UAAI5O,IAAMyb,GAAa7b,GAAUgE,CAAO;AACxC,MAAA8K,EAAsB1O,CAAG,IAAI4O,EAAA;AAAA,IAC/B;AAAA,EACF;AACA,WAASiE,GAAuBjT,GAAUgE,GAAS;AACjD,QAAI8K,GAAuB;AACzB,UAAI1O,IAAMyb,GAAa7b,GAAUgE,CAAO,GACpC4X,IAAI9M,EAAsB1O,CAAG;AACjC,UAAI,OAAOwb,KAAM;AACf,eAAOA;AAAA,IAEX;AACA,WAAO;AAAA,EACT;AACA,WAASpM,GAAcxL,GAASkQ,GAAahV,GAAU;AACrD,QAAIiD,EAAK;AACP,UAAK6B;AASH,YAAI,OAAO,KAAKA,EAAQ,CAAC,EAAE,MAAM,EAAE,SAAS;AAO1C,iBAAO,EAAE,QAAQ,IAAM,SANFN;AAAA,YACnBwQ;AAAA,YACAhV;AAAA,YACAuE;AAAA,YACA;AAAA,UAAA,EAE8B;AAAA;AATlC,eAAO,EAAE,QAAQ,IAAM,SANNC;AAAA,UACfwQ;AAAA,UACAhV;AAAA,UACAuE;AAAA,UACA;AAAA,QAAA,KAE4C,CAAA,EAAC;AAanD,WAAO,EAAE,QAAQ,IAAO,SAAS,KAAA;AAAA,EACnC;AACA,iBAAegS,GAAezR,GAAS9E,GAAU4c,GAAQhC,GAAY;AACnE,QAAI,CAAC3X,EAAK;AACR,aAAO,EAAE,MAAM,WAAW,SAAA6B,EAAA;AAE5B,QAAI+X,IAAiB/X;AACrB,eAAa;AACX,UAAIgY,IAAWxN,KAAsB,MACjC0F,IAAc1F,KAAsBD,GACpC0N,IAAgBlZ;AACpB,UAAI;AACF,cAAMZ,EAAK,wBAAwB;AAAA,UACjC,QAAA2Z;AAAA,UACA,MAAM5c;AAAA,UACN,SAAS6c;AAAA,UACT,YAAAjC;AAAA,UACA,OAAO,CAACjF,GAASqH,MAAa;AAC5B,YAAIJ,EAAO,WACXK;AAAA,cACEtH;AAAA,cACAqH;AAAA,cACAhI;AAAA,cACA+H;AAAA,cACApZ;AAAA,cACA;AAAA,YAAA;AAAA,UAEJ;AAAA,QAAA,CACD;AAAA,MACH,SAAS8J,GAAG;AACV,eAAO,EAAE,MAAM,SAAS,OAAOA,GAAG,gBAAAoP,EAAA;AAAA,MACpC,UAAA;AACE,QAAIC,KAAY,CAACF,EAAO,YACtBvN,IAAa,CAAC,GAAGA,CAAU;AAAA,MAE/B;AACA,UAAIuN,EAAO;AACT,eAAO,EAAE,MAAM,UAAA;AAEjB,UAAIM,IAAa7Y,GAAY2Q,GAAahV,GAAUuE,CAAQ,GACxD4Y,IAAoB;AACxB,UAAID,GAAY;AACd,YAAI,OAAO,KAAKA,EAAW,CAAC,EAAE,MAAM,EAAE,WAAW;AAC/C,iBAAO,EAAE,MAAM,WAAW,SAASA,EAAA;AAYnC,YAVAC,IAAoB3Y;AAAA,UAClBwQ;AAAA,UACAhV;AAAA,UACAuE;AAAA,UACA;AAAA,QAAA,GAME,EAJgB4Y,KAAqBN,EAAe,SAASM,EAAkB,UAAUC;AAAA,UAC3FP;AAAA,UACAM,EAAkB,MAAM,GAAGN,EAAe,MAAM;AAAA,QAAA;AAGhD,iBAAO,EAAE,MAAM,WAAW,SAASK,EAAA;AAAA,MAGzC;AASA,UARKC,MACHA,IAAoB3Y;AAAA,QAClBwQ;AAAA,QACAhV;AAAA,QACAuE;AAAA,QACA;AAAA,MAAA,IAGA,CAAC4Y,KAAqBC,GAAeP,GAAgBM,CAAiB;AACxE,eAAO,EAAE,MAAM,WAAW,SAAS,KAAA;AAErC,MAAAN,IAAiBM;AAAA,IACnB;AAAA,EACF;AACA,WAASC,GAAe1W,GAAGC,GAAG;AAC5B,WAAOD,EAAE,WAAWC,EAAE,UAAUD,EAAE,MAAM,CAACyE,GAAGpG,MAAMoG,EAAE,MAAM,OAAOxE,EAAE5B,CAAC,EAAE,MAAM,EAAE;AAAA,EAChF;AACA,WAASsY,GAAmBC,GAAW;AACrC,IAAAzZ,IAAW,CAAA,GACXyL,IAAqB7L;AAAA,MACnB6Z;AAAA,MACA3Z;AAAA,MACA;AAAA,MACAE;AAAA,IAAA;AAAA,EAEJ;AACA,WAAS0Z,GAAY5H,GAASqH,GAAUQ,IAAiC,IAAO;AAC9E,QAAIV,IAAWxN,KAAsB;AAErC,IAAA2N;AAAA,MACEtH;AAAA,MACAqH;AAAA,MAHgB1N,KAAsBD;AAAA,MAKtCxL;AAAA,MACAF;AAAA,MACA6Z;AAAA,IAAA,GAEEV,MACFzN,IAAa,CAAC,GAAGA,CAAU,GAC3BmD,GAAY,CAAA,CAAE;AAAA,EAElB;AACA,SAAA7F,IAAS;AAAA,IACP,IAAI,WAAW;AACb,aAAOpI;AAAA,IACT;AAAA,IACA,IAAI,SAAS;AACX,aAAOkL;AAAA,IACT;AAAA,IACA,IAAI,QAAQ;AACV,aAAOxO;AAAA,IACT;AAAA,IACA,IAAI,SAAS;AACX,aAAOoO;AAAA,IACT;AAAA,IACA,IAAI,SAAS;AACX,aAAOJ;AAAA,IACT;AAAA,IACA,YAAA+C;AAAA,IACA,WAAAgB;AAAA,IACA,yBAAAsJ;AAAA,IACA,UAAA1P;AAAA,IACA,OAAOI;AAAA,IACP,YAAA6H;AAAA;AAAA;AAAA,IAGA,YAAY,CAACxU,MAAO4C,EAAK,QAAQ,WAAW5C,CAAE;AAAA,IAC9C,gBAAgB,CAACA,MAAO4C,EAAK,QAAQ,eAAe5C,CAAE;AAAA,IACtD,YAAAkb;AAAA,IACA,cAAAC;AAAA,IACA,eAAeC;AAAA,IACf,SAAA5I;AAAA,IACA,YAAAoJ;AAAA,IACA,eAAAlJ;AAAA,IACA,aAAAwK;AAAA,IACA,2BAA2BlM;AAAA;AAAA;AAAA,IAG3B,oBAAAgM;AAAA,IACA,+CAA+CpK,GAAU;AACvD,MAAAT,GAAYS,CAAQ;AAAA,IACtB;AAAA,EAAA,GAEEhQ,EAAK,8BACP0J,IAASD;AAAA,IACPC;AAAA,IACA1J,EAAK,0BAA0B,IAAI,CAAC8B,MAAMA,EAAE,MAAM,EAAE,OAAO,OAAO;AAAA,EAAA,IAG/D4H;AACT;AA2nBA,SAAS8Q,GAAuB3Q,GAAM;AACpC,SAAOA,KAAQ,SAAS,cAAcA,KAAQA,EAAK,YAAY,QAAQ,UAAUA,KAAQA,EAAK,SAAS;AACzG;AACA,SAASyH,GAAYzT,GAAUgE,GAASP,GAAUlE,GAAIqd,GAAaC,GAAU;AAC3E,MAAIC,GACAC;AACJ,MAAIH,GAAa;AACf,IAAAE,IAAoB,CAAA;AACpB,aAASxY,KAASN;AAEhB,UADA8Y,EAAkB,KAAKxY,CAAK,GACxBA,EAAM,MAAM,OAAOsY,GAAa;AAClC,QAAAG,IAAmBzY;AACnB;AAAA,MACF;AAAA,EAEJ;AACE,IAAAwY,IAAoB9Y,GACpB+Y,IAAmB/Y,EAAQA,EAAQ,SAAS,CAAC;AAE/C,MAAI1D,IAAO4I;AAAA,IACT3J,KAAU;AAAA,IACVwJ,GAAoB+T,CAAiB;AAAA,IACrClZ,GAAc5D,EAAS,UAAUyD,CAAQ,KAAKzD,EAAS;AAAA,IACvD6c,MAAa;AAAA,EAAA;AAMf,MAJItd,KAAM,SACRe,EAAK,SAASN,EAAS,QACvBM,EAAK,OAAON,EAAS,QAElBT,KAAM,QAAQA,MAAO,MAAMA,MAAO,QAAQwd,GAAkB;AAC/D,QAAIC,IAAaC,GAAmB3c,EAAK,MAAM;AAC/C,QAAIyc,EAAiB,MAAM,SAAS,CAACC;AACnC,MAAA1c,EAAK,SAASA,EAAK,SAASA,EAAK,OAAO,QAAQ,OAAO,SAAS,IAAI;AAAA,aAC3D,CAACyc,EAAiB,MAAM,SAASC,GAAY;AACtD,UAAIxY,IAAS,IAAI,gBAAgBlE,EAAK,MAAM,GACxC4c,IAAc1Y,EAAO,OAAO,OAAO;AACvC,MAAAA,EAAO,OAAO,OAAO,GACrB0Y,EAAY,OAAO,CAACrV,MAAMA,CAAC,EAAE,QAAQ,CAACA,MAAMrD,EAAO,OAAO,SAASqD,CAAC,CAAC;AACrE,UAAIsV,IAAK3Y,EAAO,SAAA;AAChB,MAAAlE,EAAK,SAAS6c,IAAK,IAAIA,CAAE,KAAK;AAAA,IAChC;AAAA,EACF;AACA,SAAI1Z,MAAa,QACfnD,EAAK,WAAW0H,GAAgB,EAAE,UAAAvE,GAAU,UAAUnD,EAAK,UAAU,IAEhEd,GAAWc,CAAI;AACxB;AACA,SAASqT,GAAyByJ,GAAW9c,GAAM0L,GAAM;AACvD,MAAI,CAACA,KAAQ,CAAC2Q,GAAuB3Q,CAAI;AACvC,WAAO,EAAE,MAAA1L,EAAA;AAEX,MAAI0L,EAAK,cAAc,CAACqR,GAAcrR,EAAK,UAAU;AACnD,WAAO;AAAA,MACL,MAAA1L;AAAA,MACA,OAAOgP,GAAuB,KAAK,EAAE,QAAQtD,EAAK,YAAY;AAAA,IAAA;AAGlE,MAAIsR,IAAsB,OAAO;AAAA,IAC/B,MAAAhd;AAAA,IACA,OAAOgP,GAAuB,KAAK,EAAE,MAAM,gBAAgB;AAAA,EAAA,IAGzDqK,KADgB3N,EAAK,cAAc,OACR,YAAA,GAC3B4N,IAAa2D,GAAkBjd,CAAI;AACvC,MAAI0L,EAAK,SAAS;AAChB,QAAIA,EAAK,gBAAgB,cAAc;AACrC,UAAI,CAAC4G,GAAiB+G,CAAU;AAC9B,eAAO2D,EAAA;AAET,UAAIE,IAAO,OAAOxR,EAAK,QAAS,WAAWA,EAAK,OAAOA,EAAK,gBAAgB,YAAYA,EAAK,gBAAgB;AAAA;AAAA,QAE3G,MAAM,KAAKA,EAAK,KAAK,QAAA,CAAS,EAAE;AAAA,UAC9B,CAACwO,GAAK,CAACiD,GAAM9e,CAAK,MAAM,GAAG6b,CAAG,GAAGiD,CAAI,IAAI9e,CAAK;AAAA;AAAA,UAE9C;AAAA,QAAA;AAAA,UAEA,OAAOqN,EAAK,IAAI;AACpB,aAAO;AAAA,QACL,MAAA1L;AAAA,QACA,YAAY;AAAA,UACV,YAAAqZ;AAAA,UACA,YAAAC;AAAA,UACA,aAAa5N,EAAK;AAAA,UAClB,UAAU;AAAA,UACV,MAAM;AAAA,UACN,MAAAwR;AAAA,QAAA;AAAA,MACF;AAAA,IAEJ,WAAWxR,EAAK,gBAAgB,oBAAoB;AAClD,UAAI,CAAC4G,GAAiB+G,CAAU;AAC9B,eAAO2D,EAAA;AAET,UAAI;AACF,YAAII,IAAO,OAAO1R,EAAK,QAAS,WAAW,KAAK,MAAMA,EAAK,IAAI,IAAIA,EAAK;AACxE,eAAO;AAAA,UACL,MAAA1L;AAAA,UACA,YAAY;AAAA,YACV,YAAAqZ;AAAA,YACA,YAAAC;AAAA,YACA,aAAa5N,EAAK;AAAA,YAClB,UAAU;AAAA,YACV,MAAA0R;AAAA,YACA,MAAM;AAAA,UAAA;AAAA,QACR;AAAA,MAEJ,QAAY;AACV,eAAOJ,EAAA;AAAA,MACT;AAAA,IACF;AAAA;AAEF,EAAA5d;AAAA,IACE,OAAO,YAAa;AAAA,IACpB;AAAA,EAAA;AAEF,MAAIie,GACAC;AACJ,MAAI5R,EAAK;AACP,IAAA2R,IAAeE,GAA8B7R,EAAK,QAAQ,GAC1D4R,IAAW5R,EAAK;AAAA,WACPA,EAAK,gBAAgB;AAC9B,IAAA2R,IAAeE,GAA8B7R,EAAK,IAAI,GACtD4R,IAAW5R,EAAK;AAAA,WACPA,EAAK,gBAAgB;AAC9B,IAAA2R,IAAe3R,EAAK,MACpB4R,IAAWE,GAA8BH,CAAY;AAAA,WAC5C3R,EAAK,QAAQ;AACtB,IAAA2R,IAAe,IAAI,gBAAA,GACnBC,IAAW,IAAI,SAAA;AAAA;AAEf,QAAI;AACF,MAAAD,IAAe,IAAI,gBAAgB3R,EAAK,IAAI,GAC5C4R,IAAWE,GAA8BH,CAAY;AAAA,IACvD,QAAY;AACV,aAAOL,EAAA;AAAA,IACT;AAEF,MAAI5J,IAAa;AAAA,IACf,YAAAiG;AAAA,IACA,YAAAC;AAAA,IACA,aAAa5N,KAAQA,EAAK,eAAe;AAAA,IACzC,UAAA4R;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,EAAA;AAER,MAAIhL,GAAiBc,EAAW,UAAU;AACxC,WAAO,EAAE,MAAApT,GAAM,YAAAoT,EAAA;AAEjB,MAAInT,IAAaF,GAAUC,CAAI;AAC/B,SAAI8c,KAAa7c,EAAW,UAAU0c,GAAmB1c,EAAW,MAAM,KACxEod,EAAa,OAAO,SAAS,EAAE,GAEjCpd,EAAW,SAAS,IAAIod,CAAY,IAC7B,EAAE,MAAMne,GAAWe,CAAU,GAAG,YAAAmT,EAAA;AACzC;AACA,SAASoD,GAAiBlK,GAAS4H,GAAe3R,GAAqBE,GAAU3B,GAASjB,GAAO6D,GAAS0P,GAAY1T,GAAU+d,GAA2B1I,GAAkBhF,GAAwBC,GAAuBQ,GAA2BF,GAAkBD,GAAkBuD,GAAazQ,GAAUua,GAA4BvJ,GAAqB+B,GAAiC;AAClY,MAAI7B,IAAeF,IAAsBK,GAAcL,EAAoB,CAAC,CAAC,IAAIA,EAAoB,CAAC,EAAE,QAAQA,EAAoB,CAAC,EAAE,OAAO,QAC1I9J,IAAavJ,EAAQ,UAAUjB,EAAM,QAAQ,GAC7C8d,IAAU7c,EAAQ,UAAUpB,CAAQ,GACpCke;AACJ,MAAI7I,KAAoBlV,EAAM,QAAQ;AACpC,QAAIwV,IAAa,OAAO,KAAKxV,EAAM,MAAM,EAAE,CAAC;AAC5C,IAAA+d,IAASla,EAAQ,UAAU,CAACqG,OAAMA,GAAE,MAAM,OAAOsL,CAAU;AAAA,EAC7D,WAAWlB,KAAuBK,GAAcL,EAAoB,CAAC,CAAC,GAAG;AACvE,QAAIkB,IAAalB,EAAoB,CAAC;AACtC,IAAAyJ,IAASla,EAAQ,UAAU,CAACqG,OAAMA,GAAE,MAAM,OAAOsL,CAAU,IAAI;AAAA,EACjE;AACA,MAAIwI,IAAe1J,IAAsBA,EAAoB,CAAC,EAAE,aAAa,QACzE2J,IAAyBD,KAAgBA,KAAgB,KACzDE,IAA2B;AAAA,IAC7B,YAAA1T;AAAA,IACA,eAAexK,EAAM,QAAQ,CAAC,GAAG,UAAU,CAAA;AAAA,IAC3C,SAAA8d;AAAA,IACA,YAAYja,EAAQ,CAAC,EAAE;AAAA,IACvB,GAAG0P;AAAA,IACH,cAAAiB;AAAA,IACA,cAAAwJ;AAAA,EAAA,GAEElX,IAAUmD,GAAgBpG,CAAO,GACjC8R,KAAY9R,EAAQ,IAAI,CAACM,GAAOrE,OAAU;AAC5C,QAAI,EAAE,OAAAyC,OAAU4B,GACZga,IAAkB;AAgBtB,QAfIJ,KAAU,QAAQje,KAAQie,IAC5BI,IAAkB,KACT5b,GAAM,OACf4b,IAAkB,KACR7O,GAA2B/M,EAAK,IAEjC2S,IACTiJ,IAAkB3O;AAAA,MAChBjN;AAAA,MACAvC,EAAM;AAAA,MACNA,EAAM;AAAA,IAAA,IAECoe,GAAYpe,EAAM,YAAYA,EAAM,QAAQF,EAAK,GAAGqE,CAAK,MAClEga,IAAkB,MARlBA,IAAkB,IAUhBA,MAAoB;AACtB,aAAOE;AAAA,QACL3b;AAAA,QACAE;AAAA,QACA6J;AAAA,QACA3F;AAAA,QACA3C;AAAA,QACAyZ;AAAA,QACAvJ;AAAA,QACA8J;AAAA,MAAA;AAGJ,QAAIG,KAA0B;AAC9B,IAAI,OAAOjI,KAAoC,YAC7CiI,KAA0BjI,IACjB4H,IACTK,KAA0B,MACjBpO,KAEA1F,EAAW,WAAWA,EAAW,WAAWsT,EAAQ,WAAWA,EAAQ,UAEvEtT,EAAW,WAAWsT,EAAQ,UAE9BS,GAAmBve,EAAM,QAAQF,EAAK,GAAGqE,CAAK,OACvDma,KAA0B;AAE5B,QAAIE,KAAuB;AAAA,MACzB,GAAGN;AAAA,MACH,yBAAAI;AAAA,IAAA,GAEEG,KAAaC,GAAuBva,GAAOqa,EAAoB;AACnE,WAAOH;AAAA,MACL3b;AAAA,MACAE;AAAA,MACA6J;AAAA,MACA3F;AAAA,MACA3C;AAAA,MACAyZ;AAAA,MACAvJ;AAAA,MACAoK;AAAA,MACAD;AAAA,MACAnI;AAAA,IAAA;AAAA,EAEJ,CAAC,GACGK,IAAuB,CAAA;AAC3B,SAAAjG,EAAiB,QAAQ,CAACyG,GAAGjX,OAAQ;AACnC,QAAIiV,KAAoB,CAACrR,EAAQ,KAAK,CAACqG,OAAMA,GAAE,MAAM,OAAOgN,EAAE,OAAO,KAAKvG,EAA0B,IAAI1Q,EAAG;AACzG;AAEF,QAAImS,KAAUpS,EAAM,SAAS,IAAIC,EAAG,GAChC0e,IAAmBvM,MAAWA,GAAQ,UAAU,UAAUA,GAAQ,SAAS,QAC3EwM,KAAiBxb,GAAY2Q,GAAamD,EAAE,MAAM5T,CAAQ;AAC9D,QAAI,CAACsb,IAAgB;AACnB,UAAIf,KAA8Bc;AAChC;AAEF,MAAAjI,EAAqB,KAAK;AAAA,QACxB,KAAAzW;AAAA,QACA,SAASiX,EAAE;AAAA,QACX,MAAMA,EAAE;AAAA,QACR,SAAS;AAAA,QACT,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,MAAA,CACb;AACD;AAAA,IACF;AACA,QAAI1G,EAAiB,IAAIvQ,EAAG;AAC1B;AAEF,QAAI4e,KAAenJ,GAAekJ,IAAgB1H,EAAE,IAAI,GACpD4H,KAAkB,IAAI,gBAAA,GACtBvG,KAAenE;AAAA,MACjBnT;AAAA,MACAiW,EAAE;AAAA,MACF4H,GAAgB;AAAA,IAAA,GAEdC,KAAmB;AACvB,QAAI5O,EAAsB,IAAIlQ,EAAG;AAC/B,MAAAkQ,EAAsB,OAAOlQ,EAAG,GAChC8e,KAAmBnJ;AAAA,QACjBlT;AAAA,QACAE;AAAA,QACA2V;AAAA,QACAqG;AAAA,QACAC;AAAA,QACAjB;AAAA,QACAvJ;AAAA,MAAA;AAAA,aAEOsK;AACT,MAAIzO,MACF6O,KAAmBnJ;AAAA,QACjBlT;AAAA,QACAE;AAAA,QACA2V;AAAA,QACAqG;AAAA,QACAC;AAAA,QACAjB;AAAA,QACAvJ;AAAA,MAAA;AAAA,SAGC;AACL,UAAIiK;AACJ,MAAI,OAAOjI,KAAoC,YAC7CiI,KAA0BjI,IACjB4H,IACTK,KAA0B,KAE1BA,KAA0BpO;AAE5B,UAAIsO,KAAuB;AAAA,QACzB,GAAGN;AAAA,QACH,yBAAAI;AAAA,MAAA;AAEF,MAAII,GAAuBG,IAAcL,EAAoB,MAC3DO,KAAmBnJ;AAAA,QACjBlT;AAAA,QACAE;AAAA,QACA2V;AAAA,QACAqG;AAAA,QACAC;AAAA,QACAjB;AAAA,QACAvJ;AAAA,QACAmK;AAAA,MAAA;AAAA,IAGN;AACA,IAAIO,MACFrI,EAAqB,KAAK;AAAA,MACxB,KAAAzW;AAAA,MACA,SAASiX,EAAE;AAAA,MACX,MAAMA,EAAE;AAAA,MACR,SAAS6H;AAAA,MACT,OAAOF;AAAA,MACP,SAAStG;AAAA,MACT,YAAYuG;AAAA,IAAA,CACb;AAAA,EAEL,CAAC,GACM,EAAE,WAAAnJ,IAAW,sBAAAe,EAAA;AACtB;AACA,SAASpH,GAA2B/M,GAAO;AACzC,SAAOA,EAAM,UAAU,QAAQA,EAAM,cAAc,QAAQA,EAAM,WAAW,SAAS;AACvF;AACA,SAASiN,GAA2BjN,GAAO6B,GAAYmL,GAAQ;AAC7D,MAAIhN,EAAM;AACR,WAAO;AAET,MAAI,CAAC+M,GAA2B/M,CAAK;AACnC,WAAO;AAET,MAAIyc,IAAU5a,KAAc,QAAQ7B,EAAM,MAAM6B,GAC5C6a,IAAW1P,KAAU,QAAQA,EAAOhN,EAAM,EAAE,MAAM;AACtD,SAAI,CAACyc,KAAWC,IACP,KAEL,OAAO1c,EAAM,UAAW,cAAcA,EAAM,OAAO,YAAY,KAC1D,KAEF,CAACyc,KAAW,CAACC;AACtB;AACA,SAASb,GAAYc,GAAmBC,GAAchb,GAAO;AAC3D,MAAIib;AAAA;AAAA,IAEF,CAACD;AAAA,IACDhb,EAAM,MAAM,OAAOgb,EAAa,MAAM;AAAA,KAEpCE,IAAgB,CAACH,EAAkB,eAAe/a,EAAM,MAAM,EAAE;AACpE,SAAOib,KAASC;AAClB;AACA,SAASd,GAAmBY,GAAchb,GAAO;AAC/C,MAAImb,IAAcH,EAAa,MAAM;AACrC;AAAA;AAAA,IAEEA,EAAa,aAAahb,EAAM;AAAA;AAAA,IAEhCmb,KAAe,QAAQA,EAAY,SAAS,GAAG,KAAKH,EAAa,OAAO,GAAG,MAAMhb,EAAM,OAAO,GAAG;AAAA;AAErG;AACA,SAASua,GAAuBa,GAAaC,GAAK;AAChD,MAAID,EAAY,MAAM,kBAAkB;AACtC,QAAIE,IAAcF,EAAY,MAAM,iBAAiBC,CAAG;AACxD,QAAI,OAAOC,KAAgB;AACzB,aAAOA;AAAA,EAEX;AACA,SAAOD,EAAI;AACb;AACA,SAASxD,GAAgBtH,GAASqH,GAAUhI,GAAanR,GAAUF,GAAqBgd,GAAuB;AAC7G,MAAIC;AACJ,MAAIjL,GAAS;AACX,QAAInS,IAAQK,EAAS8R,CAAO;AAC5B,IAAAnV;AAAA,MACEgD;AAAA,MACA,oDAAoDmS,CAAO;AAAA,IAAA,GAExDnS,EAAM,aACTA,EAAM,WAAW,CAAA,IAEnBod,IAAkBpd,EAAM;AAAA,EAC1B;AACE,IAAAod,IAAkB5L;AAEpB,MAAI6L,IAAiB,CAAA,GACjBC,IAAmB,CAAA;AAWvB,MAVA9D,EAAS,QAAQ,CAAC+D,MAAa;AAC7B,QAAIC,IAAgBJ,EAAgB;AAAA,MAClC,CAACK,MAAmBC,GAAYH,GAAUE,CAAc;AAAA,IAAA;AAE1D,IAAID,IACFF,EAAiB,KAAK,EAAE,eAAAE,GAAe,UAAAD,EAAA,CAAU,IAEjDF,EAAe,KAAKE,CAAQ;AAAA,EAEhC,CAAC,GACGF,EAAe,SAAS,GAAG;AAC7B,QAAIvD,IAAY7Z;AAAA,MACdod;AAAA,MACAld;AAAA,MACA,CAACgS,KAAW,KAAK,SAAS,OAAOiL,GAAiB,UAAU,GAAG,CAAC;AAAA,MAChE/c;AAAA,IAAA;AAEF,IAAA+c,EAAgB,KAAK,GAAGtD,CAAS;AAAA,EACnC;AACA,MAAIqD,KAAyBG,EAAiB,SAAS;AACrD,aAAS/b,IAAI,GAAGA,IAAI+b,EAAiB,QAAQ/b,KAAK;AAChD,UAAI,EAAE,eAAAic,GAAe,UAAAD,MAAaD,EAAiB/b,CAAC,GAChDoc,IAAqBH,GACrB,CAACI,CAAa,IAAI3d;AAAA,QACpB,CAACsd,CAAQ;AAAA,QACTpd;AAAA,QACA,CAAA;AAAA;AAAA,QAEA,CAAA;AAAA;AAAA,QAEA;AAAA,MAAA;AAEF,aAAO,OAAOwd,GAAoB;AAAA,QAChC,SAASC,EAAc,UAAUA,EAAc,UAAUD,EAAmB;AAAA,QAC5E,cAAcC,EAAc,eAAeA,EAAc,eAAeD,EAAmB;AAAA,QAC3F,wBAAwBC,EAAc,yBAAyBA,EAAc,yBAAyBD,EAAmB;AAAA,MAAA,CAC1H;AAAA,IACH;AAEJ;AACA,SAASD,GAAYH,GAAUC,GAAe;AAC5C,SAAI,QAAQD,KAAY,QAAQC,KAAiBD,EAAS,OAAOC,EAAc,KACtE,KAEHD,EAAS,UAAUC,EAAc,SAASD,EAAS,SAASC,EAAc,QAAQD,EAAS,kBAAkBC,EAAc,iBAG5H,CAACD,EAAS,YAAYA,EAAS,SAAS,WAAW,OAAO,CAACC,EAAc,YAAYA,EAAc,SAAS,WAAW,KACnH,KAEFD,EAAS,SAAS;AAAA,IACvB,CAACM,GAAQtc,MAAMic,EAAc,UAAU,KAAK,CAACM,MAAWJ,GAAYG,GAAQC,CAAM,CAAC;AAAA,EAAA,IAN5E;AAQX;AACA,IAAIC,yBAA6C,QAAA,GAC7CC,KAAwB,CAAC;AAAA,EAC3B,KAAAtgB;AAAA,EACA,OAAAsC;AAAA,EACA,UAAAK;AAAA,EACA,oBAAoBF;AACtB,MAAM;AACJ,MAAI8d,IAAgB5d,EAASL,EAAM,EAAE;AAErC,MADAhD,EAAUihB,GAAe,4BAA4B,GACjD,CAACA,EAAc,QAAQ,OAAOA,EAAc,QAAS;AACvD;AAEF,MAAItV,IAASsV,EAAc,KAAKvgB,CAAG;AACnC,MAAI,CAACiL;AACH;AAEF,MAAIuV,IAAQH,GAAuB,IAAIE,CAAa;AACpD,EAAKC,MACHA,IAAQ,CAAA,GACRH,GAAuB,IAAIE,GAAeC,CAAK;AAEjD,MAAIC,IAAgBD,EAAMxgB,CAAG;AAC7B,MAAIygB;AACF,WAAOA;AAET,MAAIC,KAAmB,YAAY;AACjC,QAAIC,IAAgBze,GAAgClC,CAAG,GAEnD4gB,IADmBL,EAAcvgB,CAAG,MACO,UAAUA,MAAQ;AACjE,QAAI2gB;AACF,MAAAnhB;AAAA,QACE,CAACmhB;AAAA,QACD,oBAAoB3gB,IAAM;AAAA,MAAA,GAE5BwgB,EAAMxgB,CAAG,IAAI,QAAQ,QAAA;AAAA,aACZ4gB;AACT,MAAAphB;AAAA,QACE;AAAA,QACA,UAAU+gB,EAAc,EAAE,4BAA4BvgB,CAAG;AAAA,MAAA;AAAA,SAEtD;AACL,UAAIzB,IAAQ,MAAM0M,EAAA;AAClB,MAAI1M,KAAS,SACX,OAAO,OAAOgiB,GAAe,EAAE,CAACvgB,CAAG,GAAGzB,GAAO,GAC7C,OAAO,OAAOgiB,GAAe9d,EAAoB8d,CAAa,CAAC;AAAA,IAEnE;AACA,IAAI,OAAOA,EAAc,QAAS,aAChCA,EAAc,KAAKvgB,CAAG,IAAI,QACtB,OAAO,OAAOugB,EAAc,IAAI,EAAE,MAAM,CAAChiB,MAAUA,MAAU,MAAM,MACrEgiB,EAAc,OAAO;AAAA,EAG3B,GAAA;AACA,SAAAC,EAAMxgB,CAAG,IAAI0gB,GACNA;AACT,GACIG,yBAA6C,QAAA;AACjD,SAASC,GAAcxe,GAAOye,GAAMpe,GAAUF,GAAqBkb,GAA2B;AAC5F,MAAI4C,IAAgB5d,EAASL,EAAM,EAAE;AAErC,MADAhD,EAAUihB,GAAe,4BAA4B,GACjD,CAACje,EAAM;AACT,WAAO;AAAA,MACL,kBAAkB;AAAA,MAClB,oBAAoB;AAAA,IAAA;AAGxB,MAAI,OAAOA,EAAM,QAAS,YAAY;AACpC,QAAIme,IAAgBI,GAAuB,IAAIN,CAAa;AAC5D,QAAIE;AACF,aAAO;AAAA,QACL,kBAAkBA;AAAA,QAClB,oBAAoBA;AAAA,MAAA;AAGxB,QAAIO,KAAqB,YAAY;AACnC,MAAA1hB;AAAA,QACE,OAAOgD,EAAM,QAAS;AAAA,QACtB;AAAA,MAAA;AAEF,UAAI2e,IAAY,MAAM3e,EAAM,KAAA,GACxB4e,IAAe,CAAA;AACnB,eAASC,KAAqBF,GAAW;AACvC,YAAIG,IAAYH,EAAUE,CAAiB;AAC3C,YAAIC,MAAc;AAChB;AAEF,YAAIT,IAAgBve,GAAkC+e,CAAiB,GAEnEP,IADmBL,EAAcY,CAAiB,MACP;AAAA;AAAA,QAE/CA,MAAsB;AACtB,QAAIR,IACFnhB;AAAA,UACE,CAACmhB;AAAA,UACD,oBAAoBQ,IAAoB;AAAA,QAAA,IAEjCP,IACTphB;AAAA,UACE,CAACohB;AAAA,UACD,UAAUL,EAAc,EAAE,4BAA4BY,CAAiB,yGAAyGA,CAAiB;AAAA,QAAA,IAGnMD,EAAaC,CAAiB,IAAIC;AAAA,MAEtC;AACA,aAAO,OAAOb,GAAeW,CAAY,GACzC,OAAO,OAAOX,GAAe;AAAA;AAAA;AAAA;AAAA,QAI3B,GAAG9d,EAAoB8d,CAAa;AAAA,QACpC,MAAM;AAAA,MAAA,CACP;AAAA,IACH,GAAA;AACA,WAAAM,GAAuB,IAAIN,GAAeS,CAAiB,GAC3DA,EAAkB,MAAM,MAAM;AAAA,IAC9B,CAAC,GACM;AAAA,MACL,kBAAkBA;AAAA,MAClB,oBAAoBA;AAAA,IAAA;AAAA,EAExB;AACA,MAAIK,IAAW,OAAO,KAAK/e,EAAM,IAAI,GACjCgf,IAAuB,CAAA,GACvBC;AACJ,WAASvhB,KAAOqhB,GAAU;AACxB,QAAI1D,KAA6BA,EAA0B,SAAS3d,CAAG;AACrE;AAEF,QAAImT,IAAUmN,GAAsB;AAAA,MAClC,KAAAtgB;AAAA,MACA,OAAAsC;AAAA,MACA,UAAAK;AAAA,MACA,oBAAoBF;AAAA,IAAA,CACrB;AACD,IAAI0Q,MACFmO,EAAqB,KAAKnO,CAAO,GAC7BnT,MAAQ+gB,MACVQ,IAAqBpO;AAAA,EAG3B;AACA,MAAIqO,IAAmBF,EAAqB,SAAS,IAAI,QAAQ,IAAIA,CAAoB,EAAE,KAAK,MAAM;AAAA,EACtG,CAAC,IAAI;AACL,SAAAE,GAAkB,MAAM,MAAM;AAAA,EAC9B,CAAC,GACDD,GAAoB,MAAM,MAAM;AAAA,EAChC,CAAC,GACM;AAAA,IACL,kBAAAC;AAAA,IACA,oBAAAD;AAAA,EAAA;AAEJ;AAkBA,eAAeE,GAAoBpW,GAAM;AACvC,MAAIqW,IAAgBrW,EAAK,QAAQ,OAAO,CAACpB,MAAMA,EAAE,UAAU,GACvD0X,IAAe,CAAA;AAEnB,UADc,MAAM,QAAQ,IAAID,EAAc,IAAI,CAACzX,MAAMA,EAAE,QAAA,CAAS,CAAC,GAC7D,QAAQ,CAAC3E,GAAQzB,MAAM;AAC7B,IAAA8d,EAAaD,EAAc7d,CAAC,EAAE,MAAM,EAAE,IAAIyB;AAAA,EAC5C,CAAC,GACMqc;AACT;AACA,eAAerT,GAAkCjD,GAAM;AACrD,SAAKA,EAAK,QAAQ,KAAK,CAACpB,MAAMA,EAAE,MAAM,UAAU,IAGzC2X,GAA4BvW,GAAM,MAAMoW,GAAoBpW,CAAI,CAAC,IAF/DoW,GAAoBpW,CAAI;AAGnC;AAaA,SAASuW,GAA4BvW,GAAMF,GAAS;AAClD,SAAO0W;AAAA,IACLxW;AAAA,IACAF;AAAA,IACA,CAAC8N,MAAM;AACL,UAAI6I,GAAmB7I,CAAC;AACtB,cAAMA;AAER,aAAOA;AAAA,IACT;AAAA,IACA8I;AAAA,IACAC;AAAA,EAAA;AAEF,WAASA,EAAa5gB,GAAOqT,GAASwN,GAAY;AAChD,QAAIA;AACF,aAAO,QAAQ;AAAA,QACb,OAAO,OAAOA,EAAW,OAAO;AAAA,UAC9B,CAACxN,CAAO,GAAG,EAAE,MAAM,SAAS,QAAQrT,EAAA;AAAA,QAAM,CAC3C;AAAA,MAAA;AAEE;AACL,UAAI,EAAE,SAAAwC,MAAYyH,GACd6W,IAAiB,KAAK;AAAA;AAAA,QAExB,KAAK;AAAA,UACHte,EAAQ,UAAU,CAACqG,MAAMA,EAAE,MAAM,OAAOwK,CAAO;AAAA,UAC/C;AAAA,QAAA;AAAA;AAAA,QAGF,KAAK;AAAA,UACH7Q,EAAQ,UAAU,CAACqG,MAAMA,EAAE,mBAAmB;AAAA,UAC9C;AAAA,QAAA;AAAA,MACF,GAEEkY,IAAkB7N;AAAA,QACpB1Q;AAAA,QACAA,EAAQse,CAAc,EAAE,MAAM;AAAA,MAAA,EAC9B,MAAM;AACR,aAAO,QAAQ,QAAQ;AAAA,QACrB,CAACC,CAAe,GAAG,EAAE,MAAM,SAAS,QAAQ/gB,EAAA;AAAA,MAAM,CACnD;AAAA,IACH;AAAA,EACF;AACF;AACA,eAAeygB,GAAsBxW,GAAMF,GAASiX,GAAeC,GAAUL,GAAc;AACzF,MAAI,EAAE,SAAApe,GAAS,SAAA4I,GAAS,QAAApI,GAAQ,SAAApC,GAAS,kBAAAyK,MAAqBpB,GAC1DiX,IAAS1e,EAAQ;AAAA,IACnB,CAACqG,MAAMA,EAAE,MAAM,aAAaA,EAAE,MAAM,WAAW,IAAI,CAACzI,MAAO,CAACyI,EAAE,MAAM,IAAIzI,CAAE,CAAC,IAAI,CAAA;AAAA,EAAC;AAelF,SAba,MAAM+gB;AAAA,IACjB;AAAA,MACE,SAAA/V;AAAA,MACA,QAAApI;AAAA,MACA,SAAApC;AAAA,MACA,kBAAAyK;AAAA,IAAA;AAAA,IAEF6V;AAAA,IACAnX;AAAA,IACAiX;AAAA,IACAC;AAAA,IACAL;AAAA,EAAA;AAGJ;AACA,eAAeO,GAAoBlX,GAAMmX,GAAarX,GAASiX,GAAeC,GAAUL,GAAcnZ,IAAM,GAAG;AAC7G,MAAI,EAAE,SAAA2D,MAAYnB;AAClB,MAAImB,EAAQ,OAAO;AACjB,UAAMA,EAAQ,OAAO,UAAU,IAAI,MAAM,oBAAoBA,EAAQ,MAAM,IAAIA,EAAQ,GAAG,EAAE;AAE9F,MAAIiW,IAAQD,EAAY3Z,CAAG;AAC3B,MAAI,CAAC4Z;AAEH,WADa,MAAMtX,EAAA;AAGrB,MAAI,CAACsJ,GAASlJ,CAAU,IAAIkX,GACxBR,GACAS,IAAO,YAAY;AACrB,QAAIT;AACF,YAAM,IAAI,MAAM,gDAAgD;AAElE,QAAI;AAUF,aAAAA,IAAa,EAAE,OATF,MAAMM;AAAA,QACjBlX;AAAA,QACAmX;AAAA,QACArX;AAAA,QACAiX;AAAA,QACAC;AAAA,QACAL;AAAA,QACAnZ,IAAM;AAAA,MAAA,EAEc,GACfoZ,EAAW;AAAA,IACpB,SAAS7gB,GAAO;AACd,aAAA6gB,IAAa,EAAE,OAAO,MAAMD,EAAa5gB,GAAOqT,GAASwN,CAAU,EAAA,GAC5DA,EAAW;AAAA,IACpB;AAAA,EACF;AACA,MAAI;AACF,QAAI1jB,IAAQ,MAAMgN,EAAWF,GAAMqX,CAAI,GACnCpd,IAAS/G,KAAS,OAAO6jB,EAAc7jB,CAAK,IAAI;AACpD,WAAI8jB,EAAS/c,CAAM,IACVA,IACE2c,IACF3c,KAAU2c,EAAW,SAE5BA,IAAa,EAAE,OAAO,MAAMS,IAAK,GAC1BT,EAAW;AAAA,EAEtB,SAAS7gB,GAAO;AAEd,WADe,MAAM4gB,EAAa5gB,GAAOqT,GAASwN,CAAU;AAAA,EAE9D;AACF;AACA,SAASU,GAAiClgB,GAAqBE,GAAU6J,GAAStI,GAAOyZ,GAA2B;AAClH,MAAIiF,IAAwBtC,GAAsB;AAAA,IAChD,KAAK;AAAA,IACL,OAAOpc,EAAM;AAAA,IACb,UAAAvB;AAAA,IACA,oBAAoBF;AAAA,EAAA,CACrB,GACGogB,IAAoB/B;AAAA,IACtB5c,EAAM;AAAA,IACNsO,GAAiBhG,EAAQ,MAAM,IAAI,WAAW;AAAA,IAC9C7J;AAAA,IACAF;AAAA,IACAkb;AAAA,EAAA;AAEF,SAAO;AAAA,IACL,YAAYiF;AAAA,IACZ,OAAOC,EAAkB;AAAA,IACzB,SAASA,EAAkB;AAAA,EAAA;AAE/B;AACA,SAASzE,GAAqB3b,GAAqBE,GAAU6J,GAASC,GAAkBvI,GAAOyZ,GAA2BvJ,GAAeoK,GAAYD,IAAuB,MAAMnI,GAAiC;AACjN,MAAI0M,IAAgB,IAChBC,IAAgBJ;AAAA,IAClBlgB;AAAA,IACAE;AAAA,IACA6J;AAAA,IACAtI;AAAA,IACAyZ;AAAA,EAAA;AAEF,SAAO;AAAA,IACL,GAAGzZ;AAAA,IACH,eAAA6e;AAAA,IACA,YAAAvE;AAAA,IACA,sBAAAD;AAAA,IACA,kBAAkBF,GAAyB;AAEzC,aADAyE,IAAgB,IACXvE,IAGD,OAAOnI,KAAoC,YACtCqI,GAAuBva,GAAO;AAAA,QACnC,GAAGqa;AAAA,QACH,yBAAyBnI;AAAA,MAAA,CAC1B,IAEC,OAAOiI,KAA4B,YAC9BI,GAAuBva,GAAO;AAAA,QACnC,GAAGqa;AAAA,QACH,yBAAAF;AAAA,MAAA,CACD,IAEII,GAAuBva,GAAOqa,CAAoB,IAdhDC;AAAA,IAeX;AAAA,IACA,QAAQwE,GAAiB;AACvB,UAAI,EAAE,MAAAC,GAAM,QAAAC,GAAQ,YAAA3X,EAAA,IAAerH,EAAM,OACrCoI,IAAcwW,KAAiBtE,KAAcwE,KAAmB,CAACxQ,GAAiBhG,EAAQ,MAAM,MAAMyW,KAAQC,IAC9GC,IAAwB5X,KAAcA,EAAW,SAAS,KAAK,CAAC2X,KAAU,CAACD;AAC/E,aAAI3W,MAAgBkG,GAAiBhG,EAAQ,MAAM,KAAK,CAAC2W,KAChDC,GAAmB;AAAA,QACxB,SAAA5W;AAAA,QACA,kBAAAC;AAAA,QACA,OAAAvI;AAAA,QACA,oBAAoB6e,GAAe;AAAA,QACnC,kBAAkBA,GAAe;AAAA,QACjC,iBAAAC;AAAA,QACA,eAAA5O;AAAA,MAAA,CACD,IAEI,QAAQ,QAAQ,EAAE,MAAM,QAAmB,QAAQ,QAAQ;AAAA,IACpE;AAAA,EAAA;AAEJ;AACA,SAASuB,GAA+BlT,GAAqBE,GAAU6J,GAAS5I,GAASyf,GAAa1F,GAA2BvJ,GAAemK,IAAuB,MAAM;AAC3K,SAAO3a,EAAQ,IAAI,CAACM,MACdA,EAAM,MAAM,OAAOmf,EAAY,MAAM,KAChC;AAAA,IACL,GAAGnf;AAAA,IACH,YAAY;AAAA,IACZ,sBAAAqa;AAAA,IACA,mBAAmB,MAAM;AAAA,IACzB,eAAeoE;AAAA,MACblgB;AAAA,MACAE;AAAA,MACA6J;AAAA,MACAtI;AAAA,MACAyZ;AAAA,IAAA;AAAA,IAEF,SAAS,MAAM,QAAQ,QAAQ,EAAE,MAAM,QAAQ,QAAQ,OAAA,CAAQ;AAAA,EAAA,IAG5DS;AAAA,IACL3b;AAAA,IACAE;AAAA,IACA6J;AAAA,IACAxC,GAAgBpG,CAAO;AAAA,IACvBM;AAAA,IACAyZ;AAAA,IACAvJ;AAAA,IACA;AAAA,IACAmK;AAAA,EAAA,CAEH;AACH;AACA,eAAe3E,GAAqBvL,GAAkB7B,GAAS5I,GAAS8V,GAAYtF,GAAekP,GAAiB;AAClH,EAAI1f,EAAQ,KAAK,CAACqG,MAAMA,EAAE,eAAe,UAAU,KACjD,MAAM,QAAQ,IAAIrG,EAAQ,IAAI,CAACqG,MAAMA,EAAE,eAAe,UAAU,CAAC;AAEnE,MAAIsZ,IAAmB;AAAA,IACrB,SAAA/W;AAAA,IACA,kBAAkBxC,GAAgBpG,CAAO;AAAA,IACzC,QAAQA,EAAQ,CAAC,EAAE;AAAA,IACnB,SAASwQ;AAAA,IACT,SAAAxQ;AAAA,EAAA,GAoBEgS,IAAU,MAAMvH,EAAiB;AAAA,IACnC,GAAGkV;AAAA,IACH,YAAA7J;AAAA,IACA,qBAjBE,CAAC8J,MAAO;AACV,UAAIC,IAAwBF;AAC5B,aAAO3B,GAA4B6B,GAAuB,MACjDD,EAAG;AAAA,QACR,GAAGC;AAAA,QACH,YAAA/J;AAAA,QACA,qBAAqB,MAAM;AACzB,gBAAM,IAAI;AAAA,YACR;AAAA,UAAA;AAAA,QAEJ;AAAA,MAAA,CACD,CACF;AAAA,IACH;AAAA,EAIE,CACD;AACD,MAAI;AACF,UAAM,QAAQ;AAAA,MACZ9V,EAAQ,QAAQ,CAACqG,MAAM;AAAA,QACrBA,EAAE,eAAe;AAAA,QACjBA,EAAE,eAAe;AAAA,MAAA,CAClB;AAAA,IAAA;AAAA,EAEL,QAAY;AAAA,EACZ;AACA,SAAO2L;AACT;AACA,eAAewN,GAAmB;AAAA,EAChC,SAAA5W;AAAA,EACA,kBAAAC;AAAA,EACA,OAAAvI;AAAA,EACA,oBAAAqd;AAAA,EACA,kBAAAC;AAAA,EACA,iBAAAwB;AAAA,EACA,eAAA5O;AACF,GAAG;AACD,MAAI9O,GACAoe,GACAC,IAAWnR,GAAiBhG,EAAQ,MAAM,GAC1CuU,IAAO4C,IAAW,WAAW,UAC7BC,IAAa,CAACzY,MAAY;AAC5B,QAAI0Y,GACAC,IAAe,IAAI,QAAQ,CAACtc,GAAGyR,MAAM4K,IAAS5K,CAAC;AACnD,IAAAyK,IAAW,MAAMG,EAAA,GACjBrX,EAAQ,OAAO,iBAAiB,SAASkX,CAAQ;AACjD,QAAIK,IAAgB,CAACjX,MACf,OAAO3B,KAAY,aACd,QAAQ;AAAA,MACb,IAAI;AAAA,QACF,oEAAoE4V,CAAI,eAAe7c,EAAM,MAAM,EAAE;AAAA,MAAA;AAAA,IACvG,IAGGiH;AAAA,MACL;AAAA,QACE,SAAAqB;AAAA,QACA,kBAAAC;AAAA,QACA,QAAQvI,EAAM;AAAA,QACd,SAASkQ;AAAA,MAAA;AAAA,MAEX,GAAGtH,MAAQ,SAAS,CAACA,CAAG,IAAI,CAAA;AAAA,IAAC,GAG7BT,KAAkB,YAAY;AAChC,UAAI;AAEF,eAAO,EAAE,MAAM,QAAQ,QADb,OAAO2W,IAAkBA,EAAgB,CAAClW,MAAQiX,EAAcjX,CAAG,CAAC,IAAIiX,KACnD;AAAA,MACjC,SAASxX,GAAG;AACV,eAAO,EAAE,MAAM,SAAS,QAAQA,EAAA;AAAA,MAClC;AAAA,IACF,GAAA;AACA,WAAO,QAAQ,KAAK,CAACF,GAAgByX,CAAY,CAAC;AAAA,EACpD;AACA,MAAI;AACF,QAAI3Y,IAAUwY,IAAWzf,EAAM,MAAM,SAASA,EAAM,MAAM;AAC1D,QAAIqd,KAAsBC;AACxB,UAAIrW,GAAS;AACX,YAAI6Y,GACA,CAACzlB,CAAK,IAAI,MAAM,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA,UAI9BqlB,EAAWzY,CAAO,EAAE,MAAM,CAACoB,MAAM;AAC/B,YAAAyX,IAAezX;AAAA,UACjB,CAAC;AAAA;AAAA,UAEDgV;AAAA,UACAC;AAAA,QAAA,CACD;AACD,YAAIwC,MAAiB;AACnB,gBAAMA;AAER,QAAA1e,IAAS/G;AAAA,MACX,OAAO;AACL,cAAMgjB;AACN,YAAI0C,IAAWN,IAAWzf,EAAM,MAAM,SAASA,EAAM,MAAM;AAC3D,YAAI+f;AACF,WAAC3e,CAAM,IAAI,MAAM,QAAQ,IAAI,CAACse,EAAWK,CAAQ,GAAGzC,CAAgB,CAAC;AAAA,iBAC5DT,MAAS,UAAU;AAC5B,cAAI5f,IAAM,IAAI,IAAIqL,EAAQ,GAAG,GACzB1N,IAAWqC,EAAI,WAAWA,EAAI;AAClC,gBAAM+N,GAAuB,KAAK;AAAA,YAChC,QAAQ1C,EAAQ;AAAA,YAChB,UAAA1N;AAAA,YACA,SAASoF,EAAM,MAAM;AAAA,UAAA,CACtB;AAAA,QACH;AACE,iBAAO,EAAE,MAAM,QAAmB,QAAQ,OAAA;AAAA,MAE9C;AAAA,aACUiH;AAOV,MAAA7F,IAAS,MAAMse,EAAWzY,CAAO;AAAA,SAPd;AACnB,UAAIhK,IAAM,IAAI,IAAIqL,EAAQ,GAAG,GACzB1N,IAAWqC,EAAI,WAAWA,EAAI;AAClC,YAAM+N,GAAuB,KAAK;AAAA,QAChC,UAAApQ;AAAA,MAAA,CACD;AAAA,IACH;AAAA,EAGF,SAASyN,GAAG;AACV,WAAO,EAAE,MAAM,SAAqB,QAAQA,EAAA;AAAA,EAC9C,UAAA;AACE,IAAImX,KACFlX,EAAQ,OAAO,oBAAoB,SAASkX,CAAQ;AAAA,EAExD;AACA,SAAOpe;AACT;AACA,eAAe4e,GAAkBpK,GAAU;AACzC,MAAIqK,IAAcrK,EAAS,QAAQ,IAAI,cAAc;AACrD,SAAIqK,KAAe,wBAAwB,KAAKA,CAAW,IAClDrK,EAAS,QAAQ,OAAO,OAAOA,EAAS,KAAA,IAE1CA,EAAS,KAAA;AAClB;AACA,eAAeE,GAAsCoK,GAAoB;AACvE,MAAI,EAAE,QAAA9e,GAAQ,MAAAyb,EAAA,IAASqD;AACvB,MAAIC,GAAW/e,CAAM,GAAG;AACtB,QAAIuE;AACJ,QAAI;AACF,MAAAA,IAAQ,MAAMqa,GAAkB5e,CAAM;AAAA,IACxC,SAASiH,GAAG;AACV,aAAO,EAAE,MAAM,SAAqB,OAAOA,EAAA;AAAA,IAC7C;AACA,WAAIwU,MAAS,UACJ;AAAA,MACL,MAAM;AAAA,MACN,OAAO,IAAIrX,GAAkBpE,EAAO,QAAQA,EAAO,YAAYuE,CAAK;AAAA,MACpE,YAAYvE,EAAO;AAAA,MACnB,SAASA,EAAO;AAAA,IAAA,IAGb;AAAA,MACL,MAAM;AAAA,MACN,MAAMuE;AAAA,MACN,YAAYvE,EAAO;AAAA,MACnB,SAASA,EAAO;AAAA,IAAA;AAAA,EAEpB;AACA,SAAIyb,MAAS,UACPuD,GAAuBhf,CAAM,IAC3BA,EAAO,gBAAgB,QAClB;AAAA,IACL,MAAM;AAAA,IACN,OAAOA,EAAO;AAAA,IACd,YAAYA,EAAO,MAAM;AAAA,IACzB,SAASA,EAAO,MAAM,UAAU,IAAI,QAAQA,EAAO,KAAK,OAAO,IAAI;AAAA,EAAA,IAGhE;AAAA,IACL,MAAM;AAAA,IACN,OAAOif,GAAoCjf,CAAM;AAAA,IACjD,YAAYyE,GAAqBzE,CAAM,IAAIA,EAAO,SAAS;AAAA,IAC3D,SAASA,EAAO,MAAM,UAAU,IAAI,QAAQA,EAAO,KAAK,OAAO,IAAI;AAAA,EAAA,IAGhE;AAAA,IACL,MAAM;AAAA,IACN,OAAOA;AAAA,IACP,YAAYyE,GAAqBzE,CAAM,IAAIA,EAAO,SAAS;AAAA,EAAA,IAG3Dgf,GAAuBhf,CAAM,IACxB;AAAA,IACL,MAAM;AAAA,IACN,MAAMA,EAAO;AAAA,IACb,YAAYA,EAAO,MAAM;AAAA,IACzB,SAASA,EAAO,MAAM,UAAU,IAAI,QAAQA,EAAO,KAAK,OAAO,IAAI;AAAA,EAAA,IAGhE,EAAE,MAAM,QAAmB,MAAMA,EAAA;AAC1C;AACA,SAASyU,GAAyCD,GAAUtN,GAASiI,GAAS7Q,GAASP,GAAU;AAC/F,MAAIzD,IAAWka,EAAS,QAAQ,IAAI,UAAU;AAK9C,MAJAxa;AAAA,IACEM;AAAA,IACA;AAAA,EAAA,GAEE,CAACkI,GAAclI,CAAQ,GAAG;AAC5B,QAAI4kB,IAAiB5gB,EAAQ;AAAA,MAC3B;AAAA,MACAA,EAAQ,UAAU,CAACqG,MAAMA,EAAE,MAAM,OAAOwK,CAAO,IAAI;AAAA,IAAA;AAErD,IAAA7U,IAAWyT;AAAA,MACT,IAAI,IAAI7G,EAAQ,GAAG;AAAA,MACnBgY;AAAA,MACAnhB;AAAA,MACAzD;AAAA,IAAA,GAEFka,EAAS,QAAQ,IAAI,YAAYla,CAAQ;AAAA,EAC3C;AACA,SAAOka;AACT;AACA,SAAS/D,GAA0BnW,GAAU2K,GAAYlH,GAAUohB,GAAiB;AAClF,MAAIC,IAAmB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,EAAA;AAEF,MAAI5c,GAAclI,CAAQ,GAAG;AAC3B,QAAI+kB,IAAqB/kB,GACrBuB,IAAMwjB,EAAmB,WAAW,IAAI,IAAI,IAAI,IAAIpa,EAAW,WAAWoa,CAAkB,IAAI,IAAI,IAAIA,CAAkB;AAC9H,QAAID,EAAiB,SAASvjB,EAAI,QAAQ;AACxC,YAAM,IAAI,MAAM,2BAA2B;AAE7C,QAAIyjB,IAAiBphB,GAAcrC,EAAI,UAAUkC,CAAQ,KAAK;AAC9D,QAAIlC,EAAI,WAAWoJ,EAAW,UAAUqa;AACtC,aAAOzjB,EAAI,WAAWA,EAAI,SAASA,EAAI;AAAA,EAE3C;AACA,MAAI;AACF,QAAIA,IAAMsjB,EAAgB,UAAU7kB,CAAQ;AAC5C,QAAI8kB,EAAiB,SAASvjB,EAAI,QAAQ;AACxC,YAAM,IAAI,MAAM,2BAA2B;AAAA,EAE/C,QAAY;AAAA,EACZ;AACA,SAAOvB;AACT;AACA,SAASuU,GAAwBnT,GAASpB,GAAU8b,GAAQpI,GAAY;AACtE,MAAInS,IAAMH,EAAQ,UAAUmc,GAAkBvd,CAAQ,CAAC,EAAE,SAAA,GACrDmC,IAAO,EAAE,QAAA2Z,EAAA;AACb,MAAIpI,KAAcd,GAAiBc,EAAW,UAAU,GAAG;AACzD,QAAI,EAAE,YAAAiG,GAAY,aAAAE,EAAA,IAAgBnG;AAClC,IAAAvR,EAAK,SAASwX,EAAW,YAAA,GACrBE,MAAgB,sBAClB1X,EAAK,UAAU,IAAI,QAAQ,EAAE,gBAAgB0X,GAAa,GAC1D1X,EAAK,OAAO,KAAK,UAAUuR,EAAW,IAAI,KACjCmG,MAAgB,eACzB1X,EAAK,OAAOuR,EAAW,OACdmG,MAAgB,uCAAuCnG,EAAW,WAC3EvR,EAAK,OAAO0b,GAA8BnK,EAAW,QAAQ,IAE7DvR,EAAK,OAAOuR,EAAW;AAAA,EAE3B;AACA,SAAO,IAAI,QAAQnS,GAAKY,CAAI;AAC9B;AACA,SAAS0b,GAA8BD,GAAU;AAC/C,MAAID,IAAe,IAAI,gBAAA;AACvB,WAAS,CAACvd,GAAKzB,CAAK,KAAKif,EAAS;AAChC,IAAAD,EAAa,OAAOvd,GAAK,OAAOzB,KAAU,WAAWA,IAAQA,EAAM,IAAI;AAEzE,SAAOgf;AACT;AACA,SAASG,GAA8BH,GAAc;AACnD,MAAIC,IAAW,IAAI,SAAA;AACnB,WAAS,CAACxd,GAAKzB,CAAK,KAAKgf,EAAa;AACpC,IAAAC,EAAS,OAAOxd,GAAKzB,CAAK;AAE5B,SAAOif;AACT;AACA,SAASqH,GAAuBjhB,GAASgS,GAASvB,GAAqBiP,IAAkB,IAAOwB,IAA0B,IAAO;AAC/H,MAAI3gB,IAAa,CAAA,GACbmL,IAAS,MACTyV,GACAC,IAAa,IACbC,IAAgB,CAAA,GAChBC,IAAe7Q,KAAuBK,GAAcL,EAAoB,CAAC,CAAC,IAAIA,EAAoB,CAAC,EAAE,QAAQ;AACjH,SAAAzQ,EAAQ,QAAQ,CAACM,MAAU;AACzB,QAAI,EAAEA,EAAM,MAAM,MAAM0R;AACtB;AAEF,QAAI9S,IAAKoB,EAAM,MAAM,IACjBoB,IAASsQ,EAAQ9S,CAAE;AAKvB,QAJAxD;AAAA,MACE,CAACwW,GAAiBxQ,CAAM;AAAA,MACxB;AAAA,IAAA,GAEEoP,GAAcpP,CAAM,GAAG;AACzB,UAAIlE,IAAQkE,EAAO;AAMnB,UALI4f,MAAiB,WACnB9jB,IAAQ8jB,GACRA,IAAe,SAEjB5V,IAASA,KAAU,CAAA,GACfwV;AACF,QAAAxV,EAAOxM,CAAE,IAAI1B;AAAA,WACR;AACL,YAAI6U,IAAgB3B,GAAoB1Q,GAASd,CAAE;AACnD,QAAIwM,EAAO2G,EAAc,MAAM,EAAE,KAAK,SACpC3G,EAAO2G,EAAc,MAAM,EAAE,IAAI7U;AAAA,MAErC;AACA,MAAKkiB,MACHnf,EAAWrB,CAAE,IAAI+K,KAEdmX,MACHA,IAAa,IACbD,IAAahb,GAAqBzE,EAAO,KAAK,IAAIA,EAAO,MAAM,SAAS,MAEtEA,EAAO,YACT2f,EAAcniB,CAAE,IAAIwC,EAAO;AAAA,IAE/B;AACE,MAAAnB,EAAWrB,CAAE,IAAIwC,EAAO,MACpBA,EAAO,cAAcA,EAAO,eAAe,OAAO,CAAC0f,MACrDD,IAAazf,EAAO,aAElBA,EAAO,YACT2f,EAAcniB,CAAE,IAAIwC,EAAO;AAAA,EAGjC,CAAC,GACG4f,MAAiB,UAAU7Q,MAC7B/E,IAAS,EAAE,CAAC+E,EAAoB,CAAC,CAAC,GAAG6Q,EAAA,GACjC7Q,EAAoB,CAAC,MACvBlQ,EAAWkQ,EAAoB,CAAC,CAAC,IAAI,UAGlC;AAAA,IACL,YAAAlQ;AAAA,IACA,QAAAmL;AAAA,IACA,YAAYyV,KAAc;AAAA,IAC1B,eAAAE;AAAA,EAAA;AAEJ;AACA,SAAS1N,GAAkBxX,GAAO6D,GAASgS,GAASvB,GAAqBoC,GAAsBU,GAAgB;AAC7G,MAAI,EAAE,YAAAhT,GAAY,QAAAmL,EAAA,IAAWuV;AAAA,IAC3BjhB;AAAA,IACAgS;AAAA,IACAvB;AAAA,EAAA;AAEF,SAAAoC,EAAqB,OAAO,CAACQ,MAAM,CAACA,EAAE,WAAWA,EAAE,QAAQ,KAAK,CAAChN,MAAMA,EAAE,UAAU,CAAC,EAAE,QAAQ,CAAC6M,MAAO;AACpG,QAAI,EAAE,KAAA9W,GAAK,OAAAkE,GAAO,YAAAwW,EAAA,IAAe5D;AACjC,QAAI4D,KAAcA,EAAW,OAAO;AAClC;AAEF,QAAIpV,IAAS6R,EAAenX,CAAG;AAE/B,QADAV,EAAUgG,GAAQ,2CAA2C,GACzDoP,GAAcpP,CAAM,GAAG;AACzB,UAAI2Q,IAAgB3B,GAAoBvU,EAAM,SAASmE,GAAO,MAAM,EAAE;AACtE,MAAMoL,KAAUA,EAAO2G,EAAc,MAAM,EAAE,MAC3C3G,IAAS;AAAA,QACP,GAAGA;AAAA,QACH,CAAC2G,EAAc,MAAM,EAAE,GAAG3Q,EAAO;AAAA,MAAA,IAGrCvF,EAAM,SAAS,OAAOC,CAAG;AAAA,IAC3B,WAAW8V,GAAiBxQ,CAAM;AAChC,MAAAhG,EAAU,IAAO,yCAAyC;AAAA,SACrD;AACL,UAAI4Z,IAAcP,GAAerT,EAAO,IAAI;AAC5C,MAAAvF,EAAM,SAAS,IAAIC,GAAKkZ,CAAW;AAAA,IACrC;AAAA,EACF,CAAC,GACM,EAAE,YAAA/U,GAAY,QAAAmL,EAAA;AACvB;AACA,SAASoD,GAAgBvO,GAAYghB,GAAevhB,GAAS0L,GAAQ;AACnE,MAAI8V,IAAmB,OAAO,QAAQD,CAAa,EAAE,OAAO,CAAC,GAAG1d,CAAC,MAAMA,MAAMoG,EAAqB,EAAE,OAAO,CAACwX,GAAQ,CAAC1S,GAAGlL,CAAC,OACvH4d,EAAO1S,CAAC,IAAIlL,GACL4d,IACN,CAAA,CAAE;AACL,WAASnhB,KAASN,GAAS;AACzB,QAAId,IAAKoB,EAAM,MAAM;AAIrB,QAHI,CAACihB,EAAc,eAAeriB,CAAE,KAAKqB,EAAW,eAAerB,CAAE,KAAKoB,EAAM,MAAM,WACpFkhB,EAAiBtiB,CAAE,IAAIqB,EAAWrB,CAAE,IAElCwM,KAAUA,EAAO,eAAexM,CAAE;AACpC;AAAA,EAEJ;AACA,SAAOsiB;AACT;AACA,SAASrQ,GAAuBV,GAAqB;AACnD,SAAKA,IAGEK,GAAcL,EAAoB,CAAC,CAAC,IAAI;AAAA;AAAA,IAE7C,YAAY,CAAA;AAAA,EAAC,IACX;AAAA,IACF,YAAY;AAAA,MACV,CAACA,EAAoB,CAAC,CAAC,GAAGA,EAAoB,CAAC,EAAE;AAAA,IAAA;AAAA,EACnD,IARO,CAAA;AAUX;AACA,SAASC,GAAoB1Q,GAAS6Q,GAAS;AAE7C,UADsBA,IAAU7Q,EAAQ,MAAM,GAAGA,EAAQ,UAAU,CAACqG,MAAMA,EAAE,MAAM,OAAOwK,CAAO,IAAI,CAAC,IAAI,CAAC,GAAG7Q,CAAO,GAC7F,UAAU,KAAK,CAACqG,MAAMA,EAAE,MAAM,qBAAqB,EAAI,KAAKrG,EAAQ,CAAC;AAC9F;AACA,SAASuL,GAAuB3M,GAAQ;AACtC,MAAIF,IAAQE,EAAO,WAAW,IAAIA,EAAO,CAAC,IAAIA,EAAO,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,GAAG,KAAK;AAAA,IACxG,IAAI;AAAA,EAAA;AAEN,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,QAAQ,CAAA;AAAA,QACR,UAAU;AAAA,QACV,cAAc;AAAA,QACd,OAAAF;AAAA,MAAA;AAAA,IACF;AAAA,IAEF,OAAAA;AAAA,EAAA;AAEJ;AACA,SAAS4M,GAAuBvF,GAAQ;AAAA,EACtC,UAAA7K;AAAA,EACA,SAAA2V;AAAA,EACA,QAAA6Q;AAAA,EACA,MAAAvE;AAAA,EACA,SAAAxhB;AACF,IAAI,IAAI;AACN,MAAIqK,IAAa,wBACb2b,IAAe;AACnB,SAAI5b,MAAW,OACbC,IAAa,eACT0b,KAAUxmB,KAAY2V,IACxB8Q,IAAe,cAAcD,CAAM,gBAAgBxmB,CAAQ,iDAAiD2V,CAAO,iDAC1GsM,MAAS,mBAClBwE,IAAe,uCAER5b,MAAW,OACpBC,IAAa,aACb2b,IAAe,UAAU9Q,CAAO,yBAAyB3V,CAAQ,OACxD6K,MAAW,OACpBC,IAAa,aACb2b,IAAe,yBAAyBzmB,CAAQ,OACvC6K,MAAW,QACpBC,IAAa,sBACT0b,KAAUxmB,KAAY2V,IACxB8Q,IAAe,cAAcD,EAAO,YAAA,CAAa,gBAAgBxmB,CAAQ,kDAAkD2V,CAAO,iDACzH6Q,MACTC,IAAe,2BAA2BD,EAAO,YAAA,CAAa,OAG3D,IAAI5b;AAAA,IACTC,KAAU;AAAA,IACVC;AAAA,IACA,IAAI,MAAM2b,CAAY;AAAA,IACtB;AAAA,EAAA;AAEJ;AACA,SAASjO,GAAa1B,GAAS;AAC7B,MAAIsF,IAAU,OAAO,QAAQtF,CAAO;AACpC,WAAS/R,IAAIqX,EAAQ,SAAS,GAAGrX,KAAK,GAAGA,KAAK;AAC5C,QAAI,CAAC7D,GAAKsF,CAAM,IAAI4V,EAAQrX,CAAC;AAC7B,QAAIiS,GAAiBxQ,CAAM;AACzB,aAAO,EAAE,KAAAtF,GAAK,QAAAsF,EAAA;AAAA,EAElB;AACF;AACA,SAAS6X,GAAkBjd,GAAM;AAC/B,MAAIC,IAAa,OAAOD,KAAS,WAAWD,GAAUC,CAAI,IAAIA;AAC9D,SAAOd,GAAW,EAAE,GAAGe,GAAY,MAAM,IAAI;AAC/C;AACA,SAAS6T,GAAiBxO,GAAGC,GAAG;AAC9B,SAAID,EAAE,aAAaC,EAAE,YAAYD,EAAE,WAAWC,EAAE,SACvC,KAELD,EAAE,SAAS,KACNC,EAAE,SAAS,KACTD,EAAE,SAASC,EAAE,OACf,KACEA,EAAE,SAAS;AAIxB;AAIA,SAAS8e,GAAoC1a,GAAO;AAClD,SAAO,IAAIH;AAAA,IACTG,EAAM,MAAM,UAAU;AAAA,IACtBA,EAAM,MAAM,cAAc;AAAA,IAC1BA,EAAM;AAAA,EAAA;AAEV;AACA,SAASkY,GAAsBzc,GAAQ;AACrC,SAAOA,KAAU,QAAQ,OAAOA,KAAW,YAAY,OAAO,QAAQA,CAAM,EAAE;AAAA,IAC5E,CAAC,CAACtF,GAAKzB,CAAK,MAAM,OAAOyB,KAAQ,YAAYwlB,GAAqBjnB,CAAK;AAAA,EAAA;AAE3E;AACA,SAASinB,GAAqBlgB,GAAQ;AACpC,SAAOA,KAAU,QAAQ,OAAOA,KAAW,YAAY,UAAUA,KAAU,YAAYA,MAAWA,EAAO,SAAS,UAAqBA,EAAO,SAAS;AACzJ;AACA,SAASuU,GAA6BvU,GAAQ;AAC5C,SAAO+e,GAAW/e,EAAO,MAAM,KAAKgI,GAAoB,IAAIhI,EAAO,OAAO,MAAM;AAClF;AACA,SAASoP,GAAcpP,GAAQ;AAC7B,SAAOA,EAAO,SAAS;AACzB;AACA,SAASwQ,GAAiBxQ,GAAQ;AAChC,UAAQA,KAAUA,EAAO,UAAU;AACrC;AACA,SAASgf,GAAuB/lB,GAAO;AACrC,SAAO,OAAOA,KAAU,YAAYA,KAAS,QAAQ,UAAUA,KAAS,UAAUA,KAAS,UAAUA,KAASA,EAAM,SAAS;AAC/H;AACA,SAAS8lB,GAAW9lB,GAAO;AACzB,SAAOA,KAAS,QAAQ,OAAOA,EAAM,UAAW,YAAY,OAAOA,EAAM,cAAe,YAAY,OAAOA,EAAM,WAAY,YAAY,OAAOA,EAAM,OAAS;AACjK;AACA,SAASknB,GAAqBV,GAAY;AACxC,SAAOzX,GAAoB,IAAIyX,CAAU;AAC3C;AACA,SAASjD,GAAmBxc,GAAQ;AAClC,SAAO+e,GAAW/e,CAAM,KAAKmgB,GAAqBngB,EAAO,MAAM,KAAKA,EAAO,QAAQ,IAAI,UAAU;AACnG;AACA,SAAS2X,GAAcqI,GAAQ;AAC7B,SAAOjY,GAAoB,IAAIiY,EAAO,YAAA,CAAa;AACrD;AACA,SAAS9S,GAAiB8S,GAAQ;AAChC,SAAOnY,GAAqB,IAAImY,EAAO,YAAA,CAAa;AACtD;AACA,SAASzI,GAAmB9d,GAAQ;AAClC,SAAO,IAAI,gBAAgBA,CAAM,EAAE,OAAO,OAAO,EAAE,KAAK,CAAC0I,MAAMA,MAAM,EAAE;AACzE;AACA,SAASgO,GAAe7R,GAAShE,GAAU;AACzC,MAAIb,IAAS,OAAOa,KAAa,WAAWK,GAAUL,CAAQ,EAAE,SAASA,EAAS;AAClF,MAAIgE,EAAQA,EAAQ,SAAS,CAAC,EAAE,MAAM,SAASiZ,GAAmB9d,KAAU,EAAE;AAC5E,WAAO6E,EAAQA,EAAQ,SAAS,CAAC;AAEnC,MAAIgF,IAAcF,GAA2B9E,CAAO;AACpD,SAAOgF,EAAYA,EAAY,SAAS,CAAC;AAC3C;AACA,SAAS0N,GAA4BpB,GAAY;AAC/C,MAAI,EAAE,YAAAqE,GAAY,YAAAC,GAAY,aAAAC,GAAa,MAAA2D,GAAM,UAAAI,GAAU,MAAAF,MAASpI;AACpE,MAAI,GAACqE,KAAc,CAACC,KAAc,CAACC,IAGnC;AAAA,QAAI2D,KAAQ;AACV,aAAO;AAAA,QACL,YAAA7D;AAAA,QACA,YAAAC;AAAA,QACA,aAAAC;AAAA,QACA,UAAU;AAAA,QACV,MAAM;AAAA,QACN,MAAA2D;AAAA,MAAA;AAEJ,QAAWI,KAAY;AACrB,aAAO;AAAA,QACL,YAAAjE;AAAA,QACA,YAAAC;AAAA,QACA,aAAAC;AAAA,QACA,UAAA+D;AAAA,QACA,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAEV,QAAWF,MAAS;AAClB,aAAO;AAAA,QACL,YAAA/D;AAAA,QACA,YAAAC;AAAA,QACA,aAAAC;AAAA,QACA,UAAU;AAAA,QACV,MAAA6D;AAAA,QACA,MAAM;AAAA,MAAA;AAAA;AAGZ;AACA,SAAS3I,GAAqB/U,GAAU0T,GAAY;AAClD,SAAIA,IACe;AAAA,IACf,OAAO;AAAA,IACP,UAAA1T;AAAA,IACA,YAAY0T,EAAW;AAAA,IACvB,YAAYA,EAAW;AAAA,IACvB,aAAaA,EAAW;AAAA,IACxB,UAAUA,EAAW;AAAA,IACrB,MAAMA,EAAW;AAAA,IACjB,MAAMA,EAAW;AAAA,EAAA,IAIF;AAAA,IACf,OAAO;AAAA,IACP,UAAA1T;AAAA,IACA,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,EAAA;AAIZ;AACA,SAASuV,GAAwBvV,GAAU0T,GAAY;AAWrD,SAViB;AAAA,IACf,OAAO;AAAA,IACP,UAAA1T;AAAA,IACA,YAAY0T,EAAW;AAAA,IACvB,YAAYA,EAAW;AAAA,IACvB,aAAaA,EAAW;AAAA,IACxB,UAAUA,EAAW;AAAA,IACrB,MAAMA,EAAW;AAAA,IACjB,MAAMA,EAAW;AAAA,EAAA;AAGrB;AACA,SAASuE,GAAkBvE,GAAYzJ,GAAO;AAC5C,SAAIyJ,IACY;AAAA,IACZ,OAAO;AAAA,IACP,YAAYA,EAAW;AAAA,IACvB,YAAYA,EAAW;AAAA,IACvB,aAAaA,EAAW;AAAA,IACxB,UAAUA,EAAW;AAAA,IACrB,MAAMA,EAAW;AAAA,IACjB,MAAMA,EAAW;AAAA,IACjB,MAAMzJ;AAAA,EAAA,IAIM;AAAA,IACZ,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAMA;AAAA,EAAA;AAIZ;AACA,SAASuO,GAAqB9E,GAAY4E,GAAiB;AAWzD,SAVc;AAAA,IACZ,OAAO;AAAA,IACP,YAAY5E,EAAW;AAAA,IACvB,YAAYA,EAAW;AAAA,IACvB,aAAaA,EAAW;AAAA,IACxB,UAAUA,EAAW;AAAA,IACrB,MAAMA,EAAW;AAAA,IACjB,MAAMA,EAAW;AAAA,IACjB,MAAM4E,IAAkBA,EAAgB,OAAO;AAAA,EAAA;AAGnD;AACA,SAASS,GAAe9O,GAAO;AAW7B,SAVc;AAAA,IACZ,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAMA;AAAA,EAAA;AAGV;AACA,SAAS2H,GAA0BkU,GAASC,GAAa;AACvD,MAAI;AACF,QAAIC,IAAmBF,EAAQ,eAAe;AAAA,MAC5C9X;AAAA,IAAA;AAEF,QAAIgY,GAAkB;AACpB,UAAItI,IAAO,KAAK,MAAMsI,CAAgB;AACtC,eAAS,CAACjT,GAAGlL,CAAC,KAAK,OAAO,QAAQ6V,KAAQ,CAAA,CAAE;AAC1C,QAAI7V,KAAK,MAAM,QAAQA,CAAC,KACtBke,EAAY,IAAIhT,GAAG,IAAI,IAAIlL,KAAK,CAAA,CAAE,CAAC;AAAA,IAGzC;AAAA,EACF,QAAY;AAAA,EACZ;AACF;AACA,SAASiK,GAA0BgU,GAASC,GAAa;AACvD,MAAIA,EAAY,OAAO,GAAG;AACxB,QAAIrI,IAAO,CAAA;AACX,aAAS,CAAC3K,GAAGlL,CAAC,KAAKke;AACjB,MAAArI,EAAK3K,CAAC,IAAI,CAAC,GAAGlL,CAAC;AAEjB,QAAI;AACF,MAAAie,EAAQ,eAAe;AAAA,QACrB9X;AAAA,QACA,KAAK,UAAU0P,CAAI;AAAA,MAAA;AAAA,IAEvB,SAASlc,GAAO;AACd,MAAA5B;AAAA,QACE;AAAA,QACA,8DAA8D4B,CAAK;AAAA,MAAA;AAAA,IAEvE;AAAA,EACF;AACF;AACA,SAAS8R,KAAiB;AACxB,MAAI/B,GACA0S,GACA1Q,IAAU,IAAI,QAAQ,CAAC0S,GAAKC,MAAQ;AACtC,IAAA3U,IAAU,OAAO4U,MAAQ;AACvB,MAAAF,EAAIE,CAAG;AACP,UAAI;AACF,cAAM5S;AAAA,MACR,QAAY;AAAA,MACZ;AAAA,IACF,GACA0Q,IAAS,OAAOziB,MAAU;AACxB,MAAA0kB,EAAI1kB,CAAK;AACT,UAAI;AACF,cAAM+R;AAAA,MACR,QAAY;AAAA,MACZ;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO;AAAA,IACL,SAAAA;AAAA;AAAA,IAEA,SAAAhC;AAAA;AAAA,IAEA,QAAA0S;AAAA,EAAA;AAEJ;AAIA,IAAImC,KAAoBC,EAAM,cAAc,IAAI;AAChDD,GAAkB,cAAc;AAChC,IAAIE,KAAyBD,EAAM,cAAc,IAAI;AACrDC,GAAuB,cAAc;AACrC,IAAIC,KAAmBF,EAAM,cAAc,EAAK;AAChD,SAASG,KAAwB;AAC/B,SAAOH,EAAM,WAAWE,EAAgB;AAC1C;AACA,IAAIE,KAAwBJ,EAAM,cAAc;AAAA,EAC9C,iBAAiB;AACnB,CAAC;AACDI,GAAsB,cAAc;AACpC,IAAIC,KAAkBL,EAAM;AAAA,sBACN,IAAA;AACtB;AACAK,GAAgB,cAAc;AAC9B,IAAIC,KAAeN,EAAM,cAAc,IAAI;AAC3CM,GAAa,cAAc;AAE3B,IAAIC,KAAoBP,EAAM;AAAA,EAC5B;AACF;AACAO,GAAkB,cAAc;AAChC,IAAIC,KAAkBR,EAAM;AAAA,EAC1B;AACF;AACAQ,GAAgB,cAAc;AAC9B,IAAIC,KAAeT,EAAM,cAAc;AAAA,EACrC,QAAQ;AAAA,EACR,SAAS,CAAA;AAAA,EACT,aAAa;AACf,CAAC;AACDS,GAAa,cAAc;AAC3B,IAAIC,KAAoBV,EAAM,cAAc,IAAI;AAChDU,GAAkB,cAAc;AAOhC,IAAIC,KAAoB,sBACpBC,KAAwB,YACxBC,KAAoC;AACxC,SAASC,GAA0BC,GAAQ;AACzC,MAAIA,EAAO,WAAW,GAAGJ,EAAiB,IAAIC,EAAqB,IAAI;AACrE,QAAI;AACF,UAAII,IAAS,KAAK,MAAMD,EAAO,MAAM,EAAE,CAAC;AACxC,UAAI,OAAOC,KAAW,YAAYA,KAAU,OAAOA,EAAO,UAAW,YAAY,OAAOA,EAAO,cAAe,YAAY,OAAOA,EAAO,YAAa,YAAY,OAAOA,EAAO,kBAAmB,aAAa,OAAOA,EAAO,WAAY;AACvO,eAAOA;AAAA,IAEX,QAAQ;AAAA,IACR;AAEJ;AACA,SAASC,GAA+BF,GAAQ;AAC9C,MAAIA,EAAO;AAAA,IACT,GAAGJ,EAAiB,IAAIE,EAAiC;AAAA,EAAA;AAEzD,QAAI;AACF,UAAIG,IAAS,KAAK,MAAMD,EAAO,MAAM,EAAE,CAAC;AACxC,UAAI,OAAOC,KAAW,YAAYA,KAAU,OAAOA,EAAO,UAAW,YAAY,OAAOA,EAAO,cAAe;AAC5G,eAAO,IAAIvd;AAAA,UACTud,EAAO;AAAA,UACPA,EAAO;AAAA,UACPA,EAAO;AAAA,QAAA;AAAA,IAGb,QAAQ;AAAA,IACR;AAEJ;AAGA,SAASE,GAAQhoB,GAAI,EAAE,UAAAsd,EAAA,IAAa,CAAA,GAAI;AACtC,EAAAnd;AAAA,IACE8nB,GAAA;AAAA;AAAA;AAAA,IAGA;AAAA,EAAA;AAEF,MAAI,EAAE,UAAA/jB,GAAU,WAAAgkB,EAAA,IAAcC,EAAO,WAAWd,EAAiB,GAC7D,EAAE,MAAAxnB,GAAM,UAAAF,GAAU,QAAAC,EAAA,IAAWwoB,GAAgBpoB,GAAI,EAAE,UAAAsd,GAAU,GAC7D+K,IAAiB1oB;AACrB,SAAIuE,MAAa,QACfmkB,IAAiB1oB,MAAa,MAAMuE,IAAWsB,GAAU,CAACtB,GAAUvE,CAAQ,CAAC,IAExEuoB,EAAU,WAAW,EAAE,UAAUG,GAAgB,QAAAzoB,GAAQ,MAAAC,GAAM;AACxE;AACA,SAASooB,KAAqB;AAC5B,SAAOE,EAAO,WAAWb,EAAe,KAAK;AAC/C;AACA,SAASgB,KAAc;AACrB,SAAAnoB;AAAA,IACE8nB,GAAA;AAAA;AAAA;AAAA,IAGA;AAAA,EAAA,GAEKE,EAAO,WAAWb,EAAe,EAAE;AAC5C;AAiBA,IAAIiB,KAAwB;AAC5B,SAASC,GAA0BnE,GAAI;AAErC,EADe8D,EAAO,WAAWd,EAAiB,EAAE,UAElDc,EAAO,gBAAgB9D,CAAE;AAE7B;AACA,SAASoE,KAAc;AACrB,MAAI,EAAE,aAAAC,EAAA,IAAgBP,EAAO,WAAWZ,EAAY;AACpD,SAAOmB,IAAcC,GAAA,IAAsBC,GAAA;AAC7C;AACA,SAASA,KAAsB;AAC7B,EAAAzoB;AAAA,IACE8nB,GAAA;AAAA;AAAA;AAAA,IAGA;AAAA,EAAA;AAEF,MAAIY,IAAoBV,EAAO,WAAWtB,EAAiB,GACvD,EAAE,UAAA3iB,GAAU,WAAAgkB,EAAA,IAAcC,EAAO,WAAWd,EAAiB,GAC7D,EAAE,SAAA5iB,EAAA,IAAY0jB,EAAO,WAAWZ,EAAY,GAC5C,EAAE,UAAUzd,EAAA,IAAqBwe,GAAA,GACjCQ,IAAqB,KAAK,UAAUtf,GAAoB/E,CAAO,CAAC,GAChEskB,IAAYZ,EAAO,OAAO,EAAK;AACnC,SAAAK,GAA0B,MAAM;AAC9B,IAAAO,EAAU,UAAU;AAAA,EACtB,CAAC,GACcZ,EAAO;AAAA,IACpB,CAACnoB,GAAIT,IAAU,OAAO;AAEpB,UADAc,GAAQ0oB,EAAU,SAASR,EAAqB,GAC5C,CAACQ,EAAU,QAAS;AACxB,UAAI,OAAO/oB,KAAO,UAAU;AAC1B,QAAAkoB,EAAU,GAAGloB,CAAE;AACf;AAAA,MACF;AACA,UAAIe,IAAO4I;AAAA,QACT3J;AAAA,QACA,KAAK,MAAM8oB,CAAkB;AAAA,QAC7Bhf;AAAA,QACAvK,EAAQ,aAAa;AAAA,MAAA;AAEvB,MAAIspB,KAAqB,QAAQ3kB,MAAa,QAC5CnD,EAAK,WAAWA,EAAK,aAAa,MAAMmD,IAAWsB,GAAU,CAACtB,GAAUnD,EAAK,QAAQ,CAAC,KAErFxB,EAAQ,UAAU2oB,EAAU,UAAUA,EAAU;AAAA,QACjDnnB;AAAA,QACAxB,EAAQ;AAAA,QACRA;AAAA,MAAA;AAAA,IAEJ;AAAA,IACA;AAAA,MACE2E;AAAA,MACAgkB;AAAA,MACAY;AAAA,MACAhf;AAAA,MACA+e;AAAA,IAAA;AAAA,EACF;AAGJ;AACoBV,EAAO,cAAc,IAAI;AAW7C,SAASa,KAAY;AACnB,MAAI,EAAE,SAAAvkB,EAAA,IAAY0jB,EAAO,WAAWZ,EAAY,GAC5C0B,IAAaxkB,EAAQA,EAAQ,SAAS,CAAC;AAC3C,SAAOwkB,IAAaA,EAAW,SAAS,CAAA;AAC1C;AACA,SAASb,GAAgBpoB,GAAI,EAAE,UAAAsd,EAAA,IAAa,CAAA,GAAI;AAC9C,MAAI,EAAE,SAAA7Y,EAAA,IAAY0jB,EAAO,WAAWZ,EAAY,GAC5C,EAAE,UAAUzd,EAAA,IAAqBwe,GAAA,GACjCQ,IAAqB,KAAK,UAAUtf,GAAoB/E,CAAO,CAAC;AACpE,SAAO0jB,EAAO;AAAA,IACZ,MAAMxe;AAAA,MACJ3J;AAAA,MACA,KAAK,MAAM8oB,CAAkB;AAAA,MAC7Bhf;AAAA,MACAwT,MAAa;AAAA,IAAA;AAAA,IAEf,CAACtd,GAAI8oB,GAAoBhf,GAAkBwT,CAAQ;AAAA,EAAA;AAEvD;AAIA,SAAS4L,GAAc7lB,GAAQY,GAAaklB,GAAiBC,GAASha,GAAQ;AAC5E,EAAAjP;AAAA,IACE8nB,GAAA;AAAA;AAAA;AAAA,IAGA;AAAA,EAAA;AAEF,MAAI,EAAE,WAAAC,EAAA,IAAcC,EAAO,WAAWd,EAAiB,GACnD,EAAE,SAASgC,EAAA,IAAkBlB,EAAO,WAAWZ,EAAY,GAC3D0B,IAAaI,EAAcA,EAAc,SAAS,CAAC,GACnDC,IAAeL,IAAaA,EAAW,SAAS,CAAA,GAChDM,IAAiBN,IAAaA,EAAW,WAAW,KACpDO,IAAqBP,IAAaA,EAAW,eAAe,KAC5DQ,IAAcR,KAAcA,EAAW;AAClB;AACvB,QAAI1lB,IAAakmB,KAAeA,EAAY,QAAQ;AACpD,IAAAC;AAAA,MACEH;AAAA,MACA,CAACE,KAAelmB,EAAW,SAAS,GAAG,KAAKA,EAAW,SAAS,IAAI;AAAA,MACpE,oEAAoEgmB,CAAc,yBAAyBhmB,CAAU;AAAA;AAAA,wCAEnFA,CAAU,sBAAsBA,MAAe,MAAM,MAAM,GAAGA,CAAU,IAAI;AAAA,IAAA;AAAA,EAElH;AACA,MAAIomB,IAAsBrB,GAAA,GACtB7nB;AASF,EAAAA,IAAWkpB;AAEb,MAAIhqB,IAAWc,EAAS,YAAY,KAChC8G,IAAoB5H;AACxB,MAAI6pB,MAAuB,KAAK;AAC9B,QAAII,IAAiBJ,EAAmB,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG;AAEpE,IAAAjiB,IAAoB,MADL5H,EAAS,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG,EACjB,MAAMiqB,EAAe,MAAM,EAAE,KAAK,GAAG;AAAA,EAC1E;AACA,MAAInlB,IAAUT,GAAYX,GAAQ,EAAE,UAAUkE,GAAmB;AAE/D,SAAAlH;AAAA,IACEopB,KAAehlB,KAAW;AAAA,IAC1B,+BAA+BhE,EAAS,QAAQ,GAAGA,EAAS,MAAM,GAAGA,EAAS,IAAI;AAAA,EAAA,GAEpFJ;AAAA,IACEoE,KAAW,QAAQA,EAAQA,EAAQ,SAAS,CAAC,EAAE,MAAM,YAAY,UAAUA,EAAQA,EAAQ,SAAS,CAAC,EAAE,MAAM,cAAc,UAAUA,EAAQA,EAAQ,SAAS,CAAC,EAAE,MAAM,SAAS;AAAA,IAChL,mCAAmChE,EAAS,QAAQ,GAAGA,EAAS,MAAM,GAAGA,EAAS,IAAI;AAAA,EAAA,GAGpEopB;AAAA,IACpBplB,KAAWA,EAAQ;AAAA,MACjB,CAACM,MAAU,OAAO,OAAO,CAAA,GAAIA,GAAO;AAAA,QAClC,QAAQ,OAAO,OAAO,CAAA,GAAIukB,GAAcvkB,EAAM,MAAM;AAAA,QACpD,UAAUS,GAAU;AAAA,UAClBgkB;AAAA;AAAA;AAAA;AAAA;AAAA,UAKAtB,EAAU,iBAAiBA,EAAU;AAAA,YACnCnjB,EAAM,SAAS,QAAQ,OAAO,KAAK,EAAE,QAAQ,MAAM,KAAK;AAAA,UAAA,EACxD,WAAWA,EAAM;AAAA,QAAA,CACpB;AAAA,QACD,cAAcA,EAAM,iBAAiB,MAAMykB,IAAqBhkB,GAAU;AAAA,UACxEgkB;AAAA;AAAA;AAAA;AAAA;AAAA,UAKAtB,EAAU,iBAAiBA,EAAU;AAAA,YACnCnjB,EAAM,aAAa,QAAQ,OAAO,KAAK,EAAE,QAAQ,MAAM,KAAK;AAAA,UAAA,EAC5D,WAAWA,EAAM;AAAA,QAAA,CACpB;AAAA,MAAA,CACF;AAAA,IAAA;AAAA,IAEHskB;AAAA,IACAF;AAAA,IACAC;AAAA,IACAha;AAAA,EAAA;AAsBJ;AACA,SAAS0a,KAAwB;AAC/B,MAAI7nB,IAAQ8nB,GAAA,GACR3pB,IAAUwK,GAAqB3I,CAAK,IAAI,GAAGA,EAAM,MAAM,IAAIA,EAAM,UAAU,KAAKA,aAAiB,QAAQA,EAAM,UAAU,KAAK,UAAUA,CAAK,GAC7I+nB,IAAQ/nB,aAAiB,QAAQA,EAAM,QAAQ,MAC/CgoB,IAAY,0BACZC,IAAY,EAAE,SAAS,UAAU,iBAAiBD,EAAA,GAClDE,IAAa,EAAE,SAAS,WAAW,iBAAiBF,EAAA,GACpDG,IAAU;AAEZ,iBAAQ;AAAA,IACN;AAAA,IACAnoB;AAAA,EAAA,GAEFmoB,sBAAiC,cAAcjC,EAAO,UAAU,wBAA6B,cAAc,KAAK,MAAM,qBAAmC,GAAmBA,gBAAAA,EAAO,cAAc,KAAK,MAAM,gGAAgHA,gBAAAA,EAAO,cAAc,QAAQ,EAAE,OAAOgC,EAAA,GAAc,eAAe,GAAG,OAAO,KAAqBhC,gBAAAA,EAAO,cAAc,QAAQ,EAAE,OAAOgC,EAAA,GAAc,cAAc,GAAG,sBAAsB,CAAC,GAErehC,gBAAAA,EAAO,cAAcA,EAAO,UAAU,MAAsBA,gBAAAA,EAAO,cAAc,MAAM,MAAM,+BAA+B,GAAmBA,gBAAAA,EAAO,cAAc,MAAM,EAAE,OAAO,EAAE,WAAW,SAAA,EAAS,GAAK/nB,CAAO,GAAG4pB,IAAwB7B,gBAAAA,EAAO,cAAc,OAAO,EAAE,OAAO+B,EAAA,GAAaF,CAAK,IAAI,MAAMI,CAAO;AACjV;AACA,IAAIC,KAAsClC,gBAAAA,EAAO,cAAc2B,IAAuB,IAAI,GACtFQ,KAAsB,cAAcnC,EAAO,UAAU;AAAA,EACvD,YAAYoC,GAAO;AACjB,UAAMA,CAAK,GACX,KAAK,QAAQ;AAAA,MACX,UAAUA,EAAM;AAAA,MAChB,cAAcA,EAAM;AAAA,MACpB,OAAOA,EAAM;AAAA,IAAA;AAAA,EAEjB;AAAA,EACA,OAAO,yBAAyBtoB,GAAO;AACrC,WAAO,EAAE,OAAAA,EAAA;AAAA,EACX;AAAA,EACA,OAAO,yBAAyBsoB,GAAO3pB,GAAO;AAC5C,WAAIA,EAAM,aAAa2pB,EAAM,YAAY3pB,EAAM,iBAAiB,UAAU2pB,EAAM,iBAAiB,SACxF;AAAA,MACL,OAAOA,EAAM;AAAA,MACb,UAAUA,EAAM;AAAA,MAChB,cAAcA,EAAM;AAAA,IAAA,IAGjB;AAAA,MACL,OAAOA,EAAM,UAAU,SAASA,EAAM,QAAQ3pB,EAAM;AAAA,MACpD,UAAUA,EAAM;AAAA,MAChB,cAAc2pB,EAAM,gBAAgB3pB,EAAM;AAAA,IAAA;AAAA,EAE9C;AAAA,EACA,kBAAkBqB,GAAOuoB,GAAW;AAClC,IAAI,KAAK,MAAM,UACb,KAAK,MAAM,QAAQvoB,GAAOuoB,CAAS,IAEnC,QAAQ;AAAA,MACN;AAAA,MACAvoB;AAAA,IAAA;AAAA,EAGN;AAAA,EACA,SAAS;AACP,QAAIA,IAAQ,KAAK,MAAM;AACvB,QAAI,KAAK,WAAW,OAAOA,KAAU,YAAYA,KAAS,YAAYA,KAAS,OAAOA,EAAM,UAAW,UAAU;AAC/G,YAAM0C,IAAUojB,GAA+B9lB,EAAM,MAAM;AAC3D,MAAI0C,MAAS1C,IAAQ0C;AAAA,IACvB;AACA,QAAIwB,IAASlE,MAAU,SAAyBkmB,gBAAAA,EAAO,cAAcZ,GAAa,UAAU,EAAE,OAAO,KAAK,MAAM,aAAA,GAAgCY,gBAAAA,EAAO;AAAA,MACrJX,GAAkB;AAAA,MAClB;AAAA,QACE,OAAOvlB;AAAA,QACP,UAAU,KAAK,MAAM;AAAA,MAAA;AAAA,IACvB,CACD,IAAI,KAAK,MAAM;AAChB,WAAI,KAAK,4BACuB,cAAcwoB,IAAiB,EAAE,OAAAxoB,EAAA,GAASkE,CAAM,IAEzEA;AAAA,EACT;AACF;AACAmkB,GAAoB,cAActD;AAClC,IAAI0D,yBAA8C,QAAA;AAClD,SAASD,GAAgB;AAAA,EACvB,UAAA9N;AAAA,EACA,OAAA1a;AACF,GAAG;AACD,MAAI,EAAE,UAAAiC,EAAA,IAAaikB,EAAO,WAAWd,EAAiB;AACtD,MAAI,OAAOplB,KAAU,YAAYA,KAAS,YAAYA,KAAS,OAAOA,EAAM,UAAW,UAAU;AAC/F,QAAIiW,IAAY0P,GAA0B3lB,EAAM,MAAM;AACtD,QAAIiW,GAAW;AACb,UAAIyS,IAAmBD,GAAwB,IAAIzoB,CAAK;AACxD,UAAI0oB,EAAkB,OAAMA;AAC5B,UAAI7C,IAAS9c,GAAYkN,EAAU,UAAUhU,CAAQ;AACrD,UAAI6G,MAAa,CAAC2f,GAAwB,IAAIzoB,CAAK;AACjD,YAAI6lB,EAAO,cAAc5P,EAAU;AACjC,iBAAO,SAAS,OAAO4P,EAAO,eAAeA,EAAO;AAAA,aAC/C;AACL,gBAAM8C,IAAkB,QAAQ,QAAA,EAAU;AAAA,YACxC,MAAM,OAAO,wBAAwB,SAAS9C,EAAO,IAAI;AAAA,cACvD,SAAS5P,EAAU;AAAA,YAAA,CACpB;AAAA,UAAA;AAEH,gBAAAwS,GAAwB,IAAIzoB,GAAO2oB,CAAe,GAC5CA;AAAA,QACR;AAEF,aAAuBzC,gBAAAA,EAAO;AAAA,QAC5B;AAAA,QACA;AAAA,UACE,WAAW;AAAA,UACX,SAAS,SAASL,EAAO,eAAeA,EAAO,EAAE;AAAA,QAAA;AAAA,MACnD;AAAA,IAEJ;AAAA,EACF;AACA,SAAOnL;AACT;AACA,SAASkO,GAAc,EAAE,cAAAC,GAAc,OAAA/lB,GAAO,UAAA4X,KAAY;AACxD,MAAIkM,IAAoBV,EAAO,WAAWtB,EAAiB;AAC3D,SAAIgC,KAAqBA,EAAkB,UAAUA,EAAkB,kBAAkB9jB,EAAM,MAAM,gBAAgBA,EAAM,MAAM,mBAC/H8jB,EAAkB,cAAc,6BAA6B9jB,EAAM,MAAM,KAEpDojB,gBAAAA,EAAO,cAAcZ,GAAa,UAAU,EAAE,OAAOuD,EAAA,GAAgBnO,CAAQ;AACtG;AACA,SAASkN,GAAeplB,GAAS4kB,IAAgB,IAAIF,IAAkB,MAAM4B,IAAiB,MAAM3b,IAAS,MAAM;AACjH,MAAI3K,KAAW,MAAM;AACnB,QAAI,CAAC0kB;AACH,aAAO;AAET,QAAIA,EAAgB;AAClB,MAAA1kB,IAAU0kB,EAAgB;AAAA,aACjBE,EAAc,WAAW,KAAK,CAACF,EAAgB,eAAeA,EAAgB,QAAQ,SAAS;AACxG,MAAA1kB,IAAU0kB,EAAgB;AAAA;AAE1B,aAAO;AAAA,EAEX;AACA,MAAI6B,IAAkBvmB,GAClB0L,IAASgZ,GAAiB;AAC9B,MAAIhZ,KAAU,MAAM;AAClB,QAAI8a,IAAaD,EAAgB;AAAA,MAC/B,CAAClgB,MAAMA,EAAE,MAAM,MAAMqF,IAASrF,EAAE,MAAM,EAAE,MAAM;AAAA,IAAA;AAEhD,IAAA3K;AAAA,MACE8qB,KAAc;AAAA,MACd,4DAA4D,OAAO;AAAA,QACjE9a;AAAA,MAAA,EACA,KAAK,GAAG,CAAC;AAAA,IAAA,GAEb6a,IAAkBA,EAAgB;AAAA,MAChC;AAAA,MACA,KAAK,IAAIA,EAAgB,QAAQC,IAAa,CAAC;AAAA,IAAA;AAAA,EAEnD;AACA,MAAIC,IAAiB,IACjBC,IAAgB;AACpB,MAAIhC;AACF,aAASzkB,IAAI,GAAGA,IAAIsmB,EAAgB,QAAQtmB,KAAK;AAC/C,UAAIK,IAAQimB,EAAgBtmB,CAAC;AAI7B,WAHIK,EAAM,MAAM,mBAAmBA,EAAM,MAAM,4BAC7ComB,IAAgBzmB,IAEdK,EAAM,MAAM,IAAI;AAClB,YAAI,EAAE,YAAAC,GAAY,QAAQomB,EAAA,IAAYjC,GAClCkC,IAAmBtmB,EAAM,MAAM,UAAU,CAACC,EAAW,eAAeD,EAAM,MAAM,EAAE,MAAM,CAACqmB,KAAWA,EAAQrmB,EAAM,MAAM,EAAE,MAAM;AACpI,YAAIA,EAAM,MAAM,QAAQsmB,GAAkB;AACxC,UAAAH,IAAiB,IACbC,KAAiB,IACnBH,IAAkBA,EAAgB,MAAM,GAAGG,IAAgB,CAAC,IAE5DH,IAAkB,CAACA,EAAgB,CAAC,CAAC;AAEvC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEF,MAAI5B,IAAUD,KAAmB4B,IAAiB,CAAC9oB,GAAOuoB,MAAc;AACtE,IAAAO,EAAe9oB,GAAO;AAAA,MACpB,UAAUknB,EAAgB;AAAA,MAC1B,QAAQA,EAAgB,UAAU,CAAC,GAAG,UAAU,CAAA;AAAA,MAChD,kBAAkBte,GAAgBse,EAAgB,OAAO;AAAA,MACzD,WAAAqB;AAAA,IAAA,CACD;AAAA,EACH,IAAI;AACJ,SAAOQ,EAAgB;AAAA,IACrB,CAACM,GAAQvmB,GAAOrE,MAAU;AACxB,UAAIuB,GACAspB,IAA8B,IAC9BC,IAAe,MACfC,IAAyB;AAC7B,MAAItC,MACFlnB,IAAQkO,KAAUpL,EAAM,MAAM,KAAKoL,EAAOpL,EAAM,MAAM,EAAE,IAAI,QAC5DymB,IAAezmB,EAAM,MAAM,gBAAgBslB,IACvCa,MACEC,IAAgB,KAAKzqB,MAAU,KACjCgpB;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MAAA,GAEF6B,IAA8B,IAC9BE,IAAyB,QAChBN,MAAkBzqB,MAC3B6qB,IAA8B,IAC9BE,IAAyB1mB,EAAM,MAAM,0BAA0B;AAIrE,UAAIoR,IAAWkT,EAAc,OAAO2B,EAAgB,MAAM,GAAGtqB,IAAQ,CAAC,CAAC,GACnEgrB,IAAc,MAAM;AACtB,YAAI/O;AACJ,eAAI1a,IACF0a,IAAW6O,IACFD,IACT5O,IAAW8O,IACF1mB,EAAM,MAAM,YACrB4X,IAA2BwL,gBAAAA,EAAO,cAAcpjB,EAAM,MAAM,WAAW,IAAI,IAClEA,EAAM,MAAM,UACrB4X,IAAW5X,EAAM,MAAM,UAEvB4X,IAAW2O,GAEUnD,gBAAAA,EAAO;AAAA,UAC5B0C;AAAA,UACA;AAAA,YACE,OAAA9lB;AAAA,YACA,cAAc;AAAA,cACZ,QAAAumB;AAAA,cACA,SAASnV;AAAA,cACT,aAAagT,KAAmB;AAAA,YAAA;AAAA,YAElC,UAAAxM;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AACA,aAAOwM,MAAoBpkB,EAAM,MAAM,iBAAiBA,EAAM,MAAM,gBAAgBrE,MAAU,KAAqBynB,gBAAAA,EAAO;AAAA,QACxHmC;AAAA,QACA;AAAA,UACE,UAAUnB,EAAgB;AAAA,UAC1B,cAAcA,EAAgB;AAAA,UAC9B,WAAWqC;AAAA,UACX,OAAAvpB;AAAA,UACA,UAAUypB,EAAA;AAAA,UACV,cAAc,EAAE,QAAQ,MAAM,SAASvV,GAAU,aAAa,GAAA;AAAA,UAC9D,SAAAiT;AAAA,QAAA;AAAA,MACF,IACEsC,EAAA;AAAA,IACN;AAAA,IACA;AAAA,EAAA;AAEJ;AACA,SAASC,GAA0BC,GAAU;AAC3C,SAAO,GAAGA,CAAQ;AACpB;AACA,SAASC,GAAqBD,GAAU;AACtC,MAAIje,IAAMwa,EAAO,WAAWtB,EAAiB;AAC7C,SAAA1mB,EAAUwN,GAAKge,GAA0BC,CAAQ,CAAC,GAC3Cje;AACT;AACA,SAASme,GAAmBF,GAAU;AACpC,MAAIhrB,IAAQunB,EAAO,WAAWpB,EAAsB;AACpD,SAAA5mB,EAAUS,GAAO+qB,GAA0BC,CAAQ,CAAC,GAC7ChrB;AACT;AACA,SAASmrB,GAAgBH,GAAU;AACjC,MAAIzoB,IAAQglB,EAAO,WAAWZ,EAAY;AAC1C,SAAApnB,EAAUgD,GAAOwoB,GAA0BC,CAAQ,CAAC,GAC7CzoB;AACT;AACA,SAAS6oB,GAAkBJ,GAAU;AACnC,MAAIzoB,IAAQ4oB,GAAgBH,CAAQ,GAChCK,IAAY9oB,EAAM,QAAQA,EAAM,QAAQ,SAAS,CAAC;AACtD,SAAAhD;AAAA,IACE8rB,EAAU,MAAM;AAAA,IAChB,GAAGL,CAAQ;AAAA,EAAA,GAENK,EAAU,MAAM;AACzB;AACA,SAASC,KAAa;AACpB,SAAOF;AAAA,IAAkB;AAAA;AAAA,EAAA;AAC3B;AAuCA,SAASjC,KAAgB;AACvB,MAAI9nB,IAAQkmB,EAAO,WAAWX,EAAiB,GAC3C5mB,IAAQkrB;AAAA,IAAmB;AAAA;AAAA,EAAA,GAC3BxW,IAAU0W;AAAA,IAAkB;AAAA;AAAA,EAAA;AAChC,SAAI/pB,MAAU,SACLA,IAEFrB,EAAM,SAAS0U,CAAO;AAC/B;AAiDA,SAASqT,KAAoB;AAC3B,MAAI,EAAE,QAAArc,MAAWuf;AAAA,IAAqB;AAAA;AAAA,EAAA,GAClCloB,IAAKqoB;AAAA,IAAkB;AAAA;AAAA,EAAA,GACvBjD,IAAYZ,EAAO,OAAO,EAAK;AACnC,SAAAK,GAA0B,MAAM;AAC9B,IAAAO,EAAU,UAAU;AAAA,EACtB,CAAC,GACcZ,EAAO;AAAA,IACpB,OAAOnoB,GAAIT,IAAU,OAAO;AAE1B,MADAc,GAAQ0oB,EAAU,SAASR,EAAqB,GAC3CQ,EAAU,YACX,OAAO/oB,KAAO,WAChB,MAAMsM,EAAO,SAAStM,CAAE,IAExB,MAAMsM,EAAO,SAAStM,GAAI,EAAE,aAAa2D,GAAI,GAAGpE,GAAS;AAAA,IAE7D;AAAA,IACA,CAAC+M,GAAQ3I,CAAE;AAAA,EAAA;AAGf;AACA,IAAIwoB,KAAgB,CAAA;AACpB,SAASzC,GAAY7oB,GAAKP,GAAMF,GAAS;AACvC,EAAI,CAACE,KAAQ,CAAC6rB,GAActrB,CAAG,MAC7BsrB,GAActrB,CAAG,IAAI,IACrBR,GAAQ,IAAOD,CAAO;AAE1B;AAoBA,IAAIgsB,KAAiB,CAAA;AACrB,SAASC,GAASC,GAAWlsB,GAAS;AACpC,EAAI,CAACksB,KAAa,CAACF,GAAehsB,CAAO,MACvCgsB,GAAehsB,CAAO,IAAI,IAC1B,QAAQ,KAAKA,CAAO;AAExB;AAGA,IAAImsB,KAAiB,iBACjBC,KAAoBC,EAAOF,EAAc,GACzCG,KAA4B,MAAA;AAAA;AAChC,SAASC,GAAkB/F,GAAK;AAC9B,SAAI4F,KACKA,GAAkB5F,CAAG,IAErB,CAACA,GAAK8F,EAAyB;AAE1C;AACA,SAASE,GAAmBzpB,GAAO;AACjC,MAAIY,IAAU;AAAA;AAAA;AAAA,IAGZ,kBAAkBZ,EAAM,oBAAoBA,EAAM,iBAAiB,QAAQA,EAAM,gBAAgB;AAAA,EAAA;AAEnG,SAAIA,EAAM,cAEFA,EAAM,WACR9C;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAIN,OAAO,OAAO0D,GAAS;AAAA,IACrB,SAAS0oB,EAAO,cAActpB,EAAM,SAAS;AAAA,IAC7C,WAAW;AAAA,EAAA,CACZ,IAECA,EAAM,oBAEFA,EAAM,0BACR9C;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAIN,OAAO,OAAO0D,GAAS;AAAA,IACrB,wBAAwB0oB,EAAO,cAActpB,EAAM,eAAe;AAAA,IAClE,iBAAiB;AAAA,EAAA,CAClB,IAECA,EAAM,kBAEFA,EAAM,gBACR9C;AAAA,IACE;AAAA,IACA;AAAA,EAAA,GAIN,OAAO,OAAO0D,GAAS;AAAA,IACrB,cAAc0oB,EAAO,cAActpB,EAAM,aAAa;AAAA,IACtD,eAAe;AAAA,EAAA,CAChB,IAEIY;AACT;AACA,IAAI8oB,KAA2B;AAAA,EAC7B;AAAA,EACA;AACF,GAmBIC,KAAW,MAAM;AAAA,EACnB,cAAc;AACZ,SAAK,SAAS,WACd,KAAK,UAAU,IAAI,QAAQ,CAAC9a,GAAS0S,MAAW;AAC9C,WAAK,UAAU,CAACtlB,MAAU;AACxB,QAAI,KAAK,WAAW,cAClB,KAAK,SAAS,YACd4S,EAAQ5S,CAAK;AAAA,MAEjB,GACA,KAAK,SAAS,CAACkc,MAAW;AACxB,QAAI,KAAK,WAAW,cAClB,KAAK,SAAS,YACdoJ,EAAOpJ,CAAM;AAAA,MAEjB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AACA,SAASyR,GAAe;AAAA,EACtB,QAAAzgB;AAAA,EACA,WAAW0gB;AAAA,EACX,SAAA5D;AAAA,EACA,yBAAA6D;AACF,GAAG;AAED,EAAAA,IADmBhG,GAAA,KACuBgG;AAC1C,MAAI,CAACC,GAAQC,CAAY,IAAIV,EAAO,SAASngB,EAAO,KAAK,GACrD,CAAC1L,GAAOwsB,CAAkB,IAAIT,GAAkBO,CAAM,GACtD,CAACG,GAAcC,CAAe,IAAIb,EAAO,SAAA,GACzC,CAACc,GAAWC,CAAY,IAAIf,EAAO,SAAS;AAAA,IAC9C,iBAAiB;AAAA,EAAA,CAClB,GACG,CAACgB,GAAWC,CAAY,IAAIjB,EAAO,SAAA,GACnC,CAACkB,GAAYC,CAAa,IAAInB,EAAO,SAAA,GACrC,CAACoB,GAAcC,CAAe,IAAIrB,EAAO,SAAA,GACzCsB,IAActB,EAAO,OAAuB,oBAAI,KAAK,GACrDuB,IAAWvB,EAAO;AAAA,IACpB,CAAC7Z,GAAU,EAAE,iBAAAqb,GAAiB,WAAAC,GAAW,WAAA/a,GAAW,oBAAAS,QAAyB;AAC3E,MAAIsa,KAAa9E,KACf,OAAO,OAAO8E,CAAS,EAAE;AAAA,QACvB,CAACjsB,MAAUmnB,EAAQnnB,GAAO;AAAA,UACxB,UAAU2Q,EAAS;AAAA,UACnB,QAAQA,EAAS,QAAQ,CAAC,GAAG,UAAU,CAAA;AAAA,UACvC,kBAAkB/H,GAAgB+H,EAAS,OAAO;AAAA,QAAA,CACnD;AAAA,MAAA,GAGLA,EAAS,SAAS,QAAQ,CAACI,GAASnS,MAAQ;AAC1C,QAAImS,EAAQ,SAAS,UACnB+a,EAAY,QAAQ,IAAIltB,GAAKmS,EAAQ,IAAI;AAAA,MAE7C,CAAC,GACDib,EAAgB,QAAQ,CAACptB,MAAQktB,EAAY,QAAQ,OAAOltB,CAAG,CAAC,GAChEwrB;AAAA,QACElZ,MAAc,MAAS6Z,KAAyB;AAAA,QAChD;AAAA,MAAA;AAEF,UAAImB,KAA4B7hB,EAAO,UAAU,QAAQA,EAAO,OAAO,YAAY,QAAQ,OAAOA,EAAO,OAAO,SAAS,uBAAwB;AAKjJ,UAJA+f;AAAA,QACEzY,KAAsB,QAAQua;AAAA,QAC9B;AAAA,MAAA,GAEE,CAACva,KAAsB,CAACua,IAA2B;AACrD,QAAInB,KAAyB7Z,IAC3B6Z,EAAsB,MAAMG,EAAava,CAAQ,CAAC,IACzCqa,MAA4B,KACrCE,EAAava,CAAQ,IAErB6Z,EAAO,gBAAgB,MAAM;AAC3B,UAAIQ,MAA4B,MAC9BG,EAAmB,CAACrmB,MAAMqnB,GAAyBrnB,GAAG6L,CAAQ,CAAC,GAEjEua,EAAava,CAAQ;AAAA,QACvB,CAAC;AAEH;AAAA,MACF;AACA,UAAIoa,KAAyB7Z,GAAW;AACtC,QAAA6Z,EAAsB,MAAM;AAC1B,UAAIW,MACFF,GAAW,QAAA,GACXE,EAAW,eAAA,IAEbH,EAAa;AAAA,YACX,iBAAiB;AAAA,YACjB,WAAW;AAAA,YACX,iBAAiB5Z,EAAmB;AAAA,YACpC,cAAcA,EAAmB;AAAA,UAAA,CAClC;AAAA,QACH,CAAC;AACD,YAAIya,IAAI/hB,EAAO,OAAO,SAAS,oBAAoB,MAAM;AACvD,UAAA0gB,EAAsB,MAAMG,EAAava,CAAQ,CAAC;AAAA,QACpD,CAAC;AACD,QAAAyb,EAAE,SAAS,QAAQ,MAAM;AACvB,UAAArB,EAAsB,MAAM;AAC1B,YAAAU,EAAa,MAAM,GACnBE,EAAc,MAAM,GACpBN,EAAgB,MAAM,GACtBE,EAAa,EAAE,iBAAiB,IAAO;AAAA,UACzC,CAAC;AAAA,QACH,CAAC,GACDR,EAAsB,MAAMY,EAAcS,CAAC,CAAC;AAC5C;AAAA,MACF;AACA,MAAIV,KACFF,GAAW,QAAA,GACXE,EAAW,eAAA,GACXG,EAAgB;AAAA,QACd,OAAOlb;AAAA,QACP,iBAAiBgB,EAAmB;AAAA,QACpC,cAAcA,EAAmB;AAAA,MAAA,CAClC,MAED0Z,EAAgB1a,CAAQ,GACxB4a,EAAa;AAAA,QACX,iBAAiB;AAAA,QACjB,WAAW;AAAA,QACX,iBAAiB5Z,EAAmB;AAAA,QACpC,cAAcA,EAAmB;AAAA,MAAA,CAClC;AAAA,IAEL;AAAA,IACA;AAAA,MACEtH,EAAO;AAAA,MACP0gB;AAAA,MACAW;AAAA,MACAF;AAAA,MACAR;AAAA,MACAG;AAAA,MACAhE;AAAA,IAAA;AAAA,EACF;AAEF,EAAAqD,EAAO,gBAAgB,MAAMngB,EAAO,UAAU0hB,CAAQ,GAAG,CAAC1hB,GAAQ0hB,CAAQ,CAAC,GAC3EvB,EAAO,UAAU,MAAM;AACrB,IAAIc,EAAU,mBAAmB,CAACA,EAAU,aAC1CG,EAAa,IAAIZ,IAAU;AAAA,EAE/B,GAAG,CAACS,CAAS,CAAC,GACdd,EAAO,UAAU,MAAM;AACrB,QAAIgB,KAAaJ,KAAgB/gB,EAAO,QAAQ;AAC9C,UAAIsG,IAAWya,GACXiB,IAAgBb,EAAU,SAC1Bc,IAAcjiB,EAAO,OAAO,SAAS,oBAAoB,YAAY;AACvE,QAAI2gB,MAA4B,KAC9BE,EAAava,CAAQ,IAErB6Z,EAAO,gBAAgB,MAAM;AAC3B,UAAIQ,MAA4B,MAC9BG,EAAmB,CAACrmB,MAAMqnB,GAAyBrnB,GAAG6L,CAAQ,CAAC,GAEjEua,EAAava,CAAQ;AAAA,QACvB,CAAC,GAEH,MAAM0b;AAAA,MACR,CAAC;AACD,MAAAC,EAAY,SAAS,QAAQ,MAAM;AACjC,QAAAb,EAAa,MAAM,GACnBE,EAAc,MAAM,GACpBN,EAAgB,MAAM,GACtBE,EAAa,EAAE,iBAAiB,IAAO;AAAA,MACzC,CAAC,GACDI,EAAcW,CAAW;AAAA,IAC3B;AAAA,EACF,GAAG;AAAA,IACDlB;AAAA,IACAI;AAAA,IACAnhB,EAAO;AAAA,IACP2gB;AAAA,IACAG;AAAA,EAAA,CACD,GACDX,EAAO,UAAU,MAAM;AACrB,IAAIgB,KAAaJ,KAAgBzsB,EAAM,SAAS,QAAQysB,EAAa,SAAS,OAC5EI,EAAU,QAAA;AAAA,EAEd,GAAG,CAACA,GAAWE,GAAY/sB,EAAM,UAAUysB,CAAY,CAAC,GACxDZ,EAAO,UAAU,MAAM;AACrB,IAAI,CAACc,EAAU,mBAAmBM,MAChCP,EAAgBO,EAAa,KAAK,GAClCL,EAAa;AAAA,MACX,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,iBAAiBK,EAAa;AAAA,MAC9B,cAAcA,EAAa;AAAA,IAAA,CAC5B,GACDC,EAAgB,MAAM;AAAA,EAE1B,GAAG,CAACP,EAAU,iBAAiBM,CAAY,CAAC;AAC5C,MAAI3F,IAAYuE,EAAO,QAAQ,OACtB;AAAA,IACL,YAAYngB,EAAO;AAAA,IACnB,gBAAgBA,EAAO;AAAA,IACvB,IAAI,CAAChK,MAAMgK,EAAO,SAAShK,CAAC;AAAA,IAC5B,MAAM,CAACtC,GAAIwuB,GAAQ/hB,MAASH,EAAO,SAAStM,GAAI;AAAA,MAC9C,OAAOwuB;AAAA,MACP,oBAAoB/hB,GAAM;AAAA,IAAA,CAC3B;AAAA,IACD,SAAS,CAACzM,GAAIwuB,GAAQ/hB,MAASH,EAAO,SAAStM,GAAI;AAAA,MACjD,SAAS;AAAA,MACT,OAAOwuB;AAAA,MACP,oBAAoB/hB,GAAM;AAAA,IAAA,CAC3B;AAAA,EAAA,IAEF,CAACH,CAAM,CAAC,GACPpI,IAAWoI,EAAO,YAAY,KAC9Buc,IAAoB4D,EAAO;AAAA,IAC7B,OAAO;AAAA,MACL,QAAAngB;AAAA,MACA,WAAA4b;AAAA,MACA,QAAQ;AAAA,MACR,UAAAhkB;AAAA,MACA,SAAAklB;AAAA,IAAA;AAAA,IAEF,CAAC9c,GAAQ4b,GAAWhkB,GAAUklB,CAAO;AAAA,EAAA;AAEvC,2BAA8B,cAAcqD,EAAO,UAAU,wBAA6B,cAAc5F,GAAkB,UAAU,EAAE,OAAOgC,EAAA,qBAA4C,cAAc9B,GAAuB,UAAU,EAAE,OAAOnmB,EAAA,qBAAgC,cAAcumB,GAAgB,UAAU,EAAE,OAAO4G,EAAY,QAAA,GAA2B,gBAAAtB,EAAO,cAAcvF,GAAsB,UAAU,EAAE,OAAOqG,EAAA,GAA6B,gBAAAd,EAAO;AAAA,IACzcgC;AAAA,IACA;AAAA,MACE,UAAAvqB;AAAA,MACA,UAAUtD,EAAM;AAAA,MAChB,gBAAgBA,EAAM;AAAA,MACtB,WAAAsnB;AAAA,MACA,yBAAA+E;AAAA,IAAA;AAAA,IAEc,gBAAAR,EAAO;AAAA,MACrBiC;AAAA,MACA;AAAA,QACE,QAAQpiB,EAAO;AAAA,QACf,QAAQA,EAAO;AAAA,QACf,OAAA1L;AAAA,QACA,SAAAwoB;AAAA,MAAA;AAAA,IACF;AAAA,EACF,CACD,CAAC,CAAC,CAAC,GAAG,IAAI;AACb;AACA,SAASgF,GAAyBO,GAAc/b,GAAU;AACxD,SAAO;AAAA;AAAA;AAAA;AAAA,IAIL,GAAG+b;AAAA;AAAA;AAAA,IAGH,YAAY/b,EAAS,WAAW,UAAU,SAASA,EAAS,aAAa+b,EAAa;AAAA,IACtF,cAAc/b,EAAS,iBAAiB,SAASA,EAAS,eAAe+b,EAAa;AAAA,IACtF,YAAY/b,EAAS,WAAW,UAAU,eAAeA,EAAS,aAAa+b,EAAa;AAAA,IAC5F,UAAU/b,EAAS;AAAA,EAAA;AAEvB;AACA,IAAI8b,KAAqBjC,EAAO,KAAKmC,EAAU;AAC/C,SAASA,GAAW;AAAA,EAClB,QAAAvrB;AAAA,EACA,QAAA+L;AAAA,EACA,OAAAxO;AAAA,EACA,SAAAwoB;AACF,GAAG;AACD,SAAOF,GAAc7lB,GAAQ,QAAQzC,GAAOwoB,GAASha,CAAM;AAC7D;AAqFA,SAASqf,GAAO;AAAA,EACd,UAAUI,IAAe;AAAA,EACzB,UAAAlS,IAAW;AAAA,EACX,UAAUmS;AAAA,EACV,gBAAAC,IAAiB;AAAA,EACjB,WAAA7G;AAAA,EACA,QAAQ8G,IAAa;AAAA,EACrB,yBAAA/B;AACF,GAAG;AACD,EAAA9sB;AAAA,IACE,CAAC8nB,GAAA;AAAA,IACD;AAAA,EAAA;AAEF,MAAI/jB,IAAW2qB,EAAa,QAAQ,QAAQ,GAAG,GAC3CI,IAAoBxC,EAAO;AAAA,IAC7B,OAAO;AAAA,MACL,UAAAvoB;AAAA,MACA,WAAAgkB;AAAA,MACA,QAAQ8G;AAAA,MACR,yBAAA/B;AAAA,MACA,QAAQ,CAAA;AAAA,IAAC;AAAA,IAEX,CAAC/oB,GAAUgkB,GAAW8G,GAAY/B,CAAuB;AAAA,EAAA;AAE3D,EAAI,OAAO6B,KAAiB,aAC1BA,IAAehuB,GAAUguB,CAAY;AAEvC,MAAI;AAAA,IACF,UAAAnvB,IAAW;AAAA,IACX,QAAAC,IAAS;AAAA,IACT,MAAAC,IAAO;AAAA,IACP,OAAAe,IAAQ;AAAA,IACR,KAAAC,IAAM;AAAA,EAAA,IACJiuB,GACAI,IAAkBzC,EAAO,QAAQ,MAAM;AACzC,QAAI0C,IAAmB9qB,GAAc1E,GAAUuE,CAAQ;AACvD,WAAIirB,KAAoB,OACf,OAEF;AAAA,MACL,UAAU;AAAA,QACR,UAAUA;AAAA,QACV,QAAAvvB;AAAA,QACA,MAAAC;AAAA,QACA,OAAAe;AAAA,QACA,KAAAC;AAAA,MAAA;AAAA,MAEF,gBAAAkuB;AAAA,IAAA;AAAA,EAEJ,GAAG,CAAC7qB,GAAUvE,GAAUC,GAAQC,GAAMe,GAAOC,GAAKkuB,CAAc,CAAC;AAKjE,SAJA1uB;AAAA,IACE6uB,KAAmB;AAAA,IACnB,qBAAqBhrB,CAAQ,oCAAoCvE,CAAQ,GAAGC,CAAM,GAAGC,CAAI;AAAA,EAAA,GAEvFqvB,KAAmB,OACd,yBAEqB,cAAc7H,GAAkB,UAAU,EAAE,OAAO4H,EAAA,GAAqC,gBAAAxC,EAAO,cAAcnF,GAAgB,UAAU,EAAE,UAAA3K,GAAU,OAAOuS,EAAA,CAAiB,CAAC;AAC5M;AA6NA,IAAIE,KAAgB,OAChBC,KAAiB;AACrB,SAASC,GAAcC,GAAQ;AAC7B,SAAO,OAAO,cAAgB,OAAeA,aAAkB;AACjE;AACA,SAASC,GAAgBD,GAAQ;AAC/B,SAAOD,GAAcC,CAAM,KAAKA,EAAO,QAAQ,kBAAkB;AACnE;AACA,SAASE,GAAcF,GAAQ;AAC7B,SAAOD,GAAcC,CAAM,KAAKA,EAAO,QAAQ,kBAAkB;AACnE;AACA,SAASG,GAAeH,GAAQ;AAC9B,SAAOD,GAAcC,CAAM,KAAKA,EAAO,QAAQ,kBAAkB;AACnE;AACA,SAASI,GAAgBC,GAAO;AAC9B,SAAO,CAAC,EAAEA,EAAM,WAAWA,EAAM,UAAUA,EAAM,WAAWA,EAAM;AACpE;AACA,SAASC,GAAuBD,GAAOE,GAAQ;AAC7C,SAAOF,EAAM,WAAW;AAAA,GACvB,CAACE,KAAUA,MAAW;AAAA,EACvB,CAACH,GAAgBC,CAAK;AACxB;AAwBA,IAAIG,KAA6B;AACjC,SAASC,KAA+B;AACtC,MAAID,OAA+B;AACjC,QAAI;AACF,UAAI;AAAA,QACF,SAAS,cAAc,MAAM;AAAA;AAAA,QAE7B;AAAA,MAAA,GAEFA,KAA6B;AAAA,IAC/B,QAAY;AACV,MAAAA,KAA6B;AAAA,IAC/B;AAEF,SAAOA;AACT;AACA,IAAIE,yBAA4C,IAAI;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,SAASC,GAAeC,GAAS;AAC/B,SAAIA,KAAW,QAAQ,CAACF,GAAsB,IAAIE,CAAO,KACvD9vB;AAAA,IACE;AAAA,IACA,IAAI8vB,CAAO,uFAAuFd,EAAc;AAAA,EAAA,GAE3G,QAEFc;AACT;AACA,SAASC,GAAsBN,GAAQ5rB,GAAU;AAC/C,MAAIiiB,GACA5kB,GACA4uB,GACA9R,GACAgS;AACJ,MAAIZ,GAAcK,CAAM,GAAG;AACzB,QAAIQ,IAAOR,EAAO,aAAa,QAAQ;AACvC,IAAAvuB,IAAS+uB,IAAOjsB,GAAcisB,GAAMpsB,CAAQ,IAAI,MAChDiiB,IAAS2J,EAAO,aAAa,QAAQ,KAAKV,IAC1Ce,IAAUD,GAAeJ,EAAO,aAAa,SAAS,CAAC,KAAKT,IAC5DhR,IAAW,IAAI,SAASyR,CAAM;AAAA,EAChC,WAAWN,GAAgBM,CAAM,KAAKJ,GAAeI,CAAM,MAAMA,EAAO,SAAS,YAAYA,EAAO,SAAS,UAAU;AACrH,QAAIS,IAAOT,EAAO;AAClB,QAAIS,KAAQ;AACV,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAGJ,QAAID,IAAOR,EAAO,aAAa,YAAY,KAAKS,EAAK,aAAa,QAAQ;AAK1E,QAJAhvB,IAAS+uB,IAAOjsB,GAAcisB,GAAMpsB,CAAQ,IAAI,MAChDiiB,IAAS2J,EAAO,aAAa,YAAY,KAAKS,EAAK,aAAa,QAAQ,KAAKnB,IAC7Ee,IAAUD,GAAeJ,EAAO,aAAa,aAAa,CAAC,KAAKI,GAAeK,EAAK,aAAa,SAAS,CAAC,KAAKlB,IAChHhR,IAAW,IAAI,SAASkS,GAAMT,CAAM,GAChC,CAACE,MAAgC;AACnC,UAAI,EAAE,MAAA9R,GAAM,MAAA0D,GAAM,OAAAxiB,EAAA,IAAU0wB;AAC5B,UAAIlO,MAAS,SAAS;AACpB,YAAI4O,IAAStS,IAAO,GAAGA,CAAI,MAAM;AACjC,QAAAG,EAAS,OAAO,GAAGmS,CAAM,KAAK,GAAG,GACjCnS,EAAS,OAAO,GAAGmS,CAAM,KAAK,GAAG;AAAA,MACnC,OAAWtS,KACTG,EAAS,OAAOH,GAAM9e,CAAK;AAAA,IAE/B;AAAA,EACF,OAAA;AAAA,QAAWkwB,GAAcQ,CAAM;AAC7B,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAGF,IAAA3J,IAASiJ,IACT7tB,IAAS,MACT4uB,IAAUd,IACVgB,IAAOP;AAAA;AAET,SAAIzR,KAAY8R,MAAY,iBAC1BE,IAAOhS,GACPA,IAAW,SAEN,EAAE,QAAA9c,GAAQ,QAAQ4kB,EAAO,eAAe,SAAAgK,GAAS,UAAA9R,GAAU,MAAAgS,EAAA;AACpE;AAqNwB,OAAO,oBAAoB,OAAO,SAAS,EAAE,KAAA,EAAO,KAAK,IAAI;AA6erF,SAASI,GAAWrxB,GAAOgB,GAAS;AAClC,MAAIhB,MAAU,MAASA,MAAU,QAAQ,OAAOA,IAAU;AACxD,UAAM,IAAI,MAAMgB,CAAO;AAE3B;AA8UA,SAASswB,GAAeC,GAAQzsB,GAAU0sB,GAAoBC,GAAW;AACvE,MAAI7uB,IAAM,OAAO2uB,KAAW,WAAW,IAAI;AAAA,IACzCA;AAAA;AAAA;AAAA,IAGA,OAAO,SAAW,MAAc,0BAA0B,OAAO,SAAS;AAAA,EAAA,IACxEA;AACJ,SAAIC,IACE5uB,EAAI,SAAS,SAAS,GAAG,IAC3BA,EAAI,WAAW,GAAGA,EAAI,QAAQ,KAAK6uB,CAAS,KAE5C7uB,EAAI,WAAW,GAAGA,EAAI,QAAQ,IAAI6uB,CAAS,KAGzC7uB,EAAI,aAAa,MACnBA,EAAI,WAAW,SAAS6uB,CAAS,KACxB3sB,KAAYG,GAAcrC,EAAI,UAAUkC,CAAQ,MAAM,MAC/DlC,EAAI,WAAW,GAAGkC,EAAS,QAAQ,OAAO,EAAE,CAAC,UAAU2sB,CAAS,KAEhE7uB,EAAI,WAAW,GAAGA,EAAI,SAAS,QAAQ,OAAO,EAAE,CAAC,IAAI6uB,CAAS,IAG3D7uB;AACT;AAoKA,eAAe8uB,GAAgB3tB,GAAO4tB,GAAmB;AACvD,MAAI5tB,EAAM,MAAM4tB;AACd,WAAOA,EAAkB5tB,EAAM,EAAE;AAEnC,MAAI;AACF,QAAI6tB,IAAc,MAAM;AAAA;AAAA;AAAA,MAGtB7tB,EAAM;AAAA;AAER,WAAA4tB,EAAkB5tB,EAAM,EAAE,IAAI6tB,GACvBA;AAAA,EACT,SAAS/uB,GAAO;AACd,mBAAQ;AAAA,MACN,gCAAgCkB,EAAM,MAAM;AAAA,IAAA,GAE9C,QAAQ,MAAMlB,CAAK,GACf,OAAO,wBAAwB,OAAO,qBAAqB,WAI/D,OAAO,SAAS,OAAA,GACT,IAAI,QAAQ,MAAM;AAAA,IACzB,CAAC;AAAA,EACH;AACF;AA0EA,SAASgvB,GAAqB1B,GAAQ;AACpC,SAAIA,KAAU,OACL,KAELA,EAAO,QAAQ,OACVA,EAAO,QAAQ,aAAa,OAAOA,EAAO,eAAgB,YAAY,OAAOA,EAAO,cAAe,WAErG,OAAOA,EAAO,OAAQ,YAAY,OAAOA,EAAO,QAAS;AAClE;AACA,eAAe2B,GAAsBzsB,GAASjB,GAAU2tB,GAAc;AACpE,MAAIC,IAAQ,MAAM,QAAQ;AAAA,IACxB3sB,EAAQ,IAAI,OAAOM,MAAU;AAC3B,UAAI5B,IAAQK,EAAS,OAAOuB,EAAM,MAAM,EAAE;AAC1C,UAAI5B,GAAO;AACT,YAAIkuB,IAAM,MAAMP,GAAgB3tB,GAAOguB,CAAY;AACnD,eAAOE,EAAI,QAAQA,EAAI,MAAA,IAAU,CAAA;AAAA,MACnC;AACA,aAAO,CAAA;AAAA,IACT,CAAC;AAAA,EAAA;AAEH,SAAOC;AAAA,IACLF,EAAM,KAAK,CAAC,EAAE,OAAOH,EAAoB,EAAE,OAAO,CAACM,MAASA,EAAK,QAAQ,gBAAgBA,EAAK,QAAQ,SAAS,EAAE;AAAA,MAC/G,CAACA,MAASA,EAAK,QAAQ,eAAe,EAAE,GAAGA,GAAM,KAAK,YAAY,IAAI,QAAA,IAAY,EAAE,GAAGA,GAAM,KAAK,WAAA;AAAA,IAAW;AAAA,EAC/G;AAEJ;AACA,SAASC,GAAsBC,GAAMC,GAAaC,GAAgBnuB,GAAU/C,GAAUmxB,GAAM;AAC1F,MAAI5R,IAAQ,CAACjb,GAAOrE,MACbixB,EAAejxB,CAAK,IAClBqE,EAAM,MAAM,OAAO4sB,EAAejxB,CAAK,EAAE,MAAM,KADnB,IAGjCmxB,IAAmB,CAAC9sB,GAAOrE;AAAA;AAAA,IAG3BixB,EAAejxB,CAAK,EAAE,aAAaqE,EAAM;AAAA;AAAA,IAEzC4sB,EAAejxB,CAAK,EAAE,MAAM,MAAM,SAAS,GAAG,KAAKixB,EAAejxB,CAAK,EAAE,OAAO,GAAG,MAAMqE,EAAM,OAAO,GAAG;AAAA;AAG7G,SAAI6sB,MAAS,WACJF,EAAY;AAAA,IACjB,CAAC3sB,GAAOrE,MAAUsf,EAAMjb,GAAOrE,CAAK,KAAKmxB,EAAiB9sB,GAAOrE,CAAK;AAAA,EAAA,IAGtEkxB,MAAS,SACJF,EAAY,OAAO,CAAC3sB,GAAOrE,MAAU;AAC1C,QAAIoxB,IAAgBtuB,EAAS,OAAOuB,EAAM,MAAM,EAAE;AAClD,QAAI,CAAC+sB,KAAiB,CAACA,EAAc;AACnC,aAAO;AAET,QAAI9R,EAAMjb,GAAOrE,CAAK,KAAKmxB,EAAiB9sB,GAAOrE,CAAK;AACtD,aAAO;AAET,QAAIqE,EAAM,MAAM,kBAAkB;AAChC,UAAIsb,IAActb,EAAM,MAAM,iBAAiB;AAAA,QAC7C,YAAY,IAAI;AAAA,UACdtE,EAAS,WAAWA,EAAS,SAASA,EAAS;AAAA,UAC/C,OAAO;AAAA,QAAA;AAAA,QAET,eAAekxB,EAAe,CAAC,GAAG,UAAU,CAAA;AAAA,QAC5C,SAAS,IAAI,IAAIF,GAAM,OAAO,MAAM;AAAA,QACpC,YAAY1sB,EAAM;AAAA,QAClB,yBAAyB;AAAA,MAAA,CAC1B;AACD,UAAI,OAAOsb,KAAgB;AACzB,eAAOA;AAAA,IAEX;AACA,WAAO;AAAA,EACT,CAAC,IAEI,CAAA;AACT;AACA,SAAS0R,GAAmBttB,GAASjB,GAAU,EAAE,wBAAAwuB,EAAA,IAA2B,CAAA,GAAI;AAC9E,SAAOC;AAAA,IACLxtB,EAAQ,IAAI,CAACM,MAAU;AACrB,UAAI5B,IAAQK,EAAS,OAAOuB,EAAM,MAAM,EAAE;AAC1C,UAAI,CAAC5B,EAAO,QAAO,CAAA;AACnB,UAAI+uB,IAAQ,CAAC/uB,EAAM,MAAM;AACzB,aAAIA,EAAM,uBACR+uB,IAAQA,EAAM,OAAO/uB,EAAM,kBAAkB,IAE3CA,EAAM,uBACR+uB,IAAQA,EAAM,OAAO/uB,EAAM,kBAAkB,IAE3C6uB,KAA0B7uB,EAAM,0BAClC+uB,IAAQA,EAAM,OAAO/uB,EAAM,qBAAqB,IAE9CA,EAAM,YACR+uB,IAAQA,EAAM,OAAO/uB,EAAM,OAAO,IAE7B+uB;AAAA,IACT,CAAC,EAAE,KAAK,CAAC;AAAA,EAAA;AAEb;AACA,SAASD,GAAYC,GAAO;AAC1B,SAAO,CAAC,GAAG,IAAI,IAAIA,CAAK,CAAC;AAC3B;AACA,SAASC,GAASpzB,GAAK;AACrB,MAAIqzB,IAAS,CAAA,GACT1mB,IAAO,OAAO,KAAK3M,CAAG,EAAE,KAAA;AAC5B,WAAS8B,KAAO6K;AACd,IAAA0mB,EAAOvxB,CAAG,IAAI9B,EAAI8B,CAAG;AAEvB,SAAOuxB;AACT;AACA,SAASd,GAAsBe,GAAaC,GAAU;AACpD,MAAIC,wBAA0B,IAAA;AACZ,aAAI,IAAID,CAAQ,GAC3BD,EAAY,OAAO,CAACG,GAASC,MAAe;AAKjD,QAAI5xB,IAAM,KAAK,UAAUsxB,GAASM,CAAU,CAAC;AAC7C,WAAKF,EAAI,IAAI1xB,CAAG,MACd0xB,EAAI,IAAI1xB,CAAG,GACX2xB,EAAQ,KAAK,EAAE,KAAA3xB,GAAK,MAAM4xB,GAAY,IAEjCD;AAAA,EACT,GAAG,CAAA,CAAE;AACP;AAsoBA,SAASE,KAAwB;AAC/B,MAAI7vB,IAAU8vB,EAAO,WAAW9L,EAAiB;AACjD,SAAA4J;AAAA,IACE5tB;AAAA,IACA;AAAA,EAAA,GAEKA;AACT;AACA,SAAS+vB,KAA4B;AACnC,MAAI/vB,IAAU8vB,EAAO,WAAW5L,EAAsB;AACtD,SAAA0J;AAAA,IACE5tB;AAAA,IACA;AAAA,EAAA,GAEKA;AACT;AACA,IAAIgwB,KAAmBF,EAAO,cAAc,MAAM;AAClDE,GAAiB,cAAc;AAC/B,SAASC,KAAsB;AAC7B,MAAIjwB,IAAU8vB,EAAO,WAAWE,EAAgB;AAChD,SAAApC;AAAA,IACE5tB;AAAA,IACA;AAAA,EAAA,GAEKA;AACT;AACA,SAASkwB,GAAoBC,GAAUC,GAAmB;AACxD,MAAIC,IAAmBP,EAAO,WAAWE,EAAgB,GACrD,CAACM,GAAeC,CAAgB,IAAIT,EAAO,SAAS,EAAK,GACzD,CAACU,GAAgBC,CAAiB,IAAIX,EAAO,SAAS,EAAK,GAC3D,EAAE,SAAAY,GAAS,QAAAC,GAAQ,cAAAC,GAAc,cAAAC,GAAc,cAAAC,MAAiBV,GAChEW,IAAMjB,EAAO,OAAO,IAAI;AAC5BA,EAAAA,EAAO,UAAU,MAAM;AAIrB,QAHIK,MAAa,YACfM,EAAkB,EAAI,GAEpBN,MAAa,YAAY;AAC3B,UAAIa,IAAW,CAAC9X,MAAY;AAC1B,QAAAA,EAAQ,QAAQ,CAAC+X,MAAU;AACzB,UAAAR,EAAkBQ,EAAM,cAAc;AAAA,QACxC,CAAC;AAAA,MACH,GACIC,IAAW,IAAI,qBAAqBF,GAAU,EAAE,WAAW,KAAK;AACpE,aAAID,EAAI,WAASG,EAAS,QAAQH,EAAI,OAAO,GACtC,MAAM;AACX,QAAAG,EAAS,WAAA;AAAA,MACX;AAAA,IACF;AAAA,EACF,GAAG,CAACf,CAAQ,CAAC,GACbL,EAAO,UAAU,MAAM;AACrB,QAAIQ,GAAe;AACjB,UAAIxvB,IAAK,WAAW,MAAM;AACxB,QAAA2vB,EAAkB,EAAI;AAAA,MACxB,GAAG,GAAG;AACN,aAAO,MAAM;AACX,qBAAa3vB,CAAE;AAAA,MACjB;AAAA,IACF;AAAA,EACF,GAAG,CAACwvB,CAAa,CAAC;AAClB,MAAIa,IAAY,MAAM;AACpB,IAAAZ,EAAiB,EAAI;AAAA,EACvB,GACIa,IAAe,MAAM;AACvB,IAAAb,EAAiB,EAAK,GACtBE,EAAkB,EAAK;AAAA,EACzB;AACA,SAAKJ,IAGDF,MAAa,WACR,CAACK,GAAgBO,GAAK,EAAE,IAE1B;AAAA,IACLP;AAAA,IACAO;AAAA,IACA;AAAA,MACE,SAASM,GAAqBX,GAASS,CAAS;AAAA,MAChD,QAAQE,GAAqBV,GAAQS,CAAY;AAAA,MACjD,cAAcC,GAAqBT,GAAcO,CAAS;AAAA,MAC1D,cAAcE,GAAqBR,GAAcO,CAAY;AAAA,MAC7D,cAAcC,GAAqBP,GAAcK,CAAS;AAAA,IAAA;AAAA,EAC5D,IAdO,CAAC,IAAOJ,GAAK,EAAE;AAgB1B;AACA,SAASM,GAAqBC,GAAcC,GAAY;AACtD,SAAO,CAACxE,MAAU;AAChB,IAAAuE,KAAgBA,EAAavE,CAAK,GAC7BA,EAAM,oBACTwE,EAAWxE,CAAK;AAAA,EAEpB;AACF;AAsCA,SAASyE,GAAkB,EAAE,MAAA5C,GAAM,GAAG6C,KAAa;AACjD,MAAI,EAAE,QAAAhoB,EAAA,IAAWomB,GAAA,GACbjuB,IAAUkuB,EAAO;AAAA,IACnB,MAAM3uB,GAAYsI,EAAO,QAAQmlB,GAAMnlB,EAAO,QAAQ;AAAA,IACtD,CAACA,EAAO,QAAQmlB,GAAMnlB,EAAO,QAAQ;AAAA,EAAA;AAEvC,SAAK7H,IAGkBkuB,gBAAAA,EAAO,cAAc4B,IAAuB,EAAE,MAAA9C,GAAM,SAAAhtB,GAAS,GAAG6vB,GAAW,IAFzF;AAGX;AACA,SAASE,GAAsB/vB,GAAS;AACtC,MAAI,EAAE,UAAAjB,GAAU,cAAA2tB,EAAA,IAAiB2B,GAAA,GAC7B,CAAC2B,GAAoBC,CAAqB,IAAI/B,EAAO,SAAS,CAAA,CAAE;AACpEA,SAAAA,EAAO,UAAU,MAAM;AACrB,QAAIgC,IAAc;AAClB,WAAKzD,GAAsBzsB,GAASjB,GAAU2tB,CAAY,EAAE;AAAA,MAC1D,CAACC,MAAU;AACT,QAAKuD,KACHD,EAAsBtD,CAAK;AAAA,MAE/B;AAAA,IAAA,GAEK,MAAM;AACX,MAAAuD,IAAc;AAAA,IAChB;AAAA,EACF,GAAG,CAAClwB,GAASjB,GAAU2tB,CAAY,CAAC,GAC7BsD;AACT;AACA,SAASF,GAAsB;AAAA,EAC7B,MAAA9C;AAAA,EACA,SAASC;AAAA,EACT,GAAG4C;AACL,GAAG;AACD,MAAI7zB,IAAW6nB,GAAA,GACX,EAAE,QAAAlZ,GAAQ,UAAA5L,GAAU,cAAA2tB,EAAA,IAAiB2B,GAAA,GACrC,EAAE,UAAA5uB,EAAA,IAAawuB,GAAA,GACf,EAAE,YAAA1tB,GAAY,SAAAP,EAAA,IAAYmuB,GAAA,GAC1BgC,IAAoBjC,EAAO;AAAA,IAC7B,MAAMnB;AAAA,MACJC;AAAA,MACAC;AAAA,MACAjtB;AAAA,MACAjB;AAAA,MACA/C;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,CAACgxB,GAAMC,GAAajtB,GAASjB,GAAU/C,CAAQ;AAAA,EAAA,GAE7Co0B,IAAsBlC,EAAO;AAAA,IAC/B,MAAMnB;AAAA,MACJC;AAAA,MACAC;AAAA,MACAjtB;AAAA,MACAjB;AAAA,MACA/C;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,CAACgxB,GAAMC,GAAajtB,GAASjB,GAAU/C,CAAQ;AAAA,EAAA,GAE7Cq0B,IAAYnC,EAAO,QAAQ,MAAM;AACnC,QAAIlB,MAAShxB,EAAS,WAAWA,EAAS,SAASA,EAAS;AAC1D,aAAO,CAAA;AAET,QAAIs0B,wBAAmC,IAAA,GACnCC,IAAmB;AAcvB,QAbAtD,EAAY,QAAQ,CAAC5mB,MAAM;AACzB,UAAIgnB,IAAgBtuB,EAAS,OAAOsH,EAAE,MAAM,EAAE;AAC9C,MAAI,CAACgnB,KAAiB,CAACA,EAAc,cAGjC,CAAC8C,EAAkB,KAAK,CAACK,MAAOA,EAAG,MAAM,OAAOnqB,EAAE,MAAM,EAAE,KAAKA,EAAE,MAAM,MAAM9F,KAAcmsB,EAAarmB,EAAE,MAAM,EAAE,GAAG,oBAE9GgnB,EAAc,kBADvBkD,IAAmB,KAInBD,EAAa,IAAIjqB,EAAE,MAAM,EAAE;AAAA,IAE/B,CAAC,GACGiqB,EAAa,SAAS;AACxB,aAAO,CAAA;AAET,QAAI/yB,IAAM0uB;AAAA,MACRe;AAAA,MACAvtB;AAAA,MACAkL,EAAO;AAAA,MACP;AAAA,IAAA;AAEF,WAAI4lB,KAAoBD,EAAa,OAAO,KAC1C/yB,EAAI,aAAa;AAAA,MACf;AAAA,MACA0vB,EAAY,OAAO,CAAC5mB,MAAMiqB,EAAa,IAAIjqB,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,CAACA,MAAMA,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG;AAAA,IAAA,GAGpF,CAAC9I,EAAI,WAAWA,EAAI,MAAM;AAAA,EACnC,GAAG;AAAA,IACDkC;AAAA,IACAkL,EAAO;AAAA,IACPpK;AAAA,IACAvE;AAAA,IACA+C;AAAA,IACAoxB;AAAA,IACAlD;AAAA,IACAD;AAAA,IACAN;AAAA,EAAA,CACD,GACG+D,IAAcvC,EAAO;AAAA,IACvB,MAAMZ,GAAmB8C,GAAqBrxB,CAAQ;AAAA,IACtD,CAACqxB,GAAqBrxB,CAAQ;AAAA,EAAA,GAE5BixB,IAAqBD,GAAsBK,CAAmB;AAClE,SAAuBlC,gBAAAA,EAAO,cAAcA,EAAO,UAAU,MAAMmC,EAAU,IAAI,CAACryB,MAAyBkwB,gBAAAA,EAAO,cAAc,QAAQ,EAAE,KAAKlwB,GAAM,KAAK,YAAY,IAAI,SAAS,MAAAA,GAAM,GAAG6xB,EAAA,CAAW,CAAC,GAAGY,EAAY,IAAI,CAACzyB,MAAyBkwB,gBAAAA,EAAO,cAAc,QAAQ,EAAE,KAAKlwB,GAAM,KAAK,iBAAiB,MAAAA,GAAM,GAAG6xB,EAAA,CAAW,CAAC,GAAGG,EAAmB,IAAI,CAAC,EAAE,KAAA5zB,GAAK,MAAA0wB,EAAA;AAAA;AAAA;AAAA,IAG1VoB,gBAAAA,EAAO,cAAc,QAAQ,EAAE,KAAA9xB,GAAK,OAAOyzB,EAAU,OAAO,GAAG/C,EAAA,CAAM;AAAA,GACtF,CAAC;AACJ;AA4QA,SAAS4D,MAAaC,GAAM;AAC1B,SAAO,CAACh2B,MAAU;AAChB,IAAAg2B,EAAK,QAAQ,CAACxB,MAAQ;AACpB,MAAI,OAAOA,KAAQ,aACjBA,EAAIx0B,CAAK,IACAw0B,KAAO,SAChBA,EAAI,UAAUx0B;AAAA,IAElB,CAAC;AAAA,EACH;AACF;AAqGA,IAAIi2B,KAAa,OAAO,SAAW,OAAe,OAAO,OAAO,WAAa,OAAe,OAAO,OAAO,SAAS,gBAAkB;AACrI,IAAI;AACF,EAAIA,OACF,OAAO;AAAA,EACP;AAEJ,QAAY;AACZ;AACA,SAASC,GAAoBjyB,GAAQoJ,GAAM;AACzC,SAAOkC,GAAa;AAAA,IAClB,UAAUlC,GAAM;AAAA,IAChB,YAAYA,GAAM;AAAA,IAClB,QAAQA,GAAM;AAAA,IACd,SAASnN,GAAqB,EAAE,QAAQmN,GAAM,QAAQ;AAAA,IACtD,eAAeA,GAAM,iBAAiB8oB,GAAA;AAAA,IACtC,QAAAlyB;AAAA,IACA,oBAAAupB;AAAA,IACA,0BAAAC;AAAA,IACA,cAAcpgB,GAAM;AAAA,IACpB,yBAAyBA,GAAM;AAAA,IAC/B,QAAQA,GAAM;AAAA,IACd,2BAA2BA,GAAM;AAAA,EAAA,CAClC,EAAE,WAAA;AACL;AAiBA,SAAS8oB,KAAqB;AAC5B,MAAI30B,IAAQ,QAAQ;AACpB,SAAIA,KAASA,EAAM,WACjBA,IAAQ;AAAA,IACN,GAAGA;AAAA,IACH,QAAQ40B,GAAkB50B,EAAM,MAAM;AAAA,EAAA,IAGnCA;AACT;AACA,SAAS40B,GAAkBrlB,GAAQ;AACjC,MAAI,CAACA,EAAQ,QAAO;AACpB,MAAI4L,IAAU,OAAO,QAAQ5L,CAAM,GAC/BslB,IAAa,CAAA;AACjB,WAAS,CAAC50B,GAAK+lB,CAAG,KAAK7K;AACrB,QAAI6K,KAAOA,EAAI,WAAW;AACxB,MAAA6O,EAAW50B,CAAG,IAAI,IAAI0J;AAAA,QACpBqc,EAAI;AAAA,QACJA,EAAI;AAAA,QACJA,EAAI;AAAA,QACJA,EAAI,aAAa;AAAA,MAAA;AAAA,aAEVA,KAAOA,EAAI,WAAW,SAAS;AACxC,UAAIA,EAAI,WAAW;AACjB,YAAI8O,IAAmB,OAAO9O,EAAI,SAAS;AAC3C,YAAI,OAAO8O,KAAqB;AAC9B,cAAI;AACF,gBAAIzzB,IAAQ,IAAIyzB,EAAiB9O,EAAI,OAAO;AAC5C,YAAA3kB,EAAM,QAAQ,IACdwzB,EAAW50B,CAAG,IAAIoB;AAAA,UACpB,QAAY;AAAA,UACZ;AAAA,MAEJ;AACA,UAAIwzB,EAAW50B,CAAG,KAAK,MAAM;AAC3B,YAAIoB,IAAQ,IAAI,MAAM2kB,EAAI,OAAO;AACjC,QAAA3kB,EAAM,QAAQ,IACdwzB,EAAW50B,CAAG,IAAIoB;AAAA,MACpB;AAAA,IACF;AACE,MAAAwzB,EAAW50B,CAAG,IAAI+lB;AAGtB,SAAO6O;AACT;AA+GA,IAAIE,KAAsB,iCACtBC,KAAOC,EAAQ;AAAA,EACjB,SAAqB;AAAA,IACnB,SAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,UAAA/C,IAAW;AAAA,IACX,UAAA1V;AAAA,IACA,gBAAA0Y;AAAA,IACA,SAAS9zB;AAAA,IACT,OAAAtB;AAAA,IACA,QAAAkvB;AAAA,IACA,IAAA9vB;AAAA,IACA,oBAAA2T;AAAA,IACA,gBAAAsiB;AAAA,IACA,kCAAAC;AAAA,IACA,GAAGnwB;AAAA,EAAA,GACFowB,GAAc;AACf,QAAI,EAAE,UAAAjyB,GAAU,yBAAA+oB,EAAA,IAA4B4I,EAAQ,WAAWxO,EAAiB,GAC5E9kB,IAAa,OAAOvC,KAAO,YAAY21B,GAAoB,KAAK31B,CAAE,GAClE8nB,IAAS9c,GAAYhL,GAAIkE,CAAQ;AACrC,IAAAlE,IAAK8nB,EAAO;AACZ,QAAIrlB,IAAOulB,GAAQhoB,GAAI,EAAE,UAAAsd,GAAU,GAC/B,CAAC+V,GAAgB+C,GAAaC,CAAgB,IAAItD;AAAA,MACpDC;AAAA,MACAjtB;AAAA,IAAA,GAEEuwB,IAAkBC,GAAoBv2B,GAAI;AAAA,MAC5C,SAASkC;AAAA,MACT,OAAAtB;AAAA,MACA,QAAAkvB;AAAA,MACA,oBAAAnc;AAAA,MACA,UAAA2J;AAAA,MACA,gBAAA2Y;AAAA,MACA,kCAAAC;AAAA,MACA,yBAAAjJ;AAAA,IAAA,CACD;AACD,aAASuJ,EAAY5G,GAAO;AAC1B,MAAIkG,OAAiBlG,CAAK,GACrBA,EAAM,oBACT0G,EAAgB1G,CAAK;AAAA,IAEzB;AACA,QAAI2B;AAAA;AAAA,MAEcsE,gBAAAA,EAAQ;AAAA,QACtB;AAAA,QACA;AAAA,UACE,GAAG9vB;AAAA,UACH,GAAGswB;AAAA,UACH,MAAMvO,EAAO,eAAerlB;AAAA,UAC5B,SAASqlB,EAAO,cAAckO,IAAiBF,IAAUU;AAAA,UACzD,KAAKrB,GAAUgB,GAAcC,CAAW;AAAA,UACxC,QAAAtG;AAAA,UACA,iBAAiB,CAACvtB,KAAcwzB,MAAa,WAAW,SAAS;AAAA,QAAA;AAAA,MACnE;AAAA;AAGJ,WAAO1C,KAAkB,CAAC9wB,IAA6BszB,gBAAAA,EAAQ,cAAcA,EAAQ,UAAU,MAAMtE,GAAsBsE,gBAAAA,EAAQ,cAAcxB,IAAmB,EAAE,MAAM5xB,EAAA,CAAM,CAAC,IAAI8uB;AAAA,EACzL;AACF;AACAqE,GAAK,cAAc;AACnB,IAAIa,KAAUZ,EAAQ;AAAA,EACpB,SAAwB;AAAA,IACtB,gBAAgBa,IAAkB;AAAA,IAClC,eAAAvuB,IAAgB;AAAA,IAChB,WAAWwuB,IAAgB;AAAA,IAC3B,KAAArvB,IAAM;AAAA,IACN,OAAOsvB;AAAA,IACP,IAAA52B;AAAA,IACA,gBAAAi2B;AAAA,IACA,UAAAtZ;AAAA,IACA,GAAG5W;AAAA,EAAA,GACF6tB,GAAK;AACN,QAAI7yB,IAAOqnB,GAAgBpoB,GAAI,EAAE,UAAU+F,EAAK,UAAU,GACtDtF,IAAW6nB,GAAA,GACXuO,IAAchB,EAAQ,WAAW9O,EAAsB,GACvD,EAAE,WAAAmB,GAAW,UAAAhkB,EAAA,IAAa2xB,EAAQ,WAAWxO,EAAiB,GAC9DyP,IAAkBD,KAAe;AAAA;AAAA,IAErCE,GAAuBh2B,CAAI,KAAKk1B,MAAmB,IAC/CntB,IAAaof,EAAU,iBAAiBA,EAAU,eAAennB,CAAI,EAAE,WAAWA,EAAK,UACvF+I,IAAmBrJ,EAAS,UAC5Bu2B,IAAuBH,KAAeA,EAAY,cAAcA,EAAY,WAAW,WAAWA,EAAY,WAAW,SAAS,WAAW;AACjJ,IAAK1uB,MACH2B,IAAmBA,EAAiB,YAAA,GACpCktB,IAAuBA,IAAuBA,EAAqB,YAAA,IAAgB,MACnFluB,IAAaA,EAAW,YAAA,IAEtBkuB,KAAwB9yB,MAC1B8yB,IAAuB3yB,GAAc2yB,GAAsB9yB,CAAQ,KAAK8yB;AAE1E,UAAMC,IAAmBnuB,MAAe,OAAOA,EAAW,SAAS,GAAG,IAAIA,EAAW,SAAS,IAAIA,EAAW;AAC7G,QAAIouB,IAAWptB,MAAqBhB,KAAc,CAACxB,KAAOwC,EAAiB,WAAWhB,CAAU,KAAKgB,EAAiB,OAAOmtB,CAAgB,MAAM,KAC/IE,IAAYH,KAAwB,SAASA,MAAyBluB,KAAc,CAACxB,KAAO0vB,EAAqB,WAAWluB,CAAU,KAAKkuB,EAAqB,OAAOluB,EAAW,MAAM,MAAM,MAC9LsuB,IAAc;AAAA,MAChB,UAAAF;AAAA,MACA,WAAAC;AAAA,MACA,iBAAAL;AAAA,IAAA,GAEEO,IAAcH,IAAWR,IAAkB,QAC3CY;AACJ,IAAI,OAAOX,KAAkB,aAC3BW,IAAYX,EAAcS,CAAW,IAErCE,IAAY;AAAA,MACVX;AAAA,MACAO,IAAW,WAAW;AAAA,MACtBC,IAAY,YAAY;AAAA,MACxBL,IAAkB,kBAAkB;AAAA,IAAA,EACpC,OAAO,OAAO,EAAE,KAAK,GAAG;AAE5B,QAAIS,IAAQ,OAAOX,KAAc,aAAaA,EAAUQ,CAAW,IAAIR;AACvE,WAAuBf,gBAAAA,EAAQ;AAAA,MAC7BD;AAAA,MACA;AAAA,QACE,GAAG7vB;AAAA,QACH,gBAAgBsxB;AAAA,QAChB,WAAAC;AAAA,QACA,KAAA1D;AAAA,QACA,OAAA2D;AAAA,QACA,IAAAv3B;AAAA,QACA,gBAAAi2B;AAAA,MAAA;AAAA,MAEF,OAAOtZ,KAAa,aAAaA,EAASya,CAAW,IAAIza;AAAA,IAAA;AAAA,EAE7D;AACF;AACA8Z,GAAQ,cAAc;AACtB,IAAIe,KAAO3B,EAAQ;AAAA,EACjB,CAAC;AAAA,IACC,UAAAE,IAAW;AAAA,IACX,YAAAxb;AAAA,IACA,UAAAhO;AAAA,IACA,gBAAAypB;AAAA,IACA,SAAS9zB;AAAA,IACT,OAAAtB;AAAA,IACA,QAAAulB,IAASiJ;AAAA,IACT,QAAA7tB;AAAA,IACA,UAAAk2B;AAAA,IACA,UAAAna;AAAA,IACA,oBAAA3J;AAAA,IACA,gBAAAsiB;AAAA,IACA,kCAAAC;AAAA,IACA,GAAG3L;AAAA,EAAA,GACF4L,MAAiB;AAClB,QAAI,EAAE,yBAAAlJ,EAAA,IAA4B4I,EAAQ,WAAWxO,EAAiB,GAClEqQ,IAASC,GAAA,GACTtd,IAAaud,GAAcr2B,GAAQ,EAAE,UAAA+b,GAAU,GAC/ClD,IAAa+L,EAAO,YAAA,MAAkB,QAAQ,QAAQ,QACtD5jB,IAAa,OAAOhB,KAAW,YAAYo0B,GAAoB,KAAKp0B,CAAM,GAC1Es2B,IAAgB,CAACjI,MAAU;AAE7B,UADA6H,KAAYA,EAAS7H,CAAK,GACtBA,EAAM,iBAAkB;AAC5B,MAAAA,EAAM,eAAA;AACN,UAAIkI,IAAYlI,EAAM,YAAY,WAC9BmI,IAAeD,GAAW,aAAa,YAAY,KAAK3R,GACxD6R,IAAW,MAAMN,EAAOI,KAAalI,EAAM,eAAe;AAAA,QAC5D,YAAArV;AAAA,QACA,QAAQwd;AAAA,QACR,UAAAxrB;AAAA,QACA,SAASrK;AAAA,QACT,OAAAtB;AAAA,QACA,UAAA0c;AAAA,QACA,oBAAA3J;AAAA,QACA,gBAAAsiB;AAAA,QACA,kCAAAC;AAAA,MAAA,CACD;AACD,MAAIjJ,KAA2B1gB,MAAa,KAC1CspB,EAAQ,gBAAgB,MAAMmC,GAAU,IAExCA,EAAA;AAAA,IAEJ;AACA,WAAuBnC,gBAAAA,EAAQ;AAAA,MAC7B;AAAA,MACA;AAAA,QACE,KAAKM;AAAA,QACL,QAAQ/b;AAAA,QACR,QAAQC;AAAA,QACR,UAAU2b,IAAiByB,IAAWI;AAAA,QACtC,GAAGtN;AAAA,QACH,iBAAiB,CAAChoB,KAAcwzB,MAAa,WAAW,SAAS;AAAA,MAAA;AAAA,IACnE;AAAA,EAEJ;AACF;AACAyB,GAAK,cAAc;AA2DnB,SAASS,GAA2BrM,GAAU;AAC5C,SAAO,GAAGA,CAAQ;AACpB;AACA,SAASsM,GAAsBtM,GAAU;AACvC,MAAIje,IAAMkoB,EAAQ,WAAWhP,EAAiB;AAC9C,SAAA1mB,EAAUwN,GAAKsqB,GAA2BrM,CAAQ,CAAC,GAC5Cje;AACT;AAMA,SAAS4oB,GAAoBv2B,GAAI;AAAA,EAC/B,QAAA8vB;AAAA,EACA,SAASqI;AAAA,EACT,OAAAv3B;AAAA,EACA,oBAAA+S;AAAA,EACA,UAAA2J;AAAA,EACA,gBAAA2Y;AAAA,EACA,kCAAAC;AAAA,EACA,yBAAAjJ;AACF,IAAI,IAAI;AACN,MAAI1gB,IAAWkc,GAAA,GACXhoB,IAAW6nB,GAAA,GACXvnB,IAAOqnB,GAAgBpoB,GAAI,EAAE,UAAAsd,GAAU;AAC3C,SAAOuY,EAAQ;AAAA,IACb,CAACjG,MAAU;AACT,UAAIC,GAAuBD,GAAOE,CAAM,GAAG;AACzC,QAAAF,EAAM,eAAA;AACN,YAAI1tB,IAAWi2B,MAAgB,SAASA,IAAcl4B,GAAWQ,CAAQ,MAAMR,GAAWc,CAAI,GAC1Fq3B,IAAa,MAAM7rB,EAASvM,GAAI;AAAA,UAClC,SAASkC;AAAA,UACT,OAAAtB;AAAA,UACA,oBAAA+S;AAAA,UACA,UAAA2J;AAAA,UACA,gBAAA2Y;AAAA,UACA,kCAAAC;AAAA,QAAA,CACD;AACD,QAAIjJ,IACF4I,EAAQ,gBAAgB,MAAMuC,GAAY,IAE1CA,EAAA;AAAA,MAEJ;AAAA,IACF;AAAA,IACA;AAAA,MACE33B;AAAA,MACA8L;AAAA,MACAxL;AAAA,MACAo3B;AAAA,MACAv3B;AAAA,MACAkvB;AAAA,MACA9vB;AAAA,MACA2T;AAAA,MACA2J;AAAA,MACA2Y;AAAA,MACAC;AAAA,MACAjJ;AAAA,IAAA;AAAA,EACF;AAEJ;AAkCA,IAAIoL,KAAY,GACZC,KAAqB,MAAM,KAAK,OAAO,EAAED,EAAS,CAAC;AACvD,SAASV,KAAY;AACnB,MAAI,EAAE,QAAArrB,MAAW4rB;AAAA,IAAsB;AAAA;AAAA,EAAA,GACnC,EAAE,UAAAh0B,EAAA,IAAa2xB,EAAQ,WAAWxO,EAAiB,GACnDkR,IAAiBrM,GAAA,GACjBsM,IAAclsB,EAAO,OACrBmsB,IAAiBnsB,EAAO;AAC5B,SAAOupB,EAAQ;AAAA,IACb,OAAO/F,GAAQvwB,IAAU,OAAO;AAC9B,UAAI,EAAE,QAAAgC,GAAQ,QAAA4kB,GAAQ,SAAAgK,GAAS,UAAA9R,GAAU,MAAAgS,MAASD;AAAA,QAChDN;AAAA,QACA5rB;AAAA,MAAA;AAEF,UAAI3E,EAAQ,aAAa,IAAO;AAC9B,YAAIsB,IAAMtB,EAAQ,cAAc+4B,GAAA;AAChC,cAAME,EAAY33B,GAAK03B,GAAgBh5B,EAAQ,UAAUgC,GAAQ;AAAA,UAC/D,kCAAkChC,EAAQ;AAAA,UAC1C,oBAAoBA,EAAQ;AAAA,UAC5B,UAAA8e;AAAA,UACA,MAAAgS;AAAA,UACA,YAAY9wB,EAAQ,UAAU4mB;AAAA,UAC9B,aAAa5mB,EAAQ,WAAW4wB;AAAA,UAChC,WAAW5wB,EAAQ;AAAA,QAAA,CACpB;AAAA,MACH;AACE,cAAMk5B,EAAel5B,EAAQ,UAAUgC,GAAQ;AAAA,UAC7C,kCAAkChC,EAAQ;AAAA,UAC1C,oBAAoBA,EAAQ;AAAA,UAC5B,UAAA8e;AAAA,UACA,MAAAgS;AAAA,UACA,YAAY9wB,EAAQ,UAAU4mB;AAAA,UAC9B,aAAa5mB,EAAQ,WAAW4wB;AAAA,UAChC,SAAS5wB,EAAQ;AAAA,UACjB,OAAOA,EAAQ;AAAA,UACf,aAAag5B;AAAA,UACb,WAAWh5B,EAAQ;AAAA,UACnB,gBAAgBA,EAAQ;AAAA,QAAA,CACzB;AAAA,IAEL;AAAA,IACA,CAACi5B,GAAaC,GAAgBv0B,GAAUq0B,CAAc;AAAA,EAAA;AAE1D;AACA,SAASX,GAAcr2B,GAAQ,EAAE,UAAA+b,EAAA,IAAa,CAAA,GAAI;AAChD,MAAI,EAAE,UAAApZ,EAAA,IAAa2xB,EAAQ,WAAWxO,EAAiB,GACnDyD,IAAe+K,EAAQ,WAAWtO,EAAY;AAClD,EAAApnB,EAAU2qB,GAAc,kDAAkD;AAC1E,MAAI,CAAC/lB,CAAK,IAAI+lB,EAAa,QAAQ,MAAM,EAAE,GACvC/pB,IAAO,EAAE,GAAGqnB,GAAgB7mB,KAAkB,KAAK,EAAE,UAAA+b,EAAA,CAAU,EAAA,GAC/D7c,IAAW6nB,GAAA;AACf,MAAI/mB,KAAU,MAAM;AAClB,IAAAR,EAAK,SAASN,EAAS;AACvB,QAAIwE,IAAS,IAAI,gBAAgBlE,EAAK,MAAM,GACxC4c,IAAc1Y,EAAO,OAAO,OAAO;AAEvC,QADyB0Y,EAAY,KAAK,CAACrV,MAAMA,MAAM,EAAE,GACjC;AACtB,MAAArD,EAAO,OAAO,OAAO,GACrB0Y,EAAY,OAAO,CAACrV,MAAMA,CAAC,EAAE,QAAQ,CAACA,MAAMrD,EAAO,OAAO,SAASqD,CAAC,CAAC;AACrE,UAAIsV,IAAK3Y,EAAO,SAAA;AAChB,MAAAlE,EAAK,SAAS6c,IAAK,IAAIA,CAAE,KAAK;AAAA,IAChC;AAAA,EACF;AACA,UAAK,CAACrc,KAAUA,MAAW,QAAQwD,EAAM,MAAM,UAC7ChE,EAAK,SAASA,EAAK,SAASA,EAAK,OAAO,QAAQ,OAAO,SAAS,IAAI,WAElEmD,MAAa,QACfnD,EAAK,WAAWA,EAAK,aAAa,MAAMmD,IAAWsB,GAAU,CAACtB,GAAUnD,EAAK,QAAQ,CAAC,IAEjFd,GAAWc,CAAI;AACxB;AAwOA,SAASg2B,GAAuB/2B,GAAI,EAAE,UAAAsd,EAAA,IAAa,CAAA,GAAI;AACrD,MAAIiQ,IAAYsI,EAAQ,WAAW3O,EAAqB;AACxD,EAAA/mB;AAAA,IACEotB,KAAa;AAAA,IACb;AAAA,EAAA;AAEF,MAAI,EAAE,UAAArpB,MAAag0B;AAAA,IACjB;AAAA;AAAA,EAAA,GAEEn3B,IAAOqnB,GAAgBpoB,GAAI,EAAE,UAAAsd,GAAU;AAC3C,MAAI,CAACiQ,EAAU;AACb,WAAO;AAET,MAAIrN,IAAc7b,GAAckpB,EAAU,gBAAgB,UAAUrpB,CAAQ,KAAKqpB,EAAU,gBAAgB,UACvGmL,IAAWr0B,GAAckpB,EAAU,aAAa,UAAUrpB,CAAQ,KAAKqpB,EAAU,aAAa;AAClG,SAAO/lB,GAAUzG,EAAK,UAAU23B,CAAQ,KAAK,QAAQlxB,GAAUzG,EAAK,UAAUmf,CAAW,KAAK;AAChG;ACpyUA,SAASyY,GAAgBpO,GAAO;AAC9B,SAAuBzD,gBAAAA,EAAM,cAAciG,IAAgB,EAAE,WAAW6L,GAAS,WAAW,GAAGrO,GAAO;AACxG;ACnDA,MAAMsO,KAAkB,CAACC,MAAgB;AACvC,MAAIl4B;AACJ,QAAMm4B,IAA4B,oBAAI,IAAG,GACnC/K,IAAW,CAACgL,GAASC,MAAY;AACrC,UAAMC,IAAY,OAAOF,KAAY,aAAaA,EAAQp4B,CAAK,IAAIo4B;AACnE,QAAI,CAAC,OAAO,GAAGE,GAAWt4B,CAAK,GAAG;AAChC,YAAMu4B,IAAgBv4B;AACtB,MAAAA,IAASq4B,MAA4B,OAAOC,KAAc,YAAYA,MAAc,QAAQA,IAAY,OAAO,OAAO,CAAA,GAAIt4B,GAAOs4B,CAAS,GAC1IH,EAAU,QAAQ,CAACv3B,MAAaA,EAASZ,GAAOu4B,CAAa,CAAC;AAAA,IAChE;AAAA,EACF,GACMC,IAAW,MAAMx4B,GAMjBy4B,IAAM,EAAE,UAAArL,GAAU,UAAAoL,GAAU,iBALV,MAAME,GAKqB,WAJjC,CAAC93B,OACjBu3B,EAAU,IAAIv3B,CAAQ,GACf,MAAMu3B,EAAU,OAAOv3B,CAAQ,GAEoB,GACtD83B,IAAe14B,IAAQk4B,EAAY9K,GAAUoL,GAAUC,CAAG;AAChE,SAAOA;AACT,GACME,MAAe,CAACT,MAAgBA,IAAcD,GAAgBC,CAAW,IAAID,KClB7EW,KAAW,CAACpZ,MAAQA;AAC1B,SAASqZ,GAASJ,GAAKK,IAAWF,IAAU;AAC1C,QAAMG,IAAQ7S,GAAM;AAAA,IAClBuS,EAAI;AAAA,IACJvS,GAAM,YAAY,MAAM4S,EAASL,EAAI,SAAQ,CAAE,GAAG,CAACA,GAAKK,CAAQ,CAAC;AAAA,IACjE5S,GAAM,YAAY,MAAM4S,EAASL,EAAI,iBAAiB,GAAG,CAACA,GAAKK,CAAQ,CAAC;AAAA,EAC5E;AACE5S,SAAAA,GAAM,cAAc6S,CAAK,GAClBA;AACT;AACA,MAAMC,KAAa,CAACd,MAAgB;AAClC,QAAMO,IAAME,GAAYT,CAAW,GAC7Be,IAAgB,CAACH,MAAaD,GAASJ,GAAKK,CAAQ;AAC1D,gBAAO,OAAOG,GAAeR,CAAG,GACzBQ;AACT,GACMC,MAAU,CAAChB,MAAgBA,IAAcc,GAAWd,CAAW,IAAIc,KCa5DG,KAAmB,yBAoCnBC,KAAoB;AAa1B,SAASC,GAAe76B,GAAO;AAClC,SAAO,OAAOA,KAAU,YAAY46B,GAAkB,KAAK56B,CAAK;AACpE;AC3EO,MAAM86B,KAAoB,MAEpBC,KAAkB,MAkBlBC,KAAwB,IA2ExBC,KAAkB,kBAyBlBC,KAA0B,KAE1BC,KAA2B,KAc3BC,KAA0B,GAc1BC,KAAuC,KA2C9CC,KAAO,OAAO,UAAY,OAAe,QAAQ,MAAM,QAAQ,MAAM,CAAA;AAC1CA,GAAK;AACDA,GAAK;AClJnC,MAAMC,KAAOC,EAAE,KAAK,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC,GAE5CC,KAAa,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,GCtDjDC,KAAsB,KAItBC,KAAyB;AAIKH,EAAE,OAAO;AAAA,EACzC,MAAMA,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAQ;AAAA,EACxC,QAAQA,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAQ;AAAA;AAAA;AAAA;AAAA,EAI1C,QAAQA,EAAE,QAAQ,EAAI,EAAE,SAAQ;AACpC,CAAC;AAIW,MAACI,KAAc;AAAA,EACvB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,UAAU;AAAA,EAEV,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,cAAc;AAAA;AAAA,EAEd,aAAa;AAAA,EACb,OAAO;AACX,GAEaC,KAAcL,EAAE,KAAK,CAAC,QAAQ,SAAS,QAAQ,QAAQ,MAAM,CAAC,GAS9DM,KAAeN,EAAE,OAAO;AAAA,EACjC,QAAQA,EAAE,QAAO;AAAA,EACjB,OAAOA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW,EAAG,IAAI,EAAE;AAChD,CAAC;AACqBA,EAAE,OAAO;AAAA,EAC3B,UAAUA,EAAE,OAAM;AAAA,EAClB,MAAMA,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAQ;AAAA,EACxC,QAAQA,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAQ;AAAA,EAC1C,OAAOM,GAAa,SAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,EAK5B,cAAcN,EAAE,KAAK,CAAC,SAAS,UAAU,CAAC,EAAE,SAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYpD,WAAWA,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO9C,QAAQA,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAQ;AAAA;AAAA;AAAA;AAAA,EAI1C,WAAWA,EAAE,OAAO;AAAA,IAChB,OAAOA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,IACnC,QAAQA,EAAE,SAAS,IAAI,EAAE;AAAA,IACzB,YAAYA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,EAChD,CAAK,EAAE,SAAQ;AACf,CAAC;AACuBA,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA,EAI7B,SAASA,EAAE,OAAM;AAAA,EACjB,YAAYA,EAAE,KAAK,CAAC,QAAQ,WAAW,UAAU,OAAO,CAAC;AAAA,EACzD,aAAaA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,EACzC,WAAWA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC9B,UAAUA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC7B,YAAYA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,EACxC,WAAWA,EAAE,SAAS,IAAG,EAAG,YAAW;AAC3C,CAAC;AACwBA,EAAE,OAAO;AAAA,EAC9B,YAAYA,EAAE,OAAM,EAAG,IAAG,EAAG,SAAQ;AAAA,EACrC,MAAMK;AAAA,EACN,OAAOL,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW,EAAG,SAAQ;AAAA,EAC9C,UAAUA,EAAE,OAAM,EAAG,SAAQ;AAAA;AAEjC,CAAC;AAYM,MAAMO,KAAYP,EAAE,OAAO;AAAA,EAC9B,KAAKA,EAAE,OAAM,EAAG,MAAMZ,IAAmB,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAa9D,GAAGY,EAAE,SAAS,IAAG,EAAG,YAAW,EAAG,IAAIE,EAAmB;AAAA,EACzD,GAAGF,EAAE,SAAS,IAAG,EAAG,YAAW,EAAG,IAAIE,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAczD,OAAOF,EAAE,OAAM,EAAG,IAAIG,EAAsB,EAAE,SAAQ;AAC1D,CAAC;AAMuBH,EAAE,OAAO;AAAA,EAC7B,MAAMA,EAAE,SAAS,IAAIN,EAAuB;AAAA,EAC5C,OAAOM,EAAE,OAAM,EAAG,IAAI,EAAE,EAAE,SAAQ;AAAA,EAClC,QAAQA,EAAE,MAAMO,EAAS,EAAE,IAAIX,EAAuB,EAAE,SAAQ;AACpE,CAAC,EAAE,OAAO,CAACY,MAAMA,EAAE,KAAK,SAAS,MAAMA,EAAE,QAAQ,UAAU,KAAK,GAAG,EAAE,SAAS,gDAA+C,CAAE;AAExH,MAAMC,KAAoBT,EAAE,KAAK,CAAC,QAAQ,SAAS,gBAAgB,mBAAmB,OAAO,CAAC;AAExEA,EAAE,OAAO;AAAA,EAClC,IAAIA,EAAE,OAAM;AAAA,EACZ,WAAWA,EAAE,OAAM;AAAA;AAAA;AAAA,EAGnB,QAAQA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC3B,MAAMA,EAAE,OAAM;AAAA,EACd,QAAQA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC3B,MAAMA,EAAE,OAAM;AAAA,EACd,IAAIA,EAAE,OAAM;AAAA;AAAA;AAAA,EAGZ,QAAQA,EAAE,MAAMO,EAAS,EAAE,IAAIX,EAAuB,EAAE,SAAQ;AAAA,EAChE,UAAUI,EAAE,QAAO,EAAG,SAAQ;AAAA,EAC9B,YAAYS,GAAkB,SAAQ;AAC1C,CAAC;AAEM,MAAMC,KAAeV,EAAE,OAAO;AAAA,EACjC,uBAAuBA,EAAE,OAAM,EAAG,YAAW;AAAA,EAC7C,mBAAmBA,EAAE,OAAM,EAAG,YAAW;AAAA,EACzC,QAAQA,EAAE,OAAM,EAAG,YAAW;AAAA,EAC9B,aAAaA,EAAE,OAAM,EAAG,YAAW;AAAA,EACnC,cAAcA,EAAE,QAAO;AAAA,EACvB,kBAAkBA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,EAC9C,mBAAmBA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,EAC/C,iBAAiBA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,EAC7C,mBAAmBA,EAAE,OAAM,EAAG,IAAG,EAAG,SAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5C,yBAAyBA,EAAE,SAAS,QAAQ,EAAE;AAAA;AAAA;AAAA;AAAA,EAI9C,aAAaA,EAAE,OAAM,EAAG,YAAW,EAAG,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/C,cAAcA,EAAE,KAAK,CAAC,SAAS,UAAU,CAAC,EAAE,SAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMpD,cAAcA,EAAE,QAAO,EAAG,SAAQ;AAAA,EAClC,cAAcA,EAAE,QAAO,EAAG,SAAQ;AAAA,EAClC,OAAOA,EAAE,QAAO,EAAG,SAAQ;AAAA,EAC3B,QAAQA,EAAE,QAAO,EAAG,SAAQ;AAAA,EAC5B,UAAUA,EAAE,OAAM,EAAG,IAAI,EAAE,EAAE,SAAQ;AAAA,EACrC,YAAYA,EAAE,OAAM,EAAG,YAAW,EAAG,SAAQ;AAAA,EAC7C,mBAAmBA,EAAE,OAAM,EAAG,YAAW,EAAG,SAAQ;AAAA;AAAA;AAAA,EAGpD,aAAaA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW,EAAG,SAAQ;AAAA,EACpD,aAAaA,EAAE,SAAS,IAAG,EAAG,YAAW;AAC7C,CAAC,GAEYW,KAAeD,GAAa,OAAO;AAAA,EAC5C,WAAWV,EAAE,OAAM;AAAA,EACnB,MAAMA,EAAE,OAAM;AAAA,EACd,WAAWA,EAAE,OAAM,EAAG,SAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,EAK9B,UAAUA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW,EAAG,SAAQ;AACrD,CAAC;AAC6BA,EAAE,OAAO;AAAA,EACnC,SAASA,EAAE,MAAMW,EAAY;AAAA,EAC7B,WAAWX,EAAE,SAAS,IAAG,EAAG,YAAW;AAC3C,CAAC;AAEM,MAAMY,KAAeZ,EAAE,OAAO;AAAA,EACjC,WAAWA,EAAE,OAAM;AAAA,EACnB,WAAWA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC9B,MAAMA,EAAE,OAAM;AAAA,EACd,mBAAmBA,EAAE,OAAM,EAAG,YAAW;AAAA;AAAA;AAAA;AAAA;AAAA,EAKzC,aAAaA,EAAE,OAAM,EAAG,YAAW,EAAG,QAAQ,CAAC;AAAA,EAC/C,aAAaA,EAAE,OAAM,EAAG,YAAW,EAAG,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/C,mBAAmBA,EAAE,OAAM,EAAG,IAAG,EAAG,QAAQ,EAAE;AAClD,CAAC;AAC2BA,EAAE,OAAO;AAAA,EACjC,SAASA,EAAE,MAAMY,EAAY;AAAA,EAC7B,WAAWZ,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAC3C,CAAC;AAE0BA,EAAE,OAAO;AAAA,EAChC,UAAUA,EAAE,OAAM;AACtB,CAAC;AAKM,MAAMa,KAAYb,EAAE,KAAK,CAAC,gBAAgB,UAAU,OAAO,UAAU,CAAC,GAChEc,KAAgBd,EAAE,OAAO;AAAA,EAClC,SAASA,EAAE,OAAM;AAAA,EACjB,aAAaA,EAAE,OAAM;AAAA;AAAA;AAAA,EAGrB,aAAaA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAChC,WAAWA,EAAE,OAAM,EAAG,SAAQ;AAAA;AAAA,EAC9B,YAAYA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC/B,YAAYA,EAAE,OAAM,EAAG,SAAQ;AAAA;AACnC,CAAC,GAQYe,KAAef,EAAE,KAAK,CAAC,SAAS,MAAM,CAAC,GACvCgB,KAAiBhB,EAAE,OAAO;AAAA,EACnC,IAAIA,EAAE,OAAM;AAAA,EACZ,MAAMA,EAAE,OAAM;AAAA,EACd,MAAMe,GAAa,QAAQ,MAAM;AAAA,EACjC,QAAQf,EAAE,MAAMc,EAAa;AAAA,EAC7B,OAAOd,EAAE,OAAM,EAAG,SAAQ;AAAA;AAC9B,CAAC;AAE6BA,EAAE,OAAO,EAAE,YAAYA,EAAE,OAAM,EAAE,CAAE;AACjCA,EAAE,OAAO,EAAE,OAAOA,EAAE,OAAM,EAAG,IAAG,EAAG,IAAI,CAAC,EAAC,CAAE;AACvCA,EAAE,OAAO;AAAA,EACzC,YAAYA,EAAE,OAAM;AAAA,EACpB,SAASA,EAAE,OAAM;AAAA,EACjB,MAAMa;AACV,CAAC;AAImCb,EAAE,OAAO,EAAE,UAAUA,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,GAAG,EAAC,CAAE;AAK9CA,EAAE,OAAO,EAAE,YAAYA,EAAE,OAAM,GAAI,UAAUA,EAAE,MAAMA,EAAE,OAAM,CAAE,EAAC,CAAE;AAEzEA,EAAE,OAAO;AAAA,EACrC,UAAUgB,GAAe,SAAQ;AAAA,EACjC,aAAahB,EAAE,OAAM,EAAG,IAAG,EAAG,SAAQ;AAAA,EACtC,SAASA,EAAE,OAAOA,EAAE,OAAM,GAAIa,EAAS;AAAA;AAC3C,CAAC;AACM,MAAMI,KAA2BjB,EAAE,OAAO;AAAA,EAC7C,UAAUA,EAAE,OAAM;AAAA,EAClB,MAAMA,EAAE,OAAM;AAAA,EACd,YAAYA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,EACxC,aAAaA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAC7C,CAAC;AACsCA,EAAE,OAAO;AAAA,EAC5C,UAAUA,EAAE,MAAMiB,EAAwB;AAC9C,CAAC;AACiCjB,EAAE,OAAO;AAAA,EACvC,UAAUgB;AAAA,EACV,OAAOhB,EAAE,OAAOA,EAAE,OAAM,GAAIA,EAAE,OAAOA,EAAE,OAAM,GAAIa,EAAS,CAAC;AAAA;AAAA,EAC3D,OAAOb,EAAE,OAAOA,EAAE,UAAUA,EAAE,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,EAItC,SAASA,EAAE,OAAOA,EAAE,OAAM,GAAIA,EAAE,QAAQ,EAAE,SAAQ;AAAA;AAAA;AAAA,EAGlD,UAAUA,EAAE,OAAOA,EAAE,OAAM,GAAIA,EAAE,QAAQ,EAAE,SAAQ;AAAA;AAAA;AAAA,EAGnD,QAAQA,EAAE,QAAO,EAAG,SAAQ;AAChC,CAAC;AACM,MAAMkB,KAAkB;AAAA,EAC3B,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP,eAAe;AAAA,EACf,SAAS;AAAA;AAAA,EAET,aAAa;AAAA;AAAA,EAEb,eAAe;AACnB,GAeaC,KAAenB,EAAE,OAAO;AAAA,EACjC,IAAIA,EAAE,OAAM;AAAA,EACZ,aAAaA,EAAE,OAAM;AAAA,EACrB,WAAWA,EAAE,OAAM,EAAG,SAAQ;AAClC,CAAC;AAE6BA,EAAE,OAAO;AAAA,EACnC,OAAOA,EAAE,MAAMmB,EAAY;AAC/B,CAAC;AAGM,MAAMC,KAAgBpB,EAAE,cAAcD,IAAMC,EAAE,MAAMA,EAAE,OAAM,CAAE,CAAC;AAExCA,EAAE,OAAO,EAAE,OAAOoB,GAAa,CAAE;AAExD,MAAMC,KAAoBrB,EAAE,OAAO;AAAA,EACtC,SAASA,EAAE,OAAM;AAAA,EACjB,MAAMD;AAAA,EACN,cAAcA;AAAA;AAAA,EAEd,OAAOC,EAAE,OAAM;AAAA;AAAA,EAEf,gBAAgBA,EAAE,OAAM;AAAA,EACxB,eAAeA,EAAE,OAAM;AAAA,EACvB,OAAOA,EAAE,OAAOA,EAAE,OAAM,GAAID,EAAI;AAAA;AACpC,CAAC;AAGkCC,EAAE,OAAO;AAAA,EACxC,OAAOA,EAAE,MAAMmB,EAAY;AAAA,EAC3B,QAAQnB,EAAE,MAAMqB,EAAiB;AAAA,EACjC,SAASrB,EAAE,MAAMA,EAAE,OAAM,CAAE;AAAA,EAC3B,QAAQA,EAAE,OAAM;AAAA,EAChB,QAAQA,EAAE,QAAO;AAAA,EACjB,OAAOA,EAAE,OAAOA,EAAE,UAAUA,EAAE,QAAQ;AAAA,EACtC,SAASA,EAAE,OAAOA,EAAE,UAAUA,EAAE,QAAQ;AAAA;AAAA;AAAA,EAGxC,UAAUA,EAAE,OAAOA,EAAE,OAAM,GAAIA,EAAE,QAAQ,EAAE,SAAQ;AAAA,EACnD,YAAYA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,EACxC,SAASoB;AACb,CAAC;AACM,MAAME,KAAkB;AAAA;AAAA;AAAA;AAAA,EAI3B,SAAS;AACb;AAKiCtB,EAAE,OAAO,CAAA,CAAE;AACfA,EAAE,OAAO,EAAE,OAAOA,EAAE,QAAO,EAAE,CAAE;AAC/BA,EAAE,OAAO;AAAA,EAClC,QAAQA,EAAE,QAAO;AAAA,EACjB,OAAOA,EAAE,MAAMA,EAAE,OAAM,CAAE;AAAA;AAC7B,CAAC;AACM,MAAMuB,KAAe;AAAA,EACxB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA;AACX,GAKaC,KAAc;AAAA,EACvB,QAAQ;AAAA;AAAA,EACR,QAAQ;AAAA;AAAA,EACR,MAAM;AAAA;AACV;AAE4BxB,EAAE,OAAO;AAAA,EACjC,QAAQA,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAQ;AAC9C,CAAC;AAE4BA,EAAE,OAAO;AAAA,EAClC,QAAQA,EAAE,OAAM,EAAG,SAAQ;AAC/B,CAAC;AC7bM,MAAMyB,KAAiB;AAAA,EAC1B;AAAA,IACI,IAAI;AAAA,IACJ,YAAY;AAAA,MACR,EAAE,IAAI,QAAQ,OAAO,UAAS;AAAA,MAC9B,EAAE,IAAI,UAAU,OAAO,UAAS;AAAA,MAChC,EAAE,IAAI,UAAU,OAAO,UAAS;AAAA,MAChC,EAAE,IAAI,UAAU,OAAO,UAAS;AAAA,MAChC,EAAE,IAAI,QAAQ,OAAO,UAAS;AAAA,MAC9B,EAAE,IAAI,WAAW,OAAO,UAAS;AAAA,MACjC,EAAE,IAAI,YAAY,OAAO,UAAS;AAAA,MAClC,EAAE,IAAI,SAAS,OAAO,UAAS;AAAA,IAC3C;AAAA,EACA;AAAA,EACI;AAAA,IACI,IAAI;AAAA,IACJ,YAAY;AAAA,MACR,EAAE,IAAI,UAAU,OAAO,UAAS;AAAA,MAChC,EAAE,IAAI,SAAS,OAAO,UAAS;AAAA,MAC/B,EAAE,IAAI,UAAU,OAAO,WAAW,KAAK,EAAC;AAAA,MACxC,EAAE,IAAI,aAAa,OAAO,UAAS;AAAA,IAC/C;AAAA,EACA;AAAA,EACI;AAAA,IACI,IAAI;AAAA,IACJ,YAAY;AAAA,MACR,EAAE,IAAI,QAAQ,OAAO,UAAS;AAAA,MAC9B,EAAE,IAAI,WAAW,OAAO,UAAS;AAAA,MACjC,EAAE,IAAI,WAAW,OAAO,UAAS;AAAA,MACjC,EAAE,IAAI,aAAa,OAAO,UAAS;AAAA,MACnC,EAAE,IAAI,QAAQ,OAAO,WAAW,KAAK,EAAC;AAAA,MACtC,EAAE,IAAI,OAAO,OAAO,UAAS;AAAA,IACzC;AAAA,EACA;AAAA,EACI;AAAA,IACI,IAAI;AAAA,IACJ,YAAY;AAAA,MACR,EAAE,IAAI,cAAc,OAAO,UAAS;AAAA,MACpC,EAAE,IAAI,WAAW,OAAO,UAAS;AAAA,MACjC,EAAE,IAAI,WAAW,OAAO,UAAS;AAAA,MACjC,EAAE,IAAI,SAAS,OAAO,UAAS;AAAA,MAC/B,EAAE,IAAI,UAAU,OAAO,UAAS;AAAA,IAC5C;AAAA,EACA;AACA,GAEMC,KAAUD,GAAe,QAAQ,CAACt1B,MAAMA,EAAE,UAAU,GAI7Cw1B,KAAkBD,GAAQ,IAAI,CAACE,MAAMA,EAAE,EAAE,GACzCC,KAAmB,OAAO,YAAYH,GAAQ,IAAI,CAACE,MAAM,CAACA,EAAE,IAAIA,EAAE,KAAK,CAAC,CAAC,GAEzEE,KAAoB,OAAO,YAAYJ,GAAQ,IAAI,CAACE,MAAM,CAACA,EAAE,IAAI,SAASA,IAAIA,EAAE,MAAM,CAAC,CAAC,CAAC;AAQ/F,SAASG,GAAah5B,GAAI;AAC7B,QAAMi5B,IAAMF,GAAkB/4B,CAAE;AAChC,SAAO,yBAAyBA,CAAE,OAAOi5B,IAAM,IAAI,MAAMA,CAAG,KAAK,EAAE;AACvE;AAEO,SAASC,GAAcC,GAAQ;AAClC,SAAO,CAAC,CAACA,KAAUP,GAAgB,SAASO,CAAM;AACtD;ACvEY,MAACC,KAAsB,GAEtBC,KAAkB,KAElBC,KAAoB,KAGpBC,KAAqB,KAErBC,KAAgB,KAIhBC,KAAkC,KAGlCC,KAAsB,KAGtBC,KAA+B,KAG/BC,KAAiC,KAEjCC,KAA0B,IAG1BC,KAAsB,KAQtBC,KAAyB,GAGzBC,KAAkC,IAGlCC,KAAyB,GAGzBC,KAAqB,KAqBrBC,KAAqB,KAGrBC,KAA+B,OAG/BC,KAAuC,KAIvCC,KAAwB,mBCpExBC,KAAkB,YCElBC,KAAiC,EAAE,MAAM,OAAO,SAAS,EAAC,GAC1DC,KAA0B,CAAC,OAAO,MAAM,IAAI;AAClD,SAASC,GAAuB/1B,GAAG;AACtC,SAAO,OAAOA,KAAM,YAAY81B,GAAwB,SAAS91B,CAAC;AACtE;AAEO,SAASg2B,GAA8BC,GAAK;AAC/C,QAAMC,IAAKD,KAAO,OAAOA,KAAQ,WAAWA,IAAM,IAC5C3M,IAAOyM,GAAuBG,EAAE,IAAI,IAAIA,EAAE,OAAOL,GAA+B,MAChF,IAAI,OAAOK,EAAE,OAAO,GACpBC,IAAU,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI;AACjF,SAAO,EAAE,MAAA7M,GAAM,SAAA6M,EAAO;AAC1B;AAKA,SAASC,GAAaC,GAAU;AAC5B,MAAIC,IAAI;AACR,WAASl6B,IAAI,GAAGA,IAAIi6B,EAAS,QAAQj6B;AACjC,IAAAk6B,KAAKD,EAAS,WAAWj6B,CAAC,GAC1Bk6B,IAAI,KAAK,KAAKA,GAAG,QAAU,MAAM;AAErC,SAAOA,MAAM;AACjB;AASO,SAASC,GAAmBC,GAAMH,GAAUI,GAAU;AACzD,MAAIA,MAAa;AACb,WAAO;AACX,MAAIA,MAAa;AACb,WAAO;AACX,QAAMjnB,IAAIwmB,GAA8BQ,CAAI;AAC5C,SAAIhnB,EAAE,SAAS,OACJ,aACPA,EAAE,SAAS,SAIXA,EAAE,WAAW,IACN,UACPA,EAAE,WAAW,OAEZ6mB,KAEED,GAAaC,CAAQ,IAAI,MAAM7mB,EAAE,UAH7B,aAEA;AAEf;AC5CO,MAAMknB,KAAiBpE,EAAE,KAAK,CAAC,OAAO,UAAU,QAAQ,CAAC,GAUnDqE,KAAkBrE,EAAE,KAAK;AAAA,EAClC;AAAA,EAAW;AAAA,EAAY;AAAA,EAAY;AAAA,EAAa;AAAA,EAAS;AAAA,EAAY;AACzE,CAAC,GAqBYsE,KAAyB;AAAA,EAClC,SAAS,CAAC,YAAY,UAAU;AAAA,EAChC,UAAU,CAAC,YAAY,YAAY,QAAQ;AAAA,EAC3C,UAAU,CAAC,aAAa,QAAQ;AAAA,EAChC,WAAW,CAAC,SAAS,QAAQ;AAAA,EAC7B,OAAO,CAAA;AAAA,EACP,UAAU,CAAA;AAAA,EACV,QAAQ,CAAC,UAAU;AACvB;AAE0C,OAAO,KAAKA,EAAsB,EACvE,OAAO,CAAAn4B,MAAKm4B,GAAuBn4B,CAAC,EAAE,WAAW,CAAC;AAkBhD,MAAMo4B,KAAavE,EAAE,OAAO;AAAA,EAC/B,IAAIA,EAAE,SAAS,IAAI,CAAC;AAAA;AAAA,EAEpB,aAAaA,EAAE,SAAS,IAAI,CAAC;AAAA,EAC7B,MAAMoE;AAAA;AAAA,EAEN,QAAQpE,EAAE,SAAS,IAAI,CAAC;AAAA,EACxB,OAAOA,EAAE,OAAM,EAAG,SAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW1B,QAAQA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC3B,OAAOqE;AAAA,EACP,WAAWrE,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA,EACvC,WAAWA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA;AAAA,EAEvC,OAAOA,EAAE,OAAM,EAAG,SAAQ;AAAA;AAAA;AAAA,EAG1B,OAAOA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW,EAAG,SAAQ;AAClD,CAAC,GAGYwE,KAA8B,MAE9BC,KAA6B,KAI7BC,KAA8B;AAET1E,EAAE,OAAO;AAAA,EACvC,MAAMoE;AAAA,EACN,QAAQpE,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAIwE,EAA2B;AAAA,EACzD,OAAOxE,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAIyE,EAA0B,EAAE,SAAQ;AAAA;AAAA,EAEjE,QAAQzE,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI0E,EAA2B,EAAE,SAAQ;AACvE,CAAC;AAGiC1E,EAAE,OAAO;AAAA,EACvC,QAAQA,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAIyE,EAA0B,EAAE,SAAQ;AACtE,CAAC;AAEgCzE,EAAE,OAAO;AAAA,EACtC,aAAaA,EAAE,MAAMuE,EAAU;AACnC,CAAC;AAoCiCvE,EAAE,OAAO;AAAA,EACvC,OAAOA,EAAE,QAAQ,4BAA4B;AAAA;AAAA,EAE7C,cAAcA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAAA;AAAA,EAE1C,UAAUA,EAAE,OAAM,EAAG,IAAG,EAAG,YAAW;AAC1C,CAAC;ACvKD,MAAM2E,KAAa,6BAEbC,KAAe;AAWd,SAASC,GAAiBrgC,GAAO;AAGpC,MAFI,CAACA,EAAM,WAAW,GAAG,KAAKA,EAAM,WAAW,IAAI,KAE/C,SAAS,KAAKA,CAAK,KAAK,CAAC,GAAGA,CAAK,EAAE,KAAK,CAACo9B,MAAMA,EAAE,WAAW,CAAC,IAAI,MAAQA,EAAE,WAAW,CAAC,MAAM,GAAI;AACjG,WAAO;AACX,MAAI;AACA,WAAO,IAAI,IAAIp9B,GAAOogC,EAAY,EAAE,WAAWA;AAAA,EACnD,QACM;AACF,WAAO;AAAA,EACX;AACJ;AACA,MAAME,KAAiB9E,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,OAAO6E,IAAkB;AAAA,EACvE,SAAS;AACb,CAAC,GACKE,KAAgB;AAAA,EAClB,IAAI/E,EAAE,SAAS,MAAM2E,EAAU;AAAA,EAC/B,MAAM3E,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,EAC9B,OAAO8E,GAAe,SAAQ;AAClC,GACaE,KAAkBhF,EAAE,OAAO,EAAE,GAAG+E,IAAe,MAAM/E,EAAE,QAAQ,QAAQ,GAAG,KAAK8E,GAAc,CAAE,EAAE,OAAM,GACvGG,KAAoBjF,EAAE,MAAMgF,EAAe,EAAE,IAAI,EAAE,EAAE,OAAO,CAACE,MAAU,IAAI,IAAIA,EAAM,IAAI,CAACC,MAAMA,EAAE,EAAE,CAAC,EAAE,SAASD,EAAM,QAAQ,EAAE,SAAS,0BAAyB,CAAE,GAGpKE,KAAuB;AAAA,EAChC,EAAE,IAAI,aAAa,MAAM,aAAa,MAAM,UAAU,KAAK,sCAAqC;AACpG,GC7CaC,KAAarF,EAAE,KAAK,CAAC,WAAW,MAAM,CAAC,GACvCsF,KAAatF,EAAE,OAAO;AAAA,EAC/B,QAAQqF;AAAA;AAAA,EAER,IAAIrF,EAAE,OAAM;AAAA,EACZ,OAAOA,EAAE,OAAM;AAAA,EACf,MAAMA,EAAE,OAAM,EAAG,IAAG,EAAG,SAAQ;AAAA;AAAA,EAE/B,QAAQA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC3B,UAAUA,EAAE,OAAM,EAAG,IAAG,EAAG,SAAQ;AAAA;AAAA,EAEnC,QAAQA,EAAE,OAAM,EAAG,SAAQ;AAAA;AAAA,EAE3B,QAAQA,EAAE,OAAM;AAAA;AAAA,EAEhB,aAAaA,EAAE,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtB,SAASA,EAAE,QAAO;AACtB,CAAC;AAC4BA,EAAE,OAAO;AAAA,EAClC,SAASA,EAAE,MAAMsF,EAAU;AAAA;AAAA,EAE3B,SAAStF,EAAE,MAAMqF,EAAU;AAC/B,CAAC;AACM,MAAME,KAAcvF,EAAE,OAAO;AAAA,EAChC,IAAIA,EAAE,OAAM;AAAA,EACZ,KAAKA,EAAE,OAAM;AAAA,EACb,OAAOA,EAAE,OAAM;AAAA,EACf,SAASA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC5B,WAAWA,EAAE,OAAM,EAAG,SAAQ;AAAA,EAC9B,OAAOA,EAAE,OAAM,EAAG,SAAQ;AAC9B,CAAC;AAC6BA,EAAE,OAAO,EAAE,SAASA,EAAE,MAAMuF,EAAW,EAAC,CAAE;AAC1CvF,EAAE,OAAO;AAAA,EACnC,QAAQqF;AAAA,EACR,IAAIrF,EAAE,SAAS,MAAM,YAAY;AACrC,CAAC;AAC8BA,EAAE,OAAO,EAAE,QAAQA,EAAE,OAAM,GAAI,OAAOA,EAAE,SAAQ,CAAE;AAErE,MAACwF,KAAmB,GACnBC,KAAmB;ACnD7B,IAACC,KAAY;AAAA,EACd,OAAO,KAAK,OAAO;AAAA,EACnB,OAAO,KAAK,OAAO;AACrB,GACIC,KAAuB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GACIC,KAAuB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GACIC,KAAqB;AAAA,EACvB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAe;AAAA,EACf,cAAc;AAAA,EACd,kBAAkB;AACpB;AACA,SAASC,GAAW9e,GAAM;AACxB,QAAM,IAAIA,EAAK,YAAW;AAC1B,SAAI2e,GAAqB,SAAS,CAAC,IAAU,UACzCC,GAAqB,SAAS,CAAC,KAAK,KAAKC,KACpC,UAEF;AACT;AACA,IAAIE,KAAuB,IACvBC,KAAqB,KAGrBC,KAAW,cAAc,MAAM;AAAA,EACjC;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA,EACA,YAAYvlB,GAAQlb,GAASoK,IAAS,MAAMs2B,IAAoB,MAAM;AACpE,UAAM1gC,CAAO,GACb,KAAK,OAAO,YACZ,KAAK,SAASkb,GACd,KAAK,SAAS9Q,GACd,KAAK,oBAAoBs2B;AAAA,EAC3B;AACF;AACA,SAASC,GAAgBC,GAAQC,IAAM,KAAK,IAAG,GAAI;AACjD,MAAI,CAACD,EAAQ,QAAO;AACpB,QAAME,IAAUF,EAAO,KAAI;AAC3B,MAAI,CAACE,EAAS,QAAO;AACrB,QAAMC,IAAU,OAAOD,CAAO;AAC9B,MAAI,OAAO,SAASC,CAAO,EAAG,QAAOA,KAAW,IAAI,KAAK,KAAKA,CAAO,IAAI;AACzE,QAAMC,IAAK,KAAK,MAAMF,CAAO;AAC7B,SAAI,OAAO,MAAME,CAAE,IAAU,OACtB,KAAK,IAAI,GAAG,KAAK,MAAMA,IAAKH,KAAO,GAAG,CAAC;AAChD;AACA,SAASI,GAAgB72B,GAAQ;AAC/B,UAAQA,GAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACb;AACA;AACA,eAAe82B,GAAkB3mB,GAAU;AACzC,QAAMW,IAAS+lB,GAAgB1mB,EAAS,MAAM;AAC9C,MAAIva,IAAU,uBAAuBua,EAAS,MAAM;AACpD,MAAI;AACF,UAAM0V,IAAO,MAAM1V,EAAS,KAAI;AAChC,IAAI,OAAO0V,GAAM,WAAY,WAAUjwB,IAAUiwB,EAAK,UAC7C,OAAOA,GAAM,SAAU,aAAUjwB,IAAUiwB,EAAK;AAAA,EAC3D,QAAQ;AAAA,EACR;AACA,SAAO,IAAIwQ;AAAA,IACTvlB;AAAA,IACAlb;AAAA,IACAua,EAAS;AAAA,IACTW,MAAW,iBAAiBylB,GAAgBpmB,EAAS,QAAQ,IAAI,aAAa,CAAC,IAAI;AAAA,EACvF;AACA;AAGA,IAAI4mB,KAAsB,mBACtBC,KAAc;AAClB,SAASC,GAAUC,GAAM;AACvB,MAAIA,EAAK,SAAS;AAChB,UAAM,IAAIb,GAAS,WAAW,eAAe;AAE/C,QAAMc,IAAOD,EAAK,OAAOhB,GAAWgB,EAAK,IAAI,IAAI;AACjD,MAAIA,EAAK,QAAQ,CAACC;AAChB,UAAM,IAAId,GAAS,oBAAoB,GAAGa,EAAK,IAAI,2CAA2C;AAEhG,QAAME,IAAMD,IAAOrB,GAAUqB,CAAI,IAAI,KAAK,IAAIrB,GAAU,OAAOA,GAAU,KAAK;AAC9E,MAAIoB,EAAK,OAAOE;AACd,UAAM,IAAIf,GAAS,aAAa,WAAWa,EAAK,IAAI,0BAA0BE,CAAG,EAAE;AAEvF;AACA,SAASC,GAActD,GAAK;AAC1B,MAAI,OAAOA,KAAQ,YAAYA,MAAQ,KAAM,QAAO;AACpD,QAAMzkB,IAAIykB;AACV,SAAI,OAAOzkB,EAAE,OAAQ,YAAY,CAACA,EAAE,MAAY,OACzC;AAAA,IACL,KAAKA,EAAE;AAAA,IACP,OAAO,OAAOA,EAAE,SAAU,WAAWA,EAAE,QAAQ;AAAA,IAC/C,MAAM,MAAM,QAAQA,EAAE,IAAI,IAAIA,EAAE,KAAK,OAAO,CAACuU,MAAM,OAAOA,KAAM,QAAQ,IAAI,CAAA;AAAA,IAC5E,OAAO,OAAOvU,EAAE,SAAU,YAAYA,EAAE,QAAQ,IAAIA,EAAE,QAAQ;AAAA,IAC9D,QAAQ,OAAOA,EAAE,UAAW,YAAYA,EAAE,SAAS,IAAIA,EAAE,SAAS;AAAA,IAClE,aAAa,OAAOA,EAAE,eAAgB,WAAWA,EAAE,cAAc;AAAA,EACrE;AACA;AACA,SAASgoB,GAAgBviC,GAAS;AAChC,QAAMwiC,IAAUxiC,EAAQ,QAAQ,QAAQ,QAAQ,EAAE,GAC5CyiC,IAAaziC,EAAQ,cAAcgiC,IACnCU,IAAU1iC,EAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;AACjE,iBAAe8N,EAAQrL,GAAKY,GAAM;AAChC,QAAI+X;AACJ,QAAI;AACF,MAAAA,IAAW,MAAMsnB,EAAQjgC,GAAKY,CAAI;AAAA,IACpC,SAASs/B,GAAK;AACZ,YAAIA,aAAe,SAASA,EAAI,SAAS,eAAoBA,IACvD,IAAIrB,GAAS,WAAWqB,aAAe,QAAQA,EAAI,UAAU,gBAAgB;AAAA,IACrF;AACA,QAAI,CAACvnB,EAAS,GAAI,OAAM,MAAM2mB,GAAkB3mB,CAAQ;AACxD,WAAOA;AAAA,EACT;AACA,SAAO;AAAA,IACL,SAAAonB;AAAA,IACA,YAAAC;AAAA,IACA,MAAM,OAAON,GAAMS,GAAe;AAChC,aAAAV,GAAUC,CAAI,GASP,OARU,MAAMr0B,EAAQ20B,GAAY;AAAA,QACzC,QAAQ;AAAA,QACR,MAAMN;AAAA,QACN,QAAQS,GAAe;AAAA;AAAA;AAAA,QAGvB,aAAa;AAAA,MACrB,CAAO,GACqB,KAAI;AAAA,IAC5B;AAAA,IACA,OAAOthC,GAAK;AACV,aAAO,GAAGkhC,CAAO,IAAIlhC,EAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IAC9C;AAAA,IACA,MAAMzB,GAAO;AACX,aAAOoiC,GAAY,KAAKpiC,CAAK;AAAA,IAC/B;AAAA,IACA,UAAUgjC,GAAUC,GAAkB;AACpC,YAAM7/B,IAAO4/B,EAAS,QAAQ,QAAQ,EAAE,GAClCE,IAAiBD,GAAkB;AACzC,aAAO;AAAA,QACL,MAAM,OAAOE,IAAgB,IAAI;AAC/B,gBAAMt9B,IAAS,IAAI,gBAAe,GAC5Bu9B,IAAQD,EAAc,OAAO,KAAI;AACvC,UAAIC,KAAOv9B,EAAO,IAAI,KAAKu9B,CAAK,GAChCv9B,EAAO,IAAI,SAAS,OAAOs9B,EAAc,SAAS5B,EAAoB,CAAC,GACnE4B,EAAc,UAAQt9B,EAAO,IAAI,UAAUs9B,EAAc,MAAM;AAMnE,gBAAMlS,IAAO,OALI,MAAMhjB,EAAQ,GAAG7K,CAAI,IAAIyC,EAAO,SAAQ,CAAE,IAAI;AAAA,YAC7D,QAAQ;AAAA,YACR,QAAQs9B,EAAc;AAAA,YACtB,aAAa;AAAA,UACzB,CAAW,GAC2B,KAAI;AAEhC,iBAAO;AAAA,YACL,UAFW,MAAM,QAAQlS,EAAK,OAAO,IAAIA,EAAK,UAAU,CAAA,GAE1C,IAAIwR,EAAa,EAAE,OAAO,CAACn9B,MAAMA,MAAM,IAAI;AAAA,YACzD,MAAM,OAAO2rB,EAAK,QAAS,YAAYA,EAAK,OAAOA,EAAK,OAAO;AAAA,UAC3E;AAAA,QACQ;AAAA,QACA,UAAUxvB,GAAK4hC,GAAY;AACzB,gBAAMC,IAAUD,GAAY,WAAWH,GACjCE,IAAQE,IAAU,YAAY,mBAAmBA,CAAO,CAAC,KAAK;AACpE,UAAKT,EAAQ,GAAGz/B,CAAI,IAAI,mBAAmB3B,CAAG,CAAC,OAAO2hC,CAAK,IAAI;AAAA,YAC7D,QAAQ;AAAA,YACR,aAAa;AAAA,UACzB,CAAW,EAAE,MAAM,MAAA;AAAA,WAAY;AAAA,QACvB;AAAA,MACR;AAAA,IACI;AAAA,EACJ;AACA;AAGA,SAASG,GAAmBC,GAAeC,IAAQ,CAAC,OAAO,GAAG;AAC5D,MAAI,CAACD,EAAe,QAAO,CAAA;AAC3B,QAAME,IAAS,CAACpB,MAASqB,GAAWrB,GAAMmB,CAAK,GACzCG,IAAYJ,EAAc,QAAQ,MAAM,KAAKA,EAAc,KAAK,IAAI,CAAA;AAC1E,SAAII,EAAU,SAAS,IAAUA,EAAU,OAAOF,CAAM,KAC1CF,EAAc,QAAQ,MAAM,KAAKA,EAAc,KAAK,IAAI,CAAA,GACzD,OAAO,CAACK,MAASA,EAAK,SAAS,MAAM,EAAE,IAAI,CAACA,MAASA,EAAK,UAAS,CAAE,EAAE,OAAO,CAACvB,MAASA,MAAS,IAAI,EAAE,OAAOoB,CAAM;AACnI;AACA,SAASI,GAAcC,GAAcN,IAAQ,CAAC,OAAO,GAAG;AACtD,SAAKM,GAAc,QACZ,MAAM,KAAKA,EAAa,KAAK,EAAE,OAAO,CAACzB,MAASqB,GAAWrB,GAAMmB,CAAK,CAAC,IAD7C,CAAA;AAEnC;AACA,SAASE,GAAWrB,GAAMmB,GAAO;AAC/B,MAAI,CAACnB,EAAK,KAAM,QAAO;AACvB,QAAMC,IAAOjB,GAAWgB,EAAK,IAAI;AACjC,SAAOC,MAAS,QAAQkB,EAAM,SAASlB,CAAI;AAC7C;AAIA,eAAeyB,GAAa1B,GAAM;AAChC,QAAM2B,IAAU,WAAW;AAC3B,MAAI,OAAOA,KAAY,WAAY,QAAO;AAC1C,MAAI;AACF,UAAMC,IAAS,MAAMD,EAAQ3B,CAAI,GAC3B6B,IAAO,EAAE,OAAOD,EAAO,OAAO,QAAQA,EAAO,OAAM;AACzD,WAAAA,EAAO,QAAK,GACLC;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;ACxNA,IAAIC,KAAqD,MACrDzB,KAAkBhI;AAQf,SAAS0J,GAAmBC,GAAwC;AACzE,EAAIA,EAAO,YAAS3B,KAAU2B,EAAO;AACvC;AAGO,SAASC,KAA8B;AAC5C,SAAO5B,GAAQ,QAAQ,QAAQ,EAAE;AACnC;AAGO,SAAS6B,KAA0B;AACxC,QAAMphC,IAAOmhC,GAAA;AACb,UAAI,CAACH,MAAUA,GAAO,SAAShhC,OAC7BghC,KAAS,EAAE,MAAAhhC,GAAM,QAAQs/B,GAAgB,EAAE,SAASt/B,EAAA,CAAM,EAAA,IAErDghC,GAAO;AAChB;AAkBO,SAASK,GAAoBhjC,GAA4B;AAG9D,SAFI,CAACo5B,GAAep5B,CAAG,KAEnB,CADS8iC,GAAA,IACK,OACXC,GAAA,EAAe,OAAO/iC,CAAG;AAClC;ACjDO,MAAMijC,KAAmC;AAAA,EAC9C,cAAoD,oBAAoB5J,EAAiB;AAAA,EACzF,gBAAgB;AAAA,EAChB,SAAsFH;AACxF;AAGA,IAAIgK,KAAkC,EAAE,GAAGD,GAAA;AAEpC,SAASE,GAAiBN,GAAmC;AAElE,QAAMO,IAAW,OAAO;AAAA,IACtB,OAAO,QAAQP,CAAM,EAAE,OAAO,CAAC,CAACr7B,GAAGC,CAAC,MAAMA,MAAM,MAAS;AAAA,EAAA;AAE3D,EAAAy7B,KAAgB,EAAE,GAAGA,IAAe,GAAGE,EAAA,GAKvCR,GAAmB,EAAE,SAASM,GAAc,QAAA,CAAS;AACvD;AAEO,SAASG,KAAqC;AACnD,SAAOH;AACT;AAGO,MAAMI,KAAgBC,GAAgCN,EAAc;AAEpE,SAASO,KAA8B;AAC5C,SAAOC,GAAWH,EAAa;AACjC;AAGO,SAASI,GAAgBb,GAAkC;AAChE,SAAOA,EAAO,cAAc,QAAQ,OAAO,EAAE,KAAK;AACpD;AAGO,SAASc,KAAiC;AAC/C,SAAOD,GAAgBL,IAAkB;AAC3C;ACrDO,MAAMO,KAAe;AAAA,EAC1B,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,SAAS,CAACC,GAAeC,GAAoBC,MAC3C,mBAAmBF,CAAK,IAAIC,CAAU,IAAIC,CAAO;AACrD;ACPA,SAASC,KAA0B;AACjC,MAAI;AAUF,WAAO,WAAW,gBAAgB;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAASC,GAAWjkC,GAA4B;AACrD,MAAI;AACF,WAAOgkC,GAAA,GAAW,QAAQhkC,CAAG,KAAK;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAASkkC,GAAYlkC,GAAazB,GAAwB;AAC/D,MAAI;AACF,UAAM2H,IAAI89B,GAAA;AAIV,WAAK99B,KACLA,EAAE,QAAQlG,GAAKzB,CAAK,GACb,MAFQ;AAAA,EAGjB,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAGO,SAAS4lC,KAAuB;AACrC,MAAI;AACF,UAAMj+B,IAAI89B,GAAA;AACV,QAAI,CAAC99B,EAAG,QAAO,CAAA;AACf,UAAM2E,IAAiB,CAAA;AACvB,aAAShH,IAAI,GAAGA,IAAIqC,EAAE,QAAQrC,KAAK;AACjC,YAAM8O,IAAIzM,EAAE,IAAIrC,CAAC;AACjB,MAAI8O,MAAM,QAAM9H,EAAK,KAAK8H,CAAC;AAAA,IAC7B;AACA,WAAO9H;AAAA,EACT,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACF;AAGO,SAASu5B,GAAapkC,GAAmB;AAC9C,MAAI;AACF,IAAAgkC,GAAA,GAAW,WAAWhkC,CAAG;AAAA,EAC3B,QAAQ;AAAA,EAAwB;AAClC;AAOO,SAASqkC,GAAerkC,GAA6B;AAC1D,QAAM09B,IAAMuG,GAAWjkC,CAAG;AAC1B,SAAI09B,MAAQ,OAAa,OACrBA,MAAQ,SAAe,KACvBA,MAAQ,UAAgB,KACrB;AACT;ACxEA,MAAM4G,yBAAe,IAAA;AACrB,IAAIC,KAAU;AAEP,SAASC,GAAoBnnB,GAAc9e,GAAsB;AACtE,EAAA+lC,GAAS,IAAIjnB,GAAM9e,CAAK,GACpBgmC,MAASE,GAAQpnB,GAAM9e,CAAK;AAClC;AAEO,SAASmmC,KAA2B;AACzC,EAAAH,KAAU;AACV,aAAW,CAAClnB,GAAM9e,CAAK,KAAK+lC,GAAU,CAAAG,GAAQpnB,GAAM9e,CAAK;AAC3D;AAEA,SAASkmC,GAAQpnB,GAAc9e,GAAsB;AACnD,EAAI,OAAO,SAAW,QACrB,OAA8C8e,CAAI,IAAI9e;AACzD;ACUA,MAAMomC,KAAyB,CAAA,GACzBC,KAAc;AAGpB,IAAIC,KAAuB,CAAA,GACvBC,KAAwD;AAC5D,MAAMC,KAAkB,KAClBC,KAAuB;AAG7B,IAAIC,KAAqE;AAMlE,SAASC,GAAkBp4B,GAA2D;AAC3F,EAAAm4B,KAAqBn4B;AACvB;AAGO,SAASq4B,KAA8B;AAC5C,SAAOlB,GAAWL,GAAa,gBAAgB,MAAM;AACvD;AAGO,SAASwB,KAA0B;AACxC,MAAI,OAAO,SAAW,IAAa,QAAO;AAO1C,MAJI,OAAO,gBAGI,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAC9C,IAAI,OAAO,MAAM,OAAQ,QAAO;AAK3C,QAAMC,IAASpB,GAAWL,GAAa,UAAU;AACjD,SAAOyB,MAAW,QAAQA,MAAW;AACvC;AAGA,SAASC,KAA2C;AAClD,QAAMD,IAASpB,GAAWL,GAAa,UAAU;AACjD,MAAI,CAACyB,KAAUA,MAAW,OAAQ,QAAO;AAGzC,QAAME,IAAaF,EAAO,MAAM,GAAG,EAAE,IAAI,CAAA1J,MAAKA,EAAE,KAAA,EAAO,YAAA,CAAa,EAAE,OAAO,OAAO;AACpF,SAAO4J,EAAW,SAAS,IAAI,IAAI,IAAIA,CAAU,IAAI;AACvD;AAGA,SAASC,KAAqB;AAE5B,8BADgB,KAAA,GACL,mBAAmB,SAAS;AAAA,IACrC,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,wBAAwB;AAAA,EAAA,CACzB;AACH;AAGA,SAASC,GAAaxS,GAAiB;AACrC,EAAA0R,GAAW,KAAK1R,CAAK,GACjB0R,GAAW,SAASC,MACtBD,GAAW,MAAA;AAEf;AAGA,MAAMe,KAAS;AAAA,EACb,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AACR;AAGA,SAASC,GAAcC,GAAuB;AAC5C,MAAI;AAAE,WAAO,KAAK,UAAUA,CAAI;AAAA,EAAG,QAAQ;AAAE,WAAO;AAAA,EAAoB;AAC1E;AAaA,SAASC,GACPC,GACAC,GACAC,GACAC,GACAC,GACA3mC,GACAqmC,GACM;AACN,QAAM3S,IAAkB;AAAA,IACtB,OAAA6S;AAAA,IACA,UAAAI;AAAA,IACA,SAAA3mC;AAAA,IACA,MAAAqmC;AAAA,IACA,WAAW,KAAK,IAAA;AAAA,EAAI;AAUtB,MARAH,GAAaxS,CAAK,IAEd+S,KAEOb,SACTgB,GAAkBlT,CAAK,GAGrB,CAACgT,GAAY;AACf,QAAI,CAACb,KAAkB;AACvB,UAAMgB,IAAUd,GAAA;AAChB,QAAIc,KAAW,CAACA,EAAQ,IAAIF,EAAS,YAAA,CAAa,EAAG;AAAA,EACvD;AAEA,QAAMG,IAAOb,GAAA,GAGPc,IAASV,MAAS,SAAY,MAAMD,GAAcC,CAAI,IAAI;AAChE,EAAAG;AAAA,IACE,MAAMM,CAAI,QAAQH,CAAQ,OAAO3mC,CAAO,GAAG+mC,CAAM;AAAA,IACjDZ,GAAO;AAAA,IACPA,GAAO;AAAA,IACPA,GAAOI,CAAK;AAAA,EAAA;AAEhB;AAKO,SAASS,EAAML,GAAkB3mC,GAAiBqmC,GAAsB;AAC7E,EAAAC,GAAK,SAAS,QAAQ,KAAK,IAAO,IAAOK,GAAU3mC,GAASqmC,CAAI;AAClE;AAKO,SAASY,GAAKN,GAAkB3mC,GAAiBqmC,GAAsB;AAC5E,EAAAC,GAAK,QAAQ,QAAQ,MAAM,IAAM,IAAOK,GAAU3mC,GAASqmC,CAAI;AACjE;AAKO,SAASxkC,GAAM8kC,GAAkB3mC,GAAiBqmC,GAAsB;AAC7E,EAAAC,GAAK,SAAS,QAAQ,OAAO,IAAM,IAAMK,GAAU3mC,GAASqmC,CAAI;AAClE;AAKA,SAASa,KAA4B;AACnC,SAAO,CAAC,GAAG9B,EAAU;AACvB;AAKA,SAAS+B,KAAwB;AAC/B,EAAA/B,GAAW,SAAS;AACtB;AAKA,SAASgC,GAAYpB,GAA6B;AAChD,QAAMhnC,IAAQgnC,KAAcA,EAAW,SAAS,IAAIA,EAAW,KAAK,GAAG,IAAI;AAC3E,EAAArB,GAAYN,GAAa,YAAYrlC,CAAK,GAC1C,QAAQ,IAAI,yBAAyB;AACvC;AAKA,SAASqoC,KAAqB;AAC5B,EAAAxC,GAAaR,GAAa,UAAU,GACpC,QAAQ,IAAI,0BAA0B;AACxC;AAGA,MAAMiD,KAAgB,MAEhBC,KAAiB;AAKvB,SAASC,GAAanB,GAAwB;AAC5C,MAA0BA,KAAS,KAAM,QAAOA;AAChD,MAAI;AACF,UAAMtoB,IAAO,KAAK,UAAUsoB,CAAI;AAChC,QAAItoB,EAAK,UAAUupB,GAAe,QAAOjB;AAEzC,QAAI,OAAOA,KAAS,YAAY,CAAC,MAAM,QAAQA,CAAI,GAAG;AACpD,YAAMoB,IAAqC,CAAA;AAC3C,iBAAW,CAACr0B,GAAGlL,CAAC,KAAK,OAAO,QAAQm+B,CAA+B,GAAG;AACpE,cAAMqB,IAAO,KAAK,UAAUx/B,CAAC;AAC7B,QAAAu/B,EAAUr0B,CAAC,IAAIs0B,KAAQA,EAAK,SAAS,MAAM,cAAcA,EAAK,MAAM,YAAYx/B;AAAA,MAClF;AACA,aAAOu/B;AAAA,IACT;AACA,WAAO,cAAc1pB,EAAK,MAAM;AAAA,EAClC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAUO,SAAS4pB,GAAUpB,GAAeI,GAAkB3mC,GAAiBqmC,GAAsB;AAChG,MAAI;AAAE,YAAQ,KAAK,IAAIM,CAAQ,KAAK3mC,CAAO,IAAIqmC,KAAQ,EAAE;AAAA,EAAG,QAAQ;AAAA,EAAa;AACjF,MAAI;AACF,QAAI,OAAO,YAAc,OAAe,OAAO,UAAU,cAAe,WAAY;AAEpF,QAAIuB,IADW9D,GAAA,EACK,gBAAgB;AACpC,SAAI8D,MAAW,OAAO,CAACA,MACjB,OAAO,SAAW,KAAa;AACjC,YAAMC,IAAM,OAAO;AACnB,MAAAD,KAAUC,EAAI,aAAa,eAAeA,EAAI,aAAa,gBAAgBA,EAAI,SAAS,OAAO9N,EAAe,IAC1G,GAAG8N,EAAI,QAAQ,KAAKA,EAAI,QAAQ,IAAI/N,EAAiB,KACrD+N,EAAI;AAAA,IACV;AAEF,UAAMjmC,IAAM,GAAGgmC,EAAO,QAAQ,OAAO,EAAE,CAAC,mBAClC3X,IAAO,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,MACnC,OAAAsW;AAAA,MAAO,UAAAI;AAAA,MAAU,SAAA3mC;AAAA,MACjB,MAAMwnC,GAAanB,CAAI;AAAA,MACvB,WAAW,KAAK,IAAA;AAAA,MAChB,KAAK,OAAO,SAAW,MAAc,OAAO,SAAS,OAAO;AAAA,MAC5D,WAAW,OAAO,YAAc,MAAc,UAAU,YAAY;AAAA,MACpE,UAAUX,IAAoB;AAAA,MAC9B,WAAWA,IAAoB;AAAA,IAAA,CAChC,GAAG;AACJ,cAAU,WAAW9jC,GAAK,IAAI,KAAK,CAACquB,CAAI,GAAG,EAAE,MAAM,mBAAA,CAAoB,CAAC;AAAA,EAC1E,QAAQ;AAAA,EAAa;AACvB;AAKA,eAAe6X,KAAmC;AAChD,MAAIxC,GAAS,WAAW,EAAG;AAE3B,QAAMyC,IAAQzC;AACd,EAAAA,KAAW,CAAA,GACXC,KAAkB;AAElB,MAAI;AAEF,QAAIqC,IADW9D,GAAA,EACK,gBAAgB;AACpC,SAAI8D,MAAW,OAAO,CAACA,MACjB,OAAO,SAAW,KAAa;AACjC,YAAMC,IAAM,OAAO;AACnB,OAAKA,EAAI,aAAa,eAAeA,EAAI,aAAa,gBAAgBA,EAAI,SAAS,OAAO9N,EAAe,IACvG6N,IAAS,GAAGC,EAAI,QAAQ,KAAKA,EAAI,QAAQ,IAAI/N,EAAiB,KAE9D8N,IAASC,EAAI;AAAA,IAEjB;AAGF,UAAMjmC,IAAM,GAAGgmC,EAAO,QAAQ,OAAO,EAAE,CAAC,mBAElCI,IAAWD,EAAM,IAAI,CAAA/6B,OAAM;AAAA,MAC/B,OAAOA,EAAE;AAAA,MACT,UAAUA,EAAE;AAAA,MACZ,SAASA,EAAE;AAAA,MACX,MAAMw6B,GAAax6B,EAAE,IAAI;AAAA,MACzB,WAAWA,EAAE;AAAA,MACb,KAAK,OAAO,SAAW,MAAc,OAAO,SAAS,OAAO;AAAA,MAC5D,WAAW,OAAO,YAAc,MAAc,UAAU,YAAY;AAAA,MACpE,UAAU04B,IAAoB;AAAA,MAC9B,WAAWA,IAAoB;AAAA,IAAA,EAC/B;AAGF,QAAIuC,IAAyB,CAAA,GACzBC,IAAY;AAChB,eAAWxU,KAASsU,GAAU;AAC5B,YAAMG,IAAY,KAAK,UAAUzU,CAAK,EAAE,SAAS;AACjD,MAAIwU,IAAYC,IAAYZ,MAAkBU,EAAM,SAAS,MAC3D,MAAM,MAAMrmC,GAAK;AAAA,QACf,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAA;AAAA,QAC3B,MAAM,KAAK,UAAU,EAAE,MAAMqmC,GAAO;AAAA,MAAA,CACrC,GACDA,IAAQ,CAAA,GACRC,IAAY,IAEdD,EAAM,KAAKvU,CAAK,GAChBwU,KAAaC;AAAA,IACf;AACA,IAAIF,EAAM,SAAS,KACjB,MAAM,MAAMrmC,GAAK;AAAA,MACf,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAA;AAAA,MAC3B,MAAM,KAAK,UAAU,EAAE,MAAMqmC,GAAO;AAAA,IAAA,CACrC;AAAA,EAEL,SAASnG,GAAc;AACrB,YAAQ,KAAK,oDAAoDsG,GAAYtG,CAAG,EAAE,KAAK;AAAA,EACzF;AACF;AAKA,SAAS8E,GAAkBlT,GAAuB;AAIhD,MAHA4R,GAAS,KAAK5R,CAAK,GAGf,CAAC6R,IAAiB;AACpB,UAAM8C,IAAQzC,OAAuBH,KAAuBD;AAC5D,IAAAD,KAAkB,WAAW,MAAM;AAAE,MAAKuC,GAAA;AAAA,IAAqB,GAAGO,CAAK;AAAA,EACzE;AACF;AAWO,SAASD,GAAYtG,GAA+C;AACzE,SAAOA,aAAe,QAClB,EAAE,OAAOA,EAAI,SAAS,MAAMA,EAAI,KAAA,IAChC,EAAE,OAAO,OAAOA,CAAG,GAAG,MAAM,OAAOA,EAAA;AACzC;AAGAmD,GAAoB,aAAa;AAAA,EAC/B,QAAQmC;AAAA,EACR,SAASC;AAAA,EACT,SAASH;AAAA,EACT,OAAOC;AACT,CAAC;ACpYM,SAASmB,GAAe5L,GAA2C;AACxE,SAAOD,GAAcC,CAAM,IAAIL,GAAiBK,CAAM,IAAI;AAC5D;AAQO,SAAS6L,GAAa7L,GAAuD;AAClF,SAAKD,GAAcC,CAAM,IAElB,GADQoH,GAAA,EAAmB,aAAa,QAAQ,OAAO,EAAE,CAChD,GAAGvH,GAAaG,CAAM,CAAC,KAFX;AAG9B;AAIA,IAAI8L,KAA8C,MAC9CC,KAAoC;AAGjC,SAASC,KAAkC;AAChD,SAAIF,KAAqB,QAAQ,QAAA,IAC7BC,OACJA,MAAe,YAAY;AACzB,QAAI;AACF,YAAMb,IAAS9D,GAAA,EAAmB,aAAa,QAAQ,OAAO,EAAE,GAI1Dxd,IAAM,MAAM,MAAM,GAAGshB,CAAM,6BAA6B,EAAE,OAAO,YAAY;AACnF,UAAI,CAACthB,EAAI,GAAI;AACb,YAAM+f,IAAO,MAAM/f,EAAI,KAAA;AACvB,MAAAkiB,KAAenC,GACfpB,GAAoB,qBAAqBoB,CAAI,GAC7CW,EAAM,cAAc,wBAAwBX,CAAI;AAAA,IAClD,SAAS,GAAY;AAEnB,MAAAW,EAAM,cAAc,wDAAwDoB,GAAY,CAAC,CAAC;AAAA,IAC5F;AAAA,EACF,GAAA,GACOK;AACT;AAGO,SAASE,GAAeplC,GAAoB;AACjD,SAAOilC,KAAejlC,CAAE,KAAKA,EAAG,OAAO,CAAC,EAAE,YAAA,IAAgBA,EAAG,MAAM,CAAC;AACtE;AAGO,SAASqlC,GAAgB9qB,GAAuB;AACrD,QAAM+qB,IAAQ/qB,EAAK,YAAA;AACnB,SAAIqe,GAAgB,KAAK,CAAAC,MAAKA,MAAMyM,CAAK,IAAU,KAC/CL,KACK,OAAO,OAAOA,EAAY,EAAE,KAAK,CAAAM,MAAMA,EAAG,YAAA,MAAkBD,CAAK,IAEnE;AACT;ACrCA,MAAM/b,KAAoB;AAAA,EACxB,UAAU;AAAA,EACV,UAAU;AAAA,EACV,MAAM;AAAA,EACN,WAAW;AACb;AAaO,SAASic,KAAqC;AACnD,SAAIjc,GAAO,YAAkBA,GAAO,YAC/BA,GAAO,YACLA,GAAO,aAAa,WAAW,SADT;AAE/B;AAEO,SAASkc,GAAQC,GAAwD;AAC9E,EAAAnc,GAAO,WAAW,IACdmc,EAAM,aAAUnc,GAAO,WAAWmc,EAAM,WAGxCA,EAAM,WAAW,WACnBnc,GAAO,YAAYmc,EAAM,UAAUA,EAAM,WAAW,WAAWA,EAAM,SAAS;AAElF;AAEO,SAASC,KAAwB;AACtC,SAAOpc,GAAO;AAChB;AAMA,MAAMqc,KAAsC;AAAA,EAC1C,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AACT;AAEA,SAASC,GAAYC,GAAgBC,GAA4B;AAC/D,UAAQH,GAAUE,CAAI,KAAK,OAAOF,GAAUG,CAAO;AACrD;AAYO,SAASC,KAAwB;AACtC,SAAOH,GAAYtc,GAAO,UAAU,SAAS;AAC/C;AAGO,SAAS0c,KAAoB;AAClC,SAAO1c,GAAO,aAAa;AAC7B;AAOO,SAAS2c,KAAyB;AACvC,SAAOV,QAAyB;AAClC;AAOA,eAAsBW,KAAqC;AACzD,MAAI5c,GAAO,aAAa,SAAU,QAAO;AACzC,MAAIA,GAAO,KAAM,QAAOA,GAAO;AAC/B,MAAI;AACF,UAAMxG,IAAM,MAAM,MAAM,mBAAmB;AAAA,MACzC,aAAa;AAAA,MACb,OAAO;AAAA,IAAA,CACR;AACD,QAAI,CAACA,EAAI,GAAI,QAAO;AACpB,UAAM+f,IAAO,MAAM/f,EAAI,KAAA;AAIvB,QAHI+f,EAAK,UACPvZ,GAAO,YAAY,OAAOuZ,EAAK,UAAW,YAAYA,EAAK,SAASA,EAAK,SAAS,OAEhFA,EAAK,SAAS,OAAOA,EAAK,QAAS;AACrC,aAAAvZ,GAAO,OAAOuZ,EAAK,MACZA,EAAK;AAAA,EAEhB,SAAS,GAAY;AACnB,IAAAY,GAAK,QAAQ,uBAAuBmB,GAAY,CAAC,CAAC;AAAA,EACpD;AACA,SAAO;AACT;AC9HO,MAAMuB,KAAwBnP,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW5C,QAAQA,EAAE,OAAA,EAAS,SAAA;AAAA;AAAA,EAGnB,eAAeA,EAAE,QAAA,EAAU,SAAA;AAAA,EAC3B,qBAAqBA,EAAE,QAAA,EAAU,SAAA;AAAA;AAAA;AAAA,EAGjC,qBAAqBA,EAAE,QAAA,EAAU,SAAA;AAAA,EACjC,iBAAiBA,EAAE,OAAA,EAAS,SAAA;AAAA;AAAA,EAG5B,QAAQA,EAAE,OAAA,EAAS,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAA;AAAA,EACjC,OAAOA,EAAE,QAAA,EAAU,SAAA;AAAA,EACnB,oBAAoBA,EAAE,OAAA,EAAS,SAAA;AAAA,EAC/B,kBAAkBA,EAAE,QAAA,EAAU,SAAA;AAAA,EAC9B,eAAeA,EAAE,OAAA,EAAS,SAAA;AAE5B,CAAC,GAIYoP,KAAkBC,GAAkB;AAAA,EAC/C,OAAO;AAAA,EACP,QAAQF;AACV,CAAC,GClBKG,KAAa,oBAAI,IAAY,CAAC,SAAS,WAAW,CAAC;AAczD,SAASC,GAAYC,GAA8B;AACjD,QAAMC,IAAMlB,GAAA;AACZ,SAAOkB,IAAM,eAAeA,CAAG,IAAID,CAAK,KAAK;AAC/C;AAUA,SAASE,KAAqC;AAC5C,SAAOnB,SAA0B;AACnC;AAKA,SAASoB,GAAaH,GAAwC;AAgB5D,QAAMvpC,IAAMspC,GAAYC,CAAK;AAC7B,MAAI,CAACvpC,EAAK,QAAO,CAAA;AACjB,QAAM09B,IAAMuG,GAAWjkC,CAAG;AAC1B,MAAI,CAAC09B,EAAK,QAAO,CAAA;AACjB,MAAI;AAIF,WADe,KAAK,MAAMA,CAAG,GACd,QAAQ,CAAA;AAAA,EACzB,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACF;AAcO,SAASiM,KAAqC;AACnD,MAAIC,IAAY;AAChB,aAAW5pC,KAAOmkC,MAAc;AAC9B,UAAM0F,IAAS7pC,EAAI,WAAW,cAAc,KAAKA,EAAI,SAAS,aAAa,GACrE8pC,IAAY9pC,MAAQ+pC,MAAkB/pC,EAAI,WAAW,GAAG+pC,EAAa,GAAG,KAAK,CAAC/pC,EAAI,SAAS,mBAAmB;AACpH,QAAI,CAAC6pC,KAAU,CAACC,EAAW;AAC3B,UAAMpM,IAAMuG,GAAWjkC,CAAG;AAC1B,QAAI,CAAC09B,EAAK;AACV,QAAIzW;AACJ,QAAI;AACF,MAAAA,IAAS,KAAK,MAAMyW,CAAG;AAAA,IACzB,QAAQ;AACN;AAAA,IACF;AAEA,UAAMsM,IAAOH,IAAU5iB,GAAQ,OAA+CA;AAC9E,QAAI,CAAC+iB,KAAQ,OAAOA,KAAS,YAAY,EAAE,UAAUA,GAAO;AAC5D,UAAM,EAAE,MAAMC,GAAU,GAAG/kC,MAAS8kC,GAC9BtnB,IAAOmnB,IAAS,EAAE,GAAG5iB,GAAQ,MAAM/hB,MAASA;AAClD,IAAIg/B,GAAYlkC,GAAK,KAAK,UAAU0iB,CAAI,CAAC,KAAGknB;AAAA,EAC9C;AACA,SAAIA,IAAY,KAAGrD,EAAM,eAAe,gDAAgD,EAAE,WAAAqD,GAAW,GAC9FA;AACT;AAaA,IAAIM,KAAqC,MACrCC,KAAwC;AA+B5C,MAAMC,yBAAsB,IAAA;AACrB,SAASC,KAAmC;AAoBjD,MAAIZ;AACF,WAAAlD,EAAM,eAAe,2DAA2D,GACzE,CAAA;AAGT,QAAM+D,IAAaZ,GAAa,WAAW,GACrCa,IAAWb,GAAa,YAAY,GACpCc,IAAY,OAAO,KAAKF,CAAU,EAAE,SAAS,IAC/CA,IACEJ,MAAsD,CAAA,GACtDO,IAAU,OAAO,KAAKF,CAAQ,EAAE,SAAS,IAC3CA,IACEJ,MAAoD,CAAA,GACpDX,IAAMT,QAAe;AAE3B,MAAIqB,GAAgB,IAAIZ,CAAG;AACzB,WAAAjD,EAAM,eAAe,4CAA4C;AAAA,MAC/D,KAAAiD;AAAA,MACA,cAAc,OAAO,KAAKgB,CAAS,EAAE;AAAA,MACrC,YAAY,OAAO,KAAKC,CAAO,EAAE;AAAA;AAAA;AAAA,MAGjC,aAAa,OAAO,KAAKH,CAAU,EAAE,SAAS,IAAI,UAAU;AAAA,MAC5D,WAAW,OAAO,KAAKC,CAAQ,EAAE,SAAS,IAAI,UAAU;AAAA,IAAA,CACzD,GACM,EAAE,GAAGE,GAAS,GAAGD,EAAA;AAG1B,EAAAJ,GAAgB,IAAIZ,CAAG;AACvB,QAAMkB,IAASC,GAAA,KAAgB,CAAA,GACzBtlB,IAAS,EAAE,GAAGqlB,GAAQ,GAAGD,GAAS,GAAGD,EAAA;AAC3C,SAAAjE,EAAM,eAAe,4CAA4C;AAAA,IAC/D,KAAAiD;AAAA,IACA,cAAc,OAAO,KAAKgB,CAAS,EAAE;AAAA,IACrC,YAAY,OAAO,KAAKC,CAAO,EAAE;AAAA,IACjC,YAAY,OAAO,KAAKC,CAAM,EAAE;AAAA,IAChC,aAAa,OAAO,KAAKJ,CAAU,EAAE,SAAS,IAAI,UAAU;AAAA,IAC5D,WAAW,OAAO,KAAKC,CAAQ,EAAE,SAAS,IAAI,UAAU;AAAA,EAAA,CACzD,GACMllB;AACT;AAeA,IAAIulB,KAAqB;AAGzB,SAASC,KAA0B;AACjC,QAAMrB,IAAMT,GAAA;AACZ,SAAO,CAACS,KAAOA,MAAQ;AACzB;AAEO,SAASsB,GAA4B9qC,GAAQzB,GAAiC;AACnF,EAAIssC,GAAA,MAAkBD,KAAqB,KACvCvB,GAAW,IAAIrpC,CAAa,IACzB+qC,GACF,KAAK,EAAE,CAAC/qC,CAAG,GAAGzB,EAAA,GAAgC,EAAE,OAAO,SAAA,CAAU,EACjE,MAAM,CAAA8iC,MAAOmF,GAAK,eAAe,0BAA0B,EAAE,KAAAxmC,GAAK,KAAMqhC,GAAe,QAAA,CAAS,CAAC,IAE/F8H,GACF,KAAK,EAAE,CAACnpC,CAAG,GAAGzB,EAAA,CAAmC,EACjD,MAAM,OAAOioC,GAAK,eAAe,+BAA+B,EAAE,KAAAxmC,GAAK,KAAMqhC,GAAe,QAAA,CAAS,CAAC,GAE3GkF,EAAM,eAAe,mBAAmB,EAAE,KAAAvmC,GAAK,OAAAzB,GAAO;AACxD;AAkBA,IAAIysC,KAAwC,MACxCC,KAAiB;AACd,SAASC,KAA8C;AAC5D,SAAIF,OACJA,MAAgB,YAAY;AAC1B,QAAI,OAAO,SAAW,IAAa,QAAO;AAC1C,QAAI;AAIF,MAAKC,OACHA,KAAiB,IAajBF,GAAW,UAAU,CAAAf,MAAQ;AAC3B,QAAAE,KAAkBF,GAClBmB,GAAa,aAAanB,CAAI,GAC9BoB,GAAU,OAAO;AAAA,MACnB,CAAC,GACDjC,GAAgB,UAAU,CAAAa,MAAQ;AAChC,QAAAG,KAAgBH,GAChBmB,GAAa,cAAcnB,CAAI,GAC/BoB,GAAU,YAAY;AAAA,MACxB,CAAC;AAGH,YAAM,CAACC,GAAiBC,CAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,QACzDP,GAAW,KAAA;AAAA,QACX5B,GAAgB,KAAA;AAAA,MAAK,CACtB;AAeD,UAAI;AAMF,cAAM,EAAE,aAAAoC,EAAA,IAAgB,MAAM,QAAA,QAAA,EAAA,KAAA,MAAAC,EAAA;AAC9B,QAAAD,EAAY,SAAA,EAAW,mBAAA;AAAA,MACzB,SAASlK,GAAK;AACZ,QAAAmF,GAAK,eAAe,0CAA0C,EAAE,KAAMnF,GAAe,SAAS;AAAA,MAChG;AAcA,YAAMoK,IAAenC,GAAY,WAAW,GACtCoC,IAAapC,GAAY,YAAY,GACrCqC,IAAeF,IAAexH,GAAWwH,CAAY,IAAI,MACzDG,IAAaF,IAAazH,GAAWyH,CAAU,IAAI;AAGzD,aAAAnF,EAAM,eAAe,YAAY;AAAA,QAC/B,WAAW,OAAO,KAAK8E,KAAmB,CAAA,CAAE;AAAA,QAC5C,SAAS,OAAO,KAAKC,KAAiB,CAAA,CAAE;AAAA;AAAA,QAExC,mBAAmBK,GAAc,UAAU;AAAA,QAC3C,iBAAiBC,GAAY,UAAU;AAAA,MAAA,CACxC,GAUD,MAAMC,GAAsBR,GAAiBC,CAAa,GAmBtDV,MACFrE,EAAM,eAAe,4DAA6D,GAClF,MAAM,QAAQ,IAAI;AAAA,QAChBwE,GAAW,yBAAyB,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,QAClD5B,GAAgB,yBAAyB,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAAA,CACxD,KAED5C,EAAM,eAAe,wDAAwD,GAG/EA,EAAM,eAAe,8BAA8B,GAC5C;AAAA,IACT,SAASlF,GAAK;AACZ,aAAAmF,GAAK,eAAe,0CAA0C,EAAE,KAAMnF,GAAe,SAAS,GACvF;AAAA,IACT;AAAA,EACF,GAAA,GACO2J;AACT;AAeA,MAAMjB,KAAgB;AAGtBJ,GAAA;AAEA,SAASmC,KAAoB;AAC3B,QAAMtC,IAAMT,GAAA;AACZ,SAAO,CAACS,KAAOA,MAAQ,WAAWO,KAAgB,GAAGA,EAAa,IAAIP,CAAG;AAC3E;AAEA,SAASmB,KAA6C;AACpD,QAAMjN,IAAMuG,GAAW6H,IAAW;AAClC,MAAI,CAACpO,EAAK,QAAO;AACjB,MAAI;AACF,UAAMzW,IAAS,KAAK,MAAMyW,CAAG;AAC7B,WAAI,CAACzW,KAAU,OAAOA,KAAW,YAAY,MAAM,QAAQA,CAAM,IAAU,OACpEA;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS8kB,KAAqB;AAC5B,EAAA3H,GAAa0H,IAAW,GAIxB1H,GAAa,GAAG0H,GAAA,CAAW,mBAAmB;AAChD;AAEA,eAAeD,GACbR,GACAC,GACe;AACf,QAAMZ,IAASC,GAAA;AACf,MAAI,CAACD,KAAU,OAAO,KAAKA,CAAM,EAAE,WAAW,EAAG;AAQjD,QAAMsB,IAAc,OAAO,KAAKX,KAAmB,CAAA,CAAE,EAAE,SAAS,GAC1DY,IAAY,OAAO,KAAKX,KAAiB,CAAA,CAAE,EAAE,SAAS,GAKtDY,IAAkC,CAAA,GAClCC,IAAqC,CAAA;AAC3C,aAAW,CAACx5B,GAAGlL,CAAC,KAAK,OAAO,QAAQijC,CAAM;AACxC,IAAIsB,MAEOr5B,MAAM,WAAW,OAAOlL,KAAM,WACvCykC,EAAW,QAAQzkC,IACVkL,MAAM,gBAAgBlL,MAAM,YAAYA,MAAM,gBACvDykC,EAAW,YAAYzkC,KAErBwkC,MAEOt5B,MAAM,mBAAmB,OAAOlL,KAAM,cAAoB,gBAAgBA,IAC5EkL,MAAM,yBAAyB,OAAOlL,KAAM,cAAoB,sBAAsBA,IACtFkL,MAAM,YAAY,OAAOlL,KAAM,YAAYA,KAAK,KAAKA,KAAK,IAAG0kC,EAAS,SAAS1kC,IAC/EkL,MAAM,WAAW,OAAOlL,KAAM,cAAoB,QAAQA,IAC1DkL,MAAM,wBAAwB,OAAOlL,KAAM,aAAmB,qBAAqBA,IACnFkL,MAAM,sBAAsB,OAAOlL,KAAM,cAAoB,mBAAmBA,IAChFkL,MAAM,mBAAmB,OAAOlL,KAAM,eAAmB,gBAAgBA;AAGpF,QAAM2kC,IAAY,OAAO,KAAKF,CAAU,GAClCG,IAAU,OAAO,KAAKF,CAAQ;AAEpC,MAAIC,EAAU,WAAW,KAAKC,EAAQ,WAAW,GAAG;AAGlD,IAAAN,GAAA;AACA;AAAA,EACF;AAEA,EAAAxF,EAAM,eAAe,8CAA8C;AAAA,IACjE,WAAA6F;AAAA,IACA,SAAAC;AAAA,IACA,aAAAL;AAAA,IACA,WAAAC;AAAA,EAAA,CACD;AACD,MAAI;AACF,UAAM,QAAQ,IAAI;AAAA,MAChBG,EAAU,SAAS,IAAIrB,GAAW,KAAKmB,GAAY,EAAE,OAAO,SAAA,CAAU,IAAI,QAAQ,QAAA;AAAA,MAClFG,EAAQ,SAAS,IAAIlD,GAAgB,KAAKgD,CAAQ,IAAI,QAAQ,QAAA;AAAA,IAAQ,CACvE,GACDJ,GAAA,GACAxF,EAAM,eAAe,2BAA2B;AAAA,EAClD,SAASlF,GAAK;AACZ,IAAAmF,GAAK,eAAe,uDAAuD;AAAA,MACzE,KAAMnF,GAAe;AAAA,IAAA,CACtB;AAAA,EAEH;AACF;AAcA,IAAIiL,KAAqB;AAIzB,SAASnB,GAAa5B,GAAmCS,GAAqC;AAG5F,QAAMhqC,IAAMspC,GAAYC,CAAK;AAC7B,MAAKvpC;AACL,QAAI;AACF,YAAMusC,IAAM;AAAA,QACV,MAAAvC;AAAA,QACA,aAAa;AAAA,QACb,eAAe;AAAA,QACf,UAAU,KAAK,IAAA;AAAA,MAAI;AAErB,mBAAa,QAAQhqC,GAAK,KAAK,UAAUusC,CAAG,CAAC;AAAA,IAC/C,SAASlL,GAAK;AACZ,MAAKiL,OACHA,KAAqB,IACrB9F,GAAK,eAAe,8DAA8D;AAAA,QAChF,OAAA+C;AAAA,QACA,KAAMlI,GAAe;AAAA,QACrB,MAAOA,GAAe;AAAA,MAAA,CACvB;AAAA,IAEL;AACF;AAKA,SAAS+J,GAAU3wB,GAAsB;AACvC,EAAK,iCACF,KAAK,CAAC,EAAE,aAAA8wB,QAAkB;AACzB,QAAI;AACF,MAAAA,EAAY,SAAA,EAAW,mBAAA;AAAA,IACzB,SAASlK,GAAK;AACZ,MAAAmF,GAAK,eAAe,4BAA4B,EAAE,QAAA/rB,GAAQ,KAAM4mB,GAAe,SAAS;AAAA,IAC1F;AAAA,EACF,CAAC,EACA,MAAM,CAAAA,MAAOmF,GAAK,eAAe,uBAAuB,EAAE,QAAA/rB,GAAQ,KAAM4mB,GAAe,QAAA,CAAS,CAAC;AACtG;AC7kBO,MAAMmL,KAAwB,KAExBC,KAAoB,KACpBC,KAAoB;AAe1B,SAASC,GAAeC,GAAYC,GAA6B;AACtE,MAAI,CAAC,OAAO,SAASD,CAAE,EAAG,QAAOJ;AACjC,MAAIzL,IAAM2L;AAIV,SAAA3L,IAAM,KAAK,IAAIA,GAAK0L,EAAiB,GAC9B,KAAK,MAAM,KAAK,IAAI1L,GAAK,KAAK,IAAI0L,IAAmBG,CAAE,CAAC,CAAC;AAClE;ACwKA,MAAME,KAAazC,GAAA,GAENkB,IAActS,GAAiB,CAACvH,GAAKqb,OAAS;AAAA,EACzD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,IAAI,EAAE,UAAU,MAAM,eAAe,EAAA;AAAA,EACrC,UAAU,EAAE,QAAQ,MAAM,SAAS,MAAM,YAAY,GAAG,SAAS,IAAO,WAAW,GAAG,UAAU,KAAA;AAAA,EAChG,QAAQ,CAAA;AAAA,EACR,MAAM,CAAA;AAAA,EACN,eAAeD,GAAW,iBAAiB;AAAA,EAC3C,qBAAqBA,GAAW,uBAAuB;AAAA,EACvD,iBAAiBH,GAAeG,GAAW,mBAAmBN,EAAqB;AAAA;AAAA;AAAA;AAAA,EAInF,qBAAqB;AAAA,EACrB,OAAO,EAAE,MAAM,IAAI,UAAU,EAAA;AAAA,EAC7B,oBAAoB,KAAK,IAAA;AAAA,EACzB,gBAAgB;AAAA,EAChB,WAAW,EAAE,SAAS,MAAM,OAAO,IAAO,YAAY,GAAG,OAAO,EAAA;AAAA,EAChE,aAAa,EAAE,aAAa,IAAO,eAAe,EAAA;AAAA,EAClD,QAAQ,CAAA;AAAA,EACR,YAAY;AAAA,IACV,QAAQM,GAAW,UAAU;AAAA,IAC7B,OAAOA,GAAW,SAAS;AAAA,IAC3B,oBAAoBA,GAAW,sBAAsB;AAAA,IACrD,kBAAkBA,GAAW,oBAAoB;AAAA,IACjD,eAAgB,CAAC,WAAW,UAAU,WAAW,UAAU,EAAE,SAASA,GAAW,aAAuB,IACpGA,GAAW,gBACX;AAAA,EAAA;AAAA,EAEN,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,SAAS,CAAA;AAAA,EACT,cAAc,CAAA;AAAA,EACd,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,UAAU;AAAA,EACV,eAAe,CAAA;AAAA,EACf,gBAAgB;AAAA,EAChB,YAAY,EAAE,QAAQ,IAAO,OAAO,CAAA,EAAC;AAAA,EACrC,cAAc;AAAA,EACd,cAAc;AAAA,EACd,aAAa;AAAA,EACb,UAAU,MAAM;AACd,IAAAvG,EAAM,SAAS,WAAW,GAC1B7U,EAAI,EAAE,OAAO,IAAM;AAAA,EACrB;AAAA,EACA,oBAAoB,CAACrU,GAAM4e,MAAW;AACpC,IAAAsK,EAAM,SAAS,wCAAwC,EAAE,MAAAlpB,GAAM,QAAA4e,GAAQ,GACvEvK,EAAI,EAAE,MAAArU,GAAM,QAAA4e,GAAQ;AAAA,EACtB;AAAA,EACA,oBAAoB,MAAMvK,EAAI,CAACxrB,MAAM;AACnC,QAAIA,EAAE,KAAM,QAAO,CAAA;AAGnB,QAAIA,EAAE,QAAQ;AACZ,YAAMmX,IAAO6qB,GAAehiC,EAAE,MAAM;AACpC,aAAAqgC,EAAM,SAAS,0DAA0D,EAAE,MAAAlpB,GAAM,QAAQnX,EAAE,QAAQ,GAC5F,EAAE,MAAAmX,EAAA;AAAA,IACX;AAEA,UAAM2vB,IAAc,IAAI,IAAI,OAAO,OAAO9mC,EAAE,MAAM,EAAE,IAAI,OAAK+S,EAAE,MAAM,EAAE,OAAO,OAAO,CAAC;AACtF,IAAAstB,EAAM,SAAS,+BAA+B;AAAA,MAC5C,YAAY,OAAO,KAAKrgC,EAAE,MAAM,EAAE;AAAA,MAClC,aAAa,MAAM,KAAK8mC,CAAW;AAAA,IAAA,CACpC;AACD,eAAWrR,KAAKD;AACd,UAAI,CAACsR,EAAY,IAAIrR,CAAC,GAAG;AACvB,cAAMte,IAAO6qB,GAAevM,CAAC;AAC7B,eAAA4K,EAAM,SAAS,0BAA0B,EAAE,MAAAlpB,GAAM,QAAQse,GAAG,GACrD,EAAE,MAAAte,GAAM,QAAQse,EAAA;AAAA,MACzB;AAIF,WAAA6K,GAAK,SAAS,8CAA8C,GACrD,CAAA;AAAA,EACT,CAAC;AAAA,EACD,UAAU,CAAC1I,MAAa;AACtB,IAAAyI,EAAM,SAAS,iBAAiB,EAAE,UAAAzI,EAAA,CAAU,GAC5CpM,EAAI,CAACxrB,OAAO,EAAE,IAAI,EAAE,GAAGA,EAAE,IAAI,UAAA43B,EAAA,EAAS,EAAI;AAAA,EAC5C;AAAA,EACA,eAAe,CAACmP,MAASvb,EAAI,CAACxrB,MAAM;AAClC,UAAMgnC,IAA4C,EAAE,GAAGhnC,EAAE,OAAA;AACzD,QAAI+mC,EAAK;AACP,iBAAWE,KAAKF,EAAK,MAAO,CAAAC,EAAcC,EAAE,QAAQ,IAAIA;AAI1D,UAAMpJ,IAAUkJ,EAAK,YAAY,SAAYA,EAAK,UAAU/mC,EAAE,SAAS,SACjEknC,IAAWH,EAAK,aAAa,SAAYA,EAAK,WAAW/mC,EAAE,SAAS;AAC1E,IAAAqgC,EAAM,SAAS,oBAAoB;AAAA,MACjC,SAAAxC;AAAA,MACA,SAASkJ,EAAK,WAAW/mC,EAAE,SAAS;AAAA,MACpC,WAAW+mC,EAAK,aAAa/mC,EAAE,SAAS;AAAA,MACxC,WAAW+mC,EAAK,OAAO,UAAU;AAAA,IAAA,CAClC;AACD,UAAMI,IAAgBJ,EAAK,cAAc/mC,EAAE,SAAS;AACpD,WAAO;AAAA,MACL,UAAU;AAAA,QACR,QAAQ+mC,EAAK,WAAW,SAAYA,EAAK,SAAS/mC,EAAE,SAAS;AAAA,QAC7D,SAAA69B;AAAA,QACA,YAAYsJ;AAAA,QACZ,SAASJ,EAAK,WAAW/mC,EAAE,SAAS;AAAA,QACpC,WAAW+mC,EAAK,aAAa/mC,EAAE,SAAS;AAAA,QACxC,UAAAknC;AAAA,MAAA;AAAA,MAEF,QAAQF;AAAA;AAAA;AAAA;AAAA;AAAA,MAKR,oBAAoB,KAAK,IAAA;AAAA,IAAI;AAAA,EAEjC,CAAC;AAAA,EACD,YAAY,CAACC,MAAM;AACjB,IAAA5G,EAAM,SAAS,iBAAiB,EAAE,UAAU4G,EAAE,UAAU,MAAMA,EAAE,MAAM,UAAUA,EAAE,SAAA,CAAU,GAC5Fzb,EAAI,CAACxrB,OAAO,EAAE,QAAQ,EAAE,GAAGA,EAAE,QAAQ,CAACinC,EAAE,QAAQ,GAAGA,EAAA,IAAM;AAAA,EAC3D;AAAA,EACA,YAAY,CAACrP,MAAa;AACxB,IAAAyI,EAAM,SAAS,gBAAgB,EAAE,UAAAzI,EAAA,CAAU,GAC3CpM,EAAI,CAACxrB,MAAM;AACT,YAAMonC,IAAO,EAAE,GAAGpnC,EAAE,OAAA;AAAU,oBAAOonC,EAAKxP,CAAQ,GAAU,EAAE,QAAQwP,EAAA;AAAA,IACxE,CAAC;AAAA,EACH;AAAA,EACA,YAAY,CAACrjC,MAAM;AACjB,IAAAs8B,EAAM,QAAQ,oBAAoB,EAAE,IAAIt8B,EAAE,IAAI,MAAMA,EAAE,MAAM,UAAUA,EAAE,SAAA,CAAU,GAClFynB,EAAI,CAACxrB,OAAO,EAAE,MAAM,CAAC,GAAGA,EAAE,MAAM+D,CAAC,EAAE,MAAM,IAAuB,IAAI;AAAA,EACtE;AAAA,EACA,SAAS,CAACsjC,MAAa7b,EAAI,EAAE,MAAM6b,EAAS,MAAM,IAAuB,GAAG;AAAA,EAC5E,qBAAqB,MAAM7b,EAAI,CAACxrB,MAAM;AACpC,UAAMsnC,IAAS,CAACtnC,EAAE;AAClB,WAAA4kC,GAAS,iBAAiB0C,CAAM,GACzB,EAAE,eAAeA,EAAA;AAAA,EAC1B,CAAC;AAAA,EACD,2BAA2B,MAAM9b,EAAI,CAACxrB,MAAM;AAC1C,UAAMsnC,IAAS,CAACtnC,EAAE;AAClB,WAAA4kC,GAAS,uBAAuB0C,CAAM,GAC/B,EAAE,qBAAqBA,EAAA;AAAA,EAChC,CAAC;AAAA,EACD,oBAAoB,CAACZ,MAAOlb,EAAI,MAAM;AACpC,UAAM+b,IAAQd,GAAeC,CAAE;AAC/B,WAAA9B,GAAS,mBAAmB2C,CAAK,GAC1B,EAAE,iBAAiBA,EAAA;AAAA,EAC5B,CAAC;AAAA,EACD,oBAAoB,MAAM/b,EAAI,CAACxrB,MAAM;AACnC,UAAMsnC,IAAS,CAACtnC,EAAE;AAClB,WAAA4kC,GAAS,uBAAuB0C,CAAM,GAC/B,EAAE,qBAAqBA,EAAA;AAAA,EAChC,CAAC;AAAA,EACD,mBAAmB,MAAM;AACvB,UAAM/rC,IAAIsrC,IAAM,GAAG;AACnB,WAAArb,EAAI,CAACxrB,OAAO,EAAE,IAAI,EAAE,GAAGA,EAAE,IAAI,eAAezE,IAAI,EAAA,EAAE,EAAI,GAC/CA;AAAA,EACT;AAAA,EACA,oBAAoB,MAAMiwB,EAAI,CAACxrB,OAAO,EAAE,gBAAgBA,EAAE,iBAAiB,EAAA,EAAI;AAAA,EAC/E,oBAAoB,CAACnF,MAAU;AAC7B,IAAAwlC,EAAM,SAAS,6BAA6BxlC,CAAK,GACjD2wB,EAAI,CAACxrB,OAAO;AAAA,MACV,UAAU,EAAE,GAAGA,EAAE,UAAU,GAAGnF,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAM9B,oBAAoB,KAAK,IAAA;AAAA,IAAI,EAC7B;AAAA,EACJ;AAAA,EACA,cAAc,CAAC2sC,GAAKC,GAAYC,MAAiBlc,EAAI,CAACxrB,MAAM;AAC1D,UAAM2nC,IAAO,CAAC,GAAG3nC,EAAE,MAAM,MAAMwnC,CAAG,EAAE,MAAM,EAAE;AAC5C,QAAII,IAAW5nC,EAAE,MAAM;AACvB,QAAIynC,KAAcC,GAAc;AAC9B,YAAMG,IAAYH,IAAeF,IAAM;AACvC,MAAAI,IAAWH,IAAaI;AAAA,IAC1B;AACA,WAAO,EAAE,OAAO,EAAE,MAAAF,GAAM,UAAAC,IAAS;AAAA,EACnC,CAAC;AAAA,EAED,WAAW,CAAChN,GAAM9iC,MAAQ;AACxB,IAAAuoC,EAAM,SAAS,gBAAgB,EAAE,MAAAzF,GAAM,KAAA9iC,GAAK,GAC5C0zB,EAAI,CAACxrB,OAAO,EAAE,QAAQ,CAAC,GAAGA,EAAE,QAAQ,EAAE,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,CAAC,GAAG,MAAA46B,GAAM,KAAA9iC,GAAK,IAAI,KAAK,IAAA,EAAI,CAAG,EAAE,MAAM,EAAE,IAAI;AAAA,EAC1H;AAAA,EACA,UAAU,CAAC8E,MAAO4uB,EAAI,CAACxrB,OAAO,EAAE,QAAQA,EAAE,OAAO,OAAO,CAAAsnB,MAAKA,EAAE,OAAO1qB,CAAE,IAAI;AAAA,EAC5E,cAAc,CAAC,MAAM4uB,EAAI,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,OAAO,YAAY,EAAE,YAAY,OAAO,EAAE,MAAA,GAAS;AAAA,EACxH,gBAAgB,CAAC3xB,MAAU2xB,EAAI,CAACxrB,OAAO,EAAE,aAAa,EAAE,GAAGA,EAAE,aAAa,GAAGnG,EAAA,IAAU;AAAA,EACvF,qBAAqB,CAAC0H,MAAMiqB,EAAI,EAAE,kBAAkBjqB,GAAG;AAAA;AAAA,EAEvD,WAAW,CAACumC,MAAWtc,EAAI,CAACxrB,OAC1B4kC,GAAS,UAAUkD,CAAM,GAClB,EAAE,YAAY,EAAE,GAAG9nC,EAAE,YAAY,QAAA8nC,IAAO,EAChD;AAAA,EACD,UAAU,CAACC,MAAUvc,EAAI,CAACxrB,OACxB4kC,GAAS,SAASmD,CAAK,GAChB,EAAE,YAAY,EAAE,GAAG/nC,EAAE,YAAY,OAAA+nC,IAAM,EAC/C;AAAA,EACD,uBAAuB,CAACC,MAASxc,EAAI,CAACxrB,OACpC4kC,GAAS,sBAAsBoD,CAAI,GAC5B,EAAE,YAAY,EAAE,GAAGhoC,EAAE,YAAY,oBAAoBgoC,IAAK,EAClE;AAAA,EACD,qBAAqB,CAACC,MAAYzc,EAAI,CAACxrB,OACrC4kC,GAAS,oBAAoBqD,CAAO,GAC7B,EAAE,YAAY,EAAE,GAAGjoC,EAAE,YAAY,kBAAkBioC,IAAQ,EACnE;AAAA,EACD,kBAAkB,CAACzX,MAAUhF,EAAI,CAACxrB,OAChC4kC,GAAS,iBAAiBpU,CAAK,GACxB,EAAE,YAAY,EAAE,GAAGxwB,EAAE,YAAY,eAAewwB,IAAM,EAC9D;AAAA,EACD,mBAAmB,CAAC0X,MAAa1c,EAAI,EAAE,gBAAgB0c,GAAU;AAAA,EACjE,iBAAiB,CAACzkC,MAAW+nB,EAAI,EAAE,cAAc/nB,GAAQ;AAAA,EACzD,oBAAoB,CAAC5J,MAAU2xB,EAAI;AAAA,IACjC,UAAU3xB,EAAM;AAAA,IAChB,qBAAqBA,EAAM;AAAA,IAC3B,SAASA,EAAM;AAAA;AAAA,IAEf,iBAAiB;AAAA,EAAA,CAClB;AAAA,EACD,iBAAiB,CAACsuC,MAAa3c,EAAI,EAAE,cAAc2c,GAAU;AAAA,EAC7D,oBAAoB,CAACz4B,MAAY8b,EAAI,EAAE,iBAAiB9b,GAAS;AAAA,EAEjE,iBAAiB,CAAC04B,MAAS5c,EAAI,EAAE,cAAc4c,GAAM;AAAA,EACrD,mBAAmB,CAACC,MAAW7c,EAAI,EAAE,gBAAgB6c,GAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU7D,qBAAqB,CAACtB,GAAMuB,MAAe9c,EAAI,CAAA+c,OAAS;AAAA,IACtD,UAAUxB;AAAA,IACV,eAAeuB,IAAa,EAAE,GAAGvB,EAAK,QAAA,IAAYwB,EAAK;AAAA,EAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUF,kBAAkB,CAACC,GAAQ9F,GAAM/oC,MAAU6xB,EAAI,CAAA3xB,MAAS;AACtD,UAAM2iB,IAAyC,CAAA;AAC/C,eAAW,CAAC8K,GAAGmhB,CAAG,KAAK,OAAO,QAAQ5uC,EAAM,aAAa,GAAG;AAC1D,YAAM6uC,KAAWD,KAAO,CAAA,GAAI,OAAO,CAAA7rC,MAAMA,MAAO4rC,CAAM;AACtD,MAAIE,EAAQ,SAAS,MAAGlsB,EAAK8K,CAAU,IAAIohB;AAAA,IAC7C;AACA,QAAIhG,MAAS,MAAM;AACjB,YAAM+F,IAAMjsB,EAAKkmB,CAAI,KAAK,CAAA,GACpBrI,IAAK,KAAK,IAAI,GAAG,KAAK,IAAI1gC,KAAS8uC,EAAI,QAAQA,EAAI,MAAM,CAAC;AAChE,MAAAA,EAAI,OAAOpO,GAAI,GAAGmO,CAAM,GACxBhsB,EAAKkmB,CAAI,IAAI+F;AAAA,IACf;AACA,WAAO,EAAE,eAAejsB,EAAA;AAAA,EAC1B,CAAC;AAAA,EACD,oBAAoB,CAAC3iB,MAAU2xB,EAAI,EAAE,YAAY3xB,GAAO;AAAA,EACxD,iBAAiB,CAAC8uC,MAAWnd,EAAI,EAAE,cAAcmd,GAAQ;AAAA,EACzD,iBAAiB,CAACC,MAAUpd,EAAI,EAAE,cAAcod,GAAO;AAAA,EACvD,gBAAgB,CAACC,MAAWrd,EAAI,EAAE,aAAaqd,GAAQ;AAAA,EACvD,oBAAoB,MAAMrd,EAAI,CAACxrB,MAAM;AAenC,UAAM8oC,IAAQ3E,GAAA,GACR3nB,IAA0B,CAAA;AAWhC,QAVIssB,EAAM,kBAAkB,WAAWtsB,EAAK,gBAAgBssB,EAAM,gBAC9DA,EAAM,wBAAwB,WAAWtsB,EAAK,sBAAsBssB,EAAM,sBAC1EA,EAAM,oBAAoB,aAAgB,kBAAkBrC,GAAeqC,EAAM,eAAe,IAMlF,CAAC,UAAU,SAAS,sBAAsB,oBAAoB,eAAe,EACpE,KAAK,OAAKA,EAAMr8B,CAAC,MAAM,MAAS,GAC7C;AACZ,YAAM1I,IAAI,EAAE,GAAG/D,EAAE,WAAA;AACjB,MAAI8oC,EAAM,WAAW,WAAW/kC,EAAE,SAAS+kC,EAAM,SAC7CA,EAAM,UAAU,WAAW/kC,EAAE,QAAQ+kC,EAAM,QAC3CA,EAAM,uBAAuB,WAAW/kC,EAAE,qBAAqB+kC,EAAM,qBACrEA,EAAM,qBAAqB,WAAW/kC,EAAE,mBAAmB+kC,EAAM,mBACjEA,EAAM,kBAAkB,UAAa,CAAC,WAAW,UAAU,WAAW,UAAU,EAAE,SAASA,EAAM,aAAa,MAChH/kC,EAAE,gBAAgB+kC,EAAM,gBAE1BtsB,EAAK,aAAazY;AAAA,IACpB;AACA,WAAOyY;AAAA,EACT,CAAC;AAAA,EACD,eAAe,CAACusB,MAAQvd,EAAI,CAACxrB,MAGvBA,EAAE,eAAe+oC,KAAOA,MAAQ,SAC3B,EAAE,YAAY,OAAA,IAEhB,EAAE,YAAYA,GAAK,eAAe,GAAA,CAC1C;AACH,EAAE;AAGFzK,GAAoB,qBAAqB+G,CAAW;;;;;ACtgBpD,SAAwB2D,GAAO,EAAE,WAAAzY,IAAY,8CAAsE;AACjH,QAAM0Y,IAAS5D,EAAY,CAAArlC,MAAKA,EAAE,MAAM,GAClCkpC,IAAM7D,EAAY,CAAArlC,MAAKA,EAAE,QAAQ;AACvC,SAAAmpC,GAAU,MAAM;AACd,UAAMC,IAASH,EAAO,IAAI,CAAA3hB,MAAK,WAAW,MAAM4hB,EAAI5hB,EAAE,EAAE,GAAG,GAAI,CAAC;AAChE,WAAO,MAAM;AAAE,MAAA8hB,EAAO,QAAQ,YAAY;AAAA,IAAG;AAAA,EAC/C,GAAG,CAACH,GAAQC,CAAG,CAAC,GAEd,gBAAAG,EAAC,OAAA,EAAI,WAAW,GAAG9Y,CAAS,6BACzB,UAAA0Y,EAAO,IAAI,CAAA3hB,MACV,gBAAA+hB,EAAC,OAAA,EAAe,WAAW,uDAAuD/hB,EAAE,SAAO,UAAU,iDAAiD,0CAA0C,IAAK,YAAE,IAAA,GAA7LA,EAAE,EAA+L,CAC5M,EAAA,CACH;AAEJ;ACCA,MAAMgiB,KAAa;AAEnB,SAAwBC,KAAkB;AACxC,QAAMC,IAAYC,GAAiC,IAAI,GACjDC,IAAWD,GAAe,EAAE;AAElC,SAAAN,GAAU,MAAM;AACd,UAAMQ,IAASH,EAAU;AACzB,QAAI,CAACG,EAAQ;AACb,UAAM/iC,IAAM+iC,EAAO,WAAW,IAAI;AAClC,QAAI,CAAC/iC,EAAK;AAGV,UAAMgjC,IAAS,MAAM;AACnB,YAAMC,IAASF,EAAO;AACtB,UAAIE,GAAQ;AACV,cAAMC,IAAOD,EAAO,sBAAA;AACpB,QAAAF,EAAO,QAAQG,EAAK,OACpBH,EAAO,SAASG,EAAK;AAAA,MACvB;AAEE,QAAAH,EAAO,QAAQ,OAAO,YACtBA,EAAO,SAAS,OAAO;AAAA,IAE3B;AACA,IAAAC,EAAA;AAGA,UAAMG,IAAiB,IAAI,eAAeH,CAAM;AAChD,IAAID,EAAO,iBACTI,EAAe,QAAQJ,EAAO,aAAa,GAE7C,OAAO,iBAAiB,UAAUC,CAAM;AAE1C,QAAII,IAAkB;AAEtB,aAASC,EAAatsC,GAAW;AAC/B,aAAIA,IAAI,MAAY,EAAE,OAAO,KAAK,QAAQ,IAAA,IACtCA,IAAI,MAAY,EAAE,OAAO,KAAK,QAAQ,IAAA,IACtCA,IAAI,MAAY,EAAE,OAAO,KAAK,QAAQ,IAAA,IACtCA,IAAI,MAAY,EAAE,OAAO,KAAK,QAAQ,IAAA,IACtCA,IAAI,MAAY,EAAE,OAAO,KAAK,QAAQ,IAAA,IACnC,EAAE,OAAO,GAAK,QAAQ,EAAA;AAAA,IAC/B;AAEA,aAASusC,EAASC,GAAY70B,GAAY80B,IAAQ,IAAOzwC,GAAsB;AAE3E,UAAIoZ,IAAI,KAAK,OAAA;AAEb,YAAMs3B,IAAgB1wC,KAASqwC;AAC/B,MAAIrwC,MAAU,UAAWqwC;AACzB,YAAMM,IAAOF,IAAUH,EAAaI,CAAa,IAAI,EAAE,OAAO,GAAK,QAAQ,EAAA;AAC/E,UAAIE,IAAYx3B,IAAI,OAChBy3B,IAAO,CAACD,KAAax3B,IAAI;AACzB,MAAIu3B,EAAK,SAAS,MACZC,KAAa,KAAK,OAAA,IAAWD,EAAK,WAAQC,IAAY,KACtDC,KAAQ,KAAK,OAAA,IAAWF,EAAK,WAAQE,IAAO,MAG9CJ,MACFG,IAAY,IACZC,IAAO;AAGb,YAAMC,IAAYD;AACd,UAAI3W;AACJ,MAAI0W,IAEF1W,IAAI,OAAO,KAAK,OAAA,IAAW,OAClB2W,IACT3W,IAAI,OAAO,KAAK,OAAA,IAAW,OAE3BA,IAAI,OAAQ,KAAK,OAAA,KAAY,MAAO;AAGpC,YAAM6W,IAAM,CAACC,IAAa9P,OAAgB;AACxC,cAAM+P,KAAK,KAAK,OAAA,GACVC,KAAK,KAAK,OAAA;AAChB,eAAOF,MAAQC,KAAKC,MAAM,KAAMhQ,KAAM8P;AAAA,MACxC;AAEN,UAAIG,IAAWJ,EAAI,KAAK,GAAG,IAAK7W,KAAK,OAAQ0W,IAAY,MAAMC,IAAO,IAAM;AACtE,YAAMO,KAAeL,EAAI,MAAM,IAAI;AACzC,UAAIM,IAAOF,IAAWC;AACtB,MAAIX,KAAWE,EAAK,QAAQ,WAAWA,EAAK;AAEtC,UAAIW;AACJ,MAAIV,IAEAU,IAAQ,OAAO,KAAK,OAAA,IAAW,MACxBT,KAETS,IAAQ,OAAQpX,KAAK,OAAQ,MAAO,KAAK,WAAW,MAChDoX,IAAQ,SAAMA,IAAQ,UAG1BA,IAAQ,OAAQpX,KAAK,OAAQ,MAAO,KAAK,WAAW,MAChDoX,IAAQ,SAAMA,IAAQ,QAE9B,CAACV,KAAaU,IAAQ,SAAMA,IAAQ;AAElC,YAAMC,KAAY,QAAQR,EAAI,GAAG,IAAI,GAC/BS,KAActX,KAAK,QAAS0W,IAAY,MAAMC,IAAO,OAAO;AACxE,UAAIY,IAAQF,KAAYC,KAAaT,EAAI,MAAM,GAAG;AAClD,MAAIN,KAAWE,EAAK,QAAQ,WAAYA,EAAK;AAEvC,YAAMe,KAAY,KAAK,IAAI,GAAGJ,CAAK,GAC7BK,KAAW,KAAK,IAAI,IAAIN,IAAO,KAAK,GAAG;AAC7C,MAAAI,KAAS,IAAI,OAAO,KAAK,IAAIC,IAAWC,EAAQ,GAC5Cf,KAAaa,IAAQ,aAAc,OAAO,KAAK,WAAW;AACpE,YAAMG,KAAK5B,EAAQ,OACb6B,KAAK7B,EAAQ,QACT8B,KAAgB,OAAO,KAAK,OAAA,IAAW,MAE3CC,KAAiBnB,KAAa,KAAK,OAAA,IAAW,MAE1CoB,KAAWpB,IAAY,OAAQE,IAAY,OAAO,KAAK,IAAI,KAAM,OAAOgB,KAAgB,IAAI,GAEhGG,KAAWX,KAASU,KAAW,KAAK,YAAY,IAAIA,MACpDE,KAAYZ,KAASU,KAAW,KAAK,YAAY,IAAIA,MACjDG,MAAYvB,IAAY,MAAME,IAAY,MAAM,OAAO,KAAK,OAAA,KAAYF,IAAY,MAAM,MAK9FwB,KAAY,KAAK,IAAI,GAAGX,IADH,GAC6B,GAClDY,KAAU,IAEVC,KADU,MACUD;AAC1B,UAAI/E,KAAI,KAAK,OAAA;AACb,YAAMiF,KAAM,MAAMH,KAAY;AAC9B,MAAA9E,KAAI,KAAK,IAAIA,IAAGiF,EAAG;AACnB,YAAMC,MAAa,IAAIJ,QAAe,KAAKC,MAAWC;AACtD,MAAAhF,KAAIA,MAAK,IAAIkF,MAAaA;AAC1B,YAAMC,MAAeJ,KAAU/E,KAAIgF,MAAW;AAC1C,aAAO;AAAA,QACX,GAAG9B,KAAY,KAAK,OAAA,IAAWoB;AAAA,QAC/B,GAAGj2B,MAAiB80B,IAAU,KAAK,OAAA,IAAWoB,KAAK,CAAC,KAAK,OAAA,IAAWA;AAAA,QAC9D,GAAA3X;AAAA,QACA,OAAAuX;AAAA,QACA,MAAAJ;AAAA,QACA,OAAAC;AAAA,QACA,WAAAR;AAAA,QACA,YAAY,KAAK,OAAA,IAAW,KAAK,KAAK;AAAA,QACtC,YAAY,OAAO,KAAK,OAAA,IAAW;AAAA,QACnC,WAAW,KAAK,OAAA,IAAW,MAAM,IAAI;AAAA,QACrC,eAAAgB;AAAA,QACN,gBAAAC;AAAA,QACM,UAAAC;AAAA,QACA,cAAcC;AAAA,QACd,eAAeC;AAAA,QACf,UAAU;AAAA,QACV,iBAAiBC;AAAA,QACjB,YAAY,KAAK,OAAA,IAAW,KAAK,KAAK;AAAA,QACtC,aAAavB,IAAY,OAAO,OAAQ,KAAK,WAAW;AAAA,QACxD,WAAAA;AAAA,QACA,OAAOA,IAAY,CAAA,IAAK;AAAA,QACxB,cAAcqB;AAAA,QACd,iBAAiBQ;AAAA,QACjB,aAAAA;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,CAAC1C,EAAS,QAAQ;AACxB,eAAS/rC,IAAI,GAAGA,IAAI2rC,IAAY3rC,IAAK,CAAA+rC,EAAS,QAAQ,KAAKQ,EAAS,QAAW,QAAW,IAAMvsC,CAAC,CAAC;AAGhG,QAAI0uC,GACAC,IAAW,YAAY,IAAA;AAK3B,UAAMC,IAAe;AAErB,aAASC,EAAqBrC,GAAW70B,GAAW01B,GAAcI,GAAe;AAG/E,YAAMqB,KAAW,OAAO,OADd,KAAK,IAAI,GAAGrB,IAAQ,CAAgB,KACVJ,GAC9B0B,IAAI1B,GACJnT,IAAImT,GACJj4B,IAAI,KAAK,IAAI05B,GAAS5U,IAAI,MAAM6U,IAAI,IAAI,GACxCC,IAAKxC,GACLyC,IAAKt3B,GACLu3B,IAAK1C,IAAIuC,GACTI,KAAKx3B,IAAIuiB,GACTpC,IAAI7uB;AACV,MAAA6uB,EAAE,UAAA,GACFA,EAAE,OAAOkX,GAAIC,CAAE,GACfnX,EAAE,OAAOoX,GAAID,CAAE,GACfnX,EAAE,OAAOoX,GAAIC,KAAK/5B,CAAC,GACnB0iB,EAAE,iBAAiBoX,GAAIC,IAAID,IAAK95B,GAAG+5B,EAAE,GACrCrX,EAAE,OAAOkX,IAAK55B,GAAG+5B,EAAE,GACnBrX,EAAE,iBAAiBkX,GAAIG,IAAIH,GAAIG,KAAK/5B,CAAC,GACrC0iB,EAAE,OAAOkX,GAAIC,CAAE,GACfnX,EAAE,UAAA,GACFA,EAAE,KAAA;AAAA,IACJ;AAGA,aAASsX,EAAY/sC,GAASgtC,GAAY;AAExC,UADIA,IAAK,MAAGA,IAAK,IACb,CAAChtC,EAAE,gBAAgB;AACrB,QAAAA,EAAE,eAAeA,EAAE;AACnB;AAAA,MACF;AAEA,UADAA,EAAE,YAAYgtC,GACVhtC,EAAE,YAAYA,EAAE,iBAAiB;AAEnC,QAAAA,EAAE,eAAeA,EAAE,eAEnBA,EAAE,gBAAgBA,EAAE,SAASA,EAAE,WAAW,KAAK,OAAA,KAAY,IAAIA,EAAE;AAEjE,cAAMitC,IAAUjtC,EAAE,YAAY,MAAOA,EAAE,YAAY,MAAM,KACnDktC,IAASltC,EAAE,YAAY,MAAM;AACnC,QAAAA,EAAE,kBAAkBitC,IAAU,KAAK,OAAA,IAAWC,GAC9CltC,EAAE,WAAW;AAAA,MACf;AACA,YAAMmtC,IAAI,KAAK,IAAI,GAAGntC,EAAE,WAAWA,EAAE,eAAe,GAE9CotC,IAAQD,IAAIA,KAAK,IAAI,IAAIA;AAC/B,UAAIttB,IAAM7f,EAAE,gBAAgBA,EAAE,gBAAgBA,EAAE,gBAAgBotC;AAGhE,UADAptC,EAAE,cAAcA,EAAE,aAAagtC,GAC3BhtC,EAAE,WAAW;AACf,cAAMqtC,IAAQ,KAAK,IAAIrtC,EAAE,UAAU,IAAI;AACvC,QAAA6f,IAAM,KAAK,IAAI,GAAG,KAAK,IAAI7f,EAAE,QAAQA,EAAE,UAAU6f,KAAO,IAAIwtB,EAAM,CAAC;AAAA,MACrE;AACA,MAAArtC,EAAE,eAAe6f;AAAA,IACnB;AAGA,aAASytB,EAAYttC,GAASgtC,GAAoB;AAChD,UAAIhtC,EAAE,WAAW;AACf,QAAAA,EAAE,cAAeA,EAAE,aAAa,MAAOgtC;AACvC,cAAMO,IAAS;AAAA,UACb,CAAC,KAAK,KAAK,GAAG;AAAA;AAAA,UACd,CAAC,KAAK,KAAK,GAAG;AAAA;AAAA,UACd,CAAC,KAAK,KAAK,GAAG;AAAA;AAAA,QAAA,GAEVC,IAAQxtC,EAAE,aAAautC,EAAO,QAC9B5qC,IAAM,KAAK,MAAM6qC,CAAK,GACtBhxB,KAAQ7Z,IAAM,KAAK4qC,EAAO,QAC1BjmB,IAAIkmB,IAAQ7qC,GACZ8qC,IAAKF,EAAO5qC,CAAG,GACf+qC,IAAKH,EAAO/wB,CAAI,GAChBmxB,IAAO,KAAK,MAAMF,EAAG,CAAC,KAAKC,EAAG,CAAC,IAAID,EAAG,CAAC,KAAKnmB,CAAC,GAC7CsmB,IAAO,KAAK,MAAMH,EAAG,CAAC,KAAKC,EAAG,CAAC,IAAID,EAAG,CAAC,KAAKnmB,CAAC,GAC7CumB,IAAO,KAAK,MAAMJ,EAAG,CAAC,KAAKC,EAAG,CAAC,IAAID,EAAG,CAAC,KAAKnmB,CAAC;AACnD,eAAO,OAAOqmB,CAAI,IAAIC,CAAI,IAAIC,CAAI;AAAA,MACpC;AACA,UAAI7tC,EAAE,WAAW;AACf,QAAAA,EAAE,cAAcA,EAAE,aAAagtC;AAC/B,cAAM1lB,KAAK,KAAK,IAAItnB,EAAE,UAAU,IAAI,KAAK;AACzC,YAAIA,EAAE,cAAc,GAAG;AACrB,gBAAM2tC,IAAO,KAAK,MAAM,MAAO,MAAYrmB,CAAC,GACtCsmB,IAAO,KAAK,MAAM,MAAO,MAAatmB,CAAC;AAE7C,iBAAO,OAAOqmB,CAAI,IAAIC,CAAI;AAAA,QAC5B,OAAO;AAEL,gBAAMA,IAAO,KAAK,MAAM,MAAO,MAAYtmB,CAAC,GACtCumB,IAAO,KAAK,MAAM,MAAO,MAAYvmB,CAAC;AAC5C,iBAAO,WAAesmB,CAAI,IAAIC,CAAI;AAAA,QACpC;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,UAAMC,IAAS,MAAM;AACnB,YAAM5T,IAAM,YAAY,IAAA,GAClB6T,IAAU,KAAK,IAAI7T,IAAMoS,GAAUC,CAAY,GAC/CS,IAAKe,IAAU;AACrB,MAAAzB,IAAWpS,GACXtzB,EAAI,UAAU,GAAG,GAAG+iC,EAAO,OAAOA,EAAO,MAAM;AAC/C,YAAMqE,IAAmB;AACzB,eAASrwC,IAAI,GAAGA,IAAI+rC,EAAS,QAAQ,QAAQ/rC,KAAK;AAChD,cAAMqC,IAAI0pC,EAAS,QAAQ/rC,CAAC;AAE5B,YAAIqC,EAAE,WAAW;AAEf,cADKA,EAAE,UAAOA,EAAE,QAAQ,CAAA,IACpB,CAACA,EAAE,UAAU;AAEf,kBAAMvE,IAAOuE,EAAE,QAAQ,IACjBiuC,KAAO,KAAK,IAAI,GAAGjuC,EAAE,QAAQ,GAAgB,GAC7CkuC,IAASzyC,KAAQ,IAAI,IAAIwyC;AAC/B,YAAAjuC,EAAE,WAAW,KAAK,IAAI,KAAK,KAAK,MAAMkuC,CAAM,CAAC;AAAA,UAC/C;AACA,UAAAluC,EAAE,MAAM,KAAK,EAAE,GAAGA,EAAE,IAAIA,EAAE,OAAO,GAAG,GAAGA,EAAE,IAAIA,EAAE,OAAO,GAAG,GACrDA,EAAE,MAAM,SAASA,EAAE,YAAUA,EAAE,MAAM,OAAO,GAAGA,EAAE,MAAM,SAASA,EAAE,QAAQ;AAAA,QAChF;AAGA,YADAA,EAAE,mBAAmB+tC,GACjB/tC,EAAE,mBAAmB,GAAG;AAE1B,gBAAMmuC,IAAUjE,EAAS,KAAK,OAAA,IAAWP,EAAO,OAAO,QAAW,EAAK;AAEvE,UAAAwE,EAAQ,IAAI,CAACA,EAAQ,OAAO,GAC5BzE,EAAS,QAAQ/rC,CAAC,IAAIwwC;AACtB;AAAA,QACF;AAEA,YADAnuC,EAAE,KAAKA,EAAE,QAAQgtC,GACbhtC,EAAE,IAAIA,EAAE,OAAO2pC,EAAO,SAASqE,GAAkB;AACnD,UAAAtE,EAAS,QAAQ/rC,CAAC,IAAIusC,EAAS,KAAK,WAAWP,EAAO,OAAO,CAAC3pC,EAAE,OAAO,CAAC;AACxE;AAAA,QACF;AACJ,QAAA+sC,EAAY/sC,GAAGgtC,CAAE;AACjB,cAAMoB,IAAepuC,EAAE,gBAAgBA,EAAE,OACnCquC,IAAU,MACVC,IAAWtuC,EAAE,kBAAkBquC,IAAU,KAAK,IAAI,GAAGruC,EAAE,kBAAkBquC,CAAO,IAAI,GACpFE,IAAYH,IAAeE;AACjC,YAAIE,IAAgBlB,EAAYttC,GAAGgtC,CAAE;AACjC,YAAIhtC,EAAE,WAAW;AACf,gBAAMyuC,IAAWF;AACjB,cAAIvuC,EAAE,SAASA,EAAE,MAAM,QAAQ;AAC7B,kBAAM0uC,IAAM1uC,EAAE,MAAM;AACpB,qBAAS2uC,IAAK,GAAGA,IAAKD,GAAKC,KAAM;AAC/B,oBAAMC,KAAK5uC,EAAE,MAAM0uC,IAAM,IAAIC,CAAE,GACzBE,KAAU,IAAIF,IAAKD,GACnBI,IAAO,KAAK,IAAID,IAAQ,CAAC;AAC/B,cAAAjoC,EAAI,cAAc,KAAK,IAAI,GAAG6nC,CAAQ,IAAIK,IAAO;AACjD,oBAAMC,KAAQ,OAAO,OAAOD;AAC5B,cAAAloC,EAAI,YAAY4nC;AAChB,oBAAMQ,KAAWhvC,EAAE,OAAO+uC;AAC1B,cAAAnoC,EAAI,SAASgoC,GAAG,IAAII,KAAW,GAAGJ,GAAG,IAAII,KAAW,GAAGA,IAAUA,EAAQ;AAAA,YAC3E;AAAA,UACF;AACA,UAAApoC,EAAI,cAAc,KAAK,IAAI,GAAG6nC,IAAW,IAAI,GAC7C7nC,EAAI,YAAY4nC;AAChB,gBAAMS,IAAWjvC,EAAE,IAAIA,EAAE,OAAO,KAC1BkvC,KAAUlvC,EAAE,IAAIA,EAAE,OAAO;AAG/B,cAFAwsC,EAAqByC,GAAUC,IAASlvC,EAAE,OAAO,KAAKA,EAAE,KAAK,GAEzDyuC,IAAW,MAAM;AACnB,kBAAMU,IAAO,KAAK,IAAI,IAAIV,IAAW,KAAK,IAAI;AAC9C,YAAA7nC,EAAI,KAAA,GACJA,EAAI,2BAA2B,WAC/BA,EAAI,cAAcuoC,GAClBvoC,EAAI,YAAY4nC;AAChB,kBAAMY,IAAWpvC,EAAE,OAAO;AAC1B,YAAAwsC,EAAqByC,IAAWjvC,EAAE,OAAO,OAAOkvC,KAAUlvC,EAAE,OAAO,OAAOovC,GAAUpvC,EAAE,KAAK,GAC3F4G,EAAI,QAAA;AAAA,UACN;AAAA,QACF,WACEA,EAAI,cAAc,KAAK,IAAI,GAAG2nC,CAAS,GACvC3nC,EAAI,YAAY4nC,GAChBhC,EAAqBxsC,EAAE,GAAGA,EAAE,GAAGA,EAAE,MAAMA,EAAE,KAAK,GAC1CuuC,IAAY,MAAM;AACpB,gBAAMY,IAAO,KAAK,IAAI,MAAMZ,IAAY,KAAK,GAAG;AAChD,UAAA3nC,EAAI,KAAA,GACJA,EAAI,2BAA2B,WAC/BA,EAAI,cAAcuoC,GAClBvoC,EAAI,YAAY4nC;AAChB,gBAAMY,IAAWpvC,EAAE,OAAO;AAC1B,UAAAwsC,EAAqBxsC,EAAE,IAAIA,EAAE,OAAO,OAAOA,EAAE,IAAIA,EAAE,OAAO,OAAOovC,GAAUpvC,EAAE,KAAK,GAClF4G,EAAI,QAAA;AAAA,QACN;AAAA,MAEJ;AACA,MAAAA,EAAI,cAAc,GAClBylC,IAAU,sBAAsByB,CAAM;AAAA,IACxC;AACA,WAAAzB,IAAU,sBAAsByB,CAAM,GAC/B,MAAM;AACX,2BAAqBzB,CAAO,GAC5B,OAAO,oBAAoB,UAAUzC,CAAM,GAC3CG,EAAe,WAAA;AAAA,IACjB;AAAA,EACF,GAAG,CAAA,CAAE,GAGH,gBAAAV;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKG;AAAA,MACL,0BAAsB;AAAA,MACtB,WAAU;AAAA,IAAA;AAAA,EAAA;AAGhB;AC3XA,MAAM6F,KAAgB,KAChBC,KAAgB,MAEhBC,KAAc,IAEdC,KAAY;AAMX,SAASC,GAAaC,GAA0C;AACrE,MAAI38B,IAAI,GAAGimB,IAAI,GAAGz5B,IAAI,GAAGowC,IAAS;AAClC,WAAShyC,IAAI,GAAGA,IAAI,IAAI+xC,EAAO,QAAQ/xC,KAAK,GAAG;AAC7C,UAAM2B,IAAIowC,EAAO/xC,IAAI,CAAC;AACtB,IAAI2B,IAAIkwC,OACRz8B,KAAK28B,EAAO/xC,CAAC,IAAI2B,GACjB05B,KAAK0W,EAAO/xC,IAAI,CAAC,IAAI2B,GACrBC,KAAKmwC,EAAO/xC,IAAI,CAAC,IAAI2B,GACrBqwC,KAAUrwC;AAAA,EACZ;AACA,SAAIqwC,MAAW,IAAU,OAClBC,GAAe78B,IAAI48B,GAAQ3W,IAAI2W,GAAQpwC,IAAIowC,CAAM;AAC1D;AAEA,SAASC,GAAe78B,GAAWimB,GAAWz5B,GAAmB;AAC/D,QAAM,CAACs4B,GAAG73B,GAAG6vC,CAAC,IAAIC,GAAS/8B,IAAI,KAAKimB,IAAI,KAAKz5B,IAAI,GAAG,GAC9CwwC,IAAU,KAAK,IAAIT,IAAe,KAAK,IAAID,IAAeQ,CAAC,CAAC,GAC5D,CAACG,GAAIC,GAAIC,CAAE,IAAIC,GAAStY,GAAG73B,GAAG+vC,CAAO,GACrCK,IAAM,CAAC7uC,MAAc,KAAK,MAAMA,IAAI,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAC3E,SAAO,IAAI6uC,EAAIJ,CAAE,CAAC,GAAGI,EAAIH,CAAE,CAAC,GAAGG,EAAIF,CAAE,CAAC;AACxC;AAEA,SAASJ,GAAS/8B,GAAWimB,GAAWz5B,GAAqC;AAC3E,QAAMs7B,IAAM,KAAK,IAAI9nB,GAAGimB,GAAGz5B,CAAC,GAAGorC,IAAM,KAAK,IAAI53B,GAAGimB,GAAGz5B,CAAC,GAC/CswC,KAAKhV,IAAM8P,KAAO;AACxB,MAAI9P,MAAQ8P,EAAK,QAAO,CAAC,GAAG,GAAGkF,CAAC;AAChC,QAAMxb,IAAIwG,IAAM8P,GACV,IAAIkF,IAAI,MAAMxb,KAAK,IAAIwG,IAAM8P,KAAOtW,KAAKwG,IAAM8P;AACrD,MAAI9S;AACJ,SAAIgD,MAAQ9nB,IAAG8kB,KAAKmB,IAAIz5B,KAAK80B,KAAK2E,IAAIz5B,IAAI,IAAI,KACrCs7B,MAAQ7B,IAAGnB,KAAKt4B,IAAIwT,KAAKshB,IAAI,IACjCwD,KAAK9kB,IAAIimB,KAAK3E,IAAI,GAChB,CAACwD,IAAI,GAAG,GAAGgY,CAAC;AACrB;AAEA,SAASM,GAAStY,GAAW73B,GAAW6vC,GAAqC;AAC3E,MAAI7vC,MAAM,EAAG,QAAO,CAAC6vC,GAAGA,GAAGA,CAAC;AAC5B,QAAMQ,IAAIR,IAAI,MAAMA,KAAK,IAAI7vC,KAAK6vC,IAAI7vC,IAAI6vC,IAAI7vC,GACxCmtC,IAAI,IAAI0C,IAAIQ,GACZC,IAAU,CAAChpB,OACXA,IAAI,MAAGA,KAAK,IACZA,IAAI,MAAGA,KAAK,IACZA,IAAI,IAAI,IAAU6lB,KAAKkD,IAAIlD,KAAK,IAAI7lB,IACpCA,IAAI,IAAI,IAAU+oB,IAClB/oB,IAAI,IAAI,IAAU6lB,KAAKkD,IAAIlD,MAAM,IAAI,IAAI7lB,KAAK,IAC3C6lB;AAET,SAAO,CAACmD,EAAQzY,IAAI,IAAI,CAAC,GAAGyY,EAAQzY,CAAC,GAAGyY,EAAQzY,IAAI,IAAI,CAAC,CAAC;AAC5D;AAGA,MAAM0V,yBAAa,IAAA,GACbgD,yBAAc,IAAA,GACdve,yBAAgB,IAAA;AAEtB,SAASwe,KAAe;AACtB,aAAWX,KAAK7d,GAAW,CAAA6d,EAAA;AAC7B;AAEA,SAASY,GAAYx1C,GAAmB;AAEtC,MADIsyC,GAAO,IAAItyC,CAAG,KAAKs1C,GAAQ,IAAIt1C,CAAG,KAClC,OAAO,QAAU,OAAe,OAAO,WAAa,IAAa;AACrE,EAAAs1C,GAAQ,IAAIt1C,CAAG;AACf,QAAMy1C,IAAM,IAAI,MAAA;AAChB,EAAAA,EAAI,cAAc,aAClBA,EAAI,iBAAiB;AACrB,QAAMC,IAAS,CAACC,MAAyB;AACvC,IAAAL,GAAQ,OAAOt1C,CAAG,GAClBsyC,GAAO,IAAItyC,GAAK21C,CAAK,GACrBJ,GAAA;AAAA,EACF;AACA,EAAAE,EAAI,SAAS,MAAM;AACjB,QAAI;AACF,YAAM/G,IAAS,SAAS,cAAc,QAAQ;AAC9C,MAAAA,EAAO,QAAQ4F,IACf5F,EAAO,SAAS4F;AAChB,YAAM3oC,IAAM+iC,EAAO,WAAW,MAAM,EAAE,oBAAoB,IAAM;AAChE,UAAI,CAAC/iC,GAAK;AAAE,QAAA+pC,EAAO,IAAI;AAAG;AAAA,MAAQ;AAClC,MAAA/pC,EAAI,UAAU8pC,GAAK,GAAG,GAAGnB,IAAaA,EAAW,GACjDoB,EAAOlB,GAAa7oC,EAAI,aAAa,GAAG,GAAG2oC,IAAaA,EAAW,EAAE,IAAI,CAAC;AAAA,IAC5E,SAASpU,GAAc;AAErB,MAAAkF,EAAM,UAAU,6BAA6B,EAAE,KAAAplC,GAAK,OAAOkgC,aAAe,QAAQA,EAAI,UAAU,OAAOA,CAAG,EAAA,CAAG,GAC7GwV,EAAO,IAAI;AAAA,IACb;AAAA,EACF,GACAD,EAAI,UAAU,MAAMC,EAAO,IAAI,GAC/BD,EAAI,MAAMz1C;AACZ;AAEA,SAAS2Q,GAAUnR,GAAkC;AACnDu3B,SAAAA,GAAU,IAAIv3B,CAAQ,GACf,MAAMu3B,GAAU,OAAOv3B,CAAQ;AACxC;AAIO,SAASo2C,GAAY9a,GAAmC96B,GAAiC;AAC9F,MAAIA,GAAK;AACP,UAAM61C,IAAOvD,GAAO,IAAItyC,CAAG;AAC3B,QAAI61C,EAAM,QAAOA;AAAA,EACnB;AACA,SAAOnP,GAAe5L,CAAM;AAC9B;AAGO,SAASgb,GAAehb,GAAmC96B,GAAiC;AACjG,SAAAkuC,GAAU,MAAM;AAAE,IAAIluC,QAAiBA,CAAG;AAAA,EAAG,GAAG,CAACA,CAAG,CAAC,GAC9C+1C,GAAqBplC,IAAW,MAAMilC,GAAY9a,GAAQ96B,CAAG,GAAG,MAAM0mC,GAAe5L,CAAM,CAAC;AACrG;AClHA,SAAwBkb,GAAY,EAAE,QAAAlb,GAAQ,KAAA96B,GAAK,KAAAi2C,IAAM,IAAI,WAAA3gB,GAAW,OAAAC,GAAO,UAAA2gB,KAAmB;AAChG,QAAM,CAACC,GAAWC,CAAY,IAAIC,GAAwB,IAAI;AAC9D,MAAIr2C,KAAOA,MAAQm2C;AACjB,WACE,gBAAA/H;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKpuC;AAAA,QACL,KAAAi2C;AAAA,QACA,gBAAe;AAAA,QACf,WAAA3gB;AAAA,QACA,OAAAC;AAAA,QACA,WAAW;AAAA,QACX,SAAS,MAAM6gB,EAAap2C,CAAG;AAAA,MAAA;AAAA,IAAA;AAIrC,QAAMs2C,IAAW3P,GAAa7L,CAAM;AACpC,SAAKwb,IACE,gBAAAlI,EAAC,OAAA,EAAI,KAAKkI,GAAU,KAAAL,GAAU,aAAY,aAAY,WAAA3gB,GAAsB,OAAAC,GAAc,WAAW,GAAA,CAAO,IAD7F,gBAAA6Y,EAAAmI,IAAA,EAAG,UAAAL,GAAS;AAEpC;AC/BO,MAAMM,KAAyB;AAE/B,SAASC,GAAYC,IAAgC,OAAO,YAAc,MAAc,UAAU,YAAY,QAAoB;AACvI,SAAOA,MAAc,UAAa,sBAAsB,KAAKA,CAAS;AACxE;ACWA,MAAMC,KAAyB;AAG/B,SAASC,GAAUC,GAAgC;AACjD,SAAOA,EAAK,QAAQ;AAAA,IAClB,CAACxyC,GAAGC,OAAOA,EAAE,OAAO,UAAU,MAAMD,EAAE,OAAO,UAAU,MAAMA,EAAE,QAAQ,cAAcC,EAAE,OAAO;AAAA,EAAA;AAElG;AAGA,SAASwyC,GAAeh/B,GAAsB;AAC5C,SAAOA,EAAE,QACN,MAAM,GAAG,EACT,IAAI,OAAK25B,EAAE,OAAO,CAAC,EAAE,YAAA,IAAgBA,EAAE,MAAM,CAAC,CAAC,EAC/C,KAAK,GAAG;AACb;AAKA,SAASsF,GAAW,EAAE,MAAAC,KAA4B;AAChD,QAAMC,IAAOnB,GAAekB,EAAK,WAAWA,EAAK,UAAU;AAC3D,SACE,gBAAAE,GAAC,QAAA,EAAK,WAAU,sCACd,UAAA;AAAA,IAAA,gBAAA9I;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,aAAa6I,EAAA;AAAA,QAEtB,UAAA,gBAAA7I;AAAA,UAAC4H;AAAA,UAAA;AAAA,YACC,QAAQgB,EAAK;AAAA,YACb,KAAKA,EAAK;AAAA,YACV,KAAKA,EAAK;AAAA,YACV,WAAU;AAAA,YACV,UACE,gBAAA5I,EAAC,QAAA,EAAK,WAAU,gGACb,UAAA4I,EAAK,KAAK,MAAM,GAAG,CAAC,EAAE,YAAA,EAAY,CACrC;AAAA,UAAA;AAAA,QAAA;AAAA,MAEJ;AAAA,IAAA;AAAA,IAGF,gBAAA5I;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QAET,UAAA4I,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EACR,GACF;AAEJ;AAEA,SAASG,GAAS,EAAE,MAAAC,KAA6B;AAC/C,QAAMC,IAAQD,EAAK,SAAS,CAAA,GACtB/9B,IAAQg+B,EAAM;AACpB,SACE,gBAAAH,GAAC,MAAA,EAAG,WAAU,4BACZ,UAAA;AAAA,IAAA,gBAAA9I;AAAA,MAACxa;AAAA,MAAA;AAAA,QACC,IAAI,SAAS,mBAAmBwjB,EAAK,UAAU,CAAC;AAAA,QAChD,WAAU;AAAA,QAEV,UAAA,gBAAAF,GAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,UAAA,gBAAA9I,EAAC,OAAA,EAAI,WAAU,4DACZ,UAAA0I,GAAeM,CAAI,GACtB;AAAA,UACC/9B,IAAQ,KACP,gBAAA+0B,EAAC,OAAA,EAAI,WAAU,iBACZ,UAAAiJ,EAAM,IAAI,CAACrL,GAAGtpC,wBACZq0C,IAAA,EAAkC,MAAM/K,KAAxB,GAAGA,EAAE,IAAI,IAAItpC,CAAC,EAAa,CAC7C,EAAA,CACH;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,IAMD00C,EAAK,cAAc,CAACA,EAAK,mBACxB,gBAAAhJ;AAAA,MAACxa;AAAA,MAAA;AAAA,QACC,IAAI,SAAS,mBAAmBwjB,EAAK,UAAU,CAAC;AAAA,QAChD,OAAM;AAAA,QACN,WAAU;AAAA,QACX,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAED,GAEJ;AAEJ;AAEA,SAAwBE,KAAO;AAC7B,QAAM5V,IAASW,GAAA,GACT,CAACkV,GAAOC,CAAQ,IAAInB,GAAsB,CAAA,CAAE,GAC5C,CAACoB,GAAcC,CAAe,IAAIrB,GAAS,EAAI,GAC/C,CAACsB,GAAYC,CAAa,IAAIvB,GAAwB,IAAI,GAC1D,CAACwB,GAAYC,CAAa,IAAIzB,GAAS,CAAC,GAGxC,CAAC0B,GAAaC,CAAc,IAAI3B,GAAS3U,EAAO,YAAY;AAClE,EAAIA,EAAO,iBAAiBqW,MAC1BC,EAAetW,EAAO,YAAY,GAClCgW,EAAgB,EAAI,GACpBE,EAAc,IAAI;AAEpB,QAAMK,IAAa,MAAM;AACvB,IAAAP,EAAgB,EAAI,GACpBE,EAAc,IAAI,GAClBE,EAAc,CAAAx3C,MAAKA,IAAI,CAAC;AAAA,EAC1B;AAEA,SAAA4tC,GAAU,MAAM;AACd,UAAMgK,IAAW,KAAK,SAAS,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,GAChD3+B,IAAa,IAAI,gBAAA,GACjBysB,IAASxD,GAAA;AACf,QAAI2V,IAAU,IACVC,IAAmD,MACnDC,IAAW;AAEf,IAAAjT,EAAM,QAAQ,uBAAuB;AAAA,MACnC,UAAA8S;AAAA,MAAU,QAAAlS;AAAA,MAAQ,YAAA6R;AAAA,MAClB,UAAU,OAAO,WAAa,MAAc,SAAS,WAAW;AAAA,IAAA,CACjE;AAKD,UAAMS,IAAgB,WAAW,MAAM;AACrC,MAAID,KACJhT,GAAK,QAAQ,+DAA+D;AAAA,QAC1E,UAAA6S;AAAA,QACA,SAAAC;AAAA,QACA,eAAe,CAAC,CAACC;AAAA,QACjB,SAAS7+B,EAAW,OAAO;AAAA,QAC3B,UAAU,OAAO,WAAa,MAAc,SAAS,WAAW;AAAA,MAAA,CACjE;AAAA,IACH,GAAG,GAAM,GAEHg/B,IAAa,CAACC,MAAmB;AACrC,YAAMC,IAAiB,KAAK,IAAA;AAC5B,MAAArT,EAAM,QAAQ,6BAA6B,EAAE,UAAA8S,GAAU,SAAAM,GAAS,GAMhE,MAAM,GAAGxS,CAAM,aAAa/B,OAAmB,aAAa,EAAE,IAAI;AAAA,QAChE,OAAO;AAAA,QACP,QAAQ1qB,EAAW;AAAA,MAAA,CACpB,EACE,KAAK,CAAAmL,MAAOA,EAAI,KAAKA,EAAI,SAAS,QAAQ,OAAO,IAAI,MAAM,QAAQA,EAAI,MAAM,EAAE,CAAC,CAAC,EACjF,KAAK,CAAA+f,MAAQ;AACZ,cAAMiU,IAAY,KAAK,IAAA,IAAQD;AAC/B,QAAArT,EAAM,QAAQ,+BAA+B;AAAA,UAC3C,UAAA8S;AAAA,UAAU,SAAAM;AAAA,UAAS,WAAAE;AAAA,UAAW,YAAYjU,EAAK,SAAS,IAAI;AAAA,QAAA,CAC7D,GACD+S,EAASZ,GAAUnS,EAAK,SAAS,CAAA,CAAE,CAAC,GACpCmT,EAAc,IAAI,GAClBF,EAAgB,EAAK,GACrBW,IAAW,IACX,aAAaC,CAAa;AAAA,MAC5B,CAAC,EACA,MAAM,CAACpY,MAAiB;AACvB,cAAMwY,IAAY,KAAK,IAAA,IAAQD,GACzBr6C,IAAU8hC,aAAe,QAAQA,EAAI,UAAU;AACrD,YAAIA,aAAe,SAASA,EAAI,SAAS,cAAc;AACrD,UAAAkF,EAAM,QAAQ,6BAA6B,EAAE,UAAA8S,GAAU,SAAAM,GAAS,WAAAE,GAAW,GAI3EL,IAAW,IACX,aAAaC,CAAa;AAC1B;AAAA,QACF;AAEA,YAAI,CAACH,GAAS;AACZ,UAAAA,IAAU,IACV9S,GAAK,QAAQ,+CAA+C;AAAA,YAC1D,UAAA6S;AAAA,YAAU,SAAAM;AAAA,YAAS,WAAAE;AAAA,YAAW,OAAOt6C;AAAA,UAAA,CACtC,GACDg6C,IAAa,WAAW,MAAM;AAC5B,YAAAA,IAAa,MACbG,EAAW,CAAC;AAAA,UACd,GAAG,GAAG;AACN;AAAA,QACF;AACA,QAAAt4C,GAAM,OAAO,6BAA6B,EAAE,UAAAi4C,GAAU,OAAO95C,GAAS,WAAAs6C,GAAW,GACjFd,EAAcx5C,KAAW,eAAe,GACxCs5C,EAAgB,EAAK,GACrBW,IAAW,IACX,aAAaC,CAAa;AAAA,MAC5B,CAAC;AAAA,IACL;AAEA,IAAAC,EAAW,CAAC;AAMZ,UAAMI,IAAY,YAAY,MAAM;AAClC,YAAM,GAAG3S,CAAM,aAAa/B,OAAmB,aAAa,EAAE,IAAI;AAAA,QAChE,OAAO;AAAA,QACP,QAAQ1qB,EAAW;AAAA,MAAA,CACpB,EACE,KAAK,CAAAmL,MAAQA,EAAI,KAAKA,EAAI,KAAA,IAAS,IAAK,EACxC,KAAK,CAAA+f,MAAQ;AAAE,QAAIA,KAAM+S,EAASZ,GAAUnS,EAAK,SAAS,CAAA,CAAE,CAAC;AAAA,MAAG,CAAC,EACjE,MAAM,MAAM;AAAA,MAAwC,CAAC;AAAA,IAC1D,GAAGkS,EAAsB;AAEzB,WAAO,MAAM;AACX,MAAAvR,EAAM,QAAQ,yBAAyB;AAAA,QACrC,UAAA8S;AAAA,QAAU,UAAAG;AAAA,QAAU,SAAAF;AAAA,QAAS,eAAe,CAAC,CAACC;AAAA,MAAA,CAC/C,GACD7+B,EAAW,MAAA,GACX,aAAa++B,CAAa,GAC1B,cAAcK,CAAS,GACnBP,kBAAyBA,CAAU;AAAA,IACzC;AAAA,EACF,GAAG,CAAC1W,EAAO,cAAcmW,CAAU,CAAC,GAGlC,gBAAAX,GAAC,OAAA,EAAI,WAAU,gFACb,UAAA;AAAA,IAAA,gBAAA9I,EAACE,IAAA,EAAgB;AAAA,IACjB,gBAAAF,EAAC,MAAA,EAAG,WAAU,uDAAsD,UAAA,eAEpE;AAAA,IACA,gBAAA8I,GAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,MAAA,gBAAA9I,EAAC,MAAA,EAAG,WAAU,mEAAkE,UAAA,SAAK;AAAA,MACpFqJ,IACC,gBAAArJ,EAAC,OAAA,EAAI,WAAU,qDAAoD,UAAA,iBAAA,CAAc,IAC/EuJ,IACF,gBAAAT,GAAC,OAAA,EAAI,WAAU,iGACb,UAAA;AAAA,QAAA,gBAAAA,GAAC,OAAA,EAAI,WAAU,oDAAmD,UAAA;AAAA,UAAA;AAAA,UAAuBS;AAAA,QAAA,GAAW;AAAA,QACpG,gBAAAvJ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS6J;AAAA,YACT,WAAU;AAAA,YACX,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,EAAA,CACF,IACEV,EAAM,WAAW,IACnB,gBAAAnJ,EAAC,OAAA,EAAI,WAAU,yCAAwC,UAAA,uBAAmB,IAE1E,gBAAAA,EAAAmI,IAAA,EACE,UAAA,gBAAAnI,EAAC,MAAA,EAAG,WAAU,+BACX,UAAAmJ,EAAM,IAAI,CAAAz/B,MACT,gBAAAs2B,EAAC+I,IAAA,EAA4B,MAAMr/B,EAAA,GAApBA,EAAE,UAAqB,CACvC,EAAA,CACH,EAAA,CACF;AAAA,IAAA,GAEJ;AAAA,IAIC2+B,GAAA,KACC,gBAAAS,GAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,MAAA,gBAAA9I,EAAC,MAAA,EAAG,WAAU,mEAAkE,UAAA,iBAAa;AAAA,MAC7F,gBAAA8I;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAMV;AAAA,UACN,WAAU;AAAA,UAEV,UAAA;AAAA,YAAA,gBAAApI,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,WAAO;AAAA,YACpE,gBAAAA,EAAC,OAAA,EAAI,WAAU,+BAA8B,UAAA,uCAAA,CAAoC;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACnF,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;ACrSA,SAAwBwK,KAAkB;AACxC,SACE,gBAAA1B,GAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,IAAA,gBAAA9I,EAACE,IAAA,EAAgB;AAAA,IACjB,gBAAAF,EAAC,OAAA,EAAI,WAAU,qDACb,4BAAC,OAAA,EAAI,WAAU,eACb,UAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,sCAAqC,UAAA,sBAEnD,GACF,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;ACcO,MAAMyK,KAAyB,gCAehCC,KAAW,kBACXC,KAAc;AAQb,SAASC,GAAsBC,GAA+D;AAMnG,SALI,GAACA,KACD,CAACA,EAAI,WAAWA,EAAI,QAAQ,SAAS,GAAG,KAGxC,CAACH,GAAS,KAAKG,EAAI,KAAK,KACxBA,EAAI,YAAY,UAAa,CAACF,GAAY,KAAKE,EAAI,OAAO;AAEhE;AAOO,SAASC,GAAiBD,GAAwCnrB,GAAuC;AAC9G,MAAI,CAACkrB,GAAsBC,CAAG,EAAG,QAAO;AACxC,MAAIE;AACJ,MAAIrrB,MAAW;AACb,IAAAqrB,IAAO;AAAA,OACF;AAGL,QAAI,CAAC,OAAO,UAAUrrB,CAAM,KAAKA,IAAS,EAAG,QAAO;AACpD,IAAAqrB,IAAO,QAAQrrB,CAAM;AAAA,EACvB;AACA,QAAMU,IAASyqB,EAAI,UAAU,SAASA,EAAI,OAAO,MAAM;AACvD,SAAO,GAAGA,EAAI,OAAO,MAAMA,EAAI,KAAK,IAAIzqB,CAAM,GAAG2qB,CAAI;AACvD;AAGO,SAASC,KAAuC;AACrD,MAAI,OAAO,SAAW,IAAa,QAAO;AAC1C,MAAI;AACF,UAAMhE,IAAI,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAAE,IAAI,kBAAkB;AAC5E,QAAIA,MAAM,OAAOA,MAAM,OAAQ,QAAO;AACtC,QAAIA,MAAM,OAAOA,MAAM,QAAS,QAAO;AAAA,EACzC,QAAQ;AAAA,EAAoB;AAC5B,SAAOlS,GAAe2V,EAAsB;AAC9C;AAWA,IAAIQ,KAAoC,EAAE,GAAGld,GAAA,GACzCmd,KAAkC,MAElCC,KAAY;AAET,MAAMC,KAAyB;AAe/B,SAASC,KAA2B;AACzC,QAAMC,IAAW5W,GAAW0W,EAAsB;AAClD,MAAIE,EAAU,QAAOA;AACrB,QAAMC,IAAS,WAAW,QAAQ,aAAA,KAAkB,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAK3F,SAAO5W,GAAYyW,IAAwBG,CAAK,IAAIA,IAAQ;AAC9D;AAkBO,SAASC,GAAsBrd,GAAoB;AACxD,EAAA8c,KAAa/c,GAA8BC,CAAG,GACzCgd,OAAWD,KAAc;AAChC;AAEO,SAASO,KAA+C;AAC7D,SAAO,EAAE,GAAGR,GAAA;AACd;AASO,SAASS,KAAiC;AAC/C,SAAIR,OAAgB,SAClBA,KAAczc,GAAmBwc,IAAYI,GAAA,GAAoBL,IAAsB,IAElFE;AACT;AAcA,IAAIS,KAAmB;AACvB,eAAsBC,GAAuBhU,GAA+B;AAC1E,MAAI,CAAA+T,IACJ;AAAA,IAAAA,KAAmB;AACnB,aAASvB,IAAU,GAAGA,IAAU,GAAGA,KAAW;AAC5C,UAAI;AACF,cAAM9zB,IAAM,MAAM,MAAM,GAAGshB,CAAM,cAAc,EAAE,OAAO,YAAY;AACpE,YAAIthB,EAAI,IAAI;AACV,gBAAM2J,IAAO,MAAM3J,EAAI,KAAA;AACvB,UAAAk1B,GAAsBvrB,GAAM,iBAAiB,GAC7C+W,EAAM,OAAO,wBAAwB,EAAE,GAAGyU,GAAA,GAAyB,SAAArB,GAAS;AAC5E;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAAkC;AAC1C,MAAIA,MAAY,KAAG,MAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAAA,IAChE;AAEA,IAAAnT,GAAK,OAAO,kEAAkE;AAAA;AAChF;AASO,SAAS4U,KAAkC;AAChD,SAAOH,GAAA;AACT;AAWO,SAASI,KAAqC;AACnD,QAAMC,IAAML,GAAA;AAEZ,SAAAP,KAAY,IACLY,MAAQ;AACjB;ACxNA,IAAIrc,KAA8BE;AAClC,MAAMjH,yBAAgB,IAAA;AAEtB,SAASqjB,GAAS74B,GAAkC;AAClD,EAAAuc,KAAQvc;AACR,aAAWqzB,KAAK7d,GAAW,CAAA6d,EAAA;AAC7B;AAGO,SAASyF,GAAiBhsB,GAAwB;AACvD,QAAMvI,IAAS+X,GAAkB,UAAWxP,GAAqC,KAAK;AACtF,MAAI,CAACvI,EAAO;AACV,WAAAuf,GAAK,QAAQ,mDAAmD,EAAE,QAAQvf,EAAO,MAAM,OAAO,QAAQ,GAC/F;AAET,QAAMvE,IAA6BuE,EAAO;AAC1C,SAAAs0B,GAAS74B,CAAI,GACN;AACT;AAEA,IAAI+4B,KAAe;AAEnB,eAAsBC,GAAgBvU,GAA+B;AACnE,MAAI,CAAAsU,IACJ;AAAA,IAAAA,KAAe;AACf,QAAI;AACF,YAAM51B,IAAM,MAAM,MAAM,GAAGshB,CAAM,cAAc,EAAE,OAAO,YAAY;AACpE,UAAI,CAACthB,EAAI,IAAI;AACX,QAAA2gB,GAAK,QAAQ,qDAAqD,EAAE,QAAQ3gB,EAAI,QAAQ;AACxF;AAAA,MACF;AACA,MAAI21B,GAAiB,MAAM31B,EAAI,KAAA,CAAM,KACnC0gB,EAAM,QAAQ,uBAAuB,EAAE,OAAOtH,GAAM,IAAI,CAACC,MAAMA,EAAE,EAAE,EAAA,CAAG;AAAA,IAE1E,SAAS3yB,GAAY;AACnB,MAAAi6B,GAAK,QAAQ,qDAAqDmB,GAAYp7B,CAAC,CAAC;AAAA,IAClF;AAAA;AACF;AAEO,SAASovC,KAAuC;AACrD,SAAO1c;AACT;AAEA,SAASntB,GAAUikC,GAA2B;AAC5C,SAAA7d,GAAU,IAAI6d,CAAC,GACR,MAAM;AAAE,IAAA7d,GAAU,OAAO6d,CAAC;AAAA,EAAG;AACtC;AAEO,SAAS6F,KAAuC;AACrD,SAAO1E,GAAqBplC,IAAW6pC,EAAc;AACvD;ACjDO,SAASE,GACdC,GACmD;AACnD,SAAO71B,GAAM,KAAK,YAAY;AAC5B,QAAI;AACF,aAAO,MAAM61B,EAAA;AAAA,IACf,SAASza,GAAK;AACZ,YAAMrjC,IAAM,OAAQqjC,GAAe,WAAWA,CAAG;AAEjD,UAAI,CADiB,4DAA4D,KAAKrjC,CAAG,EACtE,OAAMqjC;AACzB,YAAMpD,IAAO;AACb,UAAI,eAAe,QAAQA,CAAI,EAAG,OAAMoD;AACxC,4BAAe,QAAQpD,GAAM,OAAO,KAAK,IAAA,CAAK,CAAC,GAC/C,OAAO,SAAS,OAAA,GAGT,IAAI,QAA6C,MAAM;AAAA,MAAC,CAAC;AAAA,IAClE;AAAA,EACF,CAAC;AACH;ACvBA,MAAM8d,KAAkB,CAAC,WAAW;AAEpC,SAASC,GAAaC,GAAsC;AAC1D,SAAKA,IACEF,GAAgB,KAAK,CAAAj5C,MAAMm5C,MAAYn5C,KAAMm5C,EAAQ,WAAWn5C,IAAK,GAAG,CAAC,IAD3D;AAEvB;AAaO,SAASo5C,GAAqBtwC,GASnB;AAEhB,MAAI,EADeA,EAAK,aAAa,aACpB,QAAO;AACxB,MAAIA,EAAK,aAAa;AACpB,QAAI68B,GAAA,MAAkB,SAAU,QAAO;AACvC,UAAM0T,IAAavwC,EAAK,YAAYA,EAAK,UAAU;AACnD,WAAO,gBAAgB,mBAAmBuwC,CAAU,CAAC;AAAA,EACvD;AAIA,MAFI,CAACvwC,EAAK,WACNowC,GAAapwC,EAAK,OAAO,KACzB68B,GAAA,MAAkB,SAAU,QAAO;AACvC,QAAM0T,IAAavwC,EAAK,YAAYA,EAAK,UAAU;AACnD,SAAO,gBAAgB,mBAAmBuwC,CAAU,CAAC;AACvD;ACrCA,MAAMC,KAAOP,GAAc,MAAM,OAAO,oBAAe,kBAAC;AAExD,SAASQ,KAAe;AACtB,SACE,gBAAA9M,EAAC,SAAI,WAAU,oDACb,4BAAC,OAAA,EAAI,WAAU,+BAA8B,UAAA,kBAAA,CAAe,EAAA,CAC9D;AAEJ;AAEA,SAAS+M,KAAY;AACnB,QAAMlV,IAAM3f,GAAA,GACNrjB,IAAS+jB,GAAA,GAMTo0B,IAAWL,GAAqB;AAAA,IACpC,SAAS93C,EAAO;AAAA,IAChB,UAAU,OAAO,SAAS;AAAA,IAC1B,UAAU,OAAO,SAAS;AAAA,IAC1B,QAAQ,OAAO,SAAS;AAAA,EAAA,CACzB;AACD,SAAIm4C,KACF,OAAO,SAAS,QAAQA,CAAQ,GACzB,QAILn4C,EAAO,UAEP,gBAAAmrC,EAACtpB,GAAM,UAAN,EAAe,4BAAWo2B,IAAA,CAAA,CAAa,GACtC,UAAA,gBAAA9M,EAAC6M,IAAA,CAAA,CAAK,EAAA,CACR,IAKAhV,EAAI,aAAa,OAAOA,EAAI,aAAa,uBACnCqR,IAAA,EAAK,IAIXrR,EAAI,SAAS,WAAW,OAAO,IAE/B,gBAAAmI,EAACtpB,GAAM,UAAN,EAAe,4BAAWo2B,IAAA,CAAA,CAAa,GACtC,UAAA,gBAAA9M,EAAC6M,IAAA,CAAA,CAAK,EAAA,CACR,IAIG,gBAAA7M,EAAC,OAAA,EAAI,WAAU,OAAM,UAAA,aAAS;AACvC;AAgBA,SAAwBiN,GAAI9yB,GAAiB;AAC3C,QAAM,CAAC+yB,GAASC,CAAU,IAAIlF,GAAS,EAAK,GAGtC3U,IAA2B;AAAA,IAC/B,cAAcnZ,EAAM,gBAAgBuZ,GAAe;AAAA,IACnD,gBAAgBvZ,EAAM,kBAAkBuZ,GAAe;AAAA,IACvD,SAASvZ,EAAM,WAAWuZ,GAAe;AAAA,EAAA,GAErCkE,IAASzD,GAAgBb,CAAM;AAuFrC,SApFAwM,GAAU,MAAM;AACd,UAAM30B,IAAa,IAAI,gBAAA;AACvB,mBAAeiiC,IAAc;AAC3B,YAAMx7C,IAAMgmC,IAAS9J;AACrB,MAAAkJ,EAAM,OAAO,uBAAuB,EAAE,KAAAplC,EAAA,CAAK;AAC3C,UAAI;AACF,cAAM0kB,IAAM,MAAM,MAAM1kB,GAAK;AAAA,UAC3B,OAAO;AAAA,UACP,QAAQuZ,EAAW;AAAA,QAAA,CACpB;AACD,YAAIA,EAAW,OAAO,QAAS;AAC/B,QAAImL,EAAI,MACN0gB,EAAM,OAAO,yBAAyB,GAIjC4U,GAAuBhU,CAAM,GAE7BuU,GAAgBvU,CAAM,MAE3B/lC,GAAM,OAAO,2BAA2B,EAAE,QAAQykB,EAAI,QAAQ,GAC9D62B,EAAW,EAAI;AAAA,MAEnB,SAASrb,GAAK;AACZ,YAAKA,GAAe,SAAS,aAAc;AAC3C,QAAAjgC,GAAM,OAAO,mBAAmB,EAAE,KAAAD,GAAK,OAAOkgC,GAAK,GACnDqb,EAAW,EAAI;AAAA,MACjB;AAAA,IACF;AAEA,WAAKC,EAAA,GACE,MAAMjiC,EAAW,MAAA;AAAA,EAC1B,GAAG,CAACysB,CAAM,CAAC,GAGXkI,GAAU,MAAM;AACd,QAAI,CAACoN,EAAS;AACd,mBAAeG,IAAgB;AAC7B,YAAMz7C,IAAMgmC,IAAS9J;AACrB,UAAI;AAKF,SAJY,MAAM,MAAMl8B,GAAK;AAAA,UAC3B,OAAO;AAAA,UACP,QAAQ,YAAY,QAAQ,GAAI;AAAA,QAAA,CACjC,GACO,OACNolC,EAAM,OAAO,kCAAkC,GAC/CmW,EAAW,EAAK;AAAA,MAEpB,SAASnwC,GAAY;AACnB,QAAAg6B,EAAM,OAAO,2CAA2CoB,GAAYp7B,CAAC,CAAC;AAAA,MACxE;AAAA,IACF;AACA,UAAMswC,IAAW,YAAY,MAAM;AAAE,MAAKD,EAAA;AAAA,IAAiB,GAAG,IAAM;AACpE,WAAO,MAAM,cAAcC,CAAQ;AAAA,EACrC,GAAG,CAACJ,GAAStV,CAAM,CAAC,GAGpBkI,GAAU,MAAM;AACd,aAASyN,IAAa;AACpB,MAAAvW,EAAM,OAAO,gCAAgC,EAAE,OAAO7K,GAAgB,QAAQ;AAC9E,iBAAWC,KAAKD,IAAiB;AAC/B,cAAMv6B,IAAM2mC,GAAanM,CAAC;AAC1B,YAAI,CAACx6B,EAAK;AACV,cAAMy1C,IAAM,IAAI,MAAA;AAChB,QAAAA,EAAI,cAAc,aAClBA,EAAI,WAAW,SACfA,EAAI,UAAU,SACdA,EAAI,MAAMz1C;AAAA,MACZ;AAAA,IACF;AACA,aAAS47C,IAAW;AAClB,MAAI,yBAAyB,SAC3B,OAAO,oBAAoBD,GAAY,EAAE,SAAS,KAAM,IAExD,WAAWA,GAAY,GAAG;AAAA,IAE9B;AACA,IAAI,SAAS,eAAe,aAC1BC,EAAA,IAEA,OAAO,iBAAiB,QAAQA,GAAU,EAAE,MAAM,IAAM;AAAA,EAE5D,GAAG,CAAA,CAAE,GAEDN,sBACM1C,IAAA,EAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASxB,gBAAAxK,EAACyN,IAAA,EACC,UAAA,gBAAAzN,EAACjM,GAAc,UAAd,EAAuB,OAAOT,GAC7B,UAAA,gBAAAwV,GAAC,OAAA,EAAI,WAAU,gCACb,UAAA;AAAA,MAAA,gBAAA9I,EAAC,QAAA,EAAK,WAAU,uDACd,UAAA,gBAAAA,EAAC+M,MAAU,GACb;AAAA,wBACCpN,IAAA,CAAA,CAAO;AAAA,IAAA,EAAA,CACV,GACF,EAAA,CACF;AAAA;AAEJ;AChMO,SAAS+N,GACd,EAAE,UAAA55C,IAAW,eAAe,UAAA65C,EAAA,IAA4C,CAAA,GACxE;AACA,QAAMC,IAAmBD,KAAa,CAAA,GAChC16C,IAAwB;AAAA,IAC5B,EAAE,MAAM,KAAK,2BAAUg6C,IAAA,EAAK,GAAGW,GAAkB,EAAA;AAAA,IACjD,EAAE,MAAM,kBAAkB,2BAAUX,IAAA,EAAK,GAAGW,GAAkB,EAAA;AAAA,IAC9D,EAAE,MAAM,aAAa,2BAAUX,IAAA,EAAK,GAAGW,GAAkB,EAAA;AAAA,EAAG;AAG9D,SAAO1oB,GAAoBjyB,GAAQ,EAAE,UAAAa,GAAU;AACjD;ACsBA,IAAIs/B;AAGJ,SAASya,KAAqC;AAC5C,SAAOnZ,GAAWoZ,EAAa,KAAK;AACtC;AAOO,SAASC,KAAsB;AACpC,MAAI3a,GAAQ;AACZ,QAAM0C,IAAS+X,GAAA;AACf,MAAI/X,GAAQ;AACV,IAAA1C,KAAS0C;AACT;AAAA,EACF;AACA,EAAKkY,GAAA,EACF,KAAK,CAACz6C,MAAO;AACZ,IAAIA,MAAI6/B,KAAS7/B;AAAA,EACnB,CAAC,EACA,MAAM,MAAM;AAIX,IAAAyjC,EAAM,YAAY,6CAA6C;AAAA,EACjE,CAAC;AACL;AAMO,SAASiX,KAAqC;AACnD,SAAQ7a,OAAWya,GAAA;AACrB;AC/EA,MAAMK,KAAe,uBAAO,OAAO,IAAI;AACvCA,GAAa,OAAU;AACvBA,GAAa,QAAW;AACxBA,GAAa,OAAU;AACvBA,GAAa,OAAU;AACvBA,GAAa,UAAa;AAC1BA,GAAa,UAAa;AAC1BA,GAAa,OAAU;AACvB,MAAMC,KAAuB,uBAAO,OAAO,IAAI;AAC/C,OAAO,KAAKD,EAAY,EAAE,QAAQ,CAACz9C,MAAQ;AACvC,EAAA09C,GAAqBD,GAAaz9C,CAAG,CAAC,IAAIA;AAC9C,CAAC;AACD,MAAM29C,KAAe,EAAE,MAAM,SAAS,MAAM,eAAc,GCXpDC,KAAiB,OAAO,QAAS,cAClC,OAAO,OAAS,OACb,OAAO,UAAU,SAAS,KAAK,IAAI,MAAM,4BAC3CC,KAAwB,OAAO,eAAgB,YAE/CC,KAAS,CAAC5/C,MACL,OAAO,YAAY,UAAW,aAC/B,YAAY,OAAOA,CAAG,IACtBA,KAAOA,EAAI,kBAAkB,aAEjC6/C,KAAe,CAAC,EAAE,MAAAh9B,GAAM,MAAA6kB,EAAI,GAAIoY,GAAgBhrB,MAC9C4qB,MAAkBhY,aAAgB,OAC9BoY,IACOhrB,EAAS4S,CAAI,IAGbqY,GAAmBrY,GAAM5S,CAAQ,IAGvC6qB,OACJjY,aAAgB,eAAekY,GAAOlY,CAAI,KACvCoY,IACOhrB,EAAS4S,CAAI,IAGbqY,GAAmB,IAAI,KAAK,CAACrY,CAAI,CAAC,GAAG5S,CAAQ,IAIrDA,EAASyqB,GAAa18B,CAAI,KAAK6kB,KAAQ,GAAG,GAE/CqY,KAAqB,CAACrY,GAAM5S,MAAa;AAC3C,QAAMkrB,IAAa,IAAI,WAAU;AACjC,SAAAA,EAAW,SAAS,WAAY;AAC5B,UAAMC,IAAUD,EAAW,OAAO,MAAM,GAAG,EAAE,CAAC;AAC9C,IAAAlrB,EAAS,OAAOmrB,KAAW,GAAG;AAAA,EAClC,GACOD,EAAW,cAActY,CAAI;AACxC;AACA,SAASwY,GAAQxY,GAAM;AACnB,SAAIA,aAAgB,aACTA,IAEFA,aAAgB,cACd,IAAI,WAAWA,CAAI,IAGnB,IAAI,WAAWA,EAAK,QAAQA,EAAK,YAAYA,EAAK,UAAU;AAE3E;AACA,IAAIyY;AACG,SAASC,GAAqBC,GAAQvrB,GAAU;AACnD,MAAI4qB,MAAkBW,EAAO,gBAAgB;AACzC,WAAOA,EAAO,KAAK,YAAW,EAAG,KAAKH,EAAO,EAAE,KAAKprB,CAAQ;AAE3D,MAAI6qB,OACJU,EAAO,gBAAgB,eAAeT,GAAOS,EAAO,IAAI;AACzD,WAAOvrB,EAASorB,GAAQG,EAAO,IAAI,CAAC;AAExC,EAAAR,GAAaQ,GAAQ,IAAO,CAACC,MAAY;AACrC,IAAKH,OACDA,KAAe,IAAI,YAAW,IAElCrrB,EAASqrB,GAAa,OAAOG,CAAO,CAAC;AAAA,EACzC,CAAC;AACL;ACjEA,MAAMC,KAAQ,oEAERC,KAAS,OAAO,aAAe,MAAc,CAAA,IAAK,IAAI,WAAW,GAAG;AAC1E,SAAS76C,IAAI,GAAGA,IAAI46C,GAAM,QAAQ56C;AAC9B66C,EAAAA,GAAOD,GAAM,WAAW56C,CAAC,CAAC,IAAIA;AAkB3B,MAAM86C,KAAS,CAACC,MAAW;AAC9B,MAAIC,IAAeD,EAAO,SAAS,MAAMhK,IAAMgK,EAAO,QAAQ/6C,GAAGwvC,IAAI,GAAGyL,GAAUC,GAAUC,GAAUC;AACtG,EAAIL,EAAOA,EAAO,SAAS,CAAC,MAAM,QAC9BC,KACID,EAAOA,EAAO,SAAS,CAAC,MAAM,OAC9BC;AAGR,QAAMK,IAAc,IAAI,YAAYL,CAAY,GAAGM,IAAQ,IAAI,WAAWD,CAAW;AACrF,OAAKr7C,IAAI,GAAGA,IAAI+wC,GAAK/wC,KAAK;AACtB,IAAAi7C,IAAWJ,GAAOE,EAAO,WAAW/6C,CAAC,CAAC,GACtCk7C,IAAWL,GAAOE,EAAO,WAAW/6C,IAAI,CAAC,CAAC,GAC1Cm7C,IAAWN,GAAOE,EAAO,WAAW/6C,IAAI,CAAC,CAAC,GAC1Co7C,IAAWP,GAAOE,EAAO,WAAW/6C,IAAI,CAAC,CAAC,GAC1Cs7C,EAAM9L,GAAG,IAAKyL,KAAY,IAAMC,KAAY,GAC5CI,EAAM9L,GAAG,KAAM0L,IAAW,OAAO,IAAMC,KAAY,GACnDG,EAAM9L,GAAG,KAAM2L,IAAW,MAAM,IAAMC,IAAW;AAErD,SAAOC;AACX,GCxCMrB,KAAwB,OAAO,eAAgB,YACxCuB,KAAe,CAACC,GAAeC,MAAe;AACvD,MAAI,OAAOD,KAAkB;AACzB,WAAO;AAAA,MACH,MAAM;AAAA,MACN,MAAME,GAAUF,GAAeC,CAAU;AAAA,IACrD;AAEI,QAAMv+B,IAAOs+B,EAAc,OAAO,CAAC;AACnC,SAAIt+B,MAAS,MACF;AAAA,IACH,MAAM;AAAA,IACN,MAAMy+B,GAAmBH,EAAc,UAAU,CAAC,GAAGC,CAAU;AAAA,EAC3E,IAEuB5B,GAAqB38B,CAAI,IAIrCs+B,EAAc,SAAS,IACxB;AAAA,IACE,MAAM3B,GAAqB38B,CAAI;AAAA,IAC/B,MAAMs+B,EAAc,UAAU,CAAC;AAAA,EAC3C,IACU;AAAA,IACE,MAAM3B,GAAqB38B,CAAI;AAAA,EAC3C,IATe48B;AAUf,GACM6B,KAAqB,CAAC5Z,GAAM0Z,MAAe;AAC7C,MAAIzB,IAAuB;AACvB,UAAM/5C,IAAU66C,GAAO/Y,CAAI;AAC3B,WAAO2Z,GAAUz7C,GAASw7C,CAAU;AAAA,EACxC;AAEI,WAAO,EAAE,QAAQ,IAAM,MAAA1Z;AAE/B,GACM2Z,KAAY,CAAC3Z,GAAM0Z,MACbA,MACC,SACG1Z,aAAgB,OAETA,IAIA,IAAI,KAAK,CAACA,CAAI,CAAC,IAItBA,aAAgB,cAETA,IAIAA,EAAK,QCvDtB6Z,KAAY,KACZC,KAAgB,CAACC,GAAS3sB,MAAa;AAEzC,QAAM4sB,IAASD,EAAQ,QACjBE,IAAiB,IAAI,MAAMD,CAAM;AACvC,MAAIplC,IAAQ;AACZ,EAAAmlC,EAAQ,QAAQ,CAACpB,GAAQ,MAAM;AAE3B,IAAAR,GAAaQ,GAAQ,IAAO,CAACc,MAAkB;AAC3C,MAAAQ,EAAe,CAAC,IAAIR,GAChB,EAAE7kC,MAAUolC,KACZ5sB,EAAS6sB,EAAe,KAAKJ,EAAS,CAAC;AAAA,IAE/C,CAAC;AAAA,EACL,CAAC;AACL,GACMK,KAAgB,CAACC,GAAgBT,MAAe;AAClD,QAAMO,IAAiBE,EAAe,MAAMN,EAAS,GAC/CE,IAAU,CAAA;AAChB,WAAS97C,IAAI,GAAGA,IAAIg8C,EAAe,QAAQh8C,KAAK;AAC5C,UAAMm8C,IAAgBZ,GAAaS,EAAeh8C,CAAC,GAAGy7C,CAAU;AAEhE,QADAK,EAAQ,KAAKK,CAAa,GACtBA,EAAc,SAAS;AACvB;AAAA,EAER;AACA,SAAOL;AACX;AACO,SAASM,KAA4B;AACxC,SAAO,IAAI,gBAAgB;AAAA,IACvB,UAAU1B,GAAQ7jC,GAAY;AAC1B,MAAA4jC,GAAqBC,GAAQ,CAACc,MAAkB;AAC5C,cAAMa,IAAgBb,EAAc;AACpC,YAAIlf;AAEJ,YAAI+f,IAAgB;AAChB,UAAA/f,IAAS,IAAI,WAAW,CAAC,GACzB,IAAI,SAASA,EAAO,MAAM,EAAE,SAAS,GAAG+f,CAAa;AAAA,iBAEhDA,IAAgB,OAAO;AAC5B,UAAA/f,IAAS,IAAI,WAAW,CAAC;AACzB,gBAAMggB,IAAO,IAAI,SAAShgB,EAAO,MAAM;AACvC,UAAAggB,EAAK,SAAS,GAAG,GAAG,GACpBA,EAAK,UAAU,GAAGD,CAAa;AAAA,QACnC,OACK;AACD,UAAA/f,IAAS,IAAI,WAAW,CAAC;AACzB,gBAAMggB,IAAO,IAAI,SAAShgB,EAAO,MAAM;AACvC,UAAAggB,EAAK,SAAS,GAAG,GAAG,GACpBA,EAAK,aAAa,GAAG,OAAOD,CAAa,CAAC;AAAA,QAC9C;AAEA,QAAI3B,EAAO,QAAQ,OAAOA,EAAO,QAAS,aACtCpe,EAAO,CAAC,KAAK,MAEjBzlB,EAAW,QAAQylB,CAAM,GACzBzlB,EAAW,QAAQ2kC,CAAa;AAAA,MACpC,CAAC;AAAA,IACL;AAAA,EACR,CAAK;AACL;AACA,IAAIe;AACJ,SAASC,GAAYC,GAAQ;AACzB,SAAOA,EAAO,OAAO,CAAClmC,GAAKotB,MAAUptB,IAAMotB,EAAM,QAAQ,CAAC;AAC9D;AACA,SAAS+Y,GAAaD,GAAQpP,GAAM;AAChC,MAAIoP,EAAO,CAAC,EAAE,WAAWpP;AACrB,WAAOoP,EAAO,MAAK;AAEvB,QAAME,IAAS,IAAI,WAAWtP,CAAI;AAClC,MAAIuP,IAAI;AACR,WAAS58C,IAAI,GAAGA,IAAIqtC,GAAMrtC;AACtB,IAAA28C,EAAO38C,CAAC,IAAIy8C,EAAO,CAAC,EAAEG,GAAG,GACrBA,MAAMH,EAAO,CAAC,EAAE,WAChBA,EAAO,MAAK,GACZG,IAAI;AAGZ,SAAIH,EAAO,UAAUG,IAAIH,EAAO,CAAC,EAAE,WAC/BA,EAAO,CAAC,IAAIA,EAAO,CAAC,EAAE,MAAMG,CAAC,IAE1BD;AACX;AACO,SAASE,GAA0BC,GAAYrB,GAAY;AAC9D,EAAKc,OACDA,KAAe,IAAI,YAAW;AAElC,QAAME,IAAS,CAAA;AACf,MAAIvgD,IAAQ,GACR6gD,IAAiB,IACjBC,IAAW;AACf,SAAO,IAAI,gBAAgB;AAAA,IACvB,UAAUrZ,GAAO9sB,GAAY;AAEzB,WADA4lC,EAAO,KAAK9Y,CAAK,OACJ;AACT,YAAIznC,MAAU,GAA2B;AACrC,cAAIsgD,GAAYC,CAAM,IAAI;AACtB;AAEJ,gBAAMngB,IAASogB,GAAaD,GAAQ,CAAC;AACrC,UAAAO,KAAY1gB,EAAO,CAAC,IAAI,SAAU,KAClCygB,IAAiBzgB,EAAO,CAAC,IAAI,KACzBygB,IAAiB,MACjB7gD,IAAQ,IAEH6gD,MAAmB,MACxB7gD,IAAQ,IAGRA,IAAQ;AAAA,QAEhB,WACSA,MAAU,GAAuC;AACtD,cAAIsgD,GAAYC,CAAM,IAAI;AACtB;AAEJ,gBAAMQ,IAAcP,GAAaD,GAAQ,CAAC;AAC1C,UAAAM,IAAiB,IAAI,SAASE,EAAY,QAAQA,EAAY,YAAYA,EAAY,MAAM,EAAE,UAAU,CAAC,GACzG/gD,IAAQ;AAAA,QACZ,WACSA,MAAU,GAAuC;AACtD,cAAIsgD,GAAYC,CAAM,IAAI;AACtB;AAEJ,gBAAMQ,IAAcP,GAAaD,GAAQ,CAAC,GACpCH,IAAO,IAAI,SAASW,EAAY,QAAQA,EAAY,YAAYA,EAAY,MAAM,GAClFr/C,IAAI0+C,EAAK,UAAU,CAAC;AAC1B,cAAI1+C,IAAI,KAAK,IAAI,GAAG,EAAO,IAAI,GAAG;AAE9B,YAAAiZ,EAAW,QAAQijC,EAAY;AAC/B;AAAA,UACJ;AACA,UAAAiD,IAAiBn/C,IAAI,KAAK,IAAI,GAAG,EAAE,IAAI0+C,EAAK,UAAU,CAAC,GACvDpgD,IAAQ;AAAA,QACZ,OACK;AACD,cAAIsgD,GAAYC,CAAM,IAAIM;AACtB;AAEJ,gBAAMhb,IAAO2a,GAAaD,GAAQM,CAAc;AAChD,UAAAlmC,EAAW,QAAQ0kC,GAAayB,IAAWjb,IAAOwa,GAAa,OAAOxa,CAAI,GAAG0Z,CAAU,CAAC,GACxFv/C,IAAQ;AAAA,QACZ;AACA,YAAI6gD,MAAmB,KAAKA,IAAiBD,GAAY;AACrD,UAAAjmC,EAAW,QAAQijC,EAAY;AAC/B;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACR,CAAK;AACL;AACO,MAAMoD,KAAW;ACpJjB,SAASC,GAAQ9iD,GAAK;AAC3B,MAAIA,EAAK,QAAO+iD,GAAM/iD,CAAG;AAC3B;AAUA,SAAS+iD,GAAM/iD,GAAK;AAClB,WAAS8B,KAAOghD,GAAQ;AACtB,IAAA9iD,EAAI8B,CAAG,IAAIghD,GAAQ,UAAUhhD,CAAG;AAElC,SAAO9B;AACT;AAWA8iD,GAAQ,UAAU,KAClBA,GAAQ,UAAU,mBAAmB,SAASjyB,GAAOvtB,GAAG;AACtD,cAAK,aAAa,KAAK,cAAc,CAAA,IACpC,KAAK,WAAW,MAAMutB,CAAK,IAAI,KAAK,WAAW,MAAMA,CAAK,KAAK,CAAA,GAC7D,KAAKvtB,CAAE,GACH;AACT;AAYAw/C,GAAQ,UAAU,OAAO,SAASjyB,GAAOvtB,GAAG;AAC1C,WAAS0/C,IAAK;AACZ,SAAK,IAAInyB,GAAOmyB,CAAE,GAClB1/C,EAAG,MAAM,MAAM,SAAS;AAAA,EAC1B;AAEA,SAAA0/C,EAAG,KAAK1/C,GACR,KAAK,GAAGutB,GAAOmyB,CAAE,GACV;AACT;AAYAF,GAAQ,UAAU,MAClBA,GAAQ,UAAU,iBAClBA,GAAQ,UAAU,qBAClBA,GAAQ,UAAU,sBAAsB,SAASjyB,GAAOvtB,GAAG;AAIzD,MAHA,KAAK,aAAa,KAAK,cAAc,CAAA,GAG5B,UAAU,UAAf;AACF,gBAAK,aAAa,CAAA,GACX;AAIT,MAAI2/C,IAAY,KAAK,WAAW,MAAMpyB,CAAK;AAC3C,MAAI,CAACoyB,EAAW,QAAO;AAGvB,MAAS,UAAU,UAAf;AACF,kBAAO,KAAK,WAAW,MAAMpyB,CAAK,GAC3B;AAKT,WADIvL,GACK3f,IAAI,GAAGA,IAAIs9C,EAAU,QAAQt9C;AAEpC,QADA2f,IAAK29B,EAAUt9C,CAAC,GACZ2f,MAAOhiB,KAAMgiB,EAAG,OAAOhiB,GAAI;AAC7B,MAAA2/C,EAAU,OAAOt9C,GAAG,CAAC;AACrB;AAAA,IACF;AAKF,SAAIs9C,EAAU,WAAW,KACvB,OAAO,KAAK,WAAW,MAAMpyB,CAAK,GAG7B;AACT;AAUAiyB,GAAQ,UAAU,OAAO,SAASjyB,GAAM;AACtC,OAAK,aAAa,KAAK,cAAc,CAAA;AAKrC,WAHI1jB,IAAO,IAAI,MAAM,UAAU,SAAS,CAAC,GACrC81C,IAAY,KAAK,WAAW,MAAMpyB,CAAK,GAElClrB,IAAI,GAAGA,IAAI,UAAU,QAAQA;AACpC,IAAAwH,EAAKxH,IAAI,CAAC,IAAI,UAAUA,CAAC;AAG3B,MAAIs9C,GAAW;AACb,IAAAA,IAAYA,EAAU,MAAM,CAAC;AAC7B,aAASt9C,IAAI,GAAG+wC,IAAMuM,EAAU,QAAQt9C,IAAI+wC,GAAK,EAAE/wC;AACjD,MAAAs9C,EAAUt9C,CAAC,EAAE,MAAM,MAAMwH,CAAI;AAAA,EAEjC;AAEA,SAAO;AACT;AAGA21C,GAAQ,UAAU,eAAeA,GAAQ,UAAU;AAUnDA,GAAQ,UAAU,YAAY,SAASjyB,GAAM;AAC3C,cAAK,aAAa,KAAK,cAAc,CAAA,GAC9B,KAAK,WAAW,MAAMA,CAAK,KAAK,CAAA;AACzC;AAUAiyB,GAAQ,UAAU,eAAe,SAASjyB,GAAM;AAC9C,SAAO,CAAC,CAAE,KAAK,UAAUA,CAAK,EAAE;AAClC;ACxKO,MAAMqyB,KACkB,OAAO,WAAY,cAAc,OAAO,QAAQ,WAAY,aAE5E,CAAC59B,MAAO,QAAQ,QAAO,EAAG,KAAKA,CAAE,IAGjC,CAACA,GAAI69B,MAAiBA,EAAa79B,GAAI,CAAC,GAG1C89B,KACL,OAAO,OAAS,MACT,OAEF,OAAO,SAAW,MAChB,SAGA,SAAS,aAAa,EAAC,GAGzBC,KAAoB;ACnB1B,SAASC,GAAKtjD,MAAQuxB,GAAM;AAC/B,SAAOA,EAAK,OAAO,CAACrV,GAAKzH,OACjBzU,EAAI,eAAeyU,CAAC,MACpByH,EAAIzH,CAAC,IAAIzU,EAAIyU,CAAC,IAEXyH,IACR,CAAA,CAAE;AACT;AAEA,MAAMqnC,KAAqBC,GAAW,YAChCC,KAAuBD,GAAW;AACjC,SAASE,GAAsB1jD,GAAK0N,GAAM;AAC7C,EAAIA,EAAK,mBACL1N,EAAI,eAAeujD,GAAmB,KAAKC,EAAU,GACrDxjD,EAAI,iBAAiByjD,GAAqB,KAAKD,EAAU,MAGzDxjD,EAAI,eAAewjD,GAAW,WAAW,KAAKA,EAAU,GACxDxjD,EAAI,iBAAiBwjD,GAAW,aAAa,KAAKA,EAAU;AAEpE;AAEA,MAAMG,KAAkB;AAEjB,SAASC,GAAW5jD,GAAK;AAC5B,SAAI,OAAOA,KAAQ,WACR6jD,GAAW7jD,CAAG,IAGlB,KAAK,MAAMA,EAAI,cAAcA,EAAI,QAAQ2jD,EAAe;AACnE;AACA,SAASE,GAAWC,GAAK;AACrB,MAAIrmB,IAAI,GAAGikB,IAAS;AACpB,WAAS/7C,IAAI,GAAGkyC,IAAIiM,EAAI,QAAQn+C,IAAIkyC,GAAGlyC;AACnC,IAAA83B,IAAIqmB,EAAI,WAAWn+C,CAAC,GAChB83B,IAAI,MACJikB,KAAU,IAELjkB,IAAI,OACTikB,KAAU,IAELjkB,IAAI,SAAUA,KAAK,QACxBikB,KAAU,KAGV/7C,KACA+7C,KAAU;AAGlB,SAAOA;AACX;AAIO,SAASqC,KAAe;AAC3B,SAAQ,KAAK,MAAM,SAAS,EAAE,EAAE,UAAU,CAAC,IACvC,KAAK,OAAM,EAAG,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC;AACjD;AClDO,SAASC,GAAOhkD,GAAK;AACxB,MAAI8jD,IAAM;AACV,WAASn+C,KAAK3F;AACV,IAAIA,EAAI,eAAe2F,CAAC,MAChBm+C,EAAI,WACJA,KAAO,MACXA,KAAO,mBAAmBn+C,CAAC,IAAI,MAAM,mBAAmB3F,EAAI2F,CAAC,CAAC;AAGtE,SAAOm+C;AACX;AAOO,SAASrD,GAAO5hC,GAAI;AACvB,MAAIolC,IAAM,CAAA,GACNC,IAAQrlC,EAAG,MAAM,GAAG;AACxB,WAASlZ,IAAI,GAAGkyC,IAAIqM,EAAM,QAAQv+C,IAAIkyC,GAAGlyC,KAAK;AAC1C,QAAIw+C,IAAOD,EAAMv+C,CAAC,EAAE,MAAM,GAAG;AAC7B,IAAAs+C,EAAI,mBAAmBE,EAAK,CAAC,CAAC,CAAC,IAAI,mBAAmBA,EAAK,CAAC,CAAC;AAAA,EACjE;AACA,SAAOF;AACX;AC7BO,MAAMG,WAAuB,MAAM;AAAA,EACtC,YAAY7nC,GAAQ8nC,GAAavgD,GAAS;AACtC,UAAMyY,CAAM,GACZ,KAAK,cAAc8nC,GACnB,KAAK,UAAUvgD,GACf,KAAK,OAAO;AAAA,EAChB;AACJ;AACO,MAAMwgD,WAAkBxB,GAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOnC,YAAYp1C,GAAM;AACd,UAAK,GACL,KAAK,WAAW,IAChBg2C,GAAsB,MAAMh2C,CAAI,GAChC,KAAK,OAAOA,GACZ,KAAK,QAAQA,EAAK,OAClB,KAAK,SAASA,EAAK,QACnB,KAAK,iBAAiB,CAACA,EAAK;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,QAAQ6O,GAAQ8nC,GAAavgD,GAAS;AAClC,iBAAM,aAAa,SAAS,IAAIsgD,GAAe7nC,GAAQ8nC,GAAavgD,CAAO,CAAC,GACrE;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO;AACH,gBAAK,aAAa,WAClB,KAAK,OAAM,GACJ;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAIA,QAAQ;AACJ,YAAI,KAAK,eAAe,aAAa,KAAK,eAAe,YACrD,KAAK,QAAO,GACZ,KAAK,QAAO,IAET;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK29C,GAAS;AACV,IAAI,KAAK,eAAe,UACpB,KAAK,MAAMA,CAAO;AAAA,EAK1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AACL,SAAK,aAAa,QAClB,KAAK,WAAW,IAChB,MAAM,aAAa,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO/Z,GAAM;AACT,UAAM2Y,IAASa,GAAaxZ,GAAM,KAAK,OAAO,UAAU;AACxD,SAAK,SAAS2Y,CAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAASA,GAAQ;AACb,UAAM,aAAa,UAAUA,CAAM;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQkE,GAAS;AACb,SAAK,aAAa,UAClB,MAAM,aAAa,SAASA,CAAO;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAMC,GAAS;AAAA,EAAE;AAAA,EACjB,UAAUC,GAAQhhB,IAAQ,IAAI;AAC1B,WAAQghB,IACJ,QACA,KAAK,UAAS,IACd,KAAK,MAAK,IACV,KAAK,KAAK,OACV,KAAK,OAAOhhB,CAAK;AAAA,EACzB;AAAA,EACA,YAAY;AACR,UAAMihB,IAAW,KAAK,KAAK;AAC3B,WAAOA,EAAS,QAAQ,GAAG,MAAM,KAAKA,IAAW,MAAMA,IAAW;AAAA,EACtE;AAAA,EACA,QAAQ;AACJ,WAAI,KAAK,KAAK,SACR,KAAK,KAAK,UAAU,EAAO,KAAK,KAAK,SAAS,QAC3C,CAAC,KAAK,KAAK,UAAU,OAAO,KAAK,KAAK,IAAI,MAAM,MAC9C,MAAM,KAAK,KAAK,OAGhB;AAAA,EAEf;AAAA,EACA,OAAOjhB,GAAO;AACV,UAAMkhB,IAAeX,GAAOvgB,CAAK;AACjC,WAAOkhB,EAAa,SAAS,MAAMA,IAAe;AAAA,EACtD;AACJ;AC1IO,MAAMC,WAAgBN,GAAU;AAAA,EACnC,cAAc;AACV,UAAM,GAAG,SAAS,GAClB,KAAK,WAAW;AAAA,EACpB;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS;AACL,SAAK,MAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAME,GAAS;AACX,SAAK,aAAa;AAClB,UAAMK,IAAQ,MAAM;AAChB,WAAK,aAAa,UAClBL,EAAO;AAAA,IACX;AACA,QAAI,KAAK,YAAY,CAAC,KAAK,UAAU;AACjC,UAAIM,IAAQ;AACZ,MAAI,KAAK,aACLA,KACA,KAAK,KAAK,gBAAgB,WAAY;AAClC,UAAEA,KAASD,EAAK;AAAA,MACpB,CAAC,IAEA,KAAK,aACNC,KACA,KAAK,KAAK,SAAS,WAAY;AAC3B,UAAEA,KAASD,EAAK;AAAA,MACpB,CAAC;AAAA,IAET;AAEI,MAAAA,EAAK;AAAA,EAEb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ;AACJ,SAAK,WAAW,IAChB,KAAK,OAAM,GACX,KAAK,aAAa,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAOnd,GAAM;AACT,UAAM5S,IAAW,CAACurB,MAAW;AAMzB,UAJkB,KAAK,eAAnB,aAAiCA,EAAO,SAAS,UACjD,KAAK,OAAM,GAGCA,EAAO,SAAnB;AACA,oBAAK,QAAQ,EAAE,aAAa,iCAAgC,CAAE,GACvD;AAGX,WAAK,SAASA,CAAM;AAAA,IACxB;AAEA,IAAAuB,GAAcla,GAAM,KAAK,OAAO,UAAU,EAAE,QAAQ5S,CAAQ,GAE3C,KAAK,eAAlB,aAEA,KAAK,WAAW,IAChB,KAAK,aAAa,cAAc,GACjB,KAAK,eAAhB,UACA,KAAK,MAAK;AAAA,EAKtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU;AACN,UAAMiwB,IAAQ,MAAM;AAChB,WAAK,MAAM,CAAC,EAAE,MAAM,QAAO,CAAE,CAAC;AAAA,IAClC;AACA,IAAe,KAAK,eAAhB,SACAA,EAAK,IAKL,KAAK,KAAK,QAAQA,CAAK;AAAA,EAE/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAMtD,GAAS;AACX,SAAK,WAAW,IAChBD,GAAcC,GAAS,CAAC/Z,MAAS;AAC7B,WAAK,QAAQA,GAAM,MAAM;AACrB,aAAK,WAAW,IAChB,KAAK,aAAa,OAAO;AAAA,MAC7B,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM;AACF,UAAM+c,IAAS,KAAK,KAAK,SAAS,UAAU,QACtChhB,IAAQ,KAAK,SAAS,CAAA;AAE5B,WAAc,KAAK,KAAK,sBAApB,OACAA,EAAM,KAAK,KAAK,cAAc,IAAIsgB,GAAY,IAE9C,CAAC,KAAK,kBAAkB,CAACtgB,EAAM,QAC/BA,EAAM,MAAM,IAET,KAAK,UAAUghB,GAAQhhB,CAAK;AAAA,EACvC;AACJ;AC/IA,IAAIpjC,KAAQ;AACZ,IAAI;AACA,EAAAA,KAAQ,OAAO,iBAAmB,OAC9B,qBAAqB,IAAI,eAAc;AAC/C,QACY;AAGZ;AACO,MAAM2kD,KAAU3kD;ACLvB,SAAS4kD,KAAQ;AAAE;AACZ,MAAMC,WAAgBN,GAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjC,YAAYl3C,GAAM;AAEd,QADA,MAAMA,CAAI,GACN,OAAO,WAAa,KAAa;AACjC,YAAMy3C,IAAqB,SAAS,aAAtB;AACd,UAAIC,IAAO,SAAS;AAEpB,MAAKA,MACDA,IAAOD,IAAQ,QAAQ,OAE3B,KAAK,KACA,OAAO,WAAa,OACjBz3C,EAAK,aAAa,SAAS,YAC3B03C,MAAS13C,EAAK;AAAA,IAC1B;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQg6B,GAAMpkC,GAAI;AACd,UAAM+hD,IAAM,KAAK,QAAQ;AAAA,MACrB,QAAQ;AAAA,MACR,MAAM3d;AAAA,IAClB,CAAS;AACD,IAAA2d,EAAI,GAAG,WAAW/hD,CAAE,GACpB+hD,EAAI,GAAG,SAAS,CAACC,GAAWxhD,MAAY;AACpC,WAAK,QAAQ,kBAAkBwhD,GAAWxhD,CAAO;AAAA,IACrD,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AACL,UAAMuhD,IAAM,KAAK,QAAO;AACxB,IAAAA,EAAI,GAAG,QAAQ,KAAK,OAAO,KAAK,IAAI,CAAC,GACrCA,EAAI,GAAG,SAAS,CAACC,GAAWxhD,MAAY;AACpC,WAAK,QAAQ,kBAAkBwhD,GAAWxhD,CAAO;AAAA,IACrD,CAAC,GACD,KAAK,UAAUuhD;AAAA,EACnB;AACJ;SACO,MAAME,WAAgBzC,GAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjC,YAAY0C,GAAeC,GAAK/3C,GAAM;AAClC,UAAK,GACL,KAAK,gBAAgB83C,GACrB9B,GAAsB,MAAMh2C,CAAI,GAChC,KAAK,QAAQA,GACb,KAAK,UAAUA,EAAK,UAAU,OAC9B,KAAK,OAAO+3C,GACZ,KAAK,QAAsB/3C,EAAK,SAAnB,SAA0BA,EAAK,OAAO,MACnD,KAAK,QAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU;AACN,QAAIg4C;AACJ,UAAMh4C,IAAO41C,GAAK,KAAK,OAAO,SAAS,OAAO,OAAO,cAAc,QAAQ,MAAM,WAAW,sBAAsB,WAAW;AAC7H,IAAA51C,EAAK,UAAU,CAAC,CAAC,KAAK,MAAM;AAC5B,UAAMi4C,IAAO,KAAK,OAAO,KAAK,cAAcj4C,CAAI;AAChD,QAAI;AACA,MAAAi4C,EAAI,KAAK,KAAK,SAAS,KAAK,MAAM,EAAI;AACtC,UAAI;AACA,YAAI,KAAK,MAAM,cAAc;AAEzB,UAAAA,EAAI,yBAAyBA,EAAI,sBAAsB,EAAI;AAC3D,mBAAShgD,KAAK,KAAK,MAAM;AACrB,YAAI,KAAK,MAAM,aAAa,eAAeA,CAAC,KACxCggD,EAAI,iBAAiBhgD,GAAG,KAAK,MAAM,aAAaA,CAAC,CAAC;AAAA,QAG9D;AAAA,MACJ,QACU;AAAA,MAAE;AACZ,UAAe,KAAK,YAAhB;AACA,YAAI;AACA,UAAAggD,EAAI,iBAAiB,gBAAgB,0BAA0B;AAAA,QACnE,QACU;AAAA,QAAE;AAEhB,UAAI;AACA,QAAAA,EAAI,iBAAiB,UAAU,KAAK;AAAA,MACxC,QACU;AAAA,MAAE;AACZ,OAACD,IAAK,KAAK,MAAM,eAAe,QAAQA,MAAO,UAAkBA,EAAG,WAAWC,CAAG,GAE9E,qBAAqBA,MACrBA,EAAI,kBAAkB,KAAK,MAAM,kBAEjC,KAAK,MAAM,mBACXA,EAAI,UAAU,KAAK,MAAM,iBAE7BA,EAAI,qBAAqB,MAAM;AAC3B,YAAID;AAMJ,QALIC,EAAI,eAAe,OAClBD,IAAK,KAAK,MAAM,eAAe,QAAQA,MAAO,UAAkBA,EAAG;AAAA;AAAA,UAEpEC,EAAI,kBAAkB,YAAY;AAAA,QAAC,IAE7BA,EAAI,eAAV,MAEQA,EAAI,WAAZ,OAA+BA,EAAI,WAAb,OACtB,KAAK,QAAO,IAKZ,KAAK,aAAa,MAAM;AACpB,eAAK,SAAS,OAAOA,EAAI,UAAW,WAAWA,EAAI,SAAS,CAAC;AAAA,QACjE,GAAG,CAAC;AAAA,MAEZ,GACAA,EAAI,KAAK,KAAK,KAAK;AAAA,IACvB,SACOt3C,GAAG;AAIN,WAAK,aAAa,MAAM;AACpB,aAAK,SAASA,CAAC;AAAA,MACnB,GAAG,CAAC;AACJ;AAAA,IACJ;AACA,IAAI,OAAO,WAAa,QACpB,KAAK,SAASk3C,GAAQ,iBACtBA,GAAQ,SAAS,KAAK,MAAM,IAAI;AAAA,EAExC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAASpiB,GAAK;AACV,SAAK,aAAa,SAASA,GAAK,KAAK,IAAI,GACzC,KAAK,SAAS,EAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAASyiB,GAAW;AAChB,QAAI,EAAgB,OAAO,KAAK,OAA5B,OAA6C,KAAK,SAAd,OAIxC;AAAA,UADA,KAAK,KAAK,qBAAqBX,IAC3BW;AACA,YAAI;AACA,eAAK,KAAK,MAAK;AAAA,QACnB,QACU;AAAA,QAAE;AAEhB,MAAI,OAAO,WAAa,OACpB,OAAOL,GAAQ,SAAS,KAAK,MAAM,GAEvC,KAAK,OAAO;AAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU;AACN,UAAM7d,IAAO,KAAK,KAAK;AACvB,IAAIA,MAAS,SACT,KAAK,aAAa,QAAQA,CAAI,GAC9B,KAAK,aAAa,SAAS,GAC3B,KAAK,SAAQ;AAAA,EAErB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ;AACJ,SAAK,SAAQ;AAAA,EACjB;AACJ;AACA6d,GAAQ,gBAAgB;AACxBA,GAAQ,WAAW,CAAA;AAMnB,IAAI,OAAO,WAAa;AAEpB,MAAI,OAAO,eAAgB;AAEvB,gBAAY,YAAYM,EAAa;AAAA,WAEhC,OAAO,oBAAqB,YAAY;AAC7C,UAAMC,IAAmB,gBAAgBtC,KAAa,aAAa;AACnE,qBAAiBsC,GAAkBD,IAAe,EAAK;AAAA,EAC3D;AAAA;AAEJ,SAASA,KAAgB;AACrB,WAASlgD,KAAK4/C,GAAQ;AAClB,IAAIA,GAAQ,SAAS,eAAe5/C,CAAC,KACjC4/C,GAAQ,SAAS5/C,CAAC,EAAE,MAAK;AAGrC;AACA,MAAMogD,MAAW,WAAY;AACzB,QAAMJ,IAAMK,GAAW;AAAA,IACnB,SAAS;AAAA,EACjB,CAAK;AACD,SAAOL,KAAOA,EAAI,iBAAiB;AACvC,GAAC;AAQM,MAAMM,WAAYf,GAAQ;AAAA,EAC7B,YAAYx3C,GAAM;AACd,UAAMA,CAAI;AACV,UAAMw4C,IAAcx4C,KAAQA,EAAK;AACjC,SAAK,iBAAiBq4C,MAAW,CAACG;AAAA,EACtC;AAAA,EACA,QAAQx4C,IAAO,IAAI;AACf,kBAAO,OAAOA,GAAM,EAAE,IAAI,KAAK,GAAE,GAAI,KAAK,IAAI,GACvC,IAAI63C,GAAQS,IAAY,KAAK,IAAG,GAAIt4C,CAAI;AAAA,EACnD;AACJ;AACA,SAASs4C,GAAWt4C,GAAM;AACtB,QAAMy4C,IAAUz4C,EAAK;AAErB,MAAI;AACA,QAAoB,OAAO,iBAAvB,QAA0C,CAACy4C,KAAWnB;AACtD,aAAO,IAAI,eAAc;AAAA,EAEjC,QACU;AAAA,EAAE;AACZ,MAAI,CAACmB;AACD,QAAI;AACA,aAAO,IAAI3C,GAAW,CAAC,QAAQ,EAAE,OAAO,QAAQ,EAAE,KAAK,GAAG,CAAC,EAAE,mBAAmB;AAAA,IACpF,QACU;AAAA,IAAE;AAEpB;ACzQA,MAAM4C,KAAgB,OAAO,YAAc,OACvC,OAAO,UAAU,WAAY,YAC7B,UAAU,QAAQ,YAAW,MAAO;AACjC,MAAMC,WAAe/B,GAAU;AAAA,EAClC,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AAAA,EACA,SAAS;AACL,UAAMmB,IAAM,KAAK,IAAG,GACda,IAAY,KAAK,KAAK,WAEtB54C,IAAO04C,KACP,CAAA,IACA9C,GAAK,KAAK,MAAM,SAAS,qBAAqB,OAAO,OAAO,cAAc,QAAQ,MAAM,WAAW,sBAAsB,gBAAgB,mBAAmB,UAAU,cAAc,UAAU,qBAAqB;AACzN,IAAI,KAAK,KAAK,iBACV51C,EAAK,UAAU,KAAK,KAAK;AAE7B,QAAI;AACA,WAAK,KAAK,KAAK,aAAa+3C,GAAKa,GAAW54C,CAAI;AAAA,IACpD,SACOy1B,GAAK;AACR,aAAO,KAAK,aAAa,SAASA,CAAG;AAAA,IACzC;AACA,SAAK,GAAG,aAAa,KAAK,OAAO,YACjC,KAAK,kBAAiB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,oBAAoB;AAChB,SAAK,GAAG,SAAS,MAAM;AACnB,MAAI,KAAK,KAAK,aACV,KAAK,GAAG,QAAQ,MAAK,GAEzB,KAAK,OAAM;AAAA,IACf,GACA,KAAK,GAAG,UAAU,CAACojB,MAAe,KAAK,QAAQ;AAAA,MAC3C,aAAa;AAAA,MACb,SAASA;AAAA,IACrB,CAAS,GACD,KAAK,GAAG,YAAY,CAACC,MAAO,KAAK,OAAOA,EAAG,IAAI,GAC/C,KAAK,GAAG,UAAU,CAACn4C,MAAM,KAAK,QAAQ,mBAAmBA,CAAC;AAAA,EAC9D;AAAA,EACA,MAAMozC,GAAS;AACX,SAAK,WAAW;AAGhB,aAAS97C,IAAI,GAAGA,IAAI87C,EAAQ,QAAQ97C,KAAK;AACrC,YAAM06C,IAASoB,EAAQ97C,CAAC,GAClB8gD,IAAa9gD,MAAM87C,EAAQ,SAAS;AAC1C,MAAA5B,GAAaQ,GAAQ,KAAK,gBAAgB,CAAC3Y,MAAS;AAIhD,YAAI;AACA,eAAK,QAAQ2Y,GAAQ3Y,CAAI;AAAA,QAC7B,QACU;AAAA,QACV;AACA,QAAI+e,KAGAvD,GAAS,MAAM;AACX,eAAK,WAAW,IAChB,KAAK,aAAa,OAAO;AAAA,QAC7B,GAAG,KAAK,YAAY;AAAA,MAE5B,CAAC;AAAA,IACL;AAAA,EACJ;AAAA,EACA,UAAU;AACN,IAAI,OAAO,KAAK,KAAO,QACnB,KAAK,GAAG,UAAU,MAAM;AAAA,IAAE,GAC1B,KAAK,GAAG,MAAK,GACb,KAAK,KAAK;AAAA,EAElB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM;AACF,UAAMuB,IAAS,KAAK,KAAK,SAAS,QAAQ,MACpChhB,IAAQ,KAAK,SAAS,CAAA;AAE5B,WAAI,KAAK,KAAK,sBACVA,EAAM,KAAK,KAAK,cAAc,IAAIsgB,GAAY,IAG7C,KAAK,mBACNtgB,EAAM,MAAM,IAET,KAAK,UAAUghB,GAAQhhB,CAAK;AAAA,EACvC;AACJ;AACA,MAAMijB,KAAgBlD,GAAW,aAAaA,GAAW;AAUlD,MAAMmD,WAAWN,GAAO;AAAA,EAC3B,aAAaZ,GAAKa,GAAW54C,GAAM;AAC/B,WAAQ04C,KAIF,IAAIM,GAAcjB,GAAKa,GAAW54C,CAAI,IAHtC44C,IACI,IAAII,GAAcjB,GAAKa,CAAS,IAChC,IAAII,GAAcjB,CAAG;AAAA,EAEnC;AAAA,EACA,QAAQmB,GAASlf,GAAM;AACnB,SAAK,GAAG,KAAKA,CAAI;AAAA,EACrB;AACJ;ACjHO,MAAMmf,WAAWvC,GAAU;AAAA,EAC9B,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AAAA,EACA,SAAS;AACL,QAAI;AAEA,WAAK,aAAa,IAAI,aAAa,KAAK,UAAU,OAAO,GAAG,KAAK,KAAK,iBAAiB,KAAK,IAAI,CAAC;AAAA,IACrG,SACOnhB,GAAK;AACR,aAAO,KAAK,aAAa,SAASA,CAAG;AAAA,IACzC;AACA,SAAK,WAAW,OACX,KAAK,MAAM;AACZ,WAAK,QAAO;AAAA,IAChB,CAAC,EACI,MAAM,CAACA,MAAQ;AAChB,WAAK,QAAQ,sBAAsBA,CAAG;AAAA,IAC1C,CAAC,GAED,KAAK,WAAW,MAAM,KAAK,MAAM;AAC7B,WAAK,WAAW,0BAAyB,EAAG,KAAK,CAAC2jB,MAAW;AACzD,cAAMC,IAAgBvE,GAA0B,OAAO,kBAAkB,KAAK,OAAO,UAAU,GACzFwE,IAASF,EAAO,SAAS,YAAYC,CAAa,EAAE,UAAS,GAC7DE,IAAgBlF,GAAyB;AAC/C,QAAAkF,EAAc,SAAS,OAAOH,EAAO,QAAQ,GAC7C,KAAK,UAAUG,EAAc,SAAS,UAAS;AAC/C,cAAMnO,IAAO,MAAM;AACf,UAAAkO,EACK,KAAI,EACJ,KAAK,CAAC,EAAE,MAAAE,GAAM,OAAA7mD,QAAY;AAC3B,YAAI6mD,MAGJ,KAAK,SAAS7mD,CAAK,GACnBy4C,EAAI;AAAA,UACR,CAAC,EACI,MAAM,CAAC3V,MAAQ;AAAA,UACpB,CAAC;AAAA,QACL;AACA,QAAA2V,EAAI;AACJ,cAAMuH,IAAS,EAAE,MAAM,OAAM;AAC7B,QAAI,KAAK,MAAM,QACXA,EAAO,OAAO,WAAW,KAAK,MAAM,GAAG,OAE3C,KAAK,QAAQ,MAAMA,CAAM,EAAE,KAAK,MAAM,KAAK,QAAQ;AAAA,MACvD,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AAAA,EACA,MAAMoB,GAAS;AACX,SAAK,WAAW;AAChB,aAAS97C,IAAI,GAAGA,IAAI87C,EAAQ,QAAQ97C,KAAK;AACrC,YAAM06C,IAASoB,EAAQ97C,CAAC,GAClB8gD,IAAa9gD,MAAM87C,EAAQ,SAAS;AAC1C,WAAK,QAAQ,MAAMpB,CAAM,EAAE,KAAK,MAAM;AAClC,QAAIoG,KACAvD,GAAS,MAAM;AACX,eAAK,WAAW,IAChB,KAAK,aAAa,OAAO;AAAA,QAC7B,GAAG,KAAK,YAAY;AAAA,MAE5B,CAAC;AAAA,IACL;AAAA,EACJ;AAAA,EACA,UAAU;AACN,QAAIwC;AACJ,KAACA,IAAK,KAAK,gBAAgB,QAAQA,MAAO,UAAkBA,EAAG,MAAK;AAAA,EACxE;AACJ;AC5EO,MAAMyB,KAAa;AAAA,EACtB,WAAWR;AAAA,EACX,cAAcE;AAAA,EACd,SAASZ;AACb,GCYMmB,KAAK,uPACLC,KAAQ;AAAA,EACV;AAAA,EAAU;AAAA,EAAY;AAAA,EAAa;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAa;AAAA,EAAQ;AAAA,EAAS;AACzI;AACO,SAASC,GAAMxD,GAAK;AACvB,MAAIA,EAAI,SAAS;AACb,UAAM;AAEV,QAAMyD,IAAMzD,GAAKv8C,IAAIu8C,EAAI,QAAQ,GAAG,GAAGz1C,IAAIy1C,EAAI,QAAQ,GAAG;AAC1D,EAAIv8C,KAAK,MAAM8G,KAAK,OAChBy1C,IAAMA,EAAI,UAAU,GAAGv8C,CAAC,IAAIu8C,EAAI,UAAUv8C,GAAG8G,CAAC,EAAE,QAAQ,MAAM,GAAG,IAAIy1C,EAAI,UAAUz1C,GAAGy1C,EAAI,MAAM;AAEpG,MAAI/3C,IAAIq7C,GAAG,KAAKtD,KAAO,EAAE,GAAG2B,IAAM,IAAI,IAAI;AAC1C,SAAO;AACH,IAAAA,EAAI4B,GAAM,CAAC,CAAC,IAAIt7C,EAAE,CAAC,KAAK;AAE5B,SAAIxE,KAAK,MAAM8G,KAAK,OAChBo3C,EAAI,SAAS8B,GACb9B,EAAI,OAAOA,EAAI,KAAK,UAAU,GAAGA,EAAI,KAAK,SAAS,CAAC,EAAE,QAAQ,MAAM,GAAG,GACvEA,EAAI,YAAYA,EAAI,UAAU,QAAQ,KAAK,EAAE,EAAE,QAAQ,KAAK,EAAE,EAAE,QAAQ,MAAM,GAAG,GACjFA,EAAI,UAAU,KAElBA,EAAI,YAAY+B,GAAU/B,GAAKA,EAAI,IAAO,GAC1CA,EAAI,WAAWgC,GAAShC,GAAKA,EAAI,KAAQ,GAClCA;AACX;AACA,SAAS+B,GAAUxnD,GAAKgC,GAAM;AAC1B,QAAM0lD,IAAO,YAAYC,IAAQ3lD,EAAK,QAAQ0lD,GAAM,GAAG,EAAE,MAAM,GAAG;AAClE,UAAI1lD,EAAK,MAAM,GAAG,CAAC,KAAK,OAAOA,EAAK,WAAW,MAC3C2lD,EAAM,OAAO,GAAG,CAAC,GAEjB3lD,EAAK,MAAM,EAAE,KAAK,OAClB2lD,EAAM,OAAOA,EAAM,SAAS,GAAG,CAAC,GAE7BA;AACX;AACA,SAASF,GAAShC,GAAKhiB,GAAO;AAC1B,QAAMiE,IAAO,CAAA;AACb,SAAAjE,EAAM,QAAQ,6BAA6B,SAAUmkB,GAAIC,GAAIC,GAAI;AAC7D,IAAID,MACAngB,EAAKmgB,CAAE,IAAIC;AAAA,EAEnB,CAAC,GACMpgB;AACX;ACxDA,MAAMqgB,KAAqB,OAAO,oBAAqB,cACnD,OAAO,uBAAwB,YAC7BC,KAA0B,CAAA;AAC5BD,MAGA,iBAAiB,WAAW,MAAM;AAC9B,EAAAC,GAAwB,QAAQ,CAACvlD,MAAaA,EAAQ,CAAE;AAC5D,GAAG,EAAK;AAyBL,MAAMwlD,WAA6BnF,GAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO9C,YAAY2C,GAAK/3C,GAAM;AAiBnB,QAhBA,MAAK,GACL,KAAK,aAAa21C,IAClB,KAAK,cAAc,CAAA,GACnB,KAAK,iBAAiB,GACtB,KAAK,gBAAgB,IACrB,KAAK,eAAe,IACpB,KAAK,cAAc,IAKnB,KAAK,mBAAmB,OACpBoC,KAAoB,OAAOA,KAApB,aACP/3C,IAAO+3C,GACPA,IAAM,OAENA,GAAK;AACL,YAAMyC,IAAYZ,GAAM7B,CAAG;AAC3B,MAAA/3C,EAAK,WAAWw6C,EAAU,MAC1Bx6C,EAAK,SACDw6C,EAAU,aAAa,WAAWA,EAAU,aAAa,OAC7Dx6C,EAAK,OAAOw6C,EAAU,MAClBA,EAAU,UACVx6C,EAAK,QAAQw6C,EAAU;AAAA,IAC/B,MACK,CAAIx6C,EAAK,SACVA,EAAK,WAAW45C,GAAM55C,EAAK,IAAI,EAAE;AAErC,IAAAg2C,GAAsB,MAAMh2C,CAAI,GAChC,KAAK,SACOA,EAAK,UAAb,OACMA,EAAK,SACL,OAAO,WAAa,OAA4B,SAAS,aAAtB,UACzCA,EAAK,YAAY,CAACA,EAAK,SAEvBA,EAAK,OAAO,KAAK,SAAS,QAAQ,OAEtC,KAAK,WACDA,EAAK,aACA,OAAO,WAAa,MAAc,SAAS,WAAW,cAC/D,KAAK,OACDA,EAAK,SACA,OAAO,WAAa,OAAe,SAAS,OACvC,SAAS,OACT,KAAK,SACD,QACA,OAClB,KAAK,aAAa,CAAA,GAClB,KAAK,oBAAoB,CAAA,GACzBA,EAAK,WAAW,QAAQ,CAAC4hB,MAAM;AAC3B,YAAM64B,IAAgB74B,EAAE,UAAU;AAClC,WAAK,WAAW,KAAK64B,CAAa,GAClC,KAAK,kBAAkBA,CAAa,IAAI74B;AAAA,IAC5C,CAAC,GACD,KAAK,OAAO,OAAO,OAAO;AAAA,MACtB,MAAM;AAAA,MACN,OAAO;AAAA,MACP,iBAAiB;AAAA,MACjB,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,oBAAoB;AAAA,MACpB,mBAAmB;AAAA,QACf,WAAW;AAAA,MAC3B;AAAA,MACY,kBAAkB,CAAA;AAAA,MAClB,qBAAqB;AAAA,IACjC,GAAW5hB,CAAI,GACP,KAAK,KAAK,OACN,KAAK,KAAK,KAAK,QAAQ,OAAO,EAAE,KAC3B,KAAK,KAAK,mBAAmB,MAAM,KACxC,OAAO,KAAK,KAAK,SAAU,aAC3B,KAAK,KAAK,QAAQ+yC,GAAO,KAAK,KAAK,KAAK,IAExCsH,OACI,KAAK,KAAK,wBAIV,KAAK,6BAA6B,MAAM;AACpC,MAAI,KAAK,cAEL,KAAK,UAAU,mBAAkB,GACjC,KAAK,UAAU,MAAK;AAAA,IAE5B,GACA,iBAAiB,gBAAgB,KAAK,4BAA4B,EAAK,IAEvE,KAAK,aAAa,gBAClB,KAAK,wBAAwB,MAAM;AAC/B,WAAK,SAAS,mBAAmB;AAAA,QAC7B,aAAa;AAAA,MACrC,CAAqB;AAAA,IACL,GACAC,GAAwB,KAAK,KAAK,qBAAqB,KAG3D,KAAK,KAAK,oBACV,KAAK,aAAa,SAEtB,KAAK,MAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAgB7oC,GAAM;AAClB,UAAMskB,IAAQ,OAAO,OAAO,CAAA,GAAI,KAAK,KAAK,KAAK;AAE/C,IAAAA,EAAM,MAAMof,IAEZpf,EAAM,YAAYtkB,GAEd,KAAK,OACLskB,EAAM,MAAM,KAAK;AACrB,UAAM/1B,IAAO,OAAO,OAAO,CAAA,GAAI,KAAK,MAAM;AAAA,MACtC,OAAA+1B;AAAA,MACA,QAAQ;AAAA,MACR,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,MAAM,KAAK;AAAA,IACvB,GAAW,KAAK,KAAK,iBAAiBtkB,CAAI,CAAC;AACnC,WAAO,IAAI,KAAK,kBAAkBA,CAAI,EAAEzR,CAAI;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ;AACJ,QAAI,KAAK,WAAW,WAAW,GAAG;AAE9B,WAAK,aAAa,MAAM;AACpB,aAAK,aAAa,SAAS,yBAAyB;AAAA,MACxD,GAAG,CAAC;AACJ;AAAA,IACJ;AACA,UAAMy6C,IAAgB,KAAK,KAAK,mBAC5BF,GAAqB,yBACrB,KAAK,WAAW,QAAQ,WAAW,MAAM,KACvC,cACA,KAAK,WAAW,CAAC;AACvB,SAAK,aAAa;AAClB,UAAMG,IAAY,KAAK,gBAAgBD,CAAa;AACpD,IAAAC,EAAU,KAAI,GACd,KAAK,aAAaA,CAAS;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAaA,GAAW;AACpB,IAAI,KAAK,aACL,KAAK,UAAU,mBAAkB,GAGrC,KAAK,YAAYA,GAEjBA,EACK,GAAG,SAAS,KAAK,SAAS,KAAK,IAAI,CAAC,EACpC,GAAG,UAAU,KAAK,UAAU,KAAK,IAAI,CAAC,EACtC,GAAG,SAAS,KAAK,SAAS,KAAK,IAAI,CAAC,EACpC,GAAG,SAAS,CAAC7rC,MAAW,KAAK,SAAS,mBAAmBA,CAAM,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AACL,SAAK,aAAa,QAClB0rC,GAAqB,wBACD,KAAK,UAAU,SAA/B,aACJ,KAAK,aAAa,MAAM,GACxB,KAAK,MAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU5H,GAAQ;AACd,QAAkB,KAAK,eAAnB,aACW,KAAK,eAAhB,UACc,KAAK,eAAnB;AAIA,cAHA,KAAK,aAAa,UAAUA,CAAM,GAElC,KAAK,aAAa,WAAW,GACrBA,EAAO,MAAI;AAAA,QACf,KAAK;AACD,eAAK,YAAY,KAAK,MAAMA,EAAO,IAAI,CAAC;AACxC;AAAA,QACJ,KAAK;AACD,eAAK,YAAY,MAAM,GACvB,KAAK,aAAa,MAAM,GACxB,KAAK,aAAa,MAAM,GACxB,KAAK,kBAAiB;AACtB;AAAA,QACJ,KAAK;AACD,gBAAMld,IAAM,IAAI,MAAM,cAAc;AAEpC,UAAAA,EAAI,OAAOkd,EAAO,MAClB,KAAK,SAASld,CAAG;AACjB;AAAA,QACJ,KAAK;AACD,eAAK,aAAa,QAAQkd,EAAO,IAAI,GACrC,KAAK,aAAa,WAAWA,EAAO,IAAI;AACxC;AAAA,MACpB;AAAA,EAII;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY3Y,GAAM;AASd,IARA,KAAK,aAAa,aAAaA,CAAI,GACnC,KAAK,KAAKA,EAAK,KACf,KAAK,UAAU,MAAM,MAAMA,EAAK,KAChC,KAAK,gBAAgBA,EAAK,cAC1B,KAAK,eAAeA,EAAK,aACzB,KAAK,cAAcA,EAAK,YACxB,KAAK,OAAM,GAEM,KAAK,eAAlB,YAEJ,KAAK,kBAAiB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,oBAAoB;AAChB,SAAK,eAAe,KAAK,iBAAiB;AAC1C,UAAMgC,IAAQ,KAAK,gBAAgB,KAAK;AACxC,SAAK,mBAAmB,KAAK,IAAG,IAAKA,GACrC,KAAK,oBAAoB,KAAK,aAAa,MAAM;AAC7C,WAAK,SAAS,cAAc;AAAA,IAChC,GAAGA,CAAK,GACJ,KAAK,KAAK,aACV,KAAK,kBAAkB,MAAK;AAAA,EAEpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW;AACP,SAAK,YAAY,OAAO,GAAG,KAAK,cAAc,GAI9C,KAAK,iBAAiB,GACZ,KAAK,YAAY,WAAvB,IACA,KAAK,aAAa,OAAO,IAGzB,KAAK,MAAK;AAAA,EAElB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ;AACJ,QAAiB,KAAK,eAAlB,YACA,KAAK,UAAU,YACf,CAAC,KAAK,aACN,KAAK,YAAY,QAAQ;AACzB,YAAM+X,IAAU,KAAK,oBAAmB;AACxC,WAAK,UAAU,KAAKA,CAAO,GAG3B,KAAK,iBAAiBA,EAAQ,QAC9B,KAAK,aAAa,OAAO;AAAA,IAC7B;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,sBAAsB;AAIlB,QAAI,EAH2B,KAAK,eAChC,KAAK,UAAU,SAAS,aACxB,KAAK,YAAY,SAAS;AAE1B,aAAO,KAAK;AAEhB,QAAI4G,IAAc;AAClB,aAAS1iD,IAAI,GAAGA,IAAI,KAAK,YAAY,QAAQA,KAAK;AAC9C,YAAM+hC,IAAO,KAAK,YAAY/hC,CAAC,EAAE;AAIjC,UAHI+hC,MACA2gB,KAAezE,GAAWlc,CAAI,IAE9B/hC,IAAI,KAAK0iD,IAAc,KAAK;AAC5B,eAAO,KAAK,YAAY,MAAM,GAAG1iD,CAAC;AAEtC,MAAA0iD,KAAe;AAAA,IACnB;AACA,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUc,kBAAkB;AAC5B,QAAI,CAAC,KAAK;AACN,aAAO;AACX,UAAMC,IAAa,KAAK,IAAG,IAAK,KAAK;AACrC,WAAIA,MACA,KAAK,mBAAmB,GACxBpF,GAAS,MAAM;AACX,WAAK,SAAS,cAAc;AAAA,IAChC,GAAG,KAAK,YAAY,IAEjBoF;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAMxoD,GAAKU,GAAS8C,GAAI;AACpB,gBAAK,YAAY,WAAWxD,GAAKU,GAAS8C,CAAE,GACrC;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,KAAKxD,GAAKU,GAAS8C,GAAI;AACnB,gBAAK,YAAY,WAAWxD,GAAKU,GAAS8C,CAAE,GACrC;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,YAAYuf,GAAM6kB,GAAMlnC,GAAS8C,GAAI;AASjC,QARmB,OAAOokC,KAAtB,eACApkC,IAAKokC,GACLA,IAAO,SAEQ,OAAOlnC,KAAtB,eACA8C,IAAK9C,GACLA,IAAU,OAEI,KAAK,eAAnB,aAA8C,KAAK,eAAlB;AACjC;AAEJ,IAAAA,IAAUA,KAAW,CAAA,GACrBA,EAAQ,WAAqBA,EAAQ,aAAlB;AACnB,UAAM6/C,IAAS;AAAA,MACX,MAAMx9B;AAAA,MACN,MAAM6kB;AAAA,MACN,SAASlnC;AAAA,IACrB;AACQ,SAAK,aAAa,gBAAgB6/C,CAAM,GACxC,KAAK,YAAY,KAAKA,CAAM,GACxB/8C,KACA,KAAK,KAAK,SAASA,CAAE,GACzB,KAAK,MAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAIA,QAAQ;AACJ,UAAMyhD,IAAQ,MAAM;AAChB,WAAK,SAAS,cAAc,GAC5B,KAAK,UAAU,MAAK;AAAA,IACxB,GACMwD,IAAkB,MAAM;AAC1B,WAAK,IAAI,WAAWA,CAAe,GACnC,KAAK,IAAI,gBAAgBA,CAAe,GACxCxD,EAAK;AAAA,IACT,GACMyD,IAAiB,MAAM;AAEzB,WAAK,KAAK,WAAWD,CAAe,GACpC,KAAK,KAAK,gBAAgBA,CAAe;AAAA,IAC7C;AACA,YAAkB,KAAK,eAAnB,aAA4C,KAAK,eAAhB,YACjC,KAAK,aAAa,WACd,KAAK,YAAY,SACjB,KAAK,KAAK,SAAS,MAAM;AACrB,MAAI,KAAK,YACLC,EAAc,IAGdzD,EAAK;AAAA,IAEb,CAAC,IAEI,KAAK,YACVyD,EAAc,IAGdzD,EAAK,IAGN;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS5hB,GAAK;AAEV,QADA8kB,GAAqB,wBAAwB,IACzC,KAAK,KAAK,oBACV,KAAK,WAAW,SAAS,KACzB,KAAK,eAAe;AACpB,kBAAK,WAAW,MAAK,GACd,KAAK,MAAK;AAErB,SAAK,aAAa,SAAS9kB,CAAG,GAC9B,KAAK,SAAS,mBAAmBA,CAAG;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS5mB,GAAQ8nC,GAAa;AAC1B,QAAkB,KAAK,eAAnB,aACW,KAAK,eAAhB,UACc,KAAK,eAAnB,WAA+B;AAS/B,UAPA,KAAK,eAAe,KAAK,iBAAiB,GAE1C,KAAK,UAAU,mBAAmB,OAAO,GAEzC,KAAK,UAAU,MAAK,GAEpB,KAAK,UAAU,mBAAkB,GAC7B0D,OACI,KAAK,8BACL,oBAAoB,gBAAgB,KAAK,4BAA4B,EAAK,GAE1E,KAAK,wBAAuB;AAC5B,cAAMpiD,IAAIqiD,GAAwB,QAAQ,KAAK,qBAAqB;AACpE,QAAIriD,MAAM,MACNqiD,GAAwB,OAAOriD,GAAG,CAAC;AAAA,MAE3C;AAGJ,WAAK,aAAa,UAElB,KAAK,KAAK,MAEV,KAAK,aAAa,SAAS4W,GAAQ8nC,CAAW,GAG9C,KAAK,cAAc,CAAA,GACnB,KAAK,iBAAiB;AAAA,IAC1B;AAAA,EACJ;AACJ;AACA4D,GAAqB,WAAWpF;AAwBzB,MAAM4F,WAA0BR,GAAqB;AAAA,EACxD,cAAc;AACV,UAAM,GAAG,SAAS,GAClB,KAAK,YAAY,CAAA;AAAA,EACrB;AAAA,EACA,SAAS;AAEL,QADA,MAAM,OAAM,GACG,KAAK,eAAhB,UAA8B,KAAK,KAAK;AACxC,eAAStiD,IAAI,GAAGA,IAAI,KAAK,UAAU,QAAQA;AACvC,aAAK,OAAO,KAAK,UAAUA,CAAC,CAAC;AAAA,EAGzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAOwZ,GAAM;AACT,QAAIipC,IAAY,KAAK,gBAAgBjpC,CAAI,GACrCupC,IAAS;AACb,IAAAT,GAAqB,wBAAwB;AAC7C,UAAMU,IAAkB,MAAM;AAC1B,MAAID,MAEJN,EAAU,KAAK,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAO,CAAE,CAAC,GAChDA,EAAU,KAAK,UAAU,CAACtoD,MAAQ;AAC9B,YAAI,CAAA4oD;AAEJ,cAAe5oD,EAAI,SAAf,UAAmCA,EAAI,SAAhB,SAAsB;AAG7C,gBAFA,KAAK,YAAY,IACjB,KAAK,aAAa,aAAasoD,CAAS,GACpC,CAACA;AACD;AACJ,YAAAH,GAAqB,wBACDG,EAAU,SAA1B,aACJ,KAAK,UAAU,MAAM,MAAM;AACvB,cAAIM,KAEa,KAAK,eAAlB,aAEJE,EAAO,GACP,KAAK,aAAaR,CAAS,GAC3BA,EAAU,KAAK,CAAC,EAAE,MAAM,UAAS,CAAE,CAAC,GACpC,KAAK,aAAa,WAAWA,CAAS,GACtCA,IAAY,MACZ,KAAK,YAAY,IACjB,KAAK,MAAK;AAAA,YACd,CAAC;AAAA,UACL,OACK;AACD,kBAAMjlB,IAAM,IAAI,MAAM,aAAa;AAEnC,YAAAA,EAAI,YAAYilB,EAAU,MAC1B,KAAK,aAAa,gBAAgBjlB,CAAG;AAAA,UACzC;AAAA,MACJ,CAAC;AAAA,IACL;AACA,aAAS0lB,IAAkB;AACvB,MAAIH,MAGJA,IAAS,IACTE,EAAO,GACPR,EAAU,MAAK,GACfA,IAAY;AAAA,IAChB;AAEA,UAAMU,IAAU,CAAC3lB,MAAQ;AACrB,YAAMjgC,IAAQ,IAAI,MAAM,kBAAkBigC,CAAG;AAE7C,MAAAjgC,EAAM,YAAYklD,EAAU,MAC5BS,EAAe,GACf,KAAK,aAAa,gBAAgB3lD,CAAK;AAAA,IAC3C;AACA,aAAS6lD,IAAmB;AACxB,MAAAD,EAAQ,kBAAkB;AAAA,IAC9B;AAEA,aAASE,IAAU;AACf,MAAAF,EAAQ,eAAe;AAAA,IAC3B;AAEA,aAASG,EAAUhoD,GAAI;AACnB,MAAImnD,KAAannD,EAAG,SAASmnD,EAAU,QACnCS,EAAe;AAAA,IAEvB;AAEA,UAAMD,IAAU,MAAM;AAClB,MAAAR,EAAU,eAAe,QAAQO,CAAe,GAChDP,EAAU,eAAe,SAASU,CAAO,GACzCV,EAAU,eAAe,SAASW,CAAgB,GAClD,KAAK,IAAI,SAASC,CAAO,GACzB,KAAK,IAAI,aAAaC,CAAS;AAAA,IACnC;AACA,IAAAb,EAAU,KAAK,QAAQO,CAAe,GACtCP,EAAU,KAAK,SAASU,CAAO,GAC/BV,EAAU,KAAK,SAASW,CAAgB,GACxC,KAAK,KAAK,SAASC,CAAO,GAC1B,KAAK,KAAK,aAAaC,CAAS,GAC5B,KAAK,UAAU,QAAQ,cAAc,MAAM,MAC3C9pC,MAAS,iBAET,KAAK,aAAa,MAAM;AACpB,MAAKupC,KACDN,EAAU,KAAI;AAAA,IAEtB,GAAG,GAAG,IAGNA,EAAU,KAAI;AAAA,EAEtB;AAAA,EACA,YAAY1gB,GAAM;AACd,SAAK,YAAY,KAAK,gBAAgBA,EAAK,QAAQ,GACnD,MAAM,YAAYA,CAAI;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAgBwhB,GAAU;AACtB,UAAMC,IAAmB,CAAA;AACzB,aAASxjD,IAAI,GAAGA,IAAIujD,EAAS,QAAQvjD;AACjC,MAAI,CAAC,KAAK,WAAW,QAAQujD,EAASvjD,CAAC,CAAC,KACpCwjD,EAAiB,KAAKD,EAASvjD,CAAC,CAAC;AAEzC,WAAOwjD;AAAA,EACX;AACJ;SAoBO,cAAqBV,GAAkB;AAAA,EAC1C,YAAYhD,GAAK/3C,IAAO,IAAI;AACxB,UAAM+xB,IAAI,OAAOgmB,KAAQ,WAAWA,IAAM/3C;AAC1C,KAAI,CAAC+xB,EAAE,cACFA,EAAE,cAAc,OAAOA,EAAE,WAAW,CAAC,KAAM,cAC5CA,EAAE,cAAcA,EAAE,cAAc,CAAC,WAAW,aAAa,cAAc,GAClE,IAAI,CAAC0oB,MAAkBiB,GAAmBjB,CAAa,CAAC,EACxD,OAAO,CAAC74B,MAAM,CAAC,CAACA,CAAC,IAE1B,MAAMm2B,GAAKhmB,CAAC;AAAA,EAChB;AACJ;AC5sBO,SAASx8B,GAAIwiD,GAAKzjD,IAAO,IAAIknC,GAAK;AACrC,MAAIlpC,IAAMylD;AAEV,EAAAvc,IAAMA,KAAQ,OAAO,WAAa,OAAe,UACrCuc,KAAR,SACAA,IAAMvc,EAAI,WAAW,OAAOA,EAAI,OAEhC,OAAOuc,KAAQ,aACHA,EAAI,OAAO,CAAC,MAApB,QACYA,EAAI,OAAO,CAAC,MAApB,MACAA,IAAMvc,EAAI,WAAWuc,IAGrBA,IAAMvc,EAAI,OAAOuc,IAGpB,sBAAsB,KAAKA,CAAG,MACX,OAAOvc,IAAvB,MACAuc,IAAMvc,EAAI,WAAW,OAAOuc,IAG5BA,IAAM,aAAaA,IAI3BzlD,IAAMsnD,GAAM7B,CAAG,IAGdzlD,EAAI,SACD,cAAc,KAAKA,EAAI,QAAQ,IAC/BA,EAAI,OAAO,OAEN,eAAe,KAAKA,EAAI,QAAQ,MACrCA,EAAI,OAAO,SAGnBA,EAAI,OAAOA,EAAI,QAAQ;AAEvB,QAAMqpD,IADOrpD,EAAI,KAAK,QAAQ,GAAG,MAAM,KACnB,MAAMA,EAAI,OAAO,MAAMA,EAAI;AAE/C,SAAAA,EAAI,KAAKA,EAAI,WAAW,QAAQqpD,IAAO,MAAMrpD,EAAI,OAAOgC,GAExDhC,EAAI,OACAA,EAAI,WACA,QACAqpD,KACCngB,KAAOA,EAAI,SAASlpC,EAAI,OAAO,KAAK,MAAMA,EAAI,OAChDA;AACX;AC1DA,MAAM2/C,KAAwB,OAAO,eAAgB,YAC/CC,KAAS,CAAC5/C,MACL,OAAO,YAAY,UAAW,aAC/B,YAAY,OAAOA,CAAG,IACtBA,EAAI,kBAAkB,aAE1BspD,KAAW,OAAO,UAAU,UAC5B5J,KAAiB,OAAO,QAAS,cAClC,OAAO,OAAS,OACb4J,GAAS,KAAK,IAAI,MAAM,4BAC1BC,KAAiB,OAAO,QAAS,cAClC,OAAO,OAAS,OACbD,GAAS,KAAK,IAAI,MAAM;AAMzB,SAAS3G,GAAS3iD,GAAK;AAC1B,SAAS2/C,OAA0B3/C,aAAe,eAAe4/C,GAAO5/C,CAAG,MACtE0/C,MAAkB1/C,aAAe,QACjCupD,MAAkBvpD,aAAe;AAC1C;AACO,SAASwpD,GAAUxpD,GAAKypD,GAAQ;AACnC,MAAI,CAACzpD,KAAO,OAAOA,KAAQ;AACvB,WAAO;AAEX,MAAI,MAAM,QAAQA,CAAG,GAAG;AACpB,aAAS2F,IAAI,GAAGkyC,IAAI73C,EAAI,QAAQ2F,IAAIkyC,GAAGlyC;AACnC,UAAI6jD,GAAUxpD,EAAI2F,CAAC,CAAC;AAChB,eAAO;AAGf,WAAO;AAAA,EACX;AACA,MAAIg9C,GAAS3iD,CAAG;AACZ,WAAO;AAEX,MAAIA,EAAI,UACJ,OAAOA,EAAI,UAAW,cACtB,UAAU,WAAW;AACrB,WAAOwpD,GAAUxpD,EAAI,OAAM,GAAI,EAAI;AAEvC,aAAW8B,KAAO9B;AACd,QAAI,OAAO,UAAU,eAAe,KAAKA,GAAK8B,CAAG,KAAK0nD,GAAUxpD,EAAI8B,CAAG,CAAC;AACpE,aAAO;AAGf,SAAO;AACX;ACzCO,SAAS4nD,GAAkBrJ,GAAQ;AACtC,QAAMsJ,IAAU,CAAA,GACVC,IAAavJ,EAAO,MACpBwJ,IAAOxJ;AACb,SAAAwJ,EAAK,OAAOC,GAAmBF,GAAYD,CAAO,GAClDE,EAAK,cAAcF,EAAQ,QACpB,EAAE,QAAQE,GAAM,SAASF,EAAO;AAC3C;AACA,SAASG,GAAmBpiB,GAAMiiB,GAAS;AACvC,MAAI,CAACjiB;AACD,WAAOA;AACX,MAAIib,GAASjb,CAAI,GAAG;AAChB,UAAMqiB,IAAc,EAAE,cAAc,IAAM,KAAKJ,EAAQ,OAAM;AAC7D,WAAAA,EAAQ,KAAKjiB,CAAI,GACVqiB;AAAA,EACX,WACS,MAAM,QAAQriB,CAAI,GAAG;AAC1B,UAAMsiB,IAAU,IAAI,MAAMtiB,EAAK,MAAM;AACrC,aAAS/hC,IAAI,GAAGA,IAAI+hC,EAAK,QAAQ/hC;AAC7B,MAAAqkD,EAAQrkD,CAAC,IAAImkD,GAAmBpiB,EAAK/hC,CAAC,GAAGgkD,CAAO;AAEpD,WAAOK;AAAA,EACX,WACS,OAAOtiB,KAAS,YAAY,EAAEA,aAAgB,OAAO;AAC1D,UAAMsiB,IAAU,CAAA;AAChB,eAAWloD,KAAO4lC;AACd,MAAI,OAAO,UAAU,eAAe,KAAKA,GAAM5lC,CAAG,MAC9CkoD,EAAQloD,CAAG,IAAIgoD,GAAmBpiB,EAAK5lC,CAAG,GAAG6nD,CAAO;AAG5D,WAAOK;AAAA,EACX;AACA,SAAOtiB;AACX;AASO,SAASuiB,GAAkB5J,GAAQsJ,GAAS;AAC/C,SAAAtJ,EAAO,OAAO6J,GAAmB7J,EAAO,MAAMsJ,CAAO,GACrD,OAAOtJ,EAAO,aACPA;AACX;AACA,SAAS6J,GAAmBxiB,GAAMiiB,GAAS;AACvC,MAAI,CAACjiB;AACD,WAAOA;AACX,MAAIA,KAAQA,EAAK,iBAAiB,IAAM;AAIpC,QAHqB,OAAOA,EAAK,OAAQ,YACrCA,EAAK,OAAO,KACZA,EAAK,MAAMiiB,EAAQ;AAEnB,aAAOA,EAAQjiB,EAAK,GAAG;AAGvB,UAAM,IAAI,MAAM,qBAAqB;AAAA,EAE7C,WACS,MAAM,QAAQA,CAAI;AACvB,aAAS/hC,IAAI,GAAGA,IAAI+hC,EAAK,QAAQ/hC;AAC7B,MAAA+hC,EAAK/hC,CAAC,IAAIukD,GAAmBxiB,EAAK/hC,CAAC,GAAGgkD,CAAO;AAAA,WAG5C,OAAOjiB,KAAS;AACrB,eAAW5lC,KAAO4lC;AACd,MAAI,OAAO,UAAU,eAAe,KAAKA,GAAM5lC,CAAG,MAC9C4lC,EAAK5lC,CAAG,IAAIooD,GAAmBxiB,EAAK5lC,CAAG,GAAG6nD,CAAO;AAI7D,SAAOjiB;AACX;AC5EA,MAAMyiB,KAAkB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AACJ,GAMatH,KAAW;AACjB,IAAIuH;AAAA,CACV,SAAUA,GAAY;AACnB,EAAAA,EAAWA,EAAW,UAAa,CAAC,IAAI,WACxCA,EAAWA,EAAW,aAAgB,CAAC,IAAI,cAC3CA,EAAWA,EAAW,QAAW,CAAC,IAAI,SACtCA,EAAWA,EAAW,MAAS,CAAC,IAAI,OACpCA,EAAWA,EAAW,gBAAmB,CAAC,IAAI,iBAC9CA,EAAWA,EAAW,eAAkB,CAAC,IAAI,gBAC7CA,EAAWA,EAAW,aAAgB,CAAC,IAAI;AAC/C,GAAGA,MAAeA,IAAa,CAAA,EAAG;AAI3B,MAAMC,GAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjB,YAAYC,GAAU;AAClB,SAAK,WAAWA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAOtqD,GAAK;AACR,YAAIA,EAAI,SAASoqD,EAAW,SAASpqD,EAAI,SAASoqD,EAAW,QACrDZ,GAAUxpD,CAAG,IACN,KAAK,eAAe;AAAA,MACvB,MAAMA,EAAI,SAASoqD,EAAW,QACxBA,EAAW,eACXA,EAAW;AAAA,MACjB,KAAKpqD,EAAI;AAAA,MACT,MAAMA,EAAI;AAAA,MACV,IAAIA,EAAI;AAAA,IAC5B,CAAiB,IAGF,CAAC,KAAK,eAAeA,CAAG,CAAC;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAIA,eAAeA,GAAK;AAEhB,QAAI8jD,IAAM,KAAK9jD,EAAI;AAEnB,YAAIA,EAAI,SAASoqD,EAAW,gBACxBpqD,EAAI,SAASoqD,EAAW,gBACxBtG,KAAO9jD,EAAI,cAAc,MAIzBA,EAAI,OAAeA,EAAI,QAAZ,QACX8jD,KAAO9jD,EAAI,MAAM,MAGTA,EAAI,MAAZ,SACA8jD,KAAO9jD,EAAI,KAGHA,EAAI,QAAZ,SACA8jD,KAAO,KAAK,UAAU9jD,EAAI,MAAM,KAAK,QAAQ,IAE1C8jD;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe9jD,GAAK;AAChB,UAAMuqD,IAAiBb,GAAkB1pD,CAAG,GACtC6pD,IAAO,KAAK,eAAeU,EAAe,MAAM,GAChDZ,IAAUY,EAAe;AAC/B,WAAAZ,EAAQ,QAAQE,CAAI,GACbF;AAAA,EACX;AACJ;AAEA,SAASa,GAASnqD,GAAO;AACrB,SAAO,OAAO,UAAU,SAAS,KAAKA,CAAK,MAAM;AACrD;AAMO,MAAMoqD,WAAgB3H,GAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjC,YAAY4H,GAAS;AACjB,UAAK,GACL,KAAK,UAAUA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI1qD,GAAK;AACL,QAAIqgD;AACJ,QAAI,OAAOrgD,KAAQ,UAAU;AACzB,UAAI,KAAK;AACL,cAAM,IAAI,MAAM,iDAAiD;AAErE,MAAAqgD,IAAS,KAAK,aAAargD,CAAG;AAC9B,YAAM2qD,IAAgBtK,EAAO,SAAS+J,EAAW;AACjD,MAAIO,KAAiBtK,EAAO,SAAS+J,EAAW,cAC5C/J,EAAO,OAAOsK,IAAgBP,EAAW,QAAQA,EAAW,KAE5D,KAAK,gBAAgB,IAAIQ,GAAoBvK,CAAM,GAE/CA,EAAO,gBAAgB,KACvB,MAAM,aAAa,WAAWA,CAAM,KAKxC,MAAM,aAAa,WAAWA,CAAM;AAAA,IAE5C,WACSsC,GAAS3iD,CAAG,KAAKA,EAAI;AAE1B,UAAK,KAAK;AAIN,QAAAqgD,IAAS,KAAK,cAAc,eAAergD,CAAG,GAC1CqgD,MAEA,KAAK,gBAAgB,MACrB,MAAM,aAAa,WAAWA,CAAM;AAAA;AAPxC,cAAM,IAAI,MAAM,kDAAkD;AAAA;AAYtE,YAAM,IAAI,MAAM,mBAAmBrgD,CAAG;AAAA,EAE9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa8jD,GAAK;AACd,QAAIn+C,IAAI;AAER,UAAMwvC,IAAI;AAAA,MACN,MAAM,OAAO2O,EAAI,OAAO,CAAC,CAAC;AAAA,IACtC;AACQ,QAAIsG,EAAWjV,EAAE,IAAI,MAAM;AACvB,YAAM,IAAI,MAAM,yBAAyBA,EAAE,IAAI;AAGnD,QAAIA,EAAE,SAASiV,EAAW,gBACtBjV,EAAE,SAASiV,EAAW,YAAY;AAClC,YAAMS,IAAQllD,IAAI;AAClB,aAAOm+C,EAAI,OAAO,EAAEn+C,CAAC,MAAM,OAAOA,KAAKm+C,EAAI;AAAQ;AACnD,YAAMgH,IAAMhH,EAAI,UAAU+G,GAAOllD,CAAC;AAClC,UAAImlD,KAAO,OAAOA,CAAG,KAAKhH,EAAI,OAAOn+C,CAAC,MAAM;AACxC,cAAM,IAAI,MAAM,qBAAqB;AAEzC,MAAAwvC,EAAE,cAAc,OAAO2V,CAAG;AAAA,IAC9B;AAEA,QAAYhH,EAAI,OAAOn+C,IAAI,CAAC,MAAxB,KAA2B;AAC3B,YAAMklD,IAAQllD,IAAI;AAClB,aAAO,EAAEA,KAED,EADMm+C,EAAI,OAAOn+C,CAAC,MAClB,OAEAA,MAAMm+C,EAAI;AAAd;AAGJ,MAAA3O,EAAE,MAAM2O,EAAI,UAAU+G,GAAOllD,CAAC;AAAA,IAClC;AAEI,MAAAwvC,EAAE,MAAM;AAGZ,UAAM3wB,IAAOs/B,EAAI,OAAOn+C,IAAI,CAAC;AAC7B,QAAW6e,MAAP,MAAe,OAAOA,CAAI,KAAKA,GAAM;AACrC,YAAMqmC,IAAQllD,IAAI;AAClB,aAAO,EAAEA,KAAG;AACR,cAAM83B,IAAIqmB,EAAI,OAAOn+C,CAAC;AACtB,YAAY83B,KAAR,QAAa,OAAOA,CAAC,KAAKA,GAAG;AAC7B,YAAE93B;AACF;AAAA,QACJ;AACA,YAAIA,MAAMm+C,EAAI;AACV;AAAA,MACR;AACA,MAAA3O,EAAE,KAAK,OAAO2O,EAAI,UAAU+G,GAAOllD,IAAI,CAAC,CAAC;AAAA,IAC7C;AAEA,QAAIm+C,EAAI,OAAO,EAAEn+C,CAAC,GAAG;AACjB,YAAMolD,IAAU,KAAK,SAASjH,EAAI,OAAOn+C,CAAC,CAAC;AAC3C,UAAI8kD,GAAQ,eAAetV,EAAE,MAAM4V,CAAO;AACtC,QAAA5V,EAAE,OAAO4V;AAAA;AAGT,cAAM,IAAI,MAAM,iBAAiB;AAAA,IAEzC;AACA,WAAO5V;AAAA,EACX;AAAA,EACA,SAAS2O,GAAK;AACV,QAAI;AACA,aAAO,KAAK,MAAMA,GAAK,KAAK,OAAO;AAAA,IACvC,QACU;AACN,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EACA,OAAO,eAAejhC,GAAMkoC,GAAS;AACjC,YAAQloC,GAAI;AAAA,MACR,KAAKunC,EAAW;AACZ,eAAOI,GAASO,CAAO;AAAA,MAC3B,KAAKX,EAAW;AACZ,eAAOW,MAAY;AAAA,MACvB,KAAKX,EAAW;AACZ,eAAO,OAAOW,KAAY,YAAYP,GAASO,CAAO;AAAA,MAC1D,KAAKX,EAAW;AAAA,MAChB,KAAKA,EAAW;AACZ,eAAQ,MAAM,QAAQW,CAAO,MACxB,OAAOA,EAAQ,CAAC,KAAM,YAClB,OAAOA,EAAQ,CAAC,KAAM,YACnBZ,GAAgB,QAAQY,EAAQ,CAAC,CAAC,MAAM;AAAA,MACxD,KAAKX,EAAW;AAAA,MAChB,KAAKA,EAAW;AACZ,eAAO,MAAM,QAAQW,CAAO;AAAA,IAC5C;AAAA,EACI;AAAA;AAAA;AAAA;AAAA,EAIA,UAAU;AACN,IAAI,KAAK,kBACL,KAAK,cAAc,uBAAsB,GACzC,KAAK,gBAAgB;AAAA,EAE7B;AACJ;AASA,MAAMH,GAAoB;AAAA,EACtB,YAAYvK,GAAQ;AAChB,SAAK,SAASA,GACd,KAAK,UAAU,CAAA,GACf,KAAK,YAAYA;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,eAAe2K,GAAS;AAEpB,QADA,KAAK,QAAQ,KAAKA,CAAO,GACrB,KAAK,QAAQ,WAAW,KAAK,UAAU,aAAa;AAEpD,YAAM3K,IAAS4J,GAAkB,KAAK,WAAW,KAAK,OAAO;AAC7D,kBAAK,uBAAsB,GACpB5J;AAAA,IACX;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAIA,yBAAyB;AACrB,SAAK,YAAY,MACjB,KAAK,UAAU,CAAA;AAAA,EACnB;AACJ;;;;;;;;;;ACtTO,SAAS2C,GAAGhjD,GAAKwmD,GAAIljD,GAAI;AAC5B,SAAAtD,EAAI,GAAGwmD,GAAIljD,CAAE,GACN,WAAsB;AACzB,IAAAtD,EAAI,IAAIwmD,GAAIljD,CAAE;AAAA,EAClB;AACJ;ACEA,MAAM6mD,KAAkB,OAAO,OAAO;AAAA,EAClC,SAAS;AAAA,EACT,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,eAAe;AAAA;AAAA,EAEf,aAAa;AAAA,EACb,gBAAgB;AACpB,CAAC;AAyBM,MAAMc,WAAenI,GAAQ;AAAA;AAAA;AAAA;AAAA,EAIhC,YAAYoI,GAAIC,GAAKz9C,GAAM;AACvB,UAAK,GAeL,KAAK,YAAY,IAKjB,KAAK,YAAY,IAIjB,KAAK,gBAAgB,CAAA,GAIrB,KAAK,aAAa,CAAA,GAOlB,KAAK,SAAS,CAAA,GAKd,KAAK,YAAY,GACjB,KAAK,MAAM,GAwBX,KAAK,OAAO,CAAA,GACZ,KAAK,QAAQ,CAAA,GACb,KAAK,KAAKw9C,GACV,KAAK,MAAMC,GACPz9C,KAAQA,EAAK,SACb,KAAK,OAAOA,EAAK,OAErB,KAAK,QAAQ,OAAO,OAAO,CAAA,GAAIA,CAAI,GAC/B,KAAK,GAAG,gBACR,KAAK,KAAI;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAI,eAAe;AACf,WAAO,CAAC,KAAK;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY;AACR,QAAI,KAAK;AACL;AACJ,UAAMw9C,IAAK,KAAK;AAChB,SAAK,OAAO;AAAA,MACRlI,GAAGkI,GAAI,QAAQ,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,MACrClI,GAAGkI,GAAI,UAAU,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA,MACzClI,GAAGkI,GAAI,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA,MACvClI,GAAGkI,GAAI,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA,IACnD;AAAA,EACI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,IAAI,SAAS;AACT,WAAO,CAAC,CAAC,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,UAAU;AACN,WAAI,KAAK,YACE,QACX,KAAK,UAAS,GACT,KAAK,GAAG,iBACT,KAAK,GAAG,QACG,KAAK,GAAG,gBAAnB,UACA,KAAK,OAAM,GACR;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO;AACH,WAAO,KAAK,QAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,QAAQ/9C,GAAM;AACV,WAAAA,EAAK,QAAQ,SAAS,GACtB,KAAK,KAAK,MAAM,MAAMA,CAAI,GACnB;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,KAAKq5C,MAAOr5C,GAAM;AACd,QAAIu4C,GAAI0F,GAAIC;AACZ,QAAIlB,GAAgB,eAAe3D,CAAE;AACjC,YAAM,IAAI,MAAM,MAAMA,EAAG,SAAQ,IAAK,4BAA4B;AAGtE,QADAr5C,EAAK,QAAQq5C,CAAE,GACX,KAAK,MAAM,WAAW,CAAC,KAAK,MAAM,aAAa,CAAC,KAAK,MAAM;AAC3D,kBAAK,YAAYr5C,CAAI,GACd;AAEX,UAAMkzC,IAAS;AAAA,MACX,MAAM+J,EAAW;AAAA,MACjB,MAAMj9C;AAAA,IAClB;AAIQ,QAHAkzC,EAAO,UAAU,CAAA,GACjBA,EAAO,QAAQ,WAAW,KAAK,MAAM,aAAa,IAE/B,OAAOlzC,EAAKA,EAAK,SAAS,CAAC,KAA1C,YAA6C;AAC7C,YAAMvI,IAAK,KAAK,OACV0mD,IAAMn+C,EAAK,IAAG;AACpB,WAAK,qBAAqBvI,GAAI0mD,CAAG,GACjCjL,EAAO,KAAKz7C;AAAA,IAChB;AACA,UAAM2mD,KAAuBH,KAAM1F,IAAK,KAAK,GAAG,YAAY,QAAQA,MAAO,SAAS,SAASA,EAAG,eAAe,QAAQ0F,MAAO,SAAS,SAASA,EAAG,UAC7II,IAAc,KAAK,aAAa,EAAG,GAAAH,IAAK,KAAK,GAAG,YAAY,QAAQA,MAAO,WAAkBA,EAAG;AAEtG,WADsB,KAAK,MAAM,YAAY,CAACE,MAGrCC,KACL,KAAK,wBAAwBnL,CAAM,GACnC,KAAK,OAAOA,CAAM,KAGlB,KAAK,WAAW,KAAKA,CAAM,IAE/B,KAAK,QAAQ,CAAA,GACN;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAIA,qBAAqBz7C,GAAI0mD,GAAK;AAC1B,QAAI5F;AACJ,UAAM+F,KAAW/F,IAAK,KAAK,MAAM,aAAa,QAAQA,MAAO,SAASA,IAAK,KAAK,MAAM;AACtF,QAAI+F,MAAY,QAAW;AACvB,WAAK,KAAK7mD,CAAE,IAAI0mD;AAChB;AAAA,IACJ;AAEA,UAAMI,IAAQ,KAAK,GAAG,aAAa,MAAM;AACrC,aAAO,KAAK,KAAK9mD,CAAE;AACnB,eAASe,IAAI,GAAGA,IAAI,KAAK,WAAW,QAAQA;AACxC,QAAI,KAAK,WAAWA,CAAC,EAAE,OAAOf,KAC1B,KAAK,WAAW,OAAOe,GAAG,CAAC;AAGnC,MAAA2lD,EAAI,KAAK,MAAM,IAAI,MAAM,yBAAyB,CAAC;AAAA,IACvD,GAAGG,CAAO,GACJnoD,IAAK,IAAI6J,MAAS;AAEpB,WAAK,GAAG,eAAeu+C,CAAK,GAC5BJ,EAAI,MAAM,MAAMn+C,CAAI;AAAA,IACxB;AACA,IAAA7J,EAAG,YAAY,IACf,KAAK,KAAKsB,CAAE,IAAItB;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,YAAYkjD,MAAOr5C,GAAM;AACrB,WAAO,IAAI,QAAQ,CAAC8F,GAAS0S,MAAW;AACpC,YAAMriB,IAAK,CAACqoD,GAAMC,MACPD,IAAOhmC,EAAOgmC,CAAI,IAAI14C,EAAQ24C,CAAI;AAE7C,MAAAtoD,EAAG,YAAY,IACf6J,EAAK,KAAK7J,CAAE,GACZ,KAAK,KAAKkjD,GAAI,GAAGr5C,CAAI;AAAA,IACzB,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAYA,GAAM;AACd,QAAIm+C;AACJ,IAAI,OAAOn+C,EAAKA,EAAK,SAAS,CAAC,KAAM,eACjCm+C,IAAMn+C,EAAK,IAAG;AAElB,UAAMkzC,IAAS;AAAA,MACX,IAAI,KAAK;AAAA,MACT,UAAU;AAAA,MACV,SAAS;AAAA,MACT,MAAAlzC;AAAA,MACA,OAAO,OAAO,OAAO,EAAE,WAAW,GAAI,GAAI,KAAK,KAAK;AAAA,IAChE;AACQ,IAAAA,EAAK,KAAK,CAACg2B,MAAQ0oB,OACA,KAAK,OAAO,CAAC,GAEX1oB,MAAQ,OAEjBkd,EAAO,WAAW,KAAK,MAAM,YAC7B,KAAK,OAAO,MAAK,GACbiL,KACAA,EAAInoB,CAAG,MAKf,KAAK,OAAO,MAAK,GACbmoB,KACAA,EAAI,MAAM,GAAGO,CAAY,IAGjCxL,EAAO,UAAU,IACV,KAAK,YAAW,EAC1B,GACD,KAAK,OAAO,KAAKA,CAAM,GACvB,KAAK,YAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAYyL,IAAQ,IAAO;AACvB,QAAI,CAAC,KAAK,aAAa,KAAK,OAAO,WAAW;AAC1C;AAEJ,UAAMzL,IAAS,KAAK,OAAO,CAAC;AAC5B,IAAIA,EAAO,WAAW,CAACyL,MAGvBzL,EAAO,UAAU,IACjBA,EAAO,YACP,KAAK,QAAQA,EAAO,OACpB,KAAK,KAAK,MAAM,MAAMA,EAAO,IAAI;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAOA,GAAQ;AACX,IAAAA,EAAO,MAAM,KAAK,KAClB,KAAK,GAAG,QAAQA,CAAM;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AACL,IAAI,OAAO,KAAK,QAAQ,aACpB,KAAK,KAAK,CAAC3Y,MAAS;AAChB,WAAK,mBAAmBA,CAAI;AAAA,IAChC,CAAC,IAGD,KAAK,mBAAmB,KAAK,IAAI;AAAA,EAEzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmBA,GAAM;AACrB,SAAK,OAAO;AAAA,MACR,MAAM0iB,EAAW;AAAA,MACjB,MAAM,KAAK,OACL,OAAO,OAAO,EAAE,KAAK,KAAK,MAAM,QAAQ,KAAK,YAAW,GAAI1iB,CAAI,IAChEA;AAAA,IAClB,CAAS;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQvE,GAAK;AACT,IAAK,KAAK,aACN,KAAK,aAAa,iBAAiBA,CAAG;AAAA,EAE9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ5mB,GAAQ8nC,GAAa;AACzB,SAAK,YAAY,IACjB,OAAO,KAAK,IACZ,KAAK,aAAa,cAAc9nC,GAAQ8nC,CAAW,GACnD,KAAK,WAAU;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa;AACT,WAAO,KAAK,KAAK,IAAI,EAAE,QAAQ,CAACz/C,MAAO;AAEnC,UAAI,CADe,KAAK,WAAW,KAAK,CAACy7C,MAAW,OAAOA,EAAO,EAAE,MAAMz7C,CAAE,GAC3D;AAEb,cAAM0mD,IAAM,KAAK,KAAK1mD,CAAE;AACxB,eAAO,KAAK,KAAKA,CAAE,GACf0mD,EAAI,aACJA,EAAI,KAAK,MAAM,IAAI,MAAM,8BAA8B,CAAC;AAAA,MAEhE;AAAA,IACJ,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAASjL,GAAQ;AAEb,QADsBA,EAAO,QAAQ,KAAK;AAG1C,cAAQA,EAAO,MAAI;AAAA,QACf,KAAK+J,EAAW;AACZ,UAAI/J,EAAO,QAAQA,EAAO,KAAK,MAC3B,KAAK,UAAUA,EAAO,KAAK,KAAKA,EAAO,KAAK,GAAG,IAG/C,KAAK,aAAa,iBAAiB,IAAI,MAAM,2LAA2L,CAAC;AAE7O;AAAA,QACJ,KAAK+J,EAAW;AAAA,QAChB,KAAKA,EAAW;AACZ,eAAK,QAAQ/J,CAAM;AACnB;AAAA,QACJ,KAAK+J,EAAW;AAAA,QAChB,KAAKA,EAAW;AACZ,eAAK,MAAM/J,CAAM;AACjB;AAAA,QACJ,KAAK+J,EAAW;AACZ,eAAK,aAAY;AACjB;AAAA,QACJ,KAAKA,EAAW;AACZ,eAAK,QAAO;AACZ,gBAAMjnB,IAAM,IAAI,MAAMkd,EAAO,KAAK,OAAO;AAEzC,UAAAld,EAAI,OAAOkd,EAAO,KAAK,MACvB,KAAK,aAAa,iBAAiBld,CAAG;AACtC;AAAA,MAChB;AAAA,EACI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQkd,GAAQ;AACZ,UAAMlzC,IAAOkzC,EAAO,QAAQ,CAAA;AAC5B,IAAYA,EAAO,MAAf,QACAlzC,EAAK,KAAK,KAAK,IAAIkzC,EAAO,EAAE,CAAC,GAE7B,KAAK,YACL,KAAK,UAAUlzC,CAAI,IAGnB,KAAK,cAAc,KAAK,OAAO,OAAOA,CAAI,CAAC;AAAA,EAEnD;AAAA,EACA,UAAUA,GAAM;AACZ,QAAI,KAAK,iBAAiB,KAAK,cAAc,QAAQ;AACjD,YAAM6sB,IAAY,KAAK,cAAc,MAAK;AAC1C,iBAAWv3B,KAAYu3B;AACnB,QAAAv3B,EAAS,MAAM,MAAM0K,CAAI;AAAA,IAEjC;AACA,UAAM,KAAK,MAAM,MAAMA,CAAI,GACvB,KAAK,QAAQA,EAAK,UAAU,OAAOA,EAAKA,EAAK,SAAS,CAAC,KAAM,aAC7D,KAAK,cAAcA,EAAKA,EAAK,SAAS,CAAC;AAAA,EAE/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAIvI,GAAI;AACJ,UAAMmnD,IAAO;AACb,QAAIC,IAAO;AACX,WAAO,YAAa7+C,GAAM;AAEtB,MAAI6+C,MAEJA,IAAO,IACPD,EAAK,OAAO;AAAA,QACR,MAAM3B,EAAW;AAAA,QACjB,IAAIxlD;AAAA,QACJ,MAAMuI;AAAA,MACtB,CAAa;AAAA,IACL;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAMkzC,GAAQ;AACV,UAAMiL,IAAM,KAAK,KAAKjL,EAAO,EAAE;AAC/B,IAAI,OAAOiL,KAAQ,eAGnB,OAAO,KAAK,KAAKjL,EAAO,EAAE,GAEtBiL,EAAI,aACJjL,EAAO,KAAK,QAAQ,IAAI,GAG5BiL,EAAI,MAAM,MAAMjL,EAAO,IAAI;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAUz7C,GAAIqnD,GAAK;AACf,SAAK,KAAKrnD,GACV,KAAK,YAAYqnD,KAAO,KAAK,SAASA,GACtC,KAAK,OAAOA,GACZ,KAAK,YAAY,IACjB,KAAK,aAAY,GACjB,KAAK,YAAY,EAAI,GACrB,KAAK,aAAa,SAAS;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe;AACX,SAAK,cAAc,QAAQ,CAAC9+C,MAAS,KAAK,UAAUA,CAAI,CAAC,GACzD,KAAK,gBAAgB,CAAA,GACrB,KAAK,WAAW,QAAQ,CAACkzC,MAAW;AAChC,WAAK,wBAAwBA,CAAM,GACnC,KAAK,OAAOA,CAAM;AAAA,IACtB,CAAC,GACD,KAAK,aAAa,CAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe;AACX,SAAK,QAAO,GACZ,KAAK,QAAQ,sBAAsB;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAU;AACN,IAAI,KAAK,SAEL,KAAK,KAAK,QAAQ,CAAC6L,MAAeA,EAAU,CAAE,GAC9C,KAAK,OAAO,SAEhB,KAAK,GAAG,SAAY,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,aAAa;AACT,WAAI,KAAK,aACL,KAAK,OAAO,EAAE,MAAM9B,EAAW,WAAU,CAAE,GAG/C,KAAK,QAAO,GACR,KAAK,aAEL,KAAK,QAAQ,sBAAsB,GAEhC;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ;AACJ,WAAO,KAAK,WAAU;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,SAAS+B,GAAU;AACf,gBAAK,MAAM,WAAWA,GACf;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,IAAI,WAAW;AACX,gBAAK,MAAM,WAAW,IACf;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,QAAQV,GAAS;AACb,gBAAK,MAAM,UAAUA,GACd;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAMhpD,GAAU;AACZ,gBAAK,gBAAgB,KAAK,iBAAiB,CAAA,GAC3C,KAAK,cAAc,KAAKA,CAAQ,GACzB;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,WAAWA,GAAU;AACjB,gBAAK,gBAAgB,KAAK,iBAAiB,CAAA,GAC3C,KAAK,cAAc,QAAQA,CAAQ,GAC5B;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,OAAOA,GAAU;AACb,QAAI,CAAC,KAAK;AACN,aAAO;AAEX,QAAIA,GAAU;AACV,YAAMu3B,IAAY,KAAK;AACvB,eAASr0B,IAAI,GAAGA,IAAIq0B,EAAU,QAAQr0B;AAClC,YAAIlD,MAAau3B,EAAUr0B,CAAC;AACxB,iBAAAq0B,EAAU,OAAOr0B,GAAG,CAAC,GACd;AAAA,IAGnB;AAEI,WAAK,gBAAgB,CAAA;AAEzB,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACX,WAAO,KAAK,iBAAiB,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,cAAclD,GAAU;AACpB,gBAAK,wBAAwB,KAAK,yBAAyB,CAAA,GAC3D,KAAK,sBAAsB,KAAKA,CAAQ,GACjC;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,mBAAmBA,GAAU;AACzB,gBAAK,wBAAwB,KAAK,yBAAyB,CAAA,GAC3D,KAAK,sBAAsB,QAAQA,CAAQ,GACpC;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,eAAeA,GAAU;AACrB,QAAI,CAAC,KAAK;AACN,aAAO;AAEX,QAAIA,GAAU;AACV,YAAMu3B,IAAY,KAAK;AACvB,eAASr0B,IAAI,GAAGA,IAAIq0B,EAAU,QAAQr0B;AAClC,YAAIlD,MAAau3B,EAAUr0B,CAAC;AACxB,iBAAAq0B,EAAU,OAAOr0B,GAAG,CAAC,GACd;AAAA,IAGnB;AAEI,WAAK,wBAAwB,CAAA;AAEjC,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB;AACnB,WAAO,KAAK,yBAAyB,CAAA;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,wBAAwB06C,GAAQ;AAC5B,QAAI,KAAK,yBAAyB,KAAK,sBAAsB,QAAQ;AACjE,YAAMrmB,IAAY,KAAK,sBAAsB,MAAK;AAClD,iBAAWv3B,KAAYu3B;AACnB,QAAAv3B,EAAS,MAAM,MAAM49C,EAAO,IAAI;AAAA,IAExC;AAAA,EACJ;AACJ;ACp2BO,SAAS+L,GAAQ1+C,GAAM;AAC1B,EAAAA,IAAOA,KAAQ,CAAA,GACf,KAAK,KAAKA,EAAK,OAAO,KACtB,KAAK,MAAMA,EAAK,OAAO,KACvB,KAAK,SAASA,EAAK,UAAU,GAC7B,KAAK,SAASA,EAAK,SAAS,KAAKA,EAAK,UAAU,IAAIA,EAAK,SAAS,GAClE,KAAK,WAAW;AACpB;AAOA0+C,GAAQ,UAAU,WAAW,WAAY;AACrC,MAAIC,IAAK,KAAK,KAAK,KAAK,IAAI,KAAK,QAAQ,KAAK,UAAU;AACxD,MAAI,KAAK,QAAQ;AACb,QAAIC,IAAO,KAAK,OAAM,GAClBC,IAAY,KAAK,MAAMD,IAAO,KAAK,SAASD,CAAE;AAClD,IAAAA,KAAM,KAAK,MAAMC,IAAO,EAAE,IAAI,MAAM,IAAID,IAAKE,IAAYF,IAAKE;AAAA,EAClE;AACA,SAAO,KAAK,IAAIF,GAAI,KAAK,GAAG,IAAI;AACpC;AAMAD,GAAQ,UAAU,QAAQ,WAAY;AAClC,OAAK,WAAW;AACpB;AAMAA,GAAQ,UAAU,SAAS,SAAUzZ,GAAK;AACtC,OAAK,KAAKA;AACd;AAMAyZ,GAAQ,UAAU,SAAS,SAAUvpB,GAAK;AACtC,OAAK,MAAMA;AACf;AAMAupB,GAAQ,UAAU,YAAY,SAAUlX,GAAQ;AAC5C,OAAK,SAASA;AAClB;AC3DO,MAAMsX,WAAgB1J,GAAQ;AAAA,EACjC,YAAY2C,GAAK/3C,GAAM;AACnB,QAAIg4C;AACJ,UAAK,GACL,KAAK,OAAO,CAAA,GACZ,KAAK,OAAO,CAAA,GACRD,KAAoB,OAAOA,KAApB,aACP/3C,IAAO+3C,GACPA,IAAM,SAEV/3C,IAAOA,KAAQ,CAAA,GACfA,EAAK,OAAOA,EAAK,QAAQ,cACzB,KAAK,OAAOA,GACZg2C,GAAsB,MAAMh2C,CAAI,GAChC,KAAK,aAAaA,EAAK,iBAAiB,EAAK,GAC7C,KAAK,qBAAqBA,EAAK,wBAAwB,KAAQ,GAC/D,KAAK,kBAAkBA,EAAK,qBAAqB,GAAI,GACrD,KAAK,qBAAqBA,EAAK,wBAAwB,GAAI,GAC3D,KAAK,qBAAqBg4C,IAAKh4C,EAAK,yBAAyB,QAAQg4C,MAAO,SAASA,IAAK,GAAG,GAC7F,KAAK,UAAU,IAAI0G,GAAQ;AAAA,MACvB,KAAK,KAAK,kBAAiB;AAAA,MAC3B,KAAK,KAAK,qBAAoB;AAAA,MAC9B,QAAQ,KAAK,oBAAmB;AAAA,IAC5C,CAAS,GACD,KAAK,QAAgB1+C,EAAK,WAAb,OAAuB,MAAQA,EAAK,OAAO,GACxD,KAAK,cAAc,UACnB,KAAK,MAAM+3C;AACX,UAAMgH,IAAU/+C,EAAK,UAAUg/C;AAC/B,SAAK,UAAU,IAAID,EAAQ,QAAO,GAClC,KAAK,UAAU,IAAIA,EAAQ,QAAO,GAClC,KAAK,eAAe/+C,EAAK,gBAAgB,IACrC,KAAK,gBACL,KAAK,KAAI;AAAA,EACjB;AAAA,EACA,aAAanE,GAAG;AACZ,WAAK,UAAU,UAEf,KAAK,gBAAgB,CAAC,CAACA,GAClBA,MACD,KAAK,gBAAgB,KAElB,QALI,KAAK;AAAA,EAMpB;AAAA,EACA,qBAAqBA,GAAG;AACpB,WAAIA,MAAM,SACC,KAAK,yBAChB,KAAK,wBAAwBA,GACtB;AAAA,EACX;AAAA,EACA,kBAAkBA,GAAG;AACjB,QAAIm8C;AACJ,WAAIn8C,MAAM,SACC,KAAK,sBAChB,KAAK,qBAAqBA,IACzBm8C,IAAK,KAAK,aAAa,QAAQA,MAAO,UAAkBA,EAAG,OAAOn8C,CAAC,GAC7D;AAAA,EACX;AAAA,EACA,oBAAoBA,GAAG;AACnB,QAAIm8C;AACJ,WAAIn8C,MAAM,SACC,KAAK,wBAChB,KAAK,uBAAuBA,IAC3Bm8C,IAAK,KAAK,aAAa,QAAQA,MAAO,UAAkBA,EAAG,UAAUn8C,CAAC,GAChE;AAAA,EACX;AAAA,EACA,qBAAqBA,GAAG;AACpB,QAAIm8C;AACJ,WAAIn8C,MAAM,SACC,KAAK,yBAChB,KAAK,wBAAwBA,IAC5Bm8C,IAAK,KAAK,aAAa,QAAQA,MAAO,UAAkBA,EAAG,OAAOn8C,CAAC,GAC7D;AAAA,EACX;AAAA,EACA,QAAQA,GAAG;AACP,WAAK,UAAU,UAEf,KAAK,WAAWA,GACT,QAFI,KAAK;AAAA,EAGpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,uBAAuB;AAEnB,IAAI,CAAC,KAAK,iBACN,KAAK,iBACL,KAAK,QAAQ,aAAa,KAE1B,KAAK,UAAS;AAAA,EAEtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAKjG,GAAI;AACL,QAAI,CAAC,KAAK,YAAY,QAAQ,MAAM;AAChC,aAAO;AACX,SAAK,SAAS,IAAIqpD,GAAO,KAAK,KAAK,KAAK,IAAI;AAC5C,UAAMC,IAAS,KAAK,QACdb,IAAO;AACb,SAAK,cAAc,WACnB,KAAK,gBAAgB;AAErB,UAAMc,IAAiB7J,GAAG4J,GAAQ,QAAQ,WAAY;AAClD,MAAAb,EAAK,OAAM,GACXzoD,KAAMA,EAAE;AAAA,IACZ,CAAC,GACK+mB,IAAU,CAAC8Y,MAAQ;AACrB,WAAK,QAAO,GACZ,KAAK,cAAc,UACnB,KAAK,aAAa,SAASA,CAAG,GAC1B7/B,IACAA,EAAG6/B,CAAG,IAIN,KAAK,qBAAoB;AAAA,IAEjC,GAEM2pB,IAAW9J,GAAG4J,GAAQ,SAASviC,CAAO;AAC5C,QAAc,KAAK,aAAf,IAAyB;AACzB,YAAMohC,IAAU,KAAK,UAEfC,IAAQ,KAAK,aAAa,MAAM;AAClC,QAAAmB,EAAc,GACdxiC,EAAQ,IAAI,MAAM,SAAS,CAAC,GAC5BuiC,EAAO,MAAK;AAAA,MAChB,GAAGnB,CAAO;AACV,MAAI,KAAK,KAAK,aACVC,EAAM,MAAK,GAEf,KAAK,KAAK,KAAK,MAAM;AACjB,aAAK,eAAeA,CAAK;AAAA,MAC7B,CAAC;AAAA,IACL;AACA,gBAAK,KAAK,KAAKmB,CAAc,GAC7B,KAAK,KAAK,KAAKC,CAAQ,GAChB;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQxpD,GAAI;AACR,WAAO,KAAK,KAAKA,CAAE;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AAEL,SAAK,QAAO,GAEZ,KAAK,cAAc,QACnB,KAAK,aAAa,MAAM;AAExB,UAAMspD,IAAS,KAAK;AACpB,SAAK,KAAK;AAAA,MAAK5J,GAAG4J,GAAQ,QAAQ,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,MAAG5J,GAAG4J,GAAQ,QAAQ,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,MAAG5J,GAAG4J,GAAQ,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA,MAAG5J,GAAG4J,GAAQ,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA;AAAA,MAEhM5J,GAAG,KAAK,SAAS,WAAW,KAAK,UAAU,KAAK,IAAI,CAAC;AAAA,IAAC;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AACL,SAAK,aAAa,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAOtb,GAAM;AACT,QAAI;AACA,WAAK,QAAQ,IAAIA,CAAI;AAAA,IACzB,SACOr5B,GAAG;AACN,WAAK,QAAQ,eAAeA,CAAC;AAAA,IACjC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAUgyC,GAAQ;AAEd,IAAA6C,GAAS,MAAM;AACX,WAAK,aAAa,UAAU7C,CAAM;AAAA,IACtC,GAAG,KAAK,YAAY;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQld,GAAK;AACT,SAAK,aAAa,SAASA,CAAG;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAOgoB,GAAKz9C,GAAM;AACd,QAAIk/C,IAAS,KAAK,KAAKzB,CAAG;AAC1B,WAAKyB,IAII,KAAK,gBAAgB,CAACA,EAAO,UAClCA,EAAO,QAAO,KAJdA,IAAS,IAAI3B,GAAO,MAAME,GAAKz9C,CAAI,GACnC,KAAK,KAAKy9C,CAAG,IAAIyB,IAKdA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAASA,GAAQ;AACb,UAAMG,IAAO,OAAO,KAAK,KAAK,IAAI;AAClC,eAAW5B,KAAO4B;AAEd,UADe,KAAK,KAAK5B,CAAG,EACjB;AACP;AAGR,SAAK,OAAM;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ9K,GAAQ;AACZ,UAAMsB,IAAiB,KAAK,QAAQ,OAAOtB,CAAM;AACjD,aAAS16C,IAAI,GAAGA,IAAIg8C,EAAe,QAAQh8C;AACvC,WAAK,OAAO,MAAMg8C,EAAeh8C,CAAC,GAAG06C,EAAO,OAAO;AAAA,EAE3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU;AACN,SAAK,KAAK,QAAQ,CAAC6L,MAAeA,EAAU,CAAE,GAC9C,KAAK,KAAK,SAAS,GACnB,KAAK,QAAQ,QAAO;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AACL,SAAK,gBAAgB,IACrB,KAAK,gBAAgB,IACrB,KAAK,QAAQ,cAAc;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa;AACT,WAAO,KAAK,OAAM;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,QAAQ3vC,GAAQ8nC,GAAa;AACzB,QAAIqB;AACJ,SAAK,QAAO,IACXA,IAAK,KAAK,YAAY,QAAQA,MAAO,UAAkBA,EAAG,MAAK,GAChE,KAAK,QAAQ,MAAK,GAClB,KAAK,cAAc,UACnB,KAAK,aAAa,SAASnpC,GAAQ8nC,CAAW,GAC1C,KAAK,iBAAiB,CAAC,KAAK,iBAC5B,KAAK,UAAS;AAAA,EAEtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY;AACR,QAAI,KAAK,iBAAiB,KAAK;AAC3B,aAAO;AACX,UAAM0H,IAAO;AACb,QAAI,KAAK,QAAQ,YAAY,KAAK;AAC9B,WAAK,QAAQ,MAAK,GAClB,KAAK,aAAa,kBAAkB,GACpC,KAAK,gBAAgB;AAAA,SAEpB;AACD,YAAMriB,IAAQ,KAAK,QAAQ,SAAQ;AACnC,WAAK,gBAAgB;AACrB,YAAMgiB,IAAQ,KAAK,aAAa,MAAM;AAClC,QAAIK,EAAK,kBAET,KAAK,aAAa,qBAAqBA,EAAK,QAAQ,QAAQ,GAExD,CAAAA,EAAK,iBAETA,EAAK,KAAK,CAAC5oB,MAAQ;AACf,UAAIA,KACA4oB,EAAK,gBAAgB,IACrBA,EAAK,UAAS,GACd,KAAK,aAAa,mBAAmB5oB,CAAG,KAGxC4oB,EAAK,YAAW;AAAA,QAExB,CAAC;AAAA,MACL,GAAGriB,CAAK;AACR,MAAI,KAAK,KAAK,aACVgiB,EAAM,MAAK,GAEf,KAAK,KAAK,KAAK,MAAM;AACjB,aAAK,eAAeA,CAAK;AAAA,MAC7B,CAAC;AAAA,IACL;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc;AACV,UAAMjQ,IAAU,KAAK,QAAQ;AAC7B,SAAK,gBAAgB,IACrB,KAAK,QAAQ,MAAK,GAClB,KAAK,aAAa,aAAaA,CAAO;AAAA,EAC1C;AACJ;ACxWA,MAAMn5B,KAAQ,CAAA;AACd,SAASk+B,GAAOiF,GAAK/3C,GAAM;AACvB,EAAI,OAAO+3C,KAAQ,aACf/3C,IAAO+3C,GACPA,IAAM,SAEV/3C,IAAOA,KAAQ,CAAA;AACf,QAAMqb,IAAS9lB,GAAIwiD,GAAK/3C,EAAK,QAAQ,YAAY,GAC3Cs/C,IAASjkC,EAAO,QAChBnkB,IAAKmkB,EAAO,IACZ/mB,IAAO+mB,EAAO,MACdkkC,IAAgB3qC,GAAM1d,CAAE,KAAK5C,KAAQsgB,GAAM1d,CAAE,EAAE,MAC/CsoD,IAAgBx/C,EAAK,YACvBA,EAAK,sBAAsB,KACjBA,EAAK,cAAf,MACAu/C;AACJ,MAAI/B;AACJ,SAAIgC,IACAhC,IAAK,IAAIsB,GAAQQ,GAAQt/C,CAAI,KAGxB4U,GAAM1d,CAAE,MACT0d,GAAM1d,CAAE,IAAI,IAAI4nD,GAAQQ,GAAQt/C,CAAI,IAExCw9C,IAAK5oC,GAAM1d,CAAE,IAEbmkB,EAAO,SAAS,CAACrb,EAAK,UACtBA,EAAK,QAAQqb,EAAO,WAEjBmiC,EAAG,OAAOniC,EAAO,MAAMrb,CAAI;AACtC;AAGA,OAAO,OAAO8yC,IAAQ;AAAA,EAClB,SAAAgM;AAAA,EACA,QAAAvB;AAAA,EACA,IAAIzK;AAAA,EACJ,SAASA;AACb,CAAC;ACxCM,SAAS2M,GAAiBtnB,GAAyD;AAExF,QAAMunB,IAAO,GADE3nB,GAAA,CACO,UAAUI,CAAO,GAAG,QAAQ,OAAO,GAAG;AAC5D,SAAO,EAAE,UAAU,GAAGunB,CAAI,IAAIluB,EAAqB,IAAI,UAAU,GAAGkuB,CAAI,cAAA;AAC1E;AAGO,SAASC,GAAkBC,GAAyB;AAEzD,SAAO,GADQ7nB,GAAA,CACC,UAAU6nB,CAAO,GAAG,QAAQ,OAAO,GAAG;AACxD;AAiBO,SAASC,GAAiB1nB,GAAiB2nB,GAA4B;AAC5E,SAAOH,GAAkBG,KAAa,GAAG3nB,CAAO,aAAa;AAC/D;ACnBA,SAAS5iC,GAAIjB,GAAsB;AACjC,SAAO,GAAGyjC,IAAwB,GAAGzjC,CAAI,GAAG,QAAQ,OAAO,GAAG;AAChE;AAUA,eAAsByrD,GAAgBnd,GAA2D;AAC/F,MAAI;AACF,UAAM3oB,IAAM,MAAM,MAAM1kB,GAAI,eAAe,CAAC;AAC5C,QAAI,CAAC0kB,EAAI;AACP,aAAA2gB,GAAK,YAAY,sBAAsB,EAAE,QAAQ3gB,EAAI,QAAQ,GACtD;AAET,UAAMonB,IAAQ,MAAMpnB,EAAI,KAAA;AACxB,WAAA0lB,EAAY,SAAA,EAAW,oBAAoB0B,GAAMuB,CAAU,GAC3DjI,EAAM,YAAY,gBAAgB;AAAA,MAChC,OAAO0G,EAAK,MAAM;AAAA,MAAQ,QAAQA,EAAK;AAAA,MAAY,QAAQA,EAAK,OAAO;AAAA,IAAA,CACxE,GACMA;AAAA,EACT,SAAS5L,GAAc;AACrB,WAAAmF,GAAK,YAAY,qBAAqBmB,GAAYtG,CAAG,CAAC,GAC/C;AAAA,EACT;AACF;AAgBA,IAAIuqB,KAAS;AACN,SAASC,KAA4B;AAC1C,MAAID,MAAU,OAAO,QAAU,IAAa;AAC5C,QAAM3e,IAAO1B,EAAY,SAAA,EAAW;AACpC,MAAI,GAAC0B,KAAQA,EAAK,MAAM,WAAW,IACnC;AAAA,IAAA2e,KAAS;AACT,eAAWxpB,KAAQ6K,EAAK,OAAO;AAC7B,YAAM2J,IAAM,IAAI,MAAA;AAChB,MAAAA,EAAI,WAAW,SACfA,EAAI,MAAM6U,GAAiBrpB,EAAK,IAAIA,EAAK,SAAS;AAAA,IACpD;AACA,IAAAmE,EAAM,YAAY,mBAAmB,EAAE,OAAO0G,EAAK,MAAM,QAAQ;AAAA;AACnE;AASA,eAAsB6e,GACpBC,GACkB;AAElB,EADcxgB,EAAY,SAAA,EACpB,kBAAkB,EAAI;AAC5B,MAAI;AAGF,UAAM1lB,IAAM,MAAM,MAAM1kB,GAAI,kBAAkB,GAAG;AAAA,MAC/C,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAA;AAAA,MAC3B,MAAM,KAAK,UAAU,EAAE,OAAA4qD,GAAO;AAAA,IAAA,CAC/B;AACD,QAAI,CAAClmC,EAAI;AACP,aAAA2gB,GAAK,YAAY,iBAAiB,EAAE,QAAQ3gB,EAAI,QAAQ,GACjD;AAET,UAAMonB,IAAQ,MAAMpnB,EAAI,KAAA;AACxB,WAAA0lB,EAAY,SAAA,EAAW,oBAAoB0B,GAAM,EAAI,GAC9C;AAAA,EACT,SAAS5L,GAAc;AACrB,WAAAmF,GAAK,YAAY,cAAcmB,GAAYtG,CAAG,CAAC,GACxC;AAAA,EACT,UAAA;AACE,IAAAkK,EAAY,SAAA,EAAW,kBAAkB,EAAK;AAAA,EAChD;AACF;ACxFO,SAASygB,KAA4D;AAC1E,QAAMC,IAAK1gB,EAAY,SAAA,GACjB2gB,IAAO,IAAI,IAAI,OAAO,OAAOD,EAAG,MAAM,EAAE,IAAI,OAAKhzC,EAAE,MAAM,EAAE,OAAO,OAAO,CAAC,GAC1EkzC,IAAOzwB,GAAgB,KAAK,CAAAC,MAAK,CAACuwB,EAAK,IAAIvwB,CAAC,CAAC;AACnD,MAAI,CAACwwB;AACH,WAAA3lB,GAAK,UAAU,kDAAkD,GAC1D;AAET,QAAM4lB,IAAW,CAAC,CAACH,EAAG,QAAQ,CAAC9jB,GAAgB8jB,EAAG,IAAI,GAChD5uC,IAAO+uC,IAAWH,EAAG,OAAO/jB,GAAeikB,CAAI;AACrD,SAAA5lB,EAAM,UAAU,8CAA8C,EAAE,MAAM0lB,EAAG,QAAQ,IAAIE,GAAM,MAAA9uC,GAAM,gBAAgB+uC,EAAA,CAAU,GAC3HH,EAAG,mBAAmB5uC,GAAM8uC,CAAI,GACzB,EAAE,MAAA9uC,GAAM,QAAQ8uC,EAAA;AACzB;AAQO,SAASE,GAAqBC,GAAyC;AAC5E,QAAML,IAAK1gB,EAAY,SAAA,GACjBghB,IAAOD,IAAaL,EAAG,OAAOK,CAAU,IAAI;AAClD,SAAO,CAACC,KAAS,CAAC,CAACA,EAAK,UAAUA,EAAK,WAAWN,EAAG;AACvD;AC1CA,IAAIO,KAAiB,2BAKjBC,KAAoB,sBAMpBC,KAAmB,sBACnBC,KAAkB;AACtB,SAASC,GAAU1L,GAAI;AACrB,MAAI;AACF,IAAIA,IAAI,eAAe,QAAQyL,IAAiB,GAAG,IAC9C,eAAe,WAAWA,EAAe;AAAA,EAChD,QAAQ;AAAA,EACR;AACF;AACA,IAAIE,KAAc,cAAc,MAAM;AAAA,EACpC,YAAYljD,GAAQpK,GAAS;AAC3B,UAAMA,CAAO,GACb,KAAK,SAASoK,GACd,KAAK,OAAO;AAAA,EACd;AAAA,EACA;AACF;AACA,eAAemjD,GAASjnC,GAAK;AAC3B,MAAI,CAACA,EAAI,IAAI;AACX,UAAM2J,IAAO,MAAM3J,EAAI,KAAI,EAAG,MAAM,MAAM,IAAI;AAC9C,UAAM,IAAIgnC,GAAYhnC,EAAI,QAAQ2J,GAAM,WAAW,QAAQ3J,EAAI,MAAM,EAAE;AAAA,EACzE;AACA,SAAO,MAAMA,EAAI,KAAI;AACvB;AACA,SAASknC,GAAmBnhD,IAAO,IAAI;AACrC,QAAMjK,IAAO,GAAGiK,EAAK,WAAW4gD,EAAc,mBACxCv1C,IAAIrL,EAAK,SAAS,OAClBohD,IAAO,CAAC9sD,GAAM6B,IAAO,CAAA,MAAOkV,EAAE,GAAGtV,CAAI,GAAGzB,CAAI,IAAI,EAAE,aAAa,WAAW,GAAG6B,GAAM,EAAE,KAAK+qD,EAAQ,GAClGG,IAAO,CAAC/sD,GAAMolB,GAAQkK,MAASw9B,EAAK9sD,GAAM;AAAA,IAC9C,QAAAolB;AAAA,IACA,GAAGkK,MAAS,SAAS,CAAA,IAAK,EAAE,SAAS,EAAE,gBAAgB,mBAAkB,GAAI,MAAM,KAAK,UAAUA,CAAI,EAAC;AAAA,EAC3G,CAAG,GACK09B,IAAc,MAAMF,EAAK,EAAE;AACjC,iBAAeG,EAAYC,GAAU;AACnC,IAAAR,GAAU,EAAI;AACd,UAAMS,IAAQ,OAAO,KAAK,eAAeX,IAAkB,4BAA4B;AAEvF,QADAE,GAAU,EAAK,GACX,CAACS;AACH,YAAM,IAAIR,GAAY,GAAG,6DAA6D;AACxF,QAAIS;AACJ,QAAI;AACF,OAAC,EAAE,cAAAA,MAAiB,MAAML,EAAK,SAASG,CAAQ,IAAI,QAAQ,EAAE;AAAA,IAChE,SAAS/rB,GAAK;AACZ,YAAAgsB,EAAM,MAAK,GACLhsB;AAAA,IACR;AACA,WAAAgsB,EAAM,SAAS,OAAOC,GACf,IAAI,QAAQ,CAACn8C,GAAS0S,MAAW;AACtC,YAAM2yB,IAAU,IAAI,iBAAiBiW,EAAiB;AACtD,UAAIc,IAAU;AACd,YAAMC,IAAS,CAACC,MAAY;AAC1B,QAAIF,MACJA,IAAU,IACV/W,EAAQ,MAAK,GACb,cAAckX,CAAU,GACxB,aAAaC,CAAM,GACfF,IAAS5pC,EAAO,IAAIgpC,GAAY,KAAKY,CAAO,CAAC,IAC5CP,IAAc,KAAK/7C,GAAS0S,CAAM;AAAA,MACzC;AACA,MAAA2yB,EAAQ,YAAY,CAACjqC,MAAM;AACzB,QAAIA,EAAE,MAAM,SAASkgD,MACrBe,EAAOjhD,EAAE,KAAK,KAAK,SAASA,EAAE,KAAK,KAAK;AAAA,MAC1C;AACA,YAAMmhD,IAAa,YAAY,MAAM;AACnC,QAAKL,EAAM,WACX,cAAcK,CAAU,GACxB,WAAW,MAAMF,EAAM,GAAI,IAAI;AAAA,MACjC,GAAG,GAAG,GACAG,IAAS,WAAW,MAAMH,EAAM,GAAI,MAAU,GAAG;AAAA,IACzD,CAAC;AAAA,EACH;AACA,SAAO;AAAA;AAAA,IAEL,KAAKN;AAAA;AAAA,IAEL,QAAQ,CAAChC,MAAW+B,EAAK,IAAI,OAAO,EAAE,QAAA/B,GAAQ;AAAA;AAAA,IAE9C,QAAQ,CAAC/d,MAAM8f,EAAK,IAAI,OAAO9f,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOhC,WAAW,CAACigB,MAAaH,EAAK,SAASG,CAAQ,IAAI,QAAQ,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAS7D,aAAa,CAACA,MAAaD,EAAYC,CAAQ;AAAA;AAAA,IAE/C,cAAc,CAACzrB,MAAUsrB,EAAK,kBAAkB,QAAQ,EAAE,OAAOtrB,EAAM,QAAQ,OAAO,EAAE,EAAC,CAAE;AAAA;AAAA,IAE3F,QAAQ,CAACyrB,MAAaH,EAAK,SAASG,CAAQ,IAAI,QAAQ;AAAA;AAAA,IAExD,QAAQ,CAACQ,MAAUZ,EAAK,WAAW,EAAE,QAAQ,QAAQ,MAAMY,GAAO;AAAA,IAClE,cAAc,MAAMX,EAAK,WAAW,QAAQ;AAAA,EAChD;AACA;ACrFO,MAAMY,KAAe;AAIrB,SAASC,GAAkBC,GAAuF;AACvH,QAAMjrD,IAAKirD,GAAU,UAAUA,GAAU,QAAQ,UAAU;AAC3D,SAAO/xB,GAAcl5B,CAAE,IAAIA,IAAK;AAClC;AAWA,eAAsBkrD,GAAqBpiD,IAAmD,IAA4B;AACxH,QAAMqL,IAAIrL,EAAK,UAAU,OAAO,QAAU,MAAc,SAAY,QAC9Du7B,IAAS,OAAO,SAAW,MAAc,SAAY,OAAO,UAAU,QACtE8mB,IAAUriD,EAAK,YAAYu7B,IAAS,GAAGA,CAAM,WAAW;AAC9D,MAAI,CAAClwB,KAAK,CAACg3C,EAAS,QAAO;AAC3B,MAAI;AACF,UAAMF,IAAW,MAAMhB,GAAmB,EAAE,SAAAkB,GAAS,OAAOh3C,EAAA,CAAG,EAAE,IAAA,GAC3DglB,IAAS6xB,GAAkBC,CAAQ;AACzC,WAAAxnB,EAAM,UAAU,sCAAsC,EAAE,QAAAtK,EAAA,CAAQ,GACzDA;AAAA,EACT,SAASoF,GAAc;AACrB,WAAIA,aAAewrB,OAAgBxrB,EAAI,WAAW,OAAOA,EAAI,WAAW,OAAOA,EAAI,WAAW,OAC5FkF,EAAM,UAAU,wEAAwE,EAAE,QAAQlF,EAAI,QAAQ,IAE9GmF,GAAK,UAAU,qEAAqE;AAAA,MAClF,QAAQnF,aAAewrB,KAAcxrB,EAAI,SAAS;AAAA,MAAW,GAAGsG,GAAYtG,CAAG;AAAA,IAAA,CAChF,GAEI;AAAA,EACT;AACF;AAQO,SAAS6sB,GAAqBjyB,GAAgC;AACnE,MAAI,CAACA,EAAQ,QAAO;AACpB,QAAMgwB,IAAK1gB,EAAY,SAAA;AACvB,MAAI0gB,EAAG,WAAWhwB,EAAQ,QAAO;AAGjC,QAAM5e,IAFgB,CAAC,EAAE4uC,EAAG,GAAG,YAAYA,EAAG,OAAOA,EAAG,GAAG,QAAQ,GAAG,iBAExC,CAACA,EAAG,QAAQ,CAAC9jB,GAAgB8jB,EAAG,IAAI,IAAIA,EAAG,OAAO/jB,GAAejM,CAAM;AACrG,SAAAgwB,EAAG,mBAAmB5uC,GAAM4e,CAAM,GAC3B;AACT;AAKO,SAASkyB,GACdC,GACAn/B,IAAkC,OAAO,SAAW,MAAc,SAAY,QAClE;AACZ,MAAI,CAACA,EAAQ,QAAO,MAAM;AAAA,EAAC;AAC3B,QAAM9jB,IAAU,CAACoB,MAAa;AAC5B,UAAM8hD,IAAU9hD,EAA8C;AAC9D,IAAI,CAAC8hD,KAAU,OAAOA,KAAW,YACjCD,EAASC,CAAM;AAAA,EACjB;AACA,SAAAp/B,EAAO,iBAAiB4+B,IAAc1iD,CAAO,GACtC,MAAM8jB,EAAO,oBAAoB4+B,IAAc1iD,CAAO;AAC/D;ACtEA,MAAMmjD,KAAkB;AAEjB,SAASC,GAAkBC,IAA0B,OAAO,SAAW,MAAc,SAAS,QAAyB;AAC5H,MAAI,CAACA,EAAK,QAAO,EAAE,QAAQ,IAAO,OAAO,EAAA;AACzC,MAAI;AACF,QAAIC,IAAQ,GACR7b,IAAY4b;AAChB,WAAO5b,MAAMA,EAAE,UAAU6b,IAAQH;AAC/B,MAAAG,KACA7b,IAAIA,EAAE;AAIR,WAAO,EAAE,QADM4b,EAAI,MAAMA,EAAI,QAAQA,EAAI,OAAOC,IAAQ,GACvC,OAAAA,EAAA;AAAA,EACnB,QAAQ;AAEN,WAAO,EAAE,QAAQ,IAAO,OAAO,EAAA;AAAA,EACjC;AACF;AC+CO,SAASC,GAAwBC,GAAOC,GAAaC,GAAe;AACvE,QAAMC,IAAY,CAAC,CAACH,EAAM,QACtB,CAACE,EAAcF,EAAM,IAAI,MACxB,CAACC,KAAeC,EAAcD,EAAY,QAAQ,EAAE,IACnDG,IAAc,CAAC,CAACJ,EAAM,aAAa,CAACC,KAAeA,EAAY,aAAaD,EAAM;AACxF,MAAI,CAACG,KAAa,CAACC;AACf,WAAO;AACX,QAAMC,IAAM,CAAA;AACZ,SAAIF,MACAE,EAAI,OAAOL,EAAM,OACjBI,MACAC,EAAI,WAAWL,EAAM,WAClBK;AACX;ACnGO,SAASC,GAAiBC,GAAsErrB,GAAuB;AAC5H,MAAIsrB,IAAU;AACd,aAAWC,KAASF,EAAS,QAAQ;AACnC,UAAMlvD,IAAM4jC,GAAa,QAAQC,GAAOqrB,EAAS,IAAIE,EAAM,OAAO;AAClE,IAAI,WAAW,cAAc,QAAQpvD,CAAG,KAAK,QAAMmvD,KACnD/qB,GAAapkC,CAAG;AAAA,EAClB;AACA,SAAOmvD;AACT;ACGO,MAAME,KAAqB,KAErBC,KAAe;AASrB,SAASC,KAA2B;AACzC,SAAO,EAAE,iBAAiB,MAAM,YAAY,MAAM,YAAY,KAAA;AAChE;AAEO,SAASC,GAASzZ,GAAa3V,GAAmB;AACvD,EAAA2V,EAAE,aAAa3V,GACf2V,EAAE,kBAAkB;AACtB;AAMO,SAAS0Z,GAAK1Z,GAAa3V,GAAasvB,GAA6B;AAC1E,QAAMC,IAAQ5Z,EAAE,eAAe,QAAQ3V,IAAM2V,EAAE,aAAauZ;AAE5D,SADAvZ,EAAE,aAAa3V,GACVsvB,IAIDC,KAIA5Z,EAAE,oBAAoB,QACxBA,EAAE,kBAAkB3V,GACb,MAEFA,IAAM2V,EAAE,kBAAkBsZ,MAX/BtZ,EAAE,kBAAkB,MACb;AAWX;AAGO,SAAS6Z,GAAQ7Z,GAAa3V,GAAiC;AACpE,SAAO2V,EAAE,eAAe,OAAO,SAAY,KAAK,IAAI,GAAG3V,IAAM2V,EAAE,UAAU;AAC3E;ACrCA,IAAI+U,KAAwB,MACxB+E,KAA0C,MAC1CC,KAA0D,MAC1DC,KAAwD,MACxDC,KAAsK;AAG1K,MAAMC,KAASC,GAAA,GACTC,KAAWZ,GAAA;AAEjB,IAAIa,KAAwD,MAExDC,KAAwC,MACxCC,KAAiB,GAGjBC,KAAmE,MAGnEC,KAAqB,IAErBC,KAAiC,IACjCC,KAAmB,IACnBC,KAAkC;AAQ/B,SAASC,GAAehlD,GAAwB;AACrD,QAAM1F,IAAI2qD,GAAA,GACJ9wD,IAAQwrC,EAAY,SAAA;AAE1B,MAAIxrC,EAAM,GAAG,YAAYA,EAAM,OAAOA,EAAM,GAAG,QAAQ;AACrD,YAAI6L,EAAK,QAAQA,EAAK,YACpB26B,EAAM,UAAU,oCAAoC,EAAE,MAAM36B,EAAK,MAAM,QAAQA,EAAK,QAAQ,GAC5F1F,EAAE,KAAKi0B,GAAY,iBAAiB,EAAE,MAAMvuB,EAAK,MAAM,QAAQA,EAAK,OAAA,CAAQ,IAEvE1F;AAET,QAAM+iD,IAAU6H,GAAallD,CAAI;AACjC,SAAAokD,KAAkB/G,GAClBsH,KAAiB,EAAE,MAAMtH,EAAQ,MAAM,QAAQA,EAAQ,OAAA,GACnD/iD,EAAE,aACJqgC,EAAM,UAAU,iBAAiB0iB,CAAO,GACxC/iD,EAAE,KAAKi0B,GAAY,MAAM8uB,CAAO,KAEhC/iD,EAAE,KAAK,WAAW,MAAM;AAAE,IAAAqgC,EAAM,UAAU,iBAAiB0iB,CAAO,GAAG/iD,EAAE,KAAKi0B,GAAY,MAAM8uB,CAAO;AAAA,EAAG,CAAC,GAEpG/iD;AACT;AAEA,SAAS4qD,GAAanzB,GAAa;AACjC,SAAO;AAAA,IACL,UAAUA,EAAE;AAAA,IACZ,MAAMA,EAAE;AAAA,IACR,QAAQA,EAAE;AAAA;AAAA;AAAA,IAGV,OAAO4wB,GAAA;AAAA,IACP,cAAcnT,GAAA;AAAA;AAAA;AAAA;AAAA,IAId,WAAWoC,GAAA;AAAA,IACX,QAAQyS;AAAA,EAAA;AAEZ;AAEA,SAASC,KAAoB;AAC3B,QAAMv0B,IAAI,WAAW;AACrB,MAAIA,KAAK,OAAOA,EAAE,cAAe,WAAY,QAAOA,EAAE,WAAA;AACtD,QAAMwjB,IAAQ,IAAI,WAAW,EAAE;AAC/B,MAAIxjB,KAAK,OAAOA,EAAE,mBAAoB,WAAY,CAAAA,EAAE,gBAAgBwjB,CAAK;AAAA,MACpE,UAASt7C,IAAI,GAAGA,IAAIs7C,EAAM,QAAQt7C,IAAK,CAAAs7C,EAAMt7C,CAAC,IAAI,KAAK,MAAM,KAAK,OAAA,IAAW,GAAG;AACrF,SAAO,MAAM,KAAKs7C,GAAO,CAAA15C,MAAKA,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACxE;AAGO,SAASsrD,KAAuC;AACrD,SAAOnB,GAAQO,IAAU,KAAK,IAAA,CAAK;AACrC;AAEO,SAASU,KAAoB;AAClC,MAAI,CAAC/F,IAAQ;AAEX,QAAI3jB,IADW9D,GAAA,EACK,gBAAgB;AACpC,QAAI8D,MAAW,OAAO,OAAO,SAAW,KAAa;AACnD,YAAMC,IAAM,OAAO;AACnB,OAAKA,EAAI,aAAa,eAAeA,EAAI,aAAa,gBAAgBA,EAAI,SAAS,OAAO9N,EAAe,MACvG6N,IAAS,GAAGC,EAAI,QAAQ,KAAKA,EAAI,QAAQ,IAAI/N,EAAiB,IAC9DkN,EAAM,UAAU,6BAA6B,EAAE,QAAAY,EAAA,CAAQ;AAAA,IAE3D;AAEA,UAAM6pB,IAAe,IAAI,IAAI7pB,EAAO,WAAW,MAAM,IAAIA,IAAS,GAAG,OAAO,SAAS,MAAM,GAAGA,CAAM,EAAE,EAAE;AACxG,IAAA2jB,KAAS1B,GAAG4H,GAAc,EAAE,MAAMx3B,IAAiB,YAAY,CAAC,aAAa,SAAS,GAAG,GACzF+M,EAAM,UAAU,sBAAsB,EAAE,QAAAY,EAAA,CAAQ,GAGhD3C,GAAoB,cAAcsmB,EAAM,GAMpCiF,OAAmB,aAAaA,EAAe,GAAGA,KAAkB,OACxEF,KAAmB,MACnBC,KAAmB,YAAY,MAAM;AACnC,UAAImB,GAAad,IAAU,KAAK,IAAA,GAAO,CAAC,CAACrF,IAAQ,SAAS,GAAG;AAI3D,QAAAtkB,GAAK,UAAU,iEAAiE;AAAA,UAC9E,KAAKskB,IAAQ;AAAA,UAAI,eAAe8E,GAAQO,IAAU,KAAK,IAAA,CAAK,KAAK;AAAA,QAAA,CAClE,GACDE,KAAyB,iBACzBF,GAAS,kBAAkB,MAC3BrF,IAAQ,GAAG,QAAQ,MAAA;AACnB;AAAA,MACF;AACA,MAAAoG,GAAA;AAAA,IACF,GAAG/zB,EAAoC,GAEvC2tB,GAAO,GAAG,WAAW,MAAM;AACzB,MAAA2F,KAAiC;AACjC,YAAMU,IAAMrG,IAAQ;AAEpB,UADAvkB,EAAM,UAAU,aAAa,EAAE,IAAI4qB,GAAK,aAAaT,IAAkB,GACnES;AACF,YAAI;AACF,UAAA5lB,EAAY,SAAA,EAAW,SAAS4lB,CAAG,GAGnC5lB,EAAY,SAAS,CAAArlC,OAAM,EAAE,IAAI,EAAE,GAAGA,EAAE,IAAI,eAAe,EAAA,EAAE,EAAI,GACjEqgC,EAAM,UAAU,0CAA0C;AAAA,QAC5D,SAASh6B,GAAG;AACV,UAAAnL,GAAM,UAAU,yCAAyC,EAAE,OAAQmL,EAAY,SAAS,KAAA4kD,GAAK;AAAA,QAC/F;AAGF,UAAIT,MAAoBV,IAAiB;AACvC,cAAM/D,IAAK1gB,EAAY,SAAA;AACvB,QAAA+kB,MAAkB;AAClB,cAAMc,IAAgB;AAAA,UACpB,GAAGpB;AAAA,UAAiB,MAAM/D,EAAG;AAAA,UAAM,QAAQA,EAAG;AAAA,UAC9C,WAAW;AAAA,YACT,OAAOqE;AAAA,YACP,SAASF,IAAgB,UAAU,WAAW,MAAM,GAAG,EAAE;AAAA,YACzD,YAAYA,KAAiB,KAAK,IAAI,GAAG,KAAK,IAAA,IAAQA,GAAe,EAAE,IAAI;AAAA,UAAA;AAAA,QAC7E,GAEIiB,IAAeV;AAQrB,YAPApqB,EAAM,UAAU,oCAAoC,EAAE,UAAU6qB,EAAc,UAAU,MAAMA,EAAc,MAAM,QAAQA,EAAc,OAAA,CAAQ,GAO5IC,GAAc;AAChB,cAAI7X,IAAW;AACf,gBAAM8X,IAAa,MAAM;AACvB,YAAI9X,MACJA,IAAW,IACXsR,GAAQ,IAAI3wB,GAAY,UAAUm3B,CAAU,GAC5CxG,GAAQ,KAAK3wB,GAAY,cAAc,EAAE,UAAUk3B,GAAc,GACjE9qB,EAAM,UAAU,oDAAoD,EAAE,SAAS8qB,GAAc;AAAA,UAC/F;AACA,UAAAvG,GAAQ,GAAG3wB,GAAY,UAAUm3B,CAAU,GAC3C,WAAW,MAAM;AACf,YAAI9X,MACJA,IAAW,IACXsR,GAAQ,IAAI3wB,GAAY,UAAUm3B,CAAU,GAC5C9qB,GAAK,UAAU,uDAAuD,EAAE,SAAS6qB,GAAc;AAAA,UACjG,GAAG,GAAM;AAAA,QACX;AACA,QAAAd,KAAiB,EAAE,MAAMa,EAAc,MAAM,QAAQA,EAAc,OAAA,GACnEtG,GAAQ,KAAK3wB,GAAY,MAAMi3B,CAAa,GAQ5C,OAAO,cAAc,IAAI,YAAY,6BAA6B,CAAC;AAAA,MACrE,OAAWV,MACTlqB,GAAK,UAAU,wDAAwD;AAEzE,MAAAkqB,KAAmB;AAAA,IACrB,CAAC,GACD5F,GAAO,GAAG,cAAc,CAACrwC,MAAW;AAClC,MAAAyqB,GAAkB,IAAI,GACtBkrB,KAAiB,EAAE,QAAQC,MAA0B51C,GAAQ,IAAI,KAAK,MAAI,GAC1E41C,KAAyB,MACzB9pB,EAAM,UAAU,gBAAgB,EAAE,QAAA9rB,EAAA,CAAQ;AAAA,IAC5C,CAAC,GACDqwC,GAAO,GAAG,iBAAiB,CAACzpB,MAAQjgC,GAAM,UAAU,oBAAoB,EAAE,SAASigC,GAAK,QAAA,CAAS,CAAC,GAClGypB,GAAO,GAAG,qBAAqB,CAAC,MAAMtkB,GAAK,UAAU,qBAAqB,EAAE,SAAS,EAAA,CAAG,CAAC,GACzFskB,GAAO,GAAG,oBAAoB,MAAM1pD,GAAM,UAAU,kBAAkB,CAAC,GACvEmwD,GAAiBzG,EAAM;AAAA,EACzB;AACA,SAAOA;AACT;AAIA,SAAS0G,GAAgBvI,GAA8D;AACrF,SAAOA,EAAQ,eAAe,aAAaA,EAAQ,YAAY;AACjE;AAEA,SAASwI,GAAqBxnD,GAAyBynD,GAAmC;AACxF,SAAO;AAAA,IACL,IAAI,OAAOznD,EAAE,MAAMA,EAAE,cAAcynD,KAAe,GAAG,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE;AAAA,IAC3G,UAAUznD,EAAE;AAAA,IACZ,QAAQ,OAAOA,EAAE,UAAW,WAAWA,EAAE,SAAS;AAAA,IAClD,MAAMA,EAAE,QAAQ;AAAA,IAChB,QAAQA,EAAE,UAAU;AAAA,IACpB,MAAMA,EAAE,QAAQ;AAAA,IAChB,IAAIA,EAAE,MAAM,KAAK,IAAA;AAAA;AAAA;AAAA;AAAA,IAIjB,QAAQ,MAAM,QAAQA,EAAE,MAAM,IAC1BA,EAAE,OACC,OAAO,CAAC0nD,MACP,CAAC,CAACA,KAAMv4B,GAAgBu4B,EAAkB,GAAG,CAAC,EAC/C,MAAM,GAAGh4B,EAAuB,IACnC;AAAA,IACJ,UAAU1vB,EAAE,YAAY;AAAA,IACxB,YAAYA,EAAE;AAAA,EAAA;AAElB;AAIA,SAAS2nD,GAAS1rD,GAAiB;AAEjC,EAAAA,EAAE,GAAGi0B,GAAY,UAAU,CAAC8uB,MAA6B;AAIvD,IAAA/iD,EAAE,KAAKq1B,GAAY,IAAI,GAMvBgQ,EAAY,SAAA,EAAW,cAAc;AAAA,MACnC,QAAQ0d,EAAQ,WAAW;AAAA,MAC3B,SAASA,EAAQ,YAAY;AAAA,MAC7B,YAAYA,EAAQ,eAAe;AAAA,MACnC,SAASuI,GAAgBvI,CAAO;AAAA,MAChC,WAAWA,EAAQ,cAAc;AAAA,MACjC,UAAUA,EAAQ,aAAa;AAAA,IAAA,CAChC,GAMI1d,EAAY,SAAA,EAAW,QAC1BhF,EAAM,UAAU,mEAAmE;AAsBrF,UAAMsrB,IAAUtmB,EAAY,SAAA,GACtB+gB,IAAaxB,IAAQ,IAWrBgH,KAVUxF,IAAauF,EAAQ,OAAOvF,CAAU,IAAI,WAUjCiE,IACnBwB,IAAWrD;AAAA,MACf,EAAE,MAAMmD,EAAQ,MAAM,UAAUA,EAAQ,OAAA;AAAA,MACxCC,IAAQ,EAAE,MAAMA,EAAM,MAAM,UAAUA,EAAM,UAAU,KAAA,IAAS;AAAA;AAAA;AAAA,MAG/D,CAACrwD,MAAMA,MAAM,MAAM0mC,GAAgB1mC,CAAC;AAAA,IAAA;AAEtC,QAAIswD,GAAU;AACZ,YAAMC,IAAY;AAAA,QAChB,GAAID,EAAS,SAAS,SAAY,EAAE,MAAMA,EAAS,KAAA,IAAS,CAAA;AAAA,QAC5D,GAAIA,EAAS,aAAa,UAAa,CAACtB,KAAiC,EAAE,QAAQsB,EAAS,aAAa,CAAA;AAAA,MAAC;AAE5G,MAAI,OAAO,KAAKC,CAAS,EAAE,SAAS,MAClCzrB,EAAM,UAAU,+BAA+ByrB,CAAS,GACxD9rD,EAAE,KAAKi0B,GAAY,iBAAiB63B,CAAS;AAAA,IAEjD;AAEA,IAAAzrB,EAAM,UAAU,qBAAqB;AAAA,MACnC,SAAS0iB,EAAQ,YAAY;AAAA,MAC7B,YAAYA,EAAQ,eAAe;AAAA,MACnC,SAASuI,GAAgBvI,CAAO;AAAA,MAChC,UAAUA,EAAQ,aAAa;AAAA,MAC/B,WAAWA,EAAQ,cAAc;AAAA,MACjC,YAAY,OAAO,KAAK4I,EAAQ,MAAM,EAAE;AAAA,IAAA,CACzC,GAGG7B,IAAiB,YAAYlF,IAAQ,MACvC5lB,GAAkB,EAAE,UAAU8qB,GAAgB,UAAU,WAAWlF,GAAO,IAAI;AAAA,EAElF,CAAC,GAGD5kD,EAAE,GAAGi0B,GAAY,mBAAmB,CAACn8B,MAAiC;AACpE,UAAM+B,IAAQwrC,EAAY,SAAA;AAE1B,QAAI,OAAO,UAAU,eAAe,KAAKvtC,GAAK,UAAU,GAAG;AACzD,YAAMi0D,IAAaj0D,EAAI,YAAY;AACnC,MAAI+B,EAAM,SAAS,YAAYkyD,MAC7BlyD,EAAM,cAAc,EAAE,SAASkyD,EAAA,CAAY,GAEvCA,KAAYlyD,EAAM,aAAa,EAAE,SAASkyD,GAAY,OAAO,IAAO,YAAY,GAAG,OAAO,EAAA,CAAG,GAMjGlyD,EAAM,mBAAA;AAAA,IAEV;AAEA,IAAAA,EAAM,mBAAmB;AAAA,MACvB,YAAY/B,EAAI;AAAA,MAChB,SAASwzD,GAAgBxzD,CAAG;AAAA,MAC5B,WAAWA,EAAI;AAAA,MACf,UAAUA,EAAI,aAAa+B,EAAM,SAAS;AAAA,IAAA,CAC3C,GACDwmC,EAAM,UAAU,8BAA8B;AAAA,MAC5C,MAAMvoC,EAAI;AAAA,MAAM,WAAWA,EAAI;AAAA,MAAY,YAAYA,EAAI;AAAA,MAC3D,WAAWA,EAAI;AAAA,MAAY,SAASA,EAAI;AAAA,IAAA,CACzC;AAAA,EACH,CAAC,GAGDkI,EAAE,GAAGi0B,GAAY,aAAa,CAACqvB,MAA2B;AACxD,IAAI,OAAOA,GAAK,cAAe,YAAY,OAAOA,GAAK,cAAe,YACpEjjB,EAAM,UAAU,wBAAwBijB,CAAG;AAAA,EAE/C,CAAC,GAGDtjD,EAAE,GAAGi0B,GAAY,WAAW,CAACkZ,MAAuB;AAIlD,QADAmc,GAASW,IAAU,KAAK,KAAK,GACzBN,MAAoBA,GAAiB,IAAI;AAC3C,YAAMniB,IAAM,KAAK,IAAA,IAAQmiB,GAAiB;AAC1C,MAAAtkB,EAAY,WAAW,aAAamC,GAAK2F,GAAG,WAAWwc,GAAiB,EAAE,GAC1EA,KAAmB,MACfE,OAAmB,aAAaA,EAAe,GAAGA,KAAkB,OACxExpB,EAAM,UAAU,iBAAiB,EAAE,KAAAmH,GAAK,QAAQnC,EAAY,SAAA,EAAW,MAAM,UAAU;AAAA,IACzF;AAAA,EACF,CAAC,GAGDrlC,EAAE,GAAGi0B,GAAY,aAAa,CAAC8uB,MAA+B;AAC5D,QAAI,CAACA,EAAS;AACd,UAAMllB,IAAUklB,EAAQ,YAAY,MAC9BiJ,IAAa,OAAOjJ,EAAQ,eAAgB,WAAWA,EAAQ,cAAc,GAC7EjG,IAAQ,OAAOiG,EAAQ,SAAU,WAAWA,EAAQ,QAAQ,GAC5DkJ,IAAQlJ,EAAQ,UAAU;AAChC,IAAA1d,EAAY,SAAA,EAAW,aAAa,EAAE,SAAAxH,GAAS,OAAAouB,GAAO,YAAAD,GAAY,OAAAlP,GAAO,GACzEzc,EAAM,UAAU,wBAAwB,EAAE,SAAAxC,GAAS,YAAAmuB,GAAY,OAAAlP,GAAO,OAAAmP,GAAO;AAAA,EAC/E,CAAC;AACH;AAEA,SAASC,GAAalsD,GAAiB;AACrC,EAAAA,EAAE,GAAGi0B,GAAY,UAAU,CAACuqB,MAAwB;AAClD,QAAI,CAACA,EAAI;AAET,QAAI,MAAM,QAAQA,EAAG,KAAK,GAAG;AAC3B,YAAM2N,IAAqC,CAAA;AAC3C,iBAAWllB,KAAKuX,EAAG;AACjB,QAAA2N,EAAOllB,EAAE,SAAS,IAAI;AAAA,UACpB,UAAUA,EAAE;AAAA,UACZ,GAAIA,EAAE,SAAS,EAAE,QAAQA,EAAE,OAAA,IAAW,CAAA;AAAA,UACtC,MAAMA,EAAE,QAAQ;AAAA,UAChB,QAAQA,EAAE,aAAaA,EAAE,UAAU;AAAA,UACnC,UAAUA,EAAE;AAAA,UACZ,GAAIA,EAAE,gBAAgB,EAAE,cAAc,GAAA,IAAS,CAAA;AAAA,UAC/C,GAAIA,EAAE,aAAa,EAAE,WAAWA,EAAE,WAAA,IAAe,CAAA;AAAA,QAAC;AAItD,YAAM8e,IAAK1gB,EAAY,SAAA,GACjB+mB,IAAOxH,IAAQ,IACfyH,IAAOD,IAAOD,EAAOC,CAAI,IAAI;AACnC,UAAIC,GAAM;AAKR,QAAAhnB,EAAY,SAAS,EAAE,QAAA8mB,GAAQ,IAC3BE,EAAK,SAAStG,EAAG,QAASsG,EAAK,UAAUA,EAAK,WAAWtG,EAAG,YAC9D1lB,EAAM,UAAU,0BAA0B,EAAE,MAAM0lB,EAAG,MAAM,IAAIsG,EAAK,MAAM,GAC1EhnB,EAAY,WAAW,mBAAmBgnB,EAAK,MAAMA,EAAK,UAAUtG,EAAG,MAAM;AAAA,eAEtEqG,KAAQD,EAAOC,CAAI,GAAG;AAC/B,cAAME,IAAaH,EAAOC,CAAI,EAAE,MAC1BG,IAAeJ,EAAOC,CAAI,EAAE;AAYlC,YAVIrG,EAAG,QAAQ,CAAC9jB,GAAgB8jB,EAAG,IAAI,MACrCoG,EAAOC,CAAI,EAAE,OAAOrG,EAAG,OAKzB1gB,EAAY,SAAS,EAAE,QAAA8mB,GAAQ,GAI3BI,KAAgBA,MAAiBxG,EAAG,QAAQ;AAC9C,gBAAMyG,IAAgBzG,EAAG,QAAQ,CAAC9jB,GAAgB8jB,EAAG,IAAI,GAInD0G,IAAYD,IAAgBzG,EAAG,OAAO/jB,GAAeuqB,CAAY;AACvE,UAAAlsB,EAAM,UAAU,4BAA4B,EAAE,MAAM0lB,EAAG,QAAQ,IAAIwG,GAAc,SAASE,GAAW,sBAAsBD,EAAA,CAAe,GAC1InnB,EAAY,SAAA,EAAW,mBAAmBonB,GAAWF,CAAY,GAG7DE,MAAcH,KAAYtsD,EAAE,KAAKi0B,GAAY,iBAAiB,EAAE,MAAMw4B,GAAW;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AACA,IAAApsB,EAAM,UAAU,4BAA4Bme,CAAE;AAE9C,UAAMkO,IAAUrnB,EAAY,SAAA;AAC5B,QAAI,CAACqnB,EAAQ,MAAM;AACjB,MAAAA,EAAQ,qBAAA;AACR,YAAMC,IAAMtnB,EAAY,SAAA;AACxB,MAAIsnB,EAAI,SACNtsB,EAAM,UAAU,sCAAsC,EAAE,MAAMssB,EAAI,MAAM,QAAQA,EAAI,QAAQ,GAC5F3sD,EAAE,KAAKi0B,GAAY,iBAAiB,EAAE,MAAM04B,EAAI,MAAM,QAAQA,EAAI,UAAU,OAAA,CAAW;AAAA,IAE3F;AAAA,EACF,CAAC;AACH;AAEA,SAASC,GAAS5sD,GAAiB;AAEjC,EAAAA,EAAE,GAAGi0B,GAAY,gBAAgB,CAAClwB,MAA4B;AAC5D,UAAM8oD,IAAUtB,GAAqBxnD,GAAGA,EAAE,UAAU;AACpD,IAAAshC,EAAY,SAAA,EAAW,WAAWwnB,CAAO,GACzCxsB,EAAM,QAAQ,oBAAoBwsB,CAAO;AAAA,EAC3C,CAAC,GAGD7sD,EAAE,GAAGi0B,GAAY,cAAc,CAACyL,MAA6B;AAC3D,QAAI,CAACA,GAAM,YAAY,CAAC,MAAM,QAAQA,EAAK,QAAQ,EAAG;AACtD,UAAM2H,IAA0B3H,EAAK,SAAS,IAAI,CAAC37B,MAAMwnD,GAAqBxnD,CAAC,CAAC;AAChF,IAAAshC,EAAY,SAAA,EAAW,QAAQgC,CAAQ,GACvChH,EAAM,QAAQ,kBAAkB,EAAE,OAAOgH,EAAS,QAAQ;AAAA,EAC5D,CAAC;AACH;AAEA,SAASylB,GAAa9sD,GAAiB;AACrC,EAAAA,EAAE,GAAG+0B,GAAgB,OAAO,CAACguB,MAAkC;AAC7D,IAAA1d,EAAY,SAAA,EAAW,mBAAmB;AAAA,MACxC,UAAU0d,GAAS,YAAY;AAAA,MAC/B,aAAaA,GAAS,eAAe;AAAA,MACrC,SAASA,GAAS,WAAW,CAAA;AAAA,IAAC,CAC/B,GACD1iB,EAAM,YAAY,2BAA2B,EAAE,YAAY0iB,GAAS,UAAU,MAAM,MAAM,aAAaA,GAAS,aAAa,aAAa,OAAO,KAAKA,GAAS,WAAW,CAAA,CAAE,EAAE,QAAQ;AAAA,EACxL,CAAC,GAED/iD,EAAE,GAAG+0B,GAAgB,eAAe,CAACguB,MAAyC;AAC5E,IAAA1d,EAAY,WAAW,gBAAgB0d,GAAS,YAAY,CAAA,CAAE,GAC9D1iB,EAAM,YAAY,iBAAiB,EAAE,eAAe0iB,GAAS,UAAU,QAAQ;AAAA,EACjF,CAAC,GAED/iD,EAAE,GAAG+0B,GAAgB,SAAS,CAACguB,MAAoC;AACjE,IAAA1d,EAAY,SAAA,EAAW,mBAAmB0d,KAAW,IAAI,GACzD1iB,EAAM,YAAY,oBAAoB,EAAE,YAAY0iB,GAAS,UAAU,IAAI,QAAQA,GAAS,WAAW,GAAA,CAAM;AAAA,EAC/G,CAAC,GAMD/iD,EAAE,GAAG+0B,GAAgB,eAAe,CAACguB,MAAyC;AAC5E,QAAI,CAACA,GAAS,cAAc,CAAC,MAAM,QAAQA,EAAQ,QAAQ,EAAG;AAC9D,UAAMkG,IAAUF;AAAA,MACd,EAAE,IAAIhG,EAAQ,YAAY,QAAQA,EAAQ,SAAS,IAAI,CAAAllB,OAAY,EAAE,SAAAA,EAAA,EAAU,EAAA;AAAA,MAC/EiF,GAAA;AAAA,IAAe,GAEXijB,IAAK1gB,EAAY,SAAA;AACvB,IAAI0gB,EAAG,UAAU,OAAOhD,EAAQ,cAC9BgD,EAAG,mBAAmB,EAAE,UAAUA,EAAG,UAAU,aAAaA,EAAG,qBAAqB,SAAS,CAAA,EAAC,CAAG,GAEnG1lB,EAAM,YAAY,2BAA2B,EAAE,YAAY0iB,EAAQ,YAAY,SAAAkG,GAAS;AAAA,EAC1F,CAAC;AACH;AAEA,SAAS8D,GAAa/sD,GAAiB;AAMrC,EAAAA,EAAE,GAAGm1B,GAAgB,SAAS,MAAM;AAClC,IAAAkL,EAAM,YAAY,sCAAsC,GACnDolB,GAAgB,EAAK;AAAA,EAC5B,CAAC;AACH;AAEA,SAASuH,GAAehtD,GAAiB;AAGvC,EAAAA,EAAE,GAAGo1B,GAAa,OAAO,CAAC2tB,MAAoC;AAC5D,QAAI,CAACA,KAAW,OAAOA,EAAQ,UAAW,UAAW;AACrD,UAAMkJ,IAAQ,MAAM,QAAQlJ,EAAQ,KAAK,IAAIA,EAAQ,MAAM,OAAO,CAAC5Y,MAAe,OAAOA,KAAM,QAAQ,IAAI,CAAA;AAC3G,IAAA9E,EAAY,SAAA,EAAW,mBAAmB,EAAE,QAAQ0d,EAAQ,QAAQ,OAAAkJ,GAAO,GAC3E5rB,EAAM,eAAe,kBAAkB,EAAE,QAAQ0iB,EAAQ,QAAQ,YAAYkJ,EAAM,QAAQ;AAAA,EAC7F,CAAC;AACH;AAGO,SAASgB,KAA4B;AAC1C,EAAArI,IAAQ,KAAKxvB,GAAa,OAAO,CAAA,CAAE;AACrC;AAGO,SAAS83B,GAAqBjB,GAAsB;AACzD,EAAArH,IAAQ,KAAKxvB,GAAa,QAAQ,EAAE,OAAA62B,GAAO;AAC7C;AAIA,SAASkB,GAASntD,GAAiB;AAGjC,EAAAA,EAAE,GAAGq1B,GAAY,QAAQ,CAAC0tB,MAA+B;AACvD,UAAMpa,IAAS,OAAOoa,GAAS,UAAW,WAAWA,EAAQ,SAAS;AACtE,IAAA1d,EAAY,SAAA,EAAW,gBAAgBsD,CAAM,GAC7CtI,EAAM,QAAQ,eAAe,EAAE,QAAAsI,EAAA,CAAQ;AAAA,EACzC,CAAC;AACH;AAIO,SAASykB,GAAezkB,GAA6B;AAC1D,EAAAic,IAAQ,KAAKvvB,GAAY,QAAQ,EAAE,QAAAsT,GAAQ;AAC7C;AAEA,SAAS0kB,GAAWrtD,GAAiB;AAEnC,EAAAA,EAAE,GAAGi0B,GAAY,iBAAiB,CAAC8uB,MAAmC;AACpE,IAAA1d,EAAY,SAAA,EAAW,kBAAkB0d,CAAO;AAAA,EAClD,CAAC,GAED/iD,EAAE,GAAGi0B,GAAY,eAAe,CAAC8uB,MAAiC;AAChE,IAAA1d,EAAY,SAAA,EAAW,gBAAgB0d,CAAO;AAAA,EAChD,CAAC;AACH;AAEA,SAASsI,GAAiBrrD,GAAiB;AACzC,EAAA0rD,GAAS1rD,CAAC,GACVksD,GAAalsD,CAAC,GACd4sD,GAAS5sD,CAAC,GACVqtD,GAAWrtD,CAAC,GACZ8sD,GAAa9sD,CAAC,GACd+sD,GAAa/sD,CAAC,GACdgtD,GAAehtD,CAAC,GAChBmtD,GAASntD,CAAC,GAGVA,EAAE,GAAGi0B,GAAY,OAAO,CAAC5tB,MAAoB;AAC3C,UAAMinD,IAAOjnD,GAAG,QAAQ;AAOxB,QAAIinD,MAAS,cAAcjnD,GAAG,YAAY,sBAAsB;AAC9D,MAAAkkD,KAAiC,IACjClqB,EAAM,UAAU,oFAAqF;AACrG;AAAA,IACF;AACA,QAAIitB,MAAS,cAAcjnD,GAAG,YAAY,gBAAgB;AAOxD,UAAI8/C,GAAqBvB,IAAQ,EAAE,GAAG;AACpC,QAAAvkB,EAAM,UAAU,wDAAwD;AACxE;AAAA,MACF;AAGA,MAAAiqB,KAAqB;AACrB,UAAIiD;AACJ,UAAI;AACF,QAAAA,IAAQzH,GAAA;AAAA,MACV,UAAA;AACE,QAAAwE,KAAqB;AAAA,MACvB;AACA,MAAIiD,KAAOvtD,EAAE,KAAKi0B,GAAY,iBAAiBs5B,CAAK;AACpD;AAAA,IACF;AAmBA,UAAMl0D,IAjB8B;AAAA,MAClC,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,MACrB,mBAAmB;AAAA,MACnB,gBAAgB;AAAA,MAChB,qBAAqB;AAAA,MACrB,aAAa;AAAA,MACb,oBAAoB;AAAA,MACpB,wBAAwB;AAAA,MACxB,wBAAwB;AAAA,MACxB,cAAgB;AAAA,MAChB,UAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,MACrB,mBAAmB;AAAA,IAAA,EAEDi0D,CAAI,KAAKA;AAI7B,QAAIA,EAAK,WAAW,QAAQ,GAAG;AAC7B,MAAAjtB,EAAM,UAAU,sBAAsBhnC,CAAO,IAAI,EAAE,MAAAi0D,GAAM,GACzDjoB,EAAY,SAAA,EAAW,UAAU,QAAQhsC,CAAO;AAChD;AAAA,IACF;AAYA,KADmBi0D,EAAK,WAAW,OAAO,IAAIhtB,KAAOplC,IAC1C,UAAU,iBAAiB7B,CAAO,IAAI,EAAE,MAAAi0D,GAAM,KAAKjnD,GAAG,GACjEg/B,EAAY,SAAA,EAAW,UAAU,SAAShsC,CAAO;AAAA,EACnD,CAAC;AACH;AAGO,SAASm0D,GAASt2C,GAAcu2C,GAAuB;AAG5D,EAAA9C,KAAY,KAAK12B,GAAY,WAAWw5B,GAAQ,SAAS,EAAE,MAAAv2C,GAAM,QAAAu2C,MAAW,EAAE,MAAAv2C,EAAA,CAAM;AACtF;AAEA,SAAS8zC,KAAmB;AAC1B,EAAIrB,OACJA,KAAmB,EAAE,IAAI,KAAK,IAAA,EAAI,GAClCgB,GAAA,EAAY,KAAK12B,GAAY,WAAW,CAAA,CAAE,GAE1C41B,KAAkB,WAAW,MAAM;AACjC,IAAIF,OACFtpB,EAAM,UAAU,kDAAkD,GAClEspB,KAAmB,OAErBE,KAAkB;AAAA,EACpB,GAAG,GAAM;AACX;AAYO,SAAS6D,GAAiB33B,GAA6B;AAC5D,QAAM43B,IAAStoB,EAAY,SAAA,GACrB+mB,IAAOuB,EAAO,GAAG;AACvB,MAAI,CAACvB,KAAQ,CAACuB,EAAO,OAAOvB,CAAI,GAAG;AACjC,IAAApE,GAAqBjyB,CAAM,GAC3BsK,EAAM,UAAU,qDAAqD,EAAE,QAAAtK,EAAA,CAAQ;AAC/E;AAAA,EACF;AAGA,EAAAu0B,KAAqB;AACrB,MAAI;AACF,IAAAtC,GAAqBjyB,CAAM;AAAA,EAC7B,UAAA;AACE,IAAAu0B,KAAqB;AAAA,EACvB;AACA,QAAMsD,IAAQvoB,EAAY,SAAA,GACpB0d,IAA4D,EAAE,QAAQ,GAAA;AAC5E,EAAI6K,EAAM,UAAUA,EAAM,WAAWD,EAAO,WAAQ5K,EAAQ,SAAS6K,EAAM,SAEvEA,EAAM,QAAQA,EAAM,SAASD,EAAO,SAAM5K,EAAQ,OAAO6K,EAAM,OACnEvtB,EAAM,UAAU,yBAAyB0iB,CAAO,GAChD4H,GAAA,EAAY,KAAK12B,GAAY,iBAAiB8uB,CAAO;AACvD;AAEO,SAAS8K,GAAmB12C,GAAe4e,GAAwB;AACxE,QAAMgtB,IAA8C,CAAA;AAGpD,EAFI5rC,QAAc,OAAOA,IAErB,GAAC4rC,EAAQ,QAAQ,CAACA,EAAQ,YAC9B1iB,EAAM,UAAU,2BAA2B0iB,CAAO,GAClD4H,GAAA,EAAY,KAAK12B,GAAY,iBAAiB8uB,CAAO;AACvD;AAmBA,IAAI+K,KAAkB,EAAE,MAAM,IAAI,QAAQ,GAAA;AAC1CzoB,EAAY,UAAU,CAACxrC,GAAO0uC,MAAS;AAErC,MADI1uC,EAAM,SAAS0uC,EAAK,QAAQ1uC,EAAM,WAAW0uC,EAAK,UAClD+hB,GAAoB;AACxB,QAAM8B,IAAOvyD,EAAM,GAAG;AACtB,MAAI,CAACuyD,EAAM;AACX,QAAM2B,IAAUl0D,EAAM,OAAOuyD,CAAI;AACjC,MAAI,CAAC2B,EAAS;AACd,QAAMnF,IAAY,CAAC,CAAC/uD,EAAM,QACrB,CAACooC,GAAgBpoC,EAAM,IAAI,KAC3BA,EAAM,SAASi0D,GAAgB,SAC9B7rB,GAAgB8rB,EAAQ,QAAQ,EAAE,KAAKA,EAAQ,SAASl0D,EAAM,OAC9Dm0D,IAAc,CAAC,CAACn0D,EAAM,UACvBA,EAAM,WAAWi0D,GAAgB,UACjCC,EAAQ,WAAWl0D,EAAM;AAC9B,MAAI,CAAC+uD,KAAa,CAACoF,EAAa;AAChC,QAAMjL,IAA8C,CAAA;AACpD,EAAI6F,MAAa7F,EAAQ,OAAOlpD,EAAM,MAAMi0D,GAAgB,OAAOj0D,EAAM,OACrEm0D,MAAejL,EAAQ,SAASlpD,EAAM,QAASi0D,GAAgB,SAASj0D,EAAM,SAClFwmC,EAAM,UAAU,oCAAoC0iB,CAAO,GACvD6B,IAAQ,YACVA,GAAO,KAAK3wB,GAAY,iBAAiB8uB,CAAO,IAGhD4H,GAAA,EAAY,KAAK12B,GAAY,iBAAiB8uB,CAAO;AAEzD,CAAC;AAGD,SAASkL,KAAgB;AACvB,EAAIrE,OAAoB,cAAcA,EAAgB,GAAGA,KAAmB,OACxEC,OAAmB,aAAaA,EAAe,GAAGA,KAAkB,OACxEF,KAAmB,MACnBM,GAAS,kBAAkB,MAC3BA,GAAS,aAAa;AACxB;AAGA,SAASiE,KAAuB;AAC9B,EAAA7tB,EAAM,UAAU,yBAAyB,EAAE,YAAYypB,OAAoB,MAAM,UAAUA,IAAiB,UAAU,GACtHA,KAAkB,MAClBU,KAAmB,IACnBC,KAAmB;AACrB;AAYO,SAAS0D,KAAkB;AAChC,EAAA9tB,EAAM,UAAU,oBAAoB,EAAE,UAAUypB,IAAiB,UAAU,GAC3EoE,GAAA,GACAD,GAAA,GACIrJ,OACFA,GAAO,WAAA,GACPA,KAAS,OAEXvf,EAAY,SAAS;AAAA,IACnB,IAAI,EAAE,UAAU,MAAM,eAAe,EAAA;AAAA,IACrC,QAAQ,CAAA;AAAA,IACR,UAAU,EAAE,QAAQ,MAAM,SAAS,MAAM,YAAY,GAAG,SAAS,IAAO,WAAW,GAAG,UAAU,KAAA;AAAA,IAChG,MAAM,CAAA;AAAA,IACN,UAAU;AAAA,IACV,qBAAqB;AAAA,IACrB,SAAS,CAAA;AAAA,IACT,cAAc,CAAA;AAAA,IACd,iBAAiB;AAAA,IACjB,WAAW,EAAE,SAAS,MAAM,OAAO,IAAO,YAAY,GAAG,OAAO,EAAA;AAAA,IAChE,YAAY,EAAE,QAAQ,IAAO,OAAO,CAAA,EAAC;AAAA,IACrC,cAAc;AAAA,EAAA,CACf;AACH;AAIO,SAAS+oB,GAAiBxwB,GAA0B;AACzD,EAAAyC,EAAM,YAAY,0BAA0B,EAAE,YAAAzC,EAAA,CAAY,GAC1D+sB,GAAA,EAAY,KAAK51B,GAAgB,MAAM,EAAE,YAAA6I,GAAY;AACvD;AAEO,SAASywB,GAAmB10D,GAAqB;AACtD,EAAA0mC,EAAM,YAAY,4BAA4B,EAAE,OAAA1mC,EAAA,CAAO,GACvDgxD,GAAA,EAAY,KAAK51B,GAAgB,QAAQ,EAAE,OAAAp7B,GAAO;AACpD;AAEO,SAAS20D,GAAe1wB,GAAoBC,GAAiB0wB,GAAwB;AAC1F,EAAAluB,EAAM,YAAY,iCAAiC,EAAE,YAAAzC,GAAY,SAAAC,GAAS,MAAA0wB,GAAM,GAChF5D,GAAA,EAAY,KAAK51B,GAAgB,aAAa,EAAE,YAAA6I,GAAY,SAAAC,GAAS,MAAA0wB,GAAM;AAC7E;AAUO,SAASC,KAAyB;AACvC,EAAAnuB,EAAM,QAAQ,wBAAwB,GACtCsqB,GAAA,EAAY,KAAK,eAAe;AAClC;AAEO,SAAS8D,KAA0B;AACxC,EAAApuB,EAAM,YAAY,kCAAkC,GACpDsqB,GAAA,EAAY,KAAK51B,GAAgB,gBAAgB,CAAA,CAAE;AACrD;AAGO,SAAS25B,GAAeC,GAAwB;AACrD,EAAAtuB,EAAM,YAAY,iCAAiC,EAAE,UAAAsuB,EAAA,CAAU,GAC/DhE,GAAA,EAAY,KAAK51B,GAAgB,aAAa,EAAE,UAAA45B,GAAU;AAC5D;AAUO,SAASC,GAAgB/wB,GAAuB;AACrD,EAAA4sB,KAAmB5sB,GACnB8sB,GAAA,EAAY,KAAK12B,GAAY,cAAc,EAAE,UAAU4J,GAAS,GAChEwC,EAAM,UAAU,wBAAwB,EAAE,SAAAxC,EAAA,CAAS;AACrD;ACn3BA,SAASgxB,GAAiB5tB,GAAgB;AAExC,MADI,CAACA,KAAUA,MAAW,OACtB,SAAS,cAAc,gCAAgCA,CAAM,IAAI,EAAG;AACxE,QAAMzW,IAAO,SAAS,cAAc,MAAM;AAC1C,EAAAA,EAAK,MAAM,cACXA,EAAK,OAAOyW,GACZzW,EAAK,cAAc,aACnB,SAAS,KAAK,YAAYA,CAAI;AAChC;AAEA,SAASsjB,GAAOghB,GAAiBC,GAAmCC,GAAqB;AACvF,QAAM5J,IAAO6J,GAAWH,CAAE,GACpBI,IAAUF,IACd,gBAAA3lB,EAACtpB,GAAM,YAAN,EAAkB,aAAc,IAEjCgvC;AAEF,SAAA3J,EAAK,OAAO8J,CAAO,GACZ9J;AACT;AAKA,IAAI+J,KAA6E,MAC7EC,KAA6D;AAGjE,MAAMC,KAAa,YAAY,IAAI,QAAQ,UAAU,EAAE;AAWvD,SAASC,GAAmBzmC,GAA4B;AACtD,SAAI,CAACA,EAAM,YAAY,CAACA,EAAM,SAAS,WAAWwmC,EAAU,IAAU,KAC/D,CAAC,uBAAuB,KAAKxmC,EAAM,WAAW,EAAE;AACzD;AAEO,SAAS+f,GAAMkmB,GAAiBtrC,IAA8B,IAAI;AACvE,QAAM,EAAE,UAAArmB,GAAU,YAAA6xD,IAAa,IAAqB,GAAGhY,MAAaxzB;AAKpE,EAAAgb,GAAA,GAGAvB,GAAiB;AAAA,IACf,cAAc+Z,EAAS;AAAA,IACvB,gBAAgBA,EAAS;AAAA,IACzB,SAASA,EAAS;AAAA,EAAA,CACnB,GAMDI,GAAA,GAKA/U,GAAQ;AAAA,IACN,UAAU2U,EAAS;AAAA,IACnB,QAAQA,EAAS;AAAA,EAAA,CAClB,GAOD3R,EAAY,SAAA,EAAW,mBAAA;AAUvB,MAAI;AACF,UAAM/B,IAAMT,QAAe,UACrB0sB,IAASntB,GAAA,GACTotB,IAAK,OAAO,eAAiB,MAAc,eAAe,MAC1DC,IAAaD,GAAI,QAAQ,wBAAwB,GACjDE,IAAcF,KAAMlsB,MAAQ,WAAWksB,EAAG,QAAQ,0BAA0BlsB,CAAG,EAAE,IAAI,MACrFqsB,IAAWJ,IAASC,GAAI,QAAQ,eAAeD,CAAM,YAAY,IAAI,MACrEK,IAASL,IAASC,GAAI,QAAQ,eAAeD,CAAM,aAAa,IAAI,MACpExJ,IAAK1gB,EAAY,SAAA;AAWvBwqB,IAAAA,EAAS,QAAQ,gBAAgB;AAAA,MAC/B,KAAAvsB;AAAA,MACA,QAAAisB;AAAA,MACA,iBAAiBE,GAAY,UAAU;AAAA,MACvC,kBAAkBC,GAAa,UAAU;AAAA,MACzC,eAAeC,GAAU,UAAU;AAAA,MACnC,aAAaC,GAAQ,UAAU;AAAA,MAC/B,WAAW7J,EAAG;AAAA,MACd,aAAaA,EAAG;AAAA,IAAA,CACjB;AAAA,EACH,SAAS1/C,GAAG;AACVypD,IAAAA,GAAQ,QAAQ,sBAAsB,EAAE,KAAMzpD,GAAa,SAAS;AAAA,EACtE;AAEA,EAAA08B,GAAA,EAAa,MAAM,CAAC18B,MAAeypD,GAAQ,QAAQ,gBAAgBruB,GAAYp7B,CAAC,CAAC,CAAC,GAMlF2+B,GAAA,EAA4B,KAAK,CAAC7lB,MAAW;AAC3C,IAAIA,KAAQkmB,EAAY,SAAA,EAAW,mBAAA;AAAA,EAIrC,CAAC,EAAE,MAAM,CAACh/B,MAAeypD,GAAQ,QAAQ,oBAAoBruB,GAAYp7B,CAAC,CAAC,CAAC,GAGvE8oD,OACHA,KAA4B,CAACtmC,MAAU;AACrCknC,IAAAA,GAAS,OAAO,+BAA+B,EAAE,QAAQ,OAAOlnC,EAAM,MAAM,GAAG;AAAA,EACjF,GACA,OAAO,iBAAiB,sBAAsBsmC,EAAyB,IAEpEC,OACHA,KAAuB,CAACvmC,MAAU;AAChC,IAAKymC,GAAmBzmC,CAAK,KAC7BknC,GAAS,OAAO,kBAAkB;AAAA,MAChC,SAASlnC,EAAM;AAAA,MACf,QAAQ,GAAGA,EAAM,SAAS,MAAMwmC,GAAW,MAAM,CAAC,IAAIxmC,EAAM,MAAM,IAAIA,EAAM,KAAK;AAAA,MACjF,OAAOA,EAAM,iBAAiB,QAAQA,EAAM,MAAM,OAAO,MAAM,GAAG,IAAI,IAAI;AAAA,IAAA,CAC3E;AAAA,EACH,GACA,OAAO,iBAAiB,SAASumC,EAAoB,IAInDpY,EAAS,gBACX6X,GAAiB7X,EAAS,YAAY;AAYxC,QAAMgZ,IAAa7rB,KAAkB;AACrC,EAAI6rB,KAAeC,GAA6B,SAASD,CAAU,KACjEE,GAAUF,CAAmB,GAI/BjuB,GAAA,EAAmB,MAAM,CAAC17B,MAAeypD,GAAQ,QAAQ,4BAA4BruB,GAAYp7B,CAAC,CAAC,CAAC,GAEpGyoD,EAAG,cAAc,KAAK,QAAA;AACtB,QAAMvpD,IAASwxC,GAAuB;AAAA,IACpC,UAAA55C;AAAA,IACA,UAAA65C;AAAA,EAAA,CACD,GAEKmZ,IAA4B,EAAE,MADvBriB,GAAOghB,qBAAK9oC,IAAA,EAAe,QAAAzgB,GAAgB,GAAIypD,CAAU,EAClC;AACpC,SAAAF,EAAG,eAAeqB,GACX5qD;AACT;AAQO,SAAS6qD,GAAQtB,GAAiB;AACvC,QAAMqB,IAAWrB,EAAG;AACpB,EAAKqB,MACLA,EAAS,KAAK,QAAA,GACd,OAAOrB,EAAG,cACVX,GAAA,GACIgB,OACF,OAAO,oBAAoB,sBAAsBA,EAAyB,GAC1EA,KAA4B,OAE1BC,OACF,OAAO,oBAAoB,SAASA,EAAoB,GACxDA,KAAuB;AAE3B;","x_google_ignoreList":[0,1,2,3,15,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,72]}