@remix-run/router
Advanced tools
147
CHANGELOG.md
# `@remix-run/router` | ||
## 1.6.3 | ||
### Patch Changes | ||
- Allow fetcher revalidations to complete if submitting fetcher is deleted ([#10535](https://github.com/remix-run/react-router/pull/10535)) | ||
- Re-throw `DOMException` (`DataCloneError`) when attempting to perform a `PUSH` navigation with non-serializable state. ([#10427](https://github.com/remix-run/react-router/pull/10427)) | ||
- Ensure revalidations happen when hash is present ([#10516](https://github.com/remix-run/react-router/pull/10516)) | ||
- upgrade jest and jsdom ([#10453](https://github.com/remix-run/react-router/pull/10453)) | ||
## 1.6.2 | ||
### Patch Changes | ||
- Fix HMR-driven error boundaries by properly reconstructing new routes and `manifest` in `\_internalSetRoutes` ([#10437](https://github.com/remix-run/react-router/pull/10437)) | ||
- Fix bug where initial data load would not kick off when hash is present ([#10493](https://github.com/remix-run/react-router/pull/10493)) | ||
## 1.6.1 | ||
### Patch Changes | ||
- Fix `basename` handling when navigating without a path ([#10433](https://github.com/remix-run/react-router/pull/10433)) | ||
- "Same hash" navigations no longer re-run loaders to match browser behavior (i.e. `/path#hash -> /path#hash`) ([#10408](https://github.com/remix-run/react-router/pull/10408)) | ||
## 1.6.0 | ||
### Minor Changes | ||
- Enable relative routing in the `@remix-run/router` when providing a source route ID from which the path is relative to: ([#10336](https://github.com/remix-run/react-router/pull/10336)) | ||
- Example: `router.navigate("../path", { fromRouteId: "some-route" })`. | ||
- This also applies to `router.fetch` which already receives a source route ID | ||
- Introduce a new `@remix-run/router` `future.v7_prependBasename` flag to enable `basename` prefixing to all paths coming into `router.navigate` and `router.fetch`. | ||
- Previously the `basename` was prepended in the React Router layer, but now that relative routing is being handled by the router we need prepend the `basename` _after_ resolving any relative paths | ||
- This also enables `basename` support in `useFetcher` as well | ||
### Patch Changes | ||
- Enhance `LoaderFunction`/`ActionFunction` return type to prevent `undefined` from being a valid return value ([#10267](https://github.com/remix-run/react-router/pull/10267)) | ||
- Ensure proper 404 error on `fetcher.load` call to a route without a `loader` ([#10345](https://github.com/remix-run/react-router/pull/10345)) | ||
- Deprecate the `createRouter` `detectErrorBoundary` option in favor of the new `mapRouteProperties` option for converting a framework-agnostic route to a framework-aware route. This allows us to set more than just the `hasErrorBoundary` property during route pre-processing, and is now used for mapping `Component -> element` and `ErrorBoundary -> errorElement` in `react-router`. ([#10287](https://github.com/remix-run/react-router/pull/10287)) | ||
- Fixed a bug where fetchers were incorrectly attempting to revalidate on search params changes or routing to the same URL (using the same logic for route `loader` revalidations). However, since fetchers have a static href, they should only revalidate on `action` submissions or `router.revalidate` calls. ([#10344](https://github.com/remix-run/react-router/pull/10344)) | ||
- Decouple `AbortController` usage between revalidating fetchers and the thing that triggered them such that the unmount/deletion of a revalidating fetcher doesn't impact the ongoing triggering navigation/revalidation ([#10271](https://github.com/remix-run/react-router/pull/10271)) | ||
## 1.5.0 | ||
### Minor Changes | ||
- Added support for [**Future Flags**](https://reactrouter.com/en/main/guides/api-development-strategy) in React Router. The first flag being introduced is `future.v7_normalizeFormMethod` which will normalize the exposed `useNavigation()/useFetcher()` `formMethod` fields as uppercase HTTP methods to align with the `fetch()` behavior. ([#10207](https://github.com/remix-run/react-router/pull/10207)) | ||
- When `future.v7_normalizeFormMethod === false` (default v6 behavior), | ||
- `useNavigation().formMethod` is lowercase | ||
- `useFetcher().formMethod` is lowercase | ||
- When `future.v7_normalizeFormMethod === true`: | ||
- `useNavigation().formMethod` is uppercase | ||
- `useFetcher().formMethod` is uppercase | ||
### Patch Changes | ||
- Provide fetcher submission to `shouldRevalidate` if the fetcher action redirects ([#10208](https://github.com/remix-run/react-router/pull/10208)) | ||
- Properly handle `lazy()` errors during router initialization ([#10201](https://github.com/remix-run/react-router/pull/10201)) | ||
- Remove `instanceof` check for `DeferredData` to be resilient to ESM/CJS boundaries in SSR bundling scenarios ([#10247](https://github.com/remix-run/react-router/pull/10247)) | ||
- Update to latest `@remix-run/web-fetch@4.3.3` ([#10216](https://github.com/remix-run/react-router/pull/10216)) | ||
## 1.4.0 | ||
### Minor Changes | ||
- **Introducing Lazy Route Modules!** ([#10045](https://github.com/remix-run/react-router/pull/10045)) | ||
In order to keep your application bundles small and support code-splitting of your routes, we've introduced a new `lazy()` route property. This is an async function that resolves the non-route-matching portions of your route definition (`loader`, `action`, `element`/`Component`, `errorElement`/`ErrorBoundary`, `shouldRevalidate`, `handle`). | ||
Lazy routes are resolved on initial load and during the `loading` or `submitting` phase of a navigation or fetcher call. You cannot lazily define route-matching properties (`path`, `index`, `children`) since we only execute your lazy route functions after we've matched known routes. | ||
Your `lazy` functions will typically return the result of a dynamic import. | ||
```jsx | ||
// In this example, we assume most folks land on the homepage so we include that | ||
// in our critical-path bundle, but then we lazily load modules for /a and /b so | ||
// they don't load until the user navigates to those routes | ||
let routes = createRoutesFromElements( | ||
<Route path="/" element={<Layout />}> | ||
<Route index element={<Home />} /> | ||
<Route path="a" lazy={() => import("./a")} /> | ||
<Route path="b" lazy={() => import("./b")} /> | ||
</Route> | ||
); | ||
``` | ||
Then in your lazy route modules, export the properties you want defined for the route: | ||
```jsx | ||
export async function loader({ request }) { | ||
let data = await fetchData(request); | ||
return json(data); | ||
} | ||
// Export a `Component` directly instead of needing to create a React Element from it | ||
export function Component() { | ||
let data = useLoaderData(); | ||
return ( | ||
<> | ||
<h1>You made it!</h1> | ||
<p>{data}</p> | ||
</> | ||
); | ||
} | ||
// Export an `ErrorBoundary` directly instead of needing to create a React Element from it | ||
export function ErrorBoundary() { | ||
let error = useRouteError(); | ||
return isRouteErrorResponse(error) ? ( | ||
<h1> | ||
{error.status} {error.statusText} | ||
</h1> | ||
) : ( | ||
<h1>{error.message || error}</h1> | ||
); | ||
} | ||
``` | ||
An example of this in action can be found in the [`examples/lazy-loading-router-provider`](https://github.com/remix-run/react-router/tree/main/examples/lazy-loading-router-provider) directory of the repository. | ||
🙌 Huge thanks to @rossipedia for the [Initial Proposal](https://github.com/remix-run/react-router/discussions/9826) and [POC Implementation](https://github.com/remix-run/react-router/pull/9830). | ||
### Patch Changes | ||
- Fix `generatePath` incorrectly applying parameters in some cases ([#10078](https://github.com/remix-run/react-router/pull/10078)) | ||
## 1.3.3 | ||
### Patch Changes | ||
- Correctly perform a hard redirect for same-origin absolute URLs outside of the router `basename` ([#10076](https://github.com/remix-run/react-router/pull/10076)) | ||
- Ensure status code and headers are maintained for `defer` loader responses in `createStaticHandler`'s `query()` method ([#10077](https://github.com/remix-run/react-router/pull/10077)) | ||
- Change `invariant` to an `UNSAFE_invariant` export since it's only intended for internal use ([#10066](https://github.com/remix-run/react-router/pull/10066)) | ||
- Add internal API for custom HMR implementations ([#9996](https://github.com/remix-run/react-router/pull/9996)) | ||
## 1.3.2 | ||
### Patch Changes | ||
- Remove inaccurate console warning for POP navigations and update active blocker logic ([#10030](https://github.com/remix-run/react-router/pull/10030)) | ||
- Only check for differing origin on absolute URL redirects ([#10033](https://github.com/remix-run/react-router/pull/10033)) | ||
## 1.3.1 | ||
@@ -4,0 +151,0 @@ |
@@ -232,2 +232,3 @@ /** | ||
export declare function invariant<T>(value: T | null | undefined, message?: string): asserts value is T; | ||
export declare function warning(cond: any, message: string): void; | ||
/** | ||
@@ -234,0 +235,0 @@ * Creates a Location object with a unique key from the given Path |
@@ -1,7 +0,9 @@ | ||
export type { ActionFunction, ActionFunctionArgs, ActionFunctionWithMiddleware, ActionFunctionArgsWithMiddleware, AgnosticDataIndexRouteObject, AgnosticDataNonIndexRouteObject, AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticIndexRouteObject, AgnosticNonIndexRouteObject, AgnosticRouteMatch, AgnosticRouteObject, TrackedPromise, FormEncType, FormMethod, JsonFunction, LoaderFunction, LoaderFunctionArgs, LoaderFunctionWithMiddleware, LoaderFunctionArgsWithMiddleware, MiddlewareContext, MiddlewareFunction, MiddlewareFunctionArgs, ParamParseKey, Params, PathMatch, PathPattern, RedirectFunction, ShouldRevalidateFunction, Submission, } from "./utils"; | ||
export { AbortedDeferredError, ErrorResponse, createMiddlewareContext, defer, generatePath, getToPathname, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, redirect, resolvePath, resolveTo, stripBasename, warning, } from "./utils"; | ||
export type { ActionFunction, ActionFunctionArgs, AgnosticDataIndexRouteObject, AgnosticDataNonIndexRouteObject, AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticIndexRouteObject, AgnosticNonIndexRouteObject, AgnosticRouteMatch, AgnosticRouteObject, LazyRouteFunction, TrackedPromise, FormEncType, FormMethod, HTMLFormMethod, JsonFunction, LoaderFunction, LoaderFunctionArgs, ParamParseKey, Params, PathMatch, PathPattern, RedirectFunction, ShouldRevalidateFunction, V7_FormMethod, } from "./utils"; | ||
export { AbortedDeferredError, ErrorResponse, defer, generatePath, getToPathname, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, redirect, resolvePath, resolveTo, stripBasename, } from "./utils"; | ||
export type { BrowserHistory, BrowserHistoryOptions, HashHistory, HashHistoryOptions, History, InitialEntry, Location, MemoryHistory, MemoryHistoryOptions, Path, To, } from "./history"; | ||
export { Action, createBrowserHistory, createPath, createHashHistory, createMemoryHistory, invariant, parsePath, } from "./history"; | ||
export { Action, createBrowserHistory, createPath, createHashHistory, createMemoryHistory, parsePath, } from "./history"; | ||
export * from "./router"; | ||
/** @internal */ | ||
export { DeferredData as UNSAFE_DeferredData, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, createMiddlewareStore as UNSAFE_createMiddlewareStore, } from "./utils"; | ||
export type { RouteManifest as UNSAFE_RouteManifest } from "./utils"; | ||
export { DeferredData as UNSAFE_DeferredData, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, } from "./utils"; | ||
export { invariant as UNSAFE_invariant, warning as UNSAFE_warning, } from "./history"; |
import type { History, Location, Path, To } from "./history"; | ||
import { Action as HistoryAction } from "./history"; | ||
import type { AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticRouteMatch, AgnosticRouteObject, FormEncType, FormMethod, MiddlewareContext, RouteData } from "./utils"; | ||
import { DeferredData } from "./utils"; | ||
import type { DeferredData, AgnosticDataRouteMatch, AgnosticDataRouteObject, FormEncType, FormMethod, DetectErrorBoundaryFunction, RouteData, AgnosticRouteObject, AgnosticRouteMatch, V7_FormMethod, HTMLFormMethod, MapRoutePropertiesFunction } from "./utils"; | ||
/** | ||
@@ -73,3 +72,3 @@ * A Router instance manages all navigation and data loading/mutations | ||
*/ | ||
navigate(to: To, opts?: RouterNavigateOptions): Promise<void>; | ||
navigate(to: To | null, opts?: RouterNavigateOptions): Promise<void>; | ||
/** | ||
@@ -86,3 +85,3 @@ * @internal | ||
*/ | ||
fetch(key: string, routeId: string, href: string, opts?: RouterNavigateOptions): void; | ||
fetch(key: string, routeId: string, href: string | null, opts?: RouterNavigateOptions): void; | ||
/** | ||
@@ -156,2 +155,10 @@ * @internal | ||
* | ||
* HMR needs to pass in-flight route updates to React Router | ||
* TODO: Replace this with granular route update APIs (addRoute, updateRoute, deleteRoute) | ||
*/ | ||
_internalSetRoutes(routes: AgnosticRouteObject[]): void; | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Internal fetch AbortControllers accessed by unit tests | ||
@@ -235,6 +242,7 @@ */ | ||
/** | ||
* Future flags to toggle on new feature behavior | ||
* Future flags to toggle new feature behavior | ||
*/ | ||
export interface FutureConfig { | ||
unstable_middleware: boolean; | ||
v7_normalizeFormMethod: boolean; | ||
v7_prependBasename: boolean; | ||
} | ||
@@ -245,7 +253,13 @@ /** | ||
export interface RouterInit { | ||
basename?: string; | ||
routes: AgnosticRouteObject[]; | ||
history: History; | ||
basename?: string; | ||
/** | ||
* @deprecated Use `mapRouteProperties` instead | ||
*/ | ||
detectErrorBoundary?: DetectErrorBoundaryFunction; | ||
mapRouteProperties?: MapRoutePropertiesFunction; | ||
future?: Partial<FutureConfig>; | ||
hydrationData?: HydrationState; | ||
future?: FutureConfig; | ||
window?: Window; | ||
} | ||
@@ -268,9 +282,2 @@ /** | ||
} | ||
interface StaticHandlerQueryOpts { | ||
requestContext?: unknown; | ||
middlewareContext?: MiddlewareContext; | ||
} | ||
interface StaticHandlerQueryRouteOpts extends StaticHandlerQueryOpts { | ||
routeId?: string; | ||
} | ||
/** | ||
@@ -281,4 +288,9 @@ * A StaticHandler instance manages a singular SSR navigation/fetch event | ||
dataRoutes: AgnosticDataRouteObject[]; | ||
query(request: Request, opts?: StaticHandlerQueryOpts): Promise<StaticHandlerContext | Response>; | ||
queryRoute(request: Request, opts?: StaticHandlerQueryRouteOpts): Promise<any>; | ||
query(request: Request, opts?: { | ||
requestContext?: unknown; | ||
}): Promise<StaticHandlerContext | Response>; | ||
queryRoute(request: Request, opts?: { | ||
routeId?: string; | ||
requestContext?: unknown; | ||
}): Promise<any>; | ||
} | ||
@@ -311,18 +323,19 @@ /** | ||
} | ||
/** | ||
* Options for a navigate() call for a Link navigation | ||
*/ | ||
declare type LinkNavigateOptions = { | ||
export declare type RelativeRoutingType = "route" | "path"; | ||
declare type BaseNavigateOptions = { | ||
replace?: boolean; | ||
state?: any; | ||
preventScrollReset?: boolean; | ||
relative?: RelativeRoutingType; | ||
fromRouteId?: string; | ||
}; | ||
/** | ||
* Options for a navigate() call for a Link navigation | ||
*/ | ||
declare type LinkNavigateOptions = BaseNavigateOptions; | ||
/** | ||
* Options for a navigate() call for a Form navigation | ||
*/ | ||
declare type SubmissionNavigateOptions = { | ||
replace?: boolean; | ||
state?: any; | ||
preventScrollReset?: boolean; | ||
formMethod?: FormMethod; | ||
declare type SubmissionNavigateOptions = BaseNavigateOptions & { | ||
formMethod?: HTMLFormMethod; | ||
formEncType?: FormEncType; | ||
@@ -354,3 +367,3 @@ formData: FormData; | ||
location: Location; | ||
formMethod: FormMethod | undefined; | ||
formMethod: FormMethod | V7_FormMethod | undefined; | ||
formAction: string | undefined; | ||
@@ -363,3 +376,3 @@ formEncType: FormEncType | undefined; | ||
location: Location; | ||
formMethod: FormMethod; | ||
formMethod: FormMethod | V7_FormMethod; | ||
formAction: string; | ||
@@ -383,7 +396,6 @@ formEncType: FormEncType; | ||
data: TData | undefined; | ||
" _hasFetcherDoneAnything "?: boolean; | ||
}; | ||
Loading: { | ||
state: "loading"; | ||
formMethod: FormMethod | undefined; | ||
formMethod: FormMethod | V7_FormMethod | undefined; | ||
formAction: string | undefined; | ||
@@ -393,7 +405,6 @@ formEncType: FormEncType | undefined; | ||
data: TData | undefined; | ||
" _hasFetcherDoneAnything "?: boolean; | ||
}; | ||
Submitting: { | ||
state: "submitting"; | ||
formMethod: FormMethod; | ||
formMethod: FormMethod | V7_FormMethod; | ||
formAction: string; | ||
@@ -403,3 +414,2 @@ formEncType: FormEncType; | ||
data: TData | undefined; | ||
" _hasFetcherDoneAnything "?: boolean; | ||
}; | ||
@@ -440,7 +450,11 @@ }; | ||
export declare const UNSAFE_DEFERRED_SYMBOL: unique symbol; | ||
export interface StaticHandlerInit { | ||
export interface CreateStaticHandlerOptions { | ||
basename?: string; | ||
future?: FutureConfig; | ||
/** | ||
* @deprecated Use `mapRouteProperties` instead | ||
*/ | ||
detectErrorBoundary?: DetectErrorBoundaryFunction; | ||
mapRouteProperties?: MapRoutePropertiesFunction; | ||
} | ||
export declare function createStaticHandler(routes: AgnosticRouteObject[], init?: StaticHandlerInit): StaticHandler; | ||
export declare function createStaticHandler(routes: AgnosticRouteObject[], opts?: CreateStaticHandlerOptions): StaticHandler; | ||
/** | ||
@@ -451,2 +465,3 @@ * Given an existing StaticHandlerContext and an error thrown at render time, | ||
export declare function getStaticContextFromError(routes: AgnosticDataRouteObject[], context: StaticHandlerContext, error: any): StaticHandlerContext; | ||
export declare function isDeferredData(value: any): value is DeferredData; | ||
export {}; |
/** | ||
* @remix-run/router v0.0.0-experimental-48058118 | ||
* @remix-run/router v0.0.0-experimental-5f08b33f | ||
* | ||
@@ -11,3 +11,3 @@ * Copyright (c) Remix Software Inc. | ||
*/ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).RemixRouter={})}(this,(function(e){"use strict";function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var a in r)Object.prototype.hasOwnProperty.call(r,a)&&(e[a]=r[a])}return e},t.apply(this,arguments)}var r;e.Action=void 0,(r=e.Action||(e.Action={})).Pop="POP",r.Push="PUSH",r.Replace="REPLACE";const a="popstate";function n(e,t){if(!1===e||null==e)throw new Error(t)}function o(e,t){if(!e){"undefined"!=typeof console&&console.warn(t);try{throw new Error(t)}catch(e){}}}function i(e,t){return{usr:e.state,key:e.key,idx:t}}function s(e,r,a,n){return void 0===a&&(a=null),t({pathname:"string"==typeof e?e:e.pathname,search:"",hash:""},"string"==typeof r?c(r):r,{state:a,key:r&&r.key||n||Math.random().toString(36).substr(2,8)})}function l(e){let{pathname:t="/",search:r="",hash:a=""}=e;return r&&"?"!==r&&(t+="?"===r.charAt(0)?r:"?"+r),a&&"#"!==a&&(t+="#"===a.charAt(0)?a:"#"+a),t}function c(e){let t={};if(e){let r=e.indexOf("#");r>=0&&(t.hash=e.substr(r),e=e.substr(0,r));let a=e.indexOf("?");a>=0&&(t.search=e.substr(a),e=e.substr(0,a)),e&&(t.pathname=e)}return t}function d(r,o,c,d){void 0===d&&(d={});let{window:u=document.defaultView,v5Compat:h=!1}=d,f=u.history,p=e.Action.Pop,m=null,g=v();function v(){return(f.state||{idx:null}).idx}function y(){p=e.Action.Pop;let t=v(),r=null==t?null:t-g;g=t,m&&m({action:p,location:b.location,delta:r})}function w(e){let t="null"!==u.location.origin?u.location.origin:u.location.href,r="string"==typeof e?e:l(e);return n(t,"No window.location.(origin|href) available to create URL for href: "+r),new URL(r,t)}null==g&&(g=0,f.replaceState(t({},f.state,{idx:g}),""));let b={get action(){return p},get location(){return r(u,f)},listen(e){if(m)throw new Error("A history only accepts one active listener");return u.addEventListener(a,y),m=e,()=>{u.removeEventListener(a,y),m=null}},createHref:e=>o(u,e),createURL:w,encodeLocation(e){let t=w(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:function(t,r){p=e.Action.Push;let a=s(b.location,t,r);c&&c(a,t),g=v()+1;let n=i(a,g),o=b.createHref(a);try{f.pushState(n,"",o)}catch(e){u.location.assign(o)}h&&m&&m({action:p,location:b.location,delta:1})},replace:function(t,r){p=e.Action.Replace;let a=s(b.location,t,r);c&&c(a,t),g=v();let n=i(a,g),o=b.createHref(a);f.replaceState(n,"",o),h&&m&&m({action:p,location:b.location,delta:0})},go:e=>f.go(e)};return b}let u;function h(e,r,a){return void 0===r&&(r=[]),void 0===a&&(a=new Set),e.map(((e,o)=>{let i=[...r,o],s="string"==typeof e.id?e.id:i.join("-");if(n(!0!==e.index||!e.children,"Cannot specify children on an index route"),n(!a.has(s),'Found a route id collision on id "'+s+"\". Route id's must be globally unique within Data Router usages"),a.add(s),function(e){return!0===e.index}(e)){return t({},e,{id:s})}return t({},e,{id:s,children:e.children?h(e.children,i,a):void 0})}))}function f(e,t,r){void 0===r&&(r="/");let a=A(("string"==typeof t?c(t):t).pathname||"/",r);if(null==a)return null;let n=p(e);!function(e){e.sort(((e,t)=>e.score!==t.score?t.score-e.score:function(e,t){return e.length===t.length&&e.slice(0,-1).every(((e,r)=>e===t[r]))?e[e.length-1]-t[t.length-1]:0}(e.routesMeta.map((e=>e.childrenIndex)),t.routesMeta.map((e=>e.childrenIndex)))))}(n);let o=null;for(let e=0;null==o&&e<n.length;++e)o=w(n[e],D(a));return o}function p(e,t,r,a){void 0===t&&(t=[]),void 0===r&&(r=[]),void 0===a&&(a="");let o=(e,o,i)=>{let s={relativePath:void 0===i?e.path||"":i,caseSensitive:!0===e.caseSensitive,childrenIndex:o,route:e};s.relativePath.startsWith("/")&&(n(s.relativePath.startsWith(a),'Absolute route path "'+s.relativePath+'" nested under path "'+a+'" is not valid. An absolute child route path must start with the combined path of all its parent routes.'),s.relativePath=s.relativePath.slice(a.length));let l=x([a,s.relativePath]),c=r.concat(s);e.children&&e.children.length>0&&(n(!0!==e.index,'Index routes must not have child routes. Please remove all child routes from route path "'+l+'".'),p(e.children,t,c,l)),(null!=e.path||e.index)&&t.push({path:l,score:y(l,e.index),routesMeta:c})};return e.forEach(((e,t)=>{var r;if(""!==e.path&&null!=(r=e.path)&&r.includes("?"))for(let r of m(e.path))o(e,t,r);else o(e,t)})),t}function m(e){let t=e.split("/");if(0===t.length)return[];let[r,...a]=t,n=r.endsWith("?"),o=r.replace(/\?$/,"");if(0===a.length)return n?[o,""]:[o];let i=m(a.join("/")),s=[];return s.push(...i.map((e=>""===e?o:[o,e].join("/")))),n&&s.push(...i),s.map((t=>e.startsWith("/")&&""===t?"/":t))}!function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"}(u||(u={}));const g=/^:\w+$/,v=e=>"*"===e;function y(e,t){let r=e.split("/"),a=r.length;return r.some(v)&&(a+=-2),t&&(a+=2),r.filter((e=>!v(e))).reduce(((e,t)=>e+(g.test(t)?3:""===t?1:10)),a)}function w(e,t){let{routesMeta:r}=e,a={},n="/",o=[];for(let e=0;e<r.length;++e){let i=r[e],s=e===r.length-1,l="/"===n?t:t.slice(n.length)||"/",c=b({path:i.relativePath,caseSensitive:i.caseSensitive,end:s},l);if(!c)return null;Object.assign(a,c.params);let d=i.route;o.push({params:a,pathname:x([n,c.pathname]),pathnameBase:L(x([n,c.pathnameBase])),route:d}),"/"!==c.pathnameBase&&(n=x([n,c.pathnameBase]))}return o}function b(e,t){"string"==typeof e&&(e={path:e,caseSensitive:!1,end:!0});let[r,a]=function(e,t,r){void 0===t&&(t=!1);void 0===r&&(r=!0);R("*"===e||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were "'+e.replace(/\*$/,"/*")+'" because the `*` character must always follow a `/` in the pattern. To get rid of this warning, please change the route path to "'+e.replace(/\*$/,"/*")+'".');let a=[],n="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^$?{}|()[\]]/g,"\\$&").replace(/\/:(\w+)/g,((e,t)=>(a.push(t),"/([^\\/]+)")));e.endsWith("*")?(a.push("*"),n+="*"===e||"/*"===e?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?n+="\\/*$":""!==e&&"/"!==e&&(n+="(?:(?=\\/|$))");return[new RegExp(n,t?void 0:"i"),a]}(e.path,e.caseSensitive,e.end),n=t.match(r);if(!n)return null;let o=n[0],i=o.replace(/(.)\/+$/,"$1"),s=n.slice(1);return{params:a.reduce(((e,t,r)=>{if("*"===t){let e=s[r]||"";i=o.slice(0,o.length-e.length).replace(/(.)\/+$/,"$1")}return e[t]=function(e,t){try{return decodeURIComponent(e)}catch(r){return R(!1,'The value for the URL param "'+t+'" will not be decoded because the string "'+e+'" is a malformed URL segment. This is probably due to a bad percent encoding ('+r+")."),e}}(s[r]||"",t),e}),{}),pathname:o,pathnameBase:i,pattern:e}}function D(e){try{return decodeURI(e)}catch(t){return R(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent encoding ('+t+")."),e}}function A(e,t){if("/"===t)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let r=t.endsWith("/")?t.length-1:t.length,a=e.charAt(r);return a&&"/"!==a?null:e.slice(r)||"/"}function R(e,t){if(!e){"undefined"!=typeof console&&console.warn(t);try{throw new Error(t)}catch(e){}}}function E(e,t){void 0===t&&(t="/");let{pathname:r,search:a="",hash:n=""}="string"==typeof e?c(e):e,o=r?r.startsWith("/")?r:function(e,t){let r=t.replace(/\/+$/,"").split("/");return e.split("/").forEach((e=>{".."===e?r.length>1&&r.pop():"."!==e&&r.push(e)})),r.length>1?r.join("/"):"/"}(r,t):t;return{pathname:o,search:k(a),hash:C(n)}}function M(e,t,r,a){return"Cannot include a '"+e+"' character in a manually specified `to."+t+"` field ["+JSON.stringify(a)+"]. Please separate it out to the `to."+r+'` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.'}function P(e){return e.filter(((e,t)=>0===t||e.route.path&&e.route.path.length>0))}function S(e,r,a,o){let i;void 0===o&&(o=!1),"string"==typeof e?i=c(e):(i=t({},e),n(!i.pathname||!i.pathname.includes("?"),M("?","pathname","search",i)),n(!i.pathname||!i.pathname.includes("#"),M("#","pathname","hash",i)),n(!i.search||!i.search.includes("#"),M("#","search","hash",i)));let s,l=""===e||""===i.pathname,d=l?"/":i.pathname;if(o||null==d)s=a;else{let e=r.length-1;if(d.startsWith("..")){let t=d.split("/");for(;".."===t[0];)t.shift(),e-=1;i.pathname=t.join("/")}s=e>=0?r[e]:"/"}let u=E(i,s),h=d&&"/"!==d&&d.endsWith("/"),f=(l||"."===d)&&a.endsWith("/");return u.pathname.endsWith("/")||!h&&!f||(u.pathname+="/"),u}const x=e=>e.join("/").replace(/\/\/+/g,"/"),L=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),k=e=>e&&"?"!==e?e.startsWith("?")?e:"?"+e:"",C=e=>e&&"#"!==e?e.startsWith("#")?e:"#"+e:"";class U extends Error{}class _{constructor(e,t){let r;this.pendingKeysSet=new Set,this.subscribers=new Set,this.deferredKeys=[],n(e&&"object"==typeof e&&!Array.isArray(e),"defer() only accepts plain objects"),this.abortPromise=new Promise(((e,t)=>r=t)),this.controller=new AbortController;let a=()=>r(new U("Deferred data aborted"));this.unlistenAbortSignal=()=>this.controller.signal.removeEventListener("abort",a),this.controller.signal.addEventListener("abort",a),this.data=Object.entries(e).reduce(((e,t)=>{let[r,a]=t;return Object.assign(e,{[r]:this.trackPromise(r,a)})}),{}),this.done&&this.unlistenAbortSignal(),this.init=t}trackPromise(e,t){if(!(t instanceof Promise))return t;this.deferredKeys.push(e),this.pendingKeysSet.add(e);let r=Promise.race([t,this.abortPromise]).then((t=>this.onSettle(r,e,null,t)),(t=>this.onSettle(r,e,t)));return r.catch((()=>{})),Object.defineProperty(r,"_tracked",{get:()=>!0}),r}onSettle(e,t,r,a){return this.controller.signal.aborted&&r instanceof U?(this.unlistenAbortSignal(),Object.defineProperty(e,"_error",{get:()=>r}),Promise.reject(r)):(this.pendingKeysSet.delete(t),this.done&&this.unlistenAbortSignal(),r?(Object.defineProperty(e,"_error",{get:()=>r}),this.emit(!1,t),Promise.reject(r)):(Object.defineProperty(e,"_data",{get:()=>a}),this.emit(!1,t),a))}emit(e,t){this.subscribers.forEach((r=>r(e,t)))}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}cancel(){this.controller.abort(),this.pendingKeysSet.forEach(((e,t)=>this.pendingKeysSet.delete(t))),this.emit(!0)}async resolveData(e){let t=!1;if(!this.done){let r=()=>this.cancel();e.addEventListener("abort",r),t=await new Promise((t=>{this.subscribe((a=>{e.removeEventListener("abort",r),(a||this.done)&&t(a)}))}))}return t}get done(){return 0===this.pendingKeysSet.size}get unwrappedData(){return n(null!==this.data&&this.done,"Can only unwrap data on initialized and settled deferreds"),Object.entries(this.data).reduce(((e,t)=>{let[r,a]=t;return Object.assign(e,{[r]:T(a)})}),{})}get pendingKeys(){return Array.from(this.pendingKeysSet)}}function T(e){if(!function(e){return e instanceof Promise&&!0===e._tracked}(e))return e;if(e._error)throw e._error;return e._data}class j{constructor(e,t,r,a){void 0===a&&(a=!1),this.status=e,this.statusText=t||"",this.internal=a,r instanceof Error?(this.data=r.toString(),this.error=r):this.data=r}}function O(e){return null!=e&&"number"==typeof e.status&&"string"==typeof e.statusText&&"boolean"==typeof e.internal&&"data"in e}class F{constructor(e){void 0!==e&&(this.defaultValue=e)}getDefaultValue(){if(void 0===this.defaultValue)throw new Error("Unable to find a value in the middleware context");return this.defaultValue}}function H(e){let t=new Map(null==e?void 0:e.entries());return{get:e=>t.has(e)?t.get(e):e.getDefaultValue(),set(e,r){if(void 0===r)throw new Error("You cannot set an undefined value in the middleware context");t.set(e,r)},next:()=>{},entries:()=>t.entries()}}const I={unstable_middleware:!1},q=["post","put","patch","delete"],W=new Set(q),$=["get",...q],N=new Set($),B=new Set([301,302,303,307,308]),z=new Set([307,308]),K={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},Y={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},V={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},J=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,G="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,X=!G;const Q=Symbol("deferred");function Z(e,t,r){void 0===r&&(r=!1);let a,n="string"==typeof e?e:l(e);if(!t||!function(e){return null!=e&&"formData"in e}(t))return{path:n};if(t.formMethod&&!Re(t.formMethod))return{path:n,error:me(405,{method:t.formMethod})};if(t.formData&&(a={formMethod:t.formMethod||"get",formAction:ve(n),formEncType:t&&t.formEncType||"application/x-www-form-urlencoded",formData:t.formData},Ee(a.formMethod)))return{path:n,submission:a};let o=c(n),i=ce(t.formData);return r&&o.search&&Se(o.search)&&i.append("index",""),o.search="?"+i,{path:l(o),submission:a}}function ee(e,t){let r=e;if(t){let a=e.findIndex((e=>e.route.id===t));a>=0&&(r=e.slice(0,a))}return r}function te(e,r,a,n,o,i,s,l,c,d,u){let h=d?Object.values(d)[0]:c?Object.values(c)[0]:void 0,f=e.createURL(r.location),p=e.createURL(o),m=i||f.toString()===p.toString()||f.search!==p.search,g=d?Object.keys(d)[0]:void 0,v=ee(a,g).filter(((e,a)=>{if(null==e.route.loader)return!1;if(function(e,t,r){let a=!t||r.route.id!==t.route.id,n=void 0===e[r.route.id];return a||n}(r.loaderData,r.matches[a],e)||s.some((t=>t===e.route.id)))return!0;let o=r.matches[a],i=e;return ae(e,t({currentUrl:f,currentParams:o.params,nextUrl:p,nextParams:i.params},n,{actionResult:h,defaultShouldRevalidate:m||re(o,i)}))})),y=[];return u&&u.forEach(((e,o)=>{if(a.some((t=>t.route.id===e.routeId)))if(l.includes(o))y.push(t({key:o},e));else{ae(e.match,t({currentUrl:f,currentParams:r.matches[r.matches.length-1].params,nextUrl:p,nextParams:a[a.length-1].params},n,{actionResult:h,defaultShouldRevalidate:m}))&&y.push(t({key:o},e))}})),[v,y]}function re(e,t){let r=e.route.path;return e.pathname!==t.pathname||null!=r&&r.endsWith("*")&&e.params["*"]!==t.params["*"]}function ae(e,t){if(e.route.shouldRevalidate){let r=e.route.shouldRevalidate(t);if("boolean"==typeof r)return r}return t.defaultShouldRevalidate}async function ne(e,t,r,a,n){if(e.signal.aborted)throw new Error("Request aborted");if(0===t.length)return a.next=()=>{throw new Error("You may only call `next()` once per middleware and you may not call it in an action or loader")},n({request:e,params:r,context:a});let o=!1,i=()=>(o=!0,ne(e,t.slice(1),r,a,n));if(!t[0].route.middleware)return i();a.next=i;let s=await t[0].route.middleware({request:e,params:r,context:a});return o?s:i()}function oe(){throw new Error("Middleware must be enabled via the `future.unstable_middleware` flag)")}const ie={get:oe,set:oe,next:oe};async function se(e,t,r,a,o,i,s,c,d,h){let f,p,m;void 0===o&&(o="/"),void 0===s&&(s=!1),void 0===c&&(c=!1);let g=new Promise(((e,t)=>m=t)),v=()=>m();t.signal.addEventListener("abort",v);try{let o=r.route[e];n(o,"Could not find the "+e+' to run on the "'+r.route.id+'" route');let s,l=a.findIndex((e=>e.route.id===r.route.id));s=i?ne(t,a.slice(0,l+1),a[0].params,H(h),o):o({request:t,params:r.params,context:d||ie}),p=await Promise.race([s,g]),n(void 0!==p,"You defined "+("action"===e?"an action":"a loader")+' for route "'+r.route.id+"\" but didn't return anything from your `"+e+"` function. Please return a value or `null`.")}catch(e){f=u.error,p=e}finally{t.signal.removeEventListener("abort",v)}if(De(p)){let e,i=p.status;if(B.has(i)){let e=p.headers.get("Location");if(n(e,"Redirects returned/thrown from loaders/actions must have a Location header"),J.test(e)){if(!s){let r=new URL(t.url),a=e.startsWith("//")?new URL(r.protocol+e):new URL(e);a.origin===r.origin&&(e=a.pathname+a.search+a.hash)}}else{let i=S(e,P(a.slice(0,a.indexOf(r)+1)).map((e=>e.pathnameBase)),new URL(t.url).pathname);if(n(l(i),"Unable to resolve redirect location: "+e),o){let e=i.pathname;i.pathname="/"===e?o:x([o,e])}e=l(i)}if(s)throw p.headers.set("Location",e),p;return{type:u.redirect,status:i,location:e,revalidate:null!==p.headers.get("X-Remix-Revalidate")}}if(c)throw{type:f||u.data,response:p};let d=p.headers.get("Content-Type");return e=d&&/\bapplication\/json\b/.test(d)?await p.json():await p.text(),f===u.error?{type:f,error:new j(i,p.statusText,e),headers:p.headers}:{type:u.data,data:e,statusCode:p.status,headers:p.headers}}return f===u.error?{type:f,error:p}:p instanceof _?{type:u.deferred,deferredData:p}:{type:u.data,data:p}}function le(e,t,r,a){let n=e.createURL(ve(t)).toString(),o={signal:r};if(a&&Ee(a.formMethod)){let{formMethod:e,formEncType:t,formData:r}=a;o.method=e.toUpperCase(),o.body="application/x-www-form-urlencoded"===t?ce(r):r}return new Request(n,o)}function ce(e){let t=new URLSearchParams;for(let[r,a]of e.entries())t.append(r,a instanceof File?a.name:a);return t}function de(e,t,r,a,o){let i,s={},l=null,c=!1,d={};return r.forEach(((r,u)=>{let h=t[u].route.id;if(n(!be(r),"Cannot handle redirect results in processLoaderData"),we(r)){let t=fe(e,h),n=r.error;a&&(n=Object.values(a)[0],a=void 0),l=l||{},null==l[t.route.id]&&(l[t.route.id]=n),s[h]=void 0,c||(c=!0,i=O(r.error)?r.error.status:500),r.headers&&(d[h]=r.headers)}else ye(r)?(o.set(h,r.deferredData),s[h]=r.deferredData.data):s[h]=r.data,null==r.statusCode||200===r.statusCode||c||(i=r.statusCode),r.headers&&(d[h]=r.headers)})),a&&(l=a,s[Object.keys(a)[0]]=void 0),{loaderData:s,errors:l,statusCode:i||200,loaderHeaders:d}}function ue(e,r,a,o,i,s,l,c){let{loaderData:d,errors:u}=de(r,a,o,i,c);for(let r=0;r<s.length;r++){let{key:a,match:o}=s[r];n(void 0!==l&&void 0!==l[r],"Did not find corresponding fetcher result");let i=l[r];if(we(i)){let r=fe(e.matches,o.route.id);u&&u[r.route.id]||(u=t({},u,{[r.route.id]:i.error})),e.fetchers.delete(a)}else if(be(i))n(!1,"Unhandled fetcher revalidation redirect");else if(ye(i))n(!1,"Unhandled fetcher deferred data");else{let t={state:"idle",data:i.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};e.fetchers.set(a,t)}}return{loaderData:d,errors:u}}function he(e,r,a,n){let o=t({},r);for(let t of a){let a=t.route.id;if(r.hasOwnProperty(a)?void 0!==r[a]&&(o[a]=r[a]):void 0!==e[a]&&(o[a]=e[a]),n&&n.hasOwnProperty(a))break}return o}function fe(e,t){return(t?e.slice(0,e.findIndex((e=>e.route.id===t))+1):[...e]).reverse().find((e=>!0===e.route.hasErrorBoundary))||e[0]}function pe(e){let t=e.find((e=>e.index||!e.path||"/"===e.path))||{id:"__shim-error-route__"};return{matches:[{params:{},pathname:"",pathnameBase:"",route:t}],route:t}}function me(e,t){let{pathname:r,routeId:a,method:n,type:o}=void 0===t?{}:t,i="Unknown Server Error",s="Unknown @remix-run/router error";return 400===e?(i="Bad Request",n&&r&&a?s="You made a "+n+' request to "'+r+'" but did not provide a `loader` for route "'+a+'", so there is no way to handle the request.':"defer-action"===o&&(s="defer() is not supported in actions")):403===e?(i="Forbidden",s='Route "'+a+'" does not match URL "'+r+'"'):404===e?(i="Not Found",s='No route matches URL "'+r+'"'):405===e&&(i="Method Not Allowed",n&&r&&a?s="You made a "+n.toUpperCase()+' request to "'+r+'" but did not provide an `action` for route "'+a+'", so there is no way to handle the request.':n&&(s='Invalid request method "'+n.toUpperCase()+'"')),new j(e||500,i,new Error(s),!0)}function ge(e){for(let t=e.length-1;t>=0;t--){let r=e[t];if(be(r))return r}}function ve(e){return l(t({},"string"==typeof e?c(e):e,{hash:""}))}function ye(e){return e.type===u.deferred}function we(e){return e.type===u.error}function be(e){return(e&&e.type)===u.redirect}function De(e){return null!=e&&"number"==typeof e.status&&"string"==typeof e.statusText&&"object"==typeof e.headers&&void 0!==e.body}function Ae(e){if(!De(e))return!1;let t=e.status,r=e.headers.get("Location");return t>=300&&t<=399&&null!=r}function Re(e){return N.has(e)}function Ee(e){return W.has(e)}async function Me(e,t,r,a,n,o){for(let i=0;i<r.length;i++){let s=r[i],l=t[i],c=e.find((e=>e.route.id===l.route.id)),d=null!=c&&!re(c,l)&&void 0!==(o&&o[l.route.id]);ye(s)&&(n||d)&&await Pe(s,a,n).then((e=>{e&&(r[i]=e||r[i])}))}}async function Pe(e,t,r){if(void 0===r&&(r=!1),!await e.deferredData.resolveData(t)){if(r)try{return{type:u.data,data:e.deferredData.unwrappedData}}catch(e){return{type:u.error,error:e}}return{type:u.data,data:e.deferredData.data}}}function Se(e){return new URLSearchParams(e).getAll("index").some((e=>""===e))}function xe(e,t){let{route:r,pathname:a,params:n}=e;return{id:r.id,pathname:a,params:n,data:t[r.id],handle:r.handle}}function Le(e,t){let r="string"==typeof t?c(t).search:t.search;if(e[e.length-1].route.index&&Se(r||""))return e[e.length-1];let a=P(e);return a[a.length-1]}e.AbortedDeferredError=U,e.ErrorResponse=j,e.IDLE_BLOCKER=V,e.IDLE_FETCHER=Y,e.IDLE_NAVIGATION=K,e.UNSAFE_DEFERRED_SYMBOL=Q,e.UNSAFE_DeferredData=_,e.UNSAFE_convertRoutesToDataRoutes=h,e.UNSAFE_createMiddlewareStore=H,e.UNSAFE_getPathContributingMatches=P,e.createBrowserHistory=function(e){return void 0===e&&(e={}),d((function(e,t){let{pathname:r,search:a,hash:n}=e.location;return s("",{pathname:r,search:a,hash:n},t.state&&t.state.usr||null,t.state&&t.state.key||"default")}),(function(e,t){return"string"==typeof t?t:l(t)}),null,e)},e.createHashHistory=function(e){return void 0===e&&(e={}),d((function(e,t){let{pathname:r="/",search:a="",hash:n=""}=c(e.location.hash.substr(1));return s("",{pathname:r,search:a,hash:n},t.state&&t.state.usr||null,t.state&&t.state.key||"default")}),(function(e,t){let r=e.document.querySelector("base"),a="";if(r&&r.getAttribute("href")){let t=e.location.href,r=t.indexOf("#");a=-1===r?t:t.slice(0,r)}return a+"#"+("string"==typeof t?t:l(t))}),(function(e,t){o("/"===e.pathname.charAt(0),"relative pathnames are not supported in hash history.push("+JSON.stringify(t)+")")}),e)},e.createMemoryHistory=function(t){void 0===t&&(t={});let r,{initialEntries:a=["/"],initialIndex:n,v5Compat:i=!1}=t;r=a.map(((e,t)=>m(e,"string"==typeof e?null:e.state,0===t?"default":void 0)));let d=f(null==n?r.length-1:n),u=e.Action.Pop,h=null;function f(e){return Math.min(Math.max(e,0),r.length-1)}function p(){return r[d]}function m(e,t,a){void 0===t&&(t=null);let n=s(r?p().pathname:"/",e,t,a);return o("/"===n.pathname.charAt(0),"relative pathnames are not supported in memory history: "+JSON.stringify(e)),n}function g(e){return"string"==typeof e?e:l(e)}return{get index(){return d},get action(){return u},get location(){return p()},createHref:g,createURL:e=>new URL(g(e),"http://localhost"),encodeLocation(e){let t="string"==typeof e?c(e):e;return{pathname:t.pathname||"",search:t.search||"",hash:t.hash||""}},push(t,a){u=e.Action.Push;let n=m(t,a);d+=1,r.splice(d,r.length,n),i&&h&&h({action:u,location:n,delta:1})},replace(t,a){u=e.Action.Replace;let n=m(t,a);r[d]=n,i&&h&&h({action:u,location:n,delta:0})},go(t){u=e.Action.Pop;let a=f(d+t),n=r[a];d=a,h&&h({action:u,location:n,delta:t})},listen:e=>(h=e,()=>{h=null})}},e.createMiddlewareContext=function(e){return new F(e)},e.createPath=l,e.createRouter=function(r){n(r.routes.length>0,"You must provide a non-empty routes array to createRouter");let a=h(r.routes),o=t({},I,r.future),i=null,l=new Set,c=null,d=null,p=null,m=null!=r.hydrationData,g=f(a,r.history.location,r.basename),v=null;if(null==g){let e=me(404,{pathname:r.history.location.pathname}),{matches:t,route:n}=pe(a);g=t,v={[n.id]:e}}let y,w,b=!g.some((e=>e.route.loader))||null!=r.hydrationData,D={historyAction:r.history.action,location:r.history.location,matches:g,initialized:b,navigation:K,restoreScrollPosition:null==r.hydrationData&&null,preventScrollReset:!1,revalidation:"idle",loaderData:r.hydrationData&&r.hydrationData.loaderData||{},actionData:r.hydrationData&&r.hydrationData.actionData||null,errors:r.hydrationData&&r.hydrationData.errors||v,fetchers:new Map,blockers:new Map},A=e.Action.Pop,E=!1,M=!1,P=!1,S=[],x=[],L=new Map,k=0,C=-1,U=new Map,_=new Set,T=new Map,j=new Map,O=new Map,F=!1;function H(e){D=t({},D,e),l.forEach((e=>e(D)))}function q(a,n){var o,i;let s,l=null!=D.actionData&&null!=D.navigation.formMethod&&Ee(D.navigation.formMethod)&&"loading"===D.navigation.state&&!0!==(null==(o=a.state)?void 0:o._isRedirect);s=n.actionData?Object.keys(n.actionData).length>0?n.actionData:null:l?D.actionData:null;let c=n.loaderData?he(D.loaderData,n.loaderData,n.matches||[],n.errors):D.loaderData;for(let[e]of O)ie(e);let d=!0===E||null!=D.navigation.formMethod&&Ee(D.navigation.formMethod)&&!0!==(null==(i=a.state)?void 0:i._isRedirect);H(t({},n,{actionData:s,loaderData:c,historyAction:A,location:a,initialized:!0,navigation:K,revalidation:"idle",restoreScrollPosition:De(a,n.matches||D.matches),preventScrollReset:d,blockers:new Map(D.blockers)})),M||A===e.Action.Pop||(A===e.Action.Push?r.history.push(a,a.state):A===e.Action.Replace&&r.history.replace(a,a.state)),A=e.Action.Pop,E=!1,M=!1,P=!1,S=[],x=[]}async function W(i,s,l){w&&w.abort(),w=null,A=i,M=!0===(l&&l.startUninterruptedRevalidation),function(e,t){if(c&&d&&p){let r=t.map((e=>xe(e,D.loaderData))),a=d(e,r)||e.key;c[a]=p()}}(D.location,D.matches),E=!0===(l&&l.preventScrollReset);let h=l&&l.overrideNavigation,m=f(a,s,r.basename);if(!m){let e=me(404,{pathname:s.pathname}),{matches:t,route:r}=pe(a);return ve(),void q(s,{matches:t,loaderData:{},errors:{[r.id]:e}})}if(!(g=D.location,v=s,g.pathname!==v.pathname||g.search!==v.search||g.hash===v.hash||l&&l.submission&&Ee(l.submission.formMethod)))return void q(s,{matches:m});var g,v;w=new AbortController;let b,R,U=le(r.history,s,w.signal,l&&l.submission);if(l&&l.pendingError)R={[fe(m).route.id]:l.pendingError};else if(l&&l.submission&&Ee(l.submission.formMethod)){let r=await async function(r,a,n,i,s){let l;Q(),H({navigation:t({state:"submitting",location:a},n)});let c=Le(i,a);if(c.route.action){if(l=await se("action",r,c,i,y.basename,o.unstable_middleware),r.signal.aborted)return{shortCircuited:!0}}else l={type:u.error,error:me(405,{method:r.method,pathname:a.pathname,routeId:c.route.id})};if(be(l)){let e;return e=s&&null!=s.replace?s.replace:l.location===D.location.pathname+D.location.search,await N(D,l,{submission:n,replace:e}),{shortCircuited:!0}}if(we(l)){let t=fe(i,c.route.id);return!0!==(s&&s.replace)&&(A=e.Action.Push),{pendingActionData:{},pendingActionError:{[t.route.id]:l.error}}}if(ye(l))throw me(400,{type:"defer-action"});return{pendingActionData:{[c.route.id]:l.data}}}(U,s,l.submission,m,{replace:l.replace});if(r.shortCircuited)return;b=r.pendingActionData,R=r.pendingActionError,h=t({state:"loading",location:s},l.submission),U=new Request(U.url,{signal:U.signal})}let{shortCircuited:O,loaderData:F,errors:I}=await async function(e,a,o,i,s,l,c,d){let u=i;if(!u){u=t({state:"loading",location:a,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},s)}let h=s||(u.formMethod&&u.formAction&&u.formData&&u.formEncType?{formMethod:u.formMethod,formAction:u.formAction,formData:u.formData,formEncType:u.formEncType}:void 0),[f,p]=te(r.history,D,o,h,a,P,S,x,c,d,T);if(ve((e=>!(o&&o.some((t=>t.route.id===e)))||f&&f.some((t=>t.route.id===e)))),0===f.length&&0===p.length)return q(a,t({matches:o,loaderData:{},errors:d||null},c?{actionData:c}:{})),{shortCircuited:!0};if(!M){p.forEach((e=>{let t=D.fetchers.get(e.key),r={state:"loading",data:t&&t.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};D.fetchers.set(e.key,r)}));let e=c||D.actionData;H(t({navigation:u},e?0===Object.keys(e).length?{actionData:null}:{actionData:e}:{},p.length>0?{fetchers:new Map(D.fetchers)}:{}))}C=++k,p.forEach((e=>L.set(e.key,w)));let{results:m,loaderResults:g,fetcherResults:v}=await B(D.matches,o,f,p,e);if(e.signal.aborted)return{shortCircuited:!0};p.forEach((e=>L.delete(e.key)));let y=ge(m);if(y)return await N(D,y,{replace:l}),{shortCircuited:!0};let{loaderData:b,errors:A}=ue(D,o,f,g,d,p,v,j);j.forEach(((e,t)=>{e.subscribe((r=>{(r||e.done)&&j.delete(t)}))})),function(){let e=[];for(let t of _){let r=D.fetchers.get(t);n(r,"Expected fetcher: "+t),"loading"===r.state&&(_.delete(t),e.push(t))}ne(e)}();let R=oe(C);return t({loaderData:b,errors:A},R||p.length>0?{fetchers:new Map(D.fetchers)}:{})}(U,s,m,h,l&&l.submission,l&&l.replace,b,R);O||(w=null,q(s,t({matches:m},b?{actionData:b}:{},{loaderData:F,errors:I})))}function $(e){return D.fetchers.get(e)||Y}async function N(a,o,i){var l;let{submission:c,replace:d,isFetchActionRedirect:u}=void 0===i?{}:i;o.revalidate&&(P=!0);let h=s(a.location,o.location,t({_isRedirect:!0},u?{_isFetchActionRedirect:!0}:{}));if(n(h,"Expected a location on the redirect navigation"),J.test(o.location)&&G&&void 0!==(null==(l=window)?void 0:l.location)){let e=r.history.createURL(o.location).origin;if(window.location.origin!==e)return void(d?window.location.replace(o.location):window.location.assign(o.location))}w=null;let f=!0===d?e.Action.Replace:e.Action.Push,{formMethod:p,formAction:m,formEncType:g,formData:v}=a.navigation;!c&&p&&m&&v&&g&&(c={formMethod:p,formAction:m,formEncType:g,formData:v}),z.has(o.status)&&c&&Ee(c.formMethod)?await W(f,h,{submission:t({},c,{formAction:o.location}),preventScrollReset:E}):await W(f,h,{overrideNavigation:{state:"loading",location:h,formMethod:c?c.formMethod:void 0,formAction:c?c.formAction:void 0,formEncType:c?c.formEncType:void 0,formData:c?c.formData:void 0},preventScrollReset:E})}async function B(e,t,a,n,i){let s=await Promise.all([...a.map((e=>se("loader",i,e,t,y.basename,o.unstable_middleware))),...n.map((e=>se("loader",le(r.history,e.path,i.signal),e.match,e.matches,y.basename,o.unstable_middleware)))]),l=s.slice(0,a.length),c=s.slice(a.length);return await Promise.all([Me(e,a,l,i.signal,!1,D.loaderData),Me(e,n.map((e=>e.match)),c,i.signal,!0)]),{results:s,loaderResults:l,fetcherResults:c}}function Q(){P=!0,S.push(...ve()),T.forEach(((e,t)=>{L.has(t)&&(x.push(t),ae(t))}))}function ee(e,t,r){let a=fe(D.matches,t);re(e),H({errors:{[a.route.id]:r},fetchers:new Map(D.fetchers)})}function re(e){L.has(e)&&ae(e),T.delete(e),U.delete(e),_.delete(e),D.fetchers.delete(e)}function ae(e){let t=L.get(e);n(t,"Expected fetch controller: "+e),t.abort(),L.delete(e)}function ne(e){for(let t of e){let e={state:"idle",data:$(t).data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};D.fetchers.set(t,e)}}function oe(e){let t=[];for(let[r,a]of U)if(a<e){let e=D.fetchers.get(r);n(e,"Expected fetcher: "+r),"loading"===e.state&&(ae(r),U.delete(r),t.push(r))}return ne(t),t.length>0}function ie(e){D.blockers.delete(e),O.delete(e)}function ce(e,t){let r=D.blockers.get(e)||V;n("unblocked"===r.state&&"blocked"===t.state||"blocked"===r.state&&"blocked"===t.state||"blocked"===r.state&&"proceeding"===t.state||"blocked"===r.state&&"unblocked"===t.state||"proceeding"===r.state&&"unblocked"===t.state,"Invalid blocker state transition: "+r.state+" -> "+t.state),D.blockers.set(e,t),H({blockers:new Map(D.blockers)})}function de(e){let{currentLocation:t,nextLocation:r,historyAction:a}=e;if(0===O.size)return;O.size>1&&R(!1,"A router only supports one blocker at a time");let n=Array.from(O.entries()),[o,i]=n[n.length-1],s=D.blockers.get(o);return s&&"proceeding"===s.state?void 0:i({currentLocation:t,nextLocation:r,historyAction:a})?o:void 0}function ve(e){let t=[];return j.forEach(((r,a)=>{e&&!e(a)||(r.cancel(),t.push(a),j.delete(a))})),t}function De(e,t){if(c&&d&&p){let r=t.map((e=>xe(e,D.loaderData))),a=d(e,r)||e.key,n=c[a];if("number"==typeof n)return n}return null}return y={get basename(){return r.basename},get state(){return D},get routes(){return a},initialize:function(){return i=r.history.listen((e=>{let{action:t,location:a,delta:n}=e;if(F)return void(F=!1);R(0===O.size||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.");let o=de({currentLocation:D.location,nextLocation:a,historyAction:t});return o&&null!=n?(F=!0,r.history.go(-1*n),void ce(o,{state:"blocked",location:a,proceed(){ce(o,{state:"proceeding",proceed:void 0,reset:void 0,location:a}),r.history.go(n)},reset(){ie(o),H({blockers:new Map(y.state.blockers)})}})):W(t,a)})),D.initialized||W(e.Action.Pop,D.location),y},subscribe:function(e){return l.add(e),()=>l.delete(e)},enableScrollRestoration:function(e,t,r){if(c=e,p=t,d=r||(e=>e.key),!m&&D.navigation===K){m=!0;let e=De(D.location,D.matches);null!=e&&H({restoreScrollPosition:e})}return()=>{c=null,p=null,d=null}},navigate:async function a(n,o){if("number"==typeof n)return void r.history.go(n);let{path:i,submission:l,error:c}=Z(n,o),d=D.location,u=s(D.location,i,o&&o.state);u=t({},u,r.history.encodeLocation(u));let h=o&&null!=o.replace?o.replace:void 0,f=e.Action.Push;!0===h?f=e.Action.Replace:!1===h||null!=l&&Ee(l.formMethod)&&l.formAction===D.location.pathname+D.location.search&&(f=e.Action.Replace);let p=o&&"preventScrollReset"in o?!0===o.preventScrollReset:void 0,m=de({currentLocation:d,nextLocation:u,historyAction:f});if(!m)return await W(f,u,{submission:l,pendingError:c,preventScrollReset:p,replace:o&&o.replace});ce(m,{state:"blocked",location:u,proceed(){ce(m,{state:"proceeding",proceed:void 0,reset:void 0,location:u}),a(n,o)},reset(){ie(m),H({blockers:new Map(D.blockers)})}})},fetch:function(e,i,s,l){if(X)throw new Error("router.fetch() was called during the server render, but it shouldn't be. You are likely calling a useFetcher() method in the body of your component. Try moving it to a useEffect or a callback.");L.has(e)&&ae(e);let c=f(a,s,r.basename);if(!c)return void ee(e,i,me(404,{pathname:s}));let{path:d,submission:u}=Z(s,l,!0),h=Le(c,d);return E=!0===(l&&l.preventScrollReset),u&&Ee(u.formMethod)?async function(e,i,s,l,c,d){if(Q(),T.delete(e),!l.route.action){let t=me(405,{method:d.formMethod,pathname:s,routeId:i});return void ee(e,i,t)}let u=D.fetchers.get(e),h=t({state:"submitting"},d,{data:u&&u.data," _hasFetcherDoneAnything ":!0});D.fetchers.set(e,h),H({fetchers:new Map(D.fetchers)});let p=new AbortController,m=le(r.history,s,p.signal,d);L.set(e,p);let g=await se("action",m,l,c,y.basename,o.unstable_middleware);if(m.signal.aborted)return void(L.get(e)===p&&L.delete(e));if(be(g)){L.delete(e),_.add(e);let r=t({state:"loading"},d,{data:void 0," _hasFetcherDoneAnything ":!0});return D.fetchers.set(e,r),H({fetchers:new Map(D.fetchers)}),N(D,g,{isFetchActionRedirect:!0})}if(we(g))return void ee(e,i,g.error);if(ye(g))throw me(400,{type:"defer-action"});let v=D.navigation.location||D.location,b=le(r.history,v,p.signal),R="idle"!==D.navigation.state?f(a,D.navigation.location,r.basename):D.matches;n(R,"Didn't find any matches after fetcher action");let E=++k;U.set(e,E);let M=t({state:"loading",data:g.data},d,{" _hasFetcherDoneAnything ":!0});D.fetchers.set(e,M);let[O,F]=te(r.history,D,R,d,v,P,S,x,{[l.route.id]:g.data},void 0,T);F.filter((t=>t.key!==e)).forEach((e=>{let t=e.key,r=D.fetchers.get(t),a={state:"loading",data:r&&r.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};D.fetchers.set(t,a),L.set(t,p)})),H({fetchers:new Map(D.fetchers)});let{results:I,loaderResults:W,fetcherResults:$}=await B(D.matches,R,O,F,b);if(p.signal.aborted)return;U.delete(e),L.delete(e),F.forEach((e=>L.delete(e.key)));let z=ge(I);if(z)return N(D,z);let{loaderData:K,errors:Y}=ue(D,D.matches,O,W,void 0,F,$,j),V={state:"idle",data:g.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};D.fetchers.set(e,V);let J=oe(E);"loading"===D.navigation.state&&E>C?(n(A,"Expected pending action"),w&&w.abort(),q(D.navigation.location,{matches:R,loaderData:K,errors:Y,fetchers:new Map(D.fetchers)})):(H(t({errors:Y,loaderData:he(D.loaderData,K,R,Y)},J?{fetchers:new Map(D.fetchers)}:{})),P=!1)}(e,i,d,h,c,u):(T.set(e,{routeId:i,path:d,match:h,matches:c}),async function(e,a,i,s,l,c){let d=D.fetchers.get(e),u=t({state:"loading",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},c,{data:d&&d.data," _hasFetcherDoneAnything ":!0});D.fetchers.set(e,u),H({fetchers:new Map(D.fetchers)});let h=new AbortController,f=le(r.history,i,h.signal);L.set(e,h);let p=await se("loader",f,s,l,y.basename,o.unstable_middleware);ye(p)&&(p=await Pe(p,f.signal,!0)||p);L.get(e)===h&&L.delete(e);if(f.signal.aborted)return;if(be(p))return void await N(D,p);if(we(p)){let t=fe(D.matches,a);return D.fetchers.delete(e),void H({fetchers:new Map(D.fetchers),errors:{[t.route.id]:p.error}})}n(!ye(p),"Unhandled fetcher deferred data");let m={state:"idle",data:p.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0," _hasFetcherDoneAnything ":!0};D.fetchers.set(e,m),H({fetchers:new Map(D.fetchers)})}(e,i,d,h,c,u))},revalidate:function(){Q(),H({revalidation:"loading"}),"submitting"!==D.navigation.state&&("idle"!==D.navigation.state?W(A||D.historyAction,D.navigation.location,{overrideNavigation:D.navigation}):W(D.historyAction,D.location,{startUninterruptedRevalidation:!0}))},createHref:e=>r.history.createHref(e),encodeLocation:e=>r.history.encodeLocation(e),getFetcher:$,deleteFetcher:re,dispose:function(){i&&i(),l.clear(),w&&w.abort(),D.fetchers.forEach(((e,t)=>re(t))),D.blockers.forEach(((e,t)=>ie(t)))},getBlocker:function(e,t){let r=D.blockers.get(e)||V;return O.get(e)!==t&&O.set(e,t),r},deleteBlocker:ie,_internalFetchControllers:L,_internalActiveDeferreds:j},y},e.createStaticHandler=function(e,r){n(e.length>0,"You must provide a non-empty routes array to createStaticHandler");let a=h(e),o=(r?r.basename:null)||"/",i=t({},I,r&&r.future?r.future:null);async function c(e,r,a,s,l,c){n(e.signal,"query()/queryRoute() requests must contain an AbortController signal");try{if(Ee(e.method.toLowerCase())){let n=await async function(e,r,a,n,s,l){let c;if(a.route.action){if(c=await se("action",e,a,r,o,i.unstable_middleware,!0,l,n,s),e.signal.aborted){throw new Error((l?"queryRoute":"query")+"() call aborted")}}else{let t=me(405,{method:e.method,pathname:new URL(e.url).pathname,routeId:a.route.id});if(l)throw t;c={type:u.error,error:t}}if(be(c))throw new Response(null,{status:c.status,headers:{Location:c.location}});if(ye(c)){let e=me(400,{type:"defer-action"});if(l)throw e;c={type:u.error,error:e}}if(l){if(we(c))throw c.error;return{matches:[a],loaderData:{},actionData:{[a.route.id]:c.data},errors:null,statusCode:200,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}if(we(c)){let o=fe(r,a.route.id);return t({},await d(e,r,n,s,void 0,{[o.route.id]:c.error}),{statusCode:O(c.error)?c.error.status:500,actionData:null,actionHeaders:t({},c.headers?{[a.route.id]:c.headers}:{})})}let h=new Request(e.url,{headers:e.headers,redirect:e.redirect,signal:e.signal});return t({},await d(h,r,n,s),c.statusCode?{statusCode:c.statusCode}:{},{actionData:{[a.route.id]:c.data},actionHeaders:t({},c.headers?{[a.route.id]:c.headers}:{})})}(e,a,c||Le(a,r),s,l,null!=c);return n}let n=await d(e,a,s,l,c);return De(n)?n:t({},n,{actionData:null,actionHeaders:{}})}catch(e){if((h=e)&&De(h.response)&&(h.type===u.data||u.error)){if(e.type===u.error&&!Ae(e.response))throw e.response;return e.response}if(Ae(e))return e;throw e}var h}async function d(e,r,a,n,s,l){let c=null!=s;if(c&&(null==s||!s.route.loader))throw me(400,{method:e.method,pathname:new URL(e.url).pathname,routeId:null==s?void 0:s.route.id});let d=(s?[s]:ee(r,Object.keys(l||{})[0])).filter((e=>e.route.loader));if(0===d.length)return{matches:r,loaderData:r.reduce(((e,t)=>Object.assign(e,{[t.route.id]:null})),{}),errors:l||null,statusCode:200,loaderHeaders:{},activeDeferreds:null};let u=await Promise.all([...d.map((t=>se("loader",e,t,r,o,i.unstable_middleware,!0,c,a,n)))]);if(e.signal.aborted){throw new Error((c?"queryRoute":"query")+"() call aborted")}let h=new Map,f=de(r,d,u,l,h),p=new Set(d.map((e=>e.route.id)));return r.forEach((e=>{p.has(e.route.id)||(f.loaderData[e.route.id]=null)})),t({},f,{matches:r,activeDeferreds:h.size>0?Object.fromEntries(h.entries()):null})}return{dataRoutes:a,query:async function(e,r){let{requestContext:n,middlewareContext:i}=void 0===r?{}:r,d=new URL(e.url),u=e.method.toLowerCase(),h=s("",l(d),null,"default"),p=f(a,h,o);if(!Re(u)&&"head"!==u){let e=me(405,{method:u}),{matches:t,route:r}=pe(a);return{basename:o,location:h,matches:t,loaderData:{},actionData:null,errors:{[r.id]:e},statusCode:e.status,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}if(!p){let e=me(404,{pathname:h.pathname}),{matches:t,route:r}=pe(a);return{basename:o,location:h,matches:t,loaderData:{},actionData:null,errors:{[r.id]:e},statusCode:e.status,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}let m=await c(e,h,p,n,i);return De(m)?m:t({location:h,basename:o},m)},queryRoute:async function(e,t){let{routeId:r,requestContext:n,middlewareContext:i}=void 0===t?{}:t,d=new URL(e.url),u=e.method.toLowerCase(),h=s("",l(d),null,"default"),p=f(a,h,o);if(!Re(u)&&"head"!==u&&"options"!==u)throw me(405,{method:u});if(!p)throw me(404,{pathname:h.pathname});let m=r?p.find((e=>e.route.id===r)):Le(p,h);if(r&&!m)throw me(403,{pathname:h.pathname,routeId:r});if(!m)throw me(404,{pathname:h.pathname});let g=await c(e,h,p,n,i,m);if(De(g))return g;let v=g.errors?Object.values(g.errors)[0]:void 0;if(void 0!==v)throw v;if(g.actionData)return Object.values(g.actionData)[0];if(g.loaderData){var y;let e=Object.values(g.loaderData)[0];return null!=(y=g.activeDeferreds)&&y[m.route.id]&&(e[Q]=g.activeDeferreds[m.route.id]),e}}}},e.defer=function(e,t){return void 0===t&&(t={}),new _(e,"number"==typeof t?{status:t}:t)},e.generatePath=function(e,t){void 0===t&&(t={});let r=e;return r.endsWith("*")&&"*"!==r&&!r.endsWith("/*")&&(R(!1,'Route path "'+r+'" will be treated as if it were "'+r.replace(/\*$/,"/*")+'" because the `*` character must always follow a `/` in the pattern. To get rid of this warning, please change the route path to "'+r.replace(/\*$/,"/*")+'".'),r=r.replace(/\*$/,"/*")),r.replace(/^:(\w+)(\??)/g,((e,r,a)=>{let o=t[r];return"?"===a?null==o?"":o:(null==o&&n(!1,'Missing ":'+r+'" param'),o)})).replace(/\/:(\w+)(\??)/g,((e,r,a)=>{let o=t[r];return"?"===a?null==o?"":"/"+o:(null==o&&n(!1,'Missing ":'+r+'" param'),"/"+o)})).replace(/\?/g,"").replace(/(\/?)\*/,((e,r,a,n)=>null==t["*"]?"/*"===n?"/":"":""+r+t["*"]))},e.getStaticContextFromError=function(e,r,a){return t({},r,{statusCode:500,errors:{[r._deepestRenderedBoundaryId||e[0].id]:a}})},e.getToPathname=function(e){return""===e||""===e.pathname?"/":"string"==typeof e?c(e).pathname:e.pathname},e.invariant=n,e.isRouteErrorResponse=O,e.joinPaths=x,e.json=function(e,r){void 0===r&&(r={});let a="number"==typeof r?{status:r}:r,n=new Headers(a.headers);return n.has("Content-Type")||n.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(e),t({},a,{headers:n}))},e.matchPath=b,e.matchRoutes=f,e.normalizePathname=L,e.parsePath=c,e.redirect=function(e,r){void 0===r&&(r=302);let a=r;"number"==typeof a?a={status:a}:void 0===a.status&&(a.status=302);let n=new Headers(a.headers);return n.set("Location",e),new Response(null,t({},a,{headers:n}))},e.resolvePath=E,e.resolveTo=S,e.stripBasename=A,e.warning=R,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).RemixRouter={})}(this,(function(e){"use strict";function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var a in r)Object.prototype.hasOwnProperty.call(r,a)&&(e[a]=r[a])}return e},t.apply(this,arguments)}var r;e.Action=void 0,(r=e.Action||(e.Action={})).Pop="POP",r.Push="PUSH",r.Replace="REPLACE";const a="popstate";function o(e,t){if(!1===e||null==e)throw new Error(t)}function n(e,t){if(!e){"undefined"!=typeof console&&console.warn(t);try{throw new Error(t)}catch(e){}}}function i(e,t){return{usr:e.state,key:e.key,idx:t}}function s(e,r,a,o){return void 0===a&&(a=null),t({pathname:"string"==typeof e?e:e.pathname,search:"",hash:""},"string"==typeof r?c(r):r,{state:a,key:r&&r.key||o||Math.random().toString(36).substr(2,8)})}function l(e){let{pathname:t="/",search:r="",hash:a=""}=e;return r&&"?"!==r&&(t+="?"===r.charAt(0)?r:"?"+r),a&&"#"!==a&&(t+="#"===a.charAt(0)?a:"#"+a),t}function c(e){let t={};if(e){let r=e.indexOf("#");r>=0&&(t.hash=e.substr(r),e=e.substr(0,r));let a=e.indexOf("?");a>=0&&(t.search=e.substr(a),e=e.substr(0,a)),e&&(t.pathname=e)}return t}function d(r,n,c,d){void 0===d&&(d={});let{window:u=document.defaultView,v5Compat:h=!1}=d,f=u.history,p=e.Action.Pop,m=null,v=y();function y(){return(f.state||{idx:null}).idx}function g(){p=e.Action.Pop;let t=y(),r=null==t?null:t-v;v=t,m&&m({action:p,location:w.location,delta:r})}function b(e){let t="null"!==u.location.origin?u.location.origin:u.location.href,r="string"==typeof e?e:l(e);return o(t,"No window.location.(origin|href) available to create URL for href: "+r),new URL(r,t)}null==v&&(v=0,f.replaceState(t({},f.state,{idx:v}),""));let w={get action(){return p},get location(){return r(u,f)},listen(e){if(m)throw new Error("A history only accepts one active listener");return u.addEventListener(a,g),m=e,()=>{u.removeEventListener(a,g),m=null}},createHref:e=>n(u,e),createURL:b,encodeLocation(e){let t=b(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:function(t,r){p=e.Action.Push;let a=s(w.location,t,r);c&&c(a,t),v=y()+1;let o=i(a,v),n=w.createHref(a);try{f.pushState(o,"",n)}catch(e){if(e instanceof DOMException&&"DataCloneError"===e.name)throw e;u.location.assign(n)}h&&m&&m({action:p,location:w.location,delta:1})},replace:function(t,r){p=e.Action.Replace;let a=s(w.location,t,r);c&&c(a,t),v=y();let o=i(a,v),n=w.createHref(a);f.replaceState(o,"",n),h&&m&&m({action:p,location:w.location,delta:0})},go:e=>f.go(e)};return w}let u;!function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"}(u||(u={}));const h=new Set(["lazy","caseSensitive","path","id","index","children"]);function f(e,r,a,n){return void 0===a&&(a=[]),void 0===n&&(n={}),e.map(((e,i)=>{let s=[...a,i],l="string"==typeof e.id?e.id:s.join("-");if(o(!0!==e.index||!e.children,"Cannot specify children on an index route"),o(!n[l],'Found a route id collision on id "'+l+"\". Route id's must be globally unique within Data Router usages"),function(e){return!0===e.index}(e)){let a=t({},e,r(e),{id:l});return n[l]=a,a}{let a=t({},e,r(e),{id:l,children:void 0});return n[l]=a,e.children&&(a.children=f(e.children,r,s,n)),a}}))}function p(e,t,r){void 0===r&&(r="/");let a=R(("string"==typeof t?c(t):t).pathname||"/",r);if(null==a)return null;let o=m(e);!function(e){e.sort(((e,t)=>e.score!==t.score?t.score-e.score:function(e,t){return e.length===t.length&&e.slice(0,-1).every(((e,r)=>e===t[r]))?e[e.length-1]-t[t.length-1]:0}(e.routesMeta.map((e=>e.childrenIndex)),t.routesMeta.map((e=>e.childrenIndex)))))}(o);let n=null;for(let e=0;null==n&&e<o.length;++e)n=w(o[e],E(a));return n}function m(e,t,r,a){void 0===t&&(t=[]),void 0===r&&(r=[]),void 0===a&&(a="");let n=(e,n,i)=>{let s={relativePath:void 0===i?e.path||"":i,caseSensitive:!0===e.caseSensitive,childrenIndex:n,route:e};s.relativePath.startsWith("/")&&(o(s.relativePath.startsWith(a),'Absolute route path "'+s.relativePath+'" nested under path "'+a+'" is not valid. An absolute child route path must start with the combined path of all its parent routes.'),s.relativePath=s.relativePath.slice(a.length));let l=L([a,s.relativePath]),c=r.concat(s);e.children&&e.children.length>0&&(o(!0!==e.index,'Index routes must not have child routes. Please remove all child routes from route path "'+l+'".'),m(e.children,t,c,l)),(null!=e.path||e.index)&&t.push({path:l,score:b(l,e.index),routesMeta:c})};return e.forEach(((e,t)=>{var r;if(""!==e.path&&null!=(r=e.path)&&r.includes("?"))for(let r of v(e.path))n(e,t,r);else n(e,t)})),t}function v(e){let t=e.split("/");if(0===t.length)return[];let[r,...a]=t,o=r.endsWith("?"),n=r.replace(/\?$/,"");if(0===a.length)return o?[n,""]:[n];let i=v(a.join("/")),s=[];return s.push(...i.map((e=>""===e?n:[n,e].join("/")))),o&&s.push(...i),s.map((t=>e.startsWith("/")&&""===t?"/":t))}const y=/^:\w+$/,g=e=>"*"===e;function b(e,t){let r=e.split("/"),a=r.length;return r.some(g)&&(a+=-2),t&&(a+=2),r.filter((e=>!g(e))).reduce(((e,t)=>e+(y.test(t)?3:""===t?1:10)),a)}function w(e,t){let{routesMeta:r}=e,a={},o="/",n=[];for(let e=0;e<r.length;++e){let i=r[e],s=e===r.length-1,l="/"===o?t:t.slice(o.length)||"/",c=D({path:i.relativePath,caseSensitive:i.caseSensitive,end:s},l);if(!c)return null;Object.assign(a,c.params);let d=i.route;n.push({params:a,pathname:L([o,c.pathname]),pathnameBase:k(L([o,c.pathnameBase])),route:d}),"/"!==c.pathnameBase&&(o=L([o,c.pathnameBase]))}return n}function D(e,t){"string"==typeof e&&(e={path:e,caseSensitive:!1,end:!0});let[r,a]=function(e,t,r){void 0===t&&(t=!1);void 0===r&&(r=!0);n("*"===e||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were "'+e.replace(/\*$/,"/*")+'" because the `*` character must always follow a `/` in the pattern. To get rid of this warning, please change the route path to "'+e.replace(/\*$/,"/*")+'".');let a=[],o="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^$?{}|()[\]]/g,"\\$&").replace(/\/:(\w+)/g,((e,t)=>(a.push(t),"/([^\\/]+)")));e.endsWith("*")?(a.push("*"),o+="*"===e||"/*"===e?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?o+="\\/*$":""!==e&&"/"!==e&&(o+="(?:(?=\\/|$))");return[new RegExp(o,t?void 0:"i"),a]}(e.path,e.caseSensitive,e.end),o=t.match(r);if(!o)return null;let i=o[0],s=i.replace(/(.)\/+$/,"$1"),l=o.slice(1);return{params:a.reduce(((e,t,r)=>{if("*"===t){let e=l[r]||"";s=i.slice(0,i.length-e.length).replace(/(.)\/+$/,"$1")}return e[t]=function(e,t){try{return decodeURIComponent(e)}catch(r){return n(!1,'The value for the URL param "'+t+'" will not be decoded because the string "'+e+'" is a malformed URL segment. This is probably due to a bad percent encoding ('+r+")."),e}}(l[r]||"",t),e}),{}),pathname:i,pathnameBase:s,pattern:e}}function E(e){try{return decodeURI(e)}catch(t){return n(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent encoding ('+t+")."),e}}function R(e,t){if("/"===t)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let r=t.endsWith("/")?t.length-1:t.length,a=e.charAt(r);return a&&"/"!==a?null:e.slice(r)||"/"}function A(e,t){void 0===t&&(t="/");let{pathname:r,search:a="",hash:o=""}="string"==typeof e?c(e):e,n=r?r.startsWith("/")?r:function(e,t){let r=t.replace(/\/+$/,"").split("/");return e.split("/").forEach((e=>{".."===e?r.length>1&&r.pop():"."!==e&&r.push(e)})),r.length>1?r.join("/"):"/"}(r,t):t;return{pathname:n,search:x(a),hash:C(o)}}function P(e,t,r,a){return"Cannot include a '"+e+"' character in a manually specified `to."+t+"` field ["+JSON.stringify(a)+"]. Please separate it out to the `to."+r+'` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.'}function S(e){return e.filter(((e,t)=>0===t||e.route.path&&e.route.path.length>0))}function M(e,r,a,n){let i;void 0===n&&(n=!1),"string"==typeof e?i=c(e):(i=t({},e),o(!i.pathname||!i.pathname.includes("?"),P("?","pathname","search",i)),o(!i.pathname||!i.pathname.includes("#"),P("#","pathname","hash",i)),o(!i.search||!i.search.includes("#"),P("#","search","hash",i)));let s,l=""===e||""===i.pathname,d=l?"/":i.pathname;if(n||null==d)s=a;else{let e=r.length-1;if(d.startsWith("..")){let t=d.split("/");for(;".."===t[0];)t.shift(),e-=1;i.pathname=t.join("/")}s=e>=0?r[e]:"/"}let u=A(i,s),h=d&&"/"!==d&&d.endsWith("/"),f=(l||"."===d)&&a.endsWith("/");return u.pathname.endsWith("/")||!h&&!f||(u.pathname+="/"),u}const L=e=>e.join("/").replace(/\/\/+/g,"/"),k=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),x=e=>e&&"?"!==e?e.startsWith("?")?e:"?"+e:"",C=e=>e&&"#"!==e?e.startsWith("#")?e:"#"+e:"";class U extends Error{}class j{constructor(e,t){let r;this.pendingKeysSet=new Set,this.subscribers=new Set,this.deferredKeys=[],o(e&&"object"==typeof e&&!Array.isArray(e),"defer() only accepts plain objects"),this.abortPromise=new Promise(((e,t)=>r=t)),this.controller=new AbortController;let a=()=>r(new U("Deferred data aborted"));this.unlistenAbortSignal=()=>this.controller.signal.removeEventListener("abort",a),this.controller.signal.addEventListener("abort",a),this.data=Object.entries(e).reduce(((e,t)=>{let[r,a]=t;return Object.assign(e,{[r]:this.trackPromise(r,a)})}),{}),this.done&&this.unlistenAbortSignal(),this.init=t}trackPromise(e,t){if(!(t instanceof Promise))return t;this.deferredKeys.push(e),this.pendingKeysSet.add(e);let r=Promise.race([t,this.abortPromise]).then((t=>this.onSettle(r,e,null,t)),(t=>this.onSettle(r,e,t)));return r.catch((()=>{})),Object.defineProperty(r,"_tracked",{get:()=>!0}),r}onSettle(e,t,r,a){return this.controller.signal.aborted&&r instanceof U?(this.unlistenAbortSignal(),Object.defineProperty(e,"_error",{get:()=>r}),Promise.reject(r)):(this.pendingKeysSet.delete(t),this.done&&this.unlistenAbortSignal(),r?(Object.defineProperty(e,"_error",{get:()=>r}),this.emit(!1,t),Promise.reject(r)):(Object.defineProperty(e,"_data",{get:()=>a}),this.emit(!1,t),a))}emit(e,t){this.subscribers.forEach((r=>r(e,t)))}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}cancel(){this.controller.abort(),this.pendingKeysSet.forEach(((e,t)=>this.pendingKeysSet.delete(t))),this.emit(!0)}async resolveData(e){let t=!1;if(!this.done){let r=()=>this.cancel();e.addEventListener("abort",r),t=await new Promise((t=>{this.subscribe((a=>{e.removeEventListener("abort",r),(a||this.done)&&t(a)}))}))}return t}get done(){return 0===this.pendingKeysSet.size}get unwrappedData(){return o(null!==this.data&&this.done,"Can only unwrap data on initialized and settled deferreds"),Object.entries(this.data).reduce(((e,t)=>{let[r,a]=t;return Object.assign(e,{[r]:O(a)})}),{})}get pendingKeys(){return Array.from(this.pendingKeysSet)}}function O(e){if(!function(e){return e instanceof Promise&&!0===e._tracked}(e))return e;if(e._error)throw e._error;return e._data}class T{constructor(e,t,r,a){void 0===a&&(a=!1),this.status=e,this.statusText=t||"",this.internal=a,r instanceof Error?(this.data=r.toString(),this.error=r):this.data=r}}function _(e){return null!=e&&"number"==typeof e.status&&"string"==typeof e.statusText&&"boolean"==typeof e.internal&&"data"in e}const I=["post","put","patch","delete"],z=new Set(I),H=["get",...I],B=new Set(H),q=new Set([301,302,303,307,308]),$=new Set([307,308]),N={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},W={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},F={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},K=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Y=e=>({hasErrorBoundary:Boolean(e.hasErrorBoundary)});const J=Symbol("deferred");function V(e,t,r,a,o,n,i){let s,c;if(null!=n&&"path"!==i){s=[];for(let e of t)if(s.push(e),e.route.id===n){c=e;break}}else s=t,c=t[t.length-1];let d=M(o||".",S(s).map((e=>e.pathnameBase)),R(e.pathname,r)||e.pathname,"path"===i);return null==o&&(d.search=e.search,d.hash=e.hash),null!=o&&""!==o&&"."!==o||!c||!c.route.index||Re(d.search)||(d.search=d.search?d.search.replace(/^\?/,"?index&"):"?index"),a&&"/"!==r&&(d.pathname="/"===d.pathname?r:L([r,d.pathname])),l(d)}function G(e,t,r,a){if(!a||!function(e){return null!=e&&"formData"in e}(a))return{path:r};if(a.formMethod&&!be(a.formMethod))return{path:r,error:de(405,{method:a.formMethod})};let o;if(a.formData){let t=a.formMethod||"get";if(o={formMethod:e?t.toUpperCase():t.toLowerCase(),formAction:he(r),formEncType:a&&a.formEncType||"application/x-www-form-urlencoded",formData:a.formData},we(o.formMethod))return{path:r,submission:o}}let n=c(r),i=oe(a.formData);return t&&n.search&&Re(n.search)&&i.append("index",""),n.search="?"+i,{path:l(n),submission:o}}function X(e,t){let r=e;if(t){let a=e.findIndex((e=>e.route.id===t));a>=0&&(r=e.slice(0,a))}return r}function Q(e,r,a,o,n,i,s,l,c,d,u,h,f){let m=f?Object.values(f)[0]:h?Object.values(h)[0]:void 0,v=e.createURL(r.location),y=e.createURL(n),g=f?Object.keys(f)[0]:void 0,b=X(a,g).filter(((e,a)=>{if(e.route.lazy)return!0;if(null==e.route.loader)return!1;if(function(e,t,r){let a=!t||r.route.id!==t.route.id,o=void 0===e[r.route.id];return a||o}(r.loaderData,r.matches[a],e)||s.some((t=>t===e.route.id)))return!0;let n=r.matches[a],l=e;return ee(e,t({currentUrl:v,currentParams:n.params,nextUrl:y,nextParams:l.params},o,{actionResult:m,defaultShouldRevalidate:i||v.pathname+v.search===y.pathname+y.search||v.search!==y.search||Z(n,l)}))})),w=[];return c.forEach(((e,n)=>{if(!a.some((t=>t.route.id===e.routeId)))return;let s=p(d,e.path,u);if(!s)return void w.push({key:n,routeId:e.routeId,path:e.path,matches:null,match:null,controller:null});let c=Ae(s,e.path);(l.includes(n)||ee(c,t({currentUrl:v,currentParams:r.matches[r.matches.length-1].params,nextUrl:y,nextParams:a[a.length-1].params},o,{actionResult:m,defaultShouldRevalidate:i})))&&w.push({key:n,routeId:e.routeId,path:e.path,matches:s,match:c,controller:new AbortController})})),[b,w]}function Z(e,t){let r=e.route.path;return e.pathname!==t.pathname||null!=r&&r.endsWith("*")&&e.params["*"]!==t.params["*"]}function ee(e,t){if(e.route.shouldRevalidate){let r=e.route.shouldRevalidate(t);if("boolean"==typeof r)return r}return t.defaultShouldRevalidate}async function te(e,r,a){if(!e.lazy)return;let i=await e.lazy();if(!e.lazy)return;let s=a[e.id];o(s,"No route found in manifest");let l={};for(let e in i){let t=void 0!==s[e]&&"hasErrorBoundary"!==e;n(!t,'Route "'+s.id+'" has a static property "'+e+'" defined but its lazy function is also returning a value for this property. The lazy route property "'+e+'" will be ignored.'),t||h.has(e)||(l[e]=i[e])}Object.assign(s,l),Object.assign(s,t({},r(s),{lazy:void 0}))}async function re(e,t,r,a,n,i,s,l,c,d){let h,f,p;void 0===l&&(l=!1),void 0===c&&(c=!1);let m=e=>{let a,o=new Promise(((e,t)=>a=t));return p=()=>a(),t.signal.addEventListener("abort",p),Promise.race([e({request:t,params:r.params,context:d}),o])};try{let a=r.route[e];if(r.route.lazy)if(a){f=(await Promise.all([m(a),te(r.route,i,n)]))[0]}else{if(await te(r.route,i,n),a=r.route[e],!a){if("action"===e){let e=new URL(t.url),a=e.pathname+e.search;throw de(405,{method:t.method,pathname:a,routeId:r.route.id})}return{type:u.data,data:void 0}}f=await m(a)}else{if(!a){let e=new URL(t.url);throw de(404,{pathname:e.pathname+e.search})}f=await m(a)}o(void 0!==f,"You defined "+("action"===e?"an action":"a loader")+' for route "'+r.route.id+"\" but didn't return anything from your `"+e+"` function. Please return a value or `null`.")}catch(e){h=u.error,f=e}finally{p&&t.signal.removeEventListener("abort",p)}if(ye(f)){let e,n=f.status;if(q.has(n)){let e=f.headers.get("Location");if(o(e,"Redirects returned/thrown from loaders/actions must have a Location header"),K.test(e)){if(!l){let r=new URL(t.url),a=e.startsWith("//")?new URL(r.protocol+e):new URL(e),o=null!=R(a.pathname,s);a.origin===r.origin&&o&&(e=a.pathname+a.search+a.hash)}}else e=V(new URL(t.url),a.slice(0,a.indexOf(r)+1),s,!0,e);if(l)throw f.headers.set("Location",e),f;return{type:u.redirect,status:n,location:e,revalidate:null!==f.headers.get("X-Remix-Revalidate")}}if(c)throw{type:h||u.data,response:f};let i=f.headers.get("Content-Type");return e=i&&/\bapplication\/json\b/.test(i)?await f.json():await f.text(),h===u.error?{type:h,error:new T(n,f.statusText,e),headers:f.headers}:{type:u.data,data:e,statusCode:f.status,headers:f.headers}}return h===u.error?{type:h,error:f}:ve(f)?{type:u.deferred,deferredData:f,statusCode:null==(v=f.init)?void 0:v.status,headers:(null==(y=f.init)?void 0:y.headers)&&new Headers(f.init.headers)}:{type:u.data,data:f};var v,y}function ae(e,t,r,a){let o=e.createURL(he(t)).toString(),n={signal:r};if(a&&we(a.formMethod)){let{formMethod:e,formEncType:t,formData:r}=a;n.method=e.toUpperCase(),n.body="application/x-www-form-urlencoded"===t?oe(r):r}return new Request(o,n)}function oe(e){let t=new URLSearchParams;for(let[r,a]of e.entries())t.append(r,a instanceof File?a.name:a);return t}function ne(e,t,r,a,n){let i,s={},l=null,c=!1,d={};return r.forEach(((r,u)=>{let h=t[u].route.id;if(o(!me(r),"Cannot handle redirect results in processLoaderData"),pe(r)){let t=le(e,h),o=r.error;a&&(o=Object.values(a)[0],a=void 0),l=l||{},null==l[t.route.id]&&(l[t.route.id]=o),s[h]=void 0,c||(c=!0,i=_(r.error)?r.error.status:500),r.headers&&(d[h]=r.headers)}else fe(r)?(n.set(h,r.deferredData),s[h]=r.deferredData.data):s[h]=r.data,null==r.statusCode||200===r.statusCode||c||(i=r.statusCode),r.headers&&(d[h]=r.headers)})),a&&(l=a,s[Object.keys(a)[0]]=void 0),{loaderData:s,errors:l,statusCode:i||200,loaderHeaders:d}}function ie(e,r,a,n,i,s,l,c){let{loaderData:d,errors:u}=ne(r,a,n,i,c);for(let r=0;r<s.length;r++){let{key:a,match:n,controller:i}=s[r];o(void 0!==l&&void 0!==l[r],"Did not find corresponding fetcher result");let c=l[r];if(!i||!i.signal.aborted)if(pe(c)){let r=le(e.matches,null==n?void 0:n.route.id);u&&u[r.route.id]||(u=t({},u,{[r.route.id]:c.error})),e.fetchers.delete(a)}else if(me(c))o(!1,"Unhandled fetcher revalidation redirect");else if(fe(c))o(!1,"Unhandled fetcher deferred data");else{let t={state:"idle",data:c.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0};e.fetchers.set(a,t)}}return{loaderData:d,errors:u}}function se(e,r,a,o){let n=t({},r);for(let t of a){let a=t.route.id;if(r.hasOwnProperty(a)?void 0!==r[a]&&(n[a]=r[a]):void 0!==e[a]&&t.route.loader&&(n[a]=e[a]),o&&o.hasOwnProperty(a))break}return n}function le(e,t){return(t?e.slice(0,e.findIndex((e=>e.route.id===t))+1):[...e]).reverse().find((e=>!0===e.route.hasErrorBoundary))||e[0]}function ce(e){let t=e.find((e=>e.index||!e.path||"/"===e.path))||{id:"__shim-error-route__"};return{matches:[{params:{},pathname:"",pathnameBase:"",route:t}],route:t}}function de(e,t){let{pathname:r,routeId:a,method:o,type:n}=void 0===t?{}:t,i="Unknown Server Error",s="Unknown @remix-run/router error";return 400===e?(i="Bad Request",o&&r&&a?s="You made a "+o+' request to "'+r+'" but did not provide a `loader` for route "'+a+'", so there is no way to handle the request.':"defer-action"===n&&(s="defer() is not supported in actions")):403===e?(i="Forbidden",s='Route "'+a+'" does not match URL "'+r+'"'):404===e?(i="Not Found",s='No route matches URL "'+r+'"'):405===e&&(i="Method Not Allowed",o&&r&&a?s="You made a "+o.toUpperCase()+' request to "'+r+'" but did not provide an `action` for route "'+a+'", so there is no way to handle the request.':o&&(s='Invalid request method "'+o.toUpperCase()+'"')),new T(e||500,i,new Error(s),!0)}function ue(e){for(let t=e.length-1;t>=0;t--){let r=e[t];if(me(r))return r}}function he(e){return l(t({},"string"==typeof e?c(e):e,{hash:""}))}function fe(e){return e.type===u.deferred}function pe(e){return e.type===u.error}function me(e){return(e&&e.type)===u.redirect}function ve(e){let t=e;return t&&"object"==typeof t&&"object"==typeof t.data&&"function"==typeof t.subscribe&&"function"==typeof t.cancel&&"function"==typeof t.resolveData}function ye(e){return null!=e&&"number"==typeof e.status&&"string"==typeof e.statusText&&"object"==typeof e.headers&&void 0!==e.body}function ge(e){if(!ye(e))return!1;let t=e.status,r=e.headers.get("Location");return t>=300&&t<=399&&null!=r}function be(e){return B.has(e.toLowerCase())}function we(e){return z.has(e.toLowerCase())}async function De(e,t,r,a,n,i){for(let s=0;s<r.length;s++){let l=r[s],c=t[s];if(!c)continue;let d=e.find((e=>e.route.id===c.route.id)),u=null!=d&&!Z(d,c)&&void 0!==(i&&i[c.route.id]);if(fe(l)&&(n||u)){let e=a[s];o(e,"Expected an AbortSignal for revalidating fetcher deferred result"),await Ee(l,e,n).then((e=>{e&&(r[s]=e||r[s])}))}}}async function Ee(e,t,r){if(void 0===r&&(r=!1),!await e.deferredData.resolveData(t)){if(r)try{return{type:u.data,data:e.deferredData.unwrappedData}}catch(e){return{type:u.error,error:e}}return{type:u.data,data:e.deferredData.data}}}function Re(e){return new URLSearchParams(e).getAll("index").some((e=>""===e))}function Ae(e,t){let r="string"==typeof t?c(t).search:t.search;if(e[e.length-1].route.index&&Re(r||""))return e[e.length-1];let a=S(e);return a[a.length-1]}e.AbortedDeferredError=U,e.ErrorResponse=T,e.IDLE_BLOCKER=F,e.IDLE_FETCHER=W,e.IDLE_NAVIGATION=N,e.UNSAFE_DEFERRED_SYMBOL=J,e.UNSAFE_DeferredData=j,e.UNSAFE_convertRoutesToDataRoutes=f,e.UNSAFE_getPathContributingMatches=S,e.UNSAFE_invariant=o,e.UNSAFE_warning=n,e.createBrowserHistory=function(e){return void 0===e&&(e={}),d((function(e,t){let{pathname:r,search:a,hash:o}=e.location;return s("",{pathname:r,search:a,hash:o},t.state&&t.state.usr||null,t.state&&t.state.key||"default")}),(function(e,t){return"string"==typeof t?t:l(t)}),null,e)},e.createHashHistory=function(e){return void 0===e&&(e={}),d((function(e,t){let{pathname:r="/",search:a="",hash:o=""}=c(e.location.hash.substr(1));return s("",{pathname:r,search:a,hash:o},t.state&&t.state.usr||null,t.state&&t.state.key||"default")}),(function(e,t){let r=e.document.querySelector("base"),a="";if(r&&r.getAttribute("href")){let t=e.location.href,r=t.indexOf("#");a=-1===r?t:t.slice(0,r)}return a+"#"+("string"==typeof t?t:l(t))}),(function(e,t){n("/"===e.pathname.charAt(0),"relative pathnames are not supported in hash history.push("+JSON.stringify(t)+")")}),e)},e.createMemoryHistory=function(t){void 0===t&&(t={});let r,{initialEntries:a=["/"],initialIndex:o,v5Compat:i=!1}=t;r=a.map(((e,t)=>m(e,"string"==typeof e?null:e.state,0===t?"default":void 0)));let d=f(null==o?r.length-1:o),u=e.Action.Pop,h=null;function f(e){return Math.min(Math.max(e,0),r.length-1)}function p(){return r[d]}function m(e,t,a){void 0===t&&(t=null);let o=s(r?p().pathname:"/",e,t,a);return n("/"===o.pathname.charAt(0),"relative pathnames are not supported in memory history: "+JSON.stringify(e)),o}function v(e){return"string"==typeof e?e:l(e)}return{get index(){return d},get action(){return u},get location(){return p()},createHref:v,createURL:e=>new URL(v(e),"http://localhost"),encodeLocation(e){let t="string"==typeof e?c(e):e;return{pathname:t.pathname||"",search:t.search||"",hash:t.hash||""}},push(t,a){u=e.Action.Push;let o=m(t,a);d+=1,r.splice(d,r.length,o),i&&h&&h({action:u,location:o,delta:1})},replace(t,a){u=e.Action.Replace;let o=m(t,a);r[d]=o,i&&h&&h({action:u,location:o,delta:0})},go(t){u=e.Action.Pop;let a=f(d+t),o=r[a];d=a,h&&h({action:u,location:o,delta:t})},listen:e=>(h=e,()=>{h=null})}},e.createPath=l,e.createRouter=function(r){const a=r.window?r.window:"undefined"!=typeof window?window:void 0,i=void 0!==a&&void 0!==a.document&&void 0!==a.document.createElement,l=!i;let c;if(o(r.routes.length>0,"You must provide a non-empty routes array to createRouter"),r.mapRouteProperties)c=r.mapRouteProperties;else if(r.detectErrorBoundary){let e=r.detectErrorBoundary;c=t=>({hasErrorBoundary:e(t)})}else c=Y;let d,h={},m=f(r.routes,c,void 0,h),v=r.basename||"/",y=t({v7_normalizeFormMethod:!1,v7_prependBasename:!1},r.future),g=null,b=new Set,w=null,D=null,E=null,A=null!=r.hydrationData,P=p(m,r.history.location,v),S=null;if(null==P){let e=de(404,{pathname:r.history.location.pathname}),{matches:t,route:a}=ce(m);P=t,S={[a.id]:e}}let M,L,k=!(P.some((e=>e.route.lazy))||P.some((e=>e.route.loader))&&null==r.hydrationData),x={historyAction:r.history.action,location:r.history.location,matches:P,initialized:k,navigation:N,restoreScrollPosition:null==r.hydrationData&&null,preventScrollReset:!1,revalidation:"idle",loaderData:r.hydrationData&&r.hydrationData.loaderData||{},actionData:r.hydrationData&&r.hydrationData.actionData||null,errors:r.hydrationData&&r.hydrationData.errors||S,fetchers:new Map,blockers:new Map},C=e.Action.Pop,U=!1,j=!1,O=!1,T=[],_=[],I=new Map,z=0,H=-1,B=new Map,q=new Set,J=new Map,X=new Map,Z=new Map,ee=!1;function te(e){x=t({},x,e),b.forEach((e=>e(x)))}function oe(a,o){var n,i;let s,l=null!=x.actionData&&null!=x.navigation.formMethod&&we(x.navigation.formMethod)&&"loading"===x.navigation.state&&!0!==(null==(n=a.state)?void 0:n._isRedirect);s=o.actionData?Object.keys(o.actionData).length>0?o.actionData:null:l?x.actionData:null;let c=o.loaderData?se(x.loaderData,o.loaderData,o.matches||[],o.errors):x.loaderData;for(let[e]of Z)ke(e);let u=!0===U||null!=x.navigation.formMethod&&we(x.navigation.formMethod)&&!0!==(null==(i=a.state)?void 0:i._isRedirect);d&&(m=d,d=void 0),j||C===e.Action.Pop||(C===e.Action.Push?r.history.push(a,a.state):C===e.Action.Replace&&r.history.replace(a,a.state)),te(t({},o,{actionData:s,loaderData:c,historyAction:C,location:a,initialized:!0,navigation:N,revalidation:"idle",restoreScrollPosition:Oe(a,o.matches||x.matches),preventScrollReset:u,blockers:new Map(x.blockers)})),C=e.Action.Pop,U=!1,j=!1,O=!1,T=[],_=[]}async function ne(a,o,n){L&&L.abort(),L=null,C=a,j=!0===(n&&n.startUninterruptedRevalidation),function(e,t){if(w&&E){let r=je(e,t);w[r]=E()}}(x.location,x.matches),U=!0===(n&&n.preventScrollReset);let i=d||m,s=n&&n.overrideNavigation,l=p(i,o,v);if(!l){let e=de(404,{pathname:o.pathname}),{matches:t,route:r}=ce(i);return Ue(),void oe(o,{matches:t,loaderData:{},errors:{[r.id]:e}})}if(x.initialized&&!O&&function(e,t){if(e.pathname!==t.pathname||e.search!==t.search)return!1;if(""===e.hash)return""!==t.hash;if(e.hash===t.hash)return!0;if(""!==t.hash)return!0;return!1}(x.location,o)&&!(n&&n.submission&&we(n.submission.formMethod)))return void oe(o,{matches:l});L=new AbortController;let f,y,g=ae(r.history,o,L.signal,n&&n.submission);if(n&&n.pendingError)y={[le(l).route.id]:n.pendingError};else if(n&&n.submission&&we(n.submission.formMethod)){let r=await async function(r,a,o,n,i){let s;ge(),te({navigation:t({state:"submitting",location:a},o)});let l=Ae(n,a);if(l.route.action||l.route.lazy){if(s=await re("action",r,l,n,h,c,v),r.signal.aborted)return{shortCircuited:!0}}else s={type:u.error,error:de(405,{method:r.method,pathname:a.pathname,routeId:l.route.id})};if(me(s)){let e;return e=i&&null!=i.replace?i.replace:s.location===x.location.pathname+x.location.search,await ve(x,s,{submission:o,replace:e}),{shortCircuited:!0}}if(pe(s)){let t=le(n,l.route.id);return!0!==(i&&i.replace)&&(C=e.Action.Push),{pendingActionData:{},pendingActionError:{[t.route.id]:s.error}}}if(fe(s))throw de(400,{type:"defer-action"});return{pendingActionData:{[l.route.id]:s.data}}}(g,o,n.submission,l,{replace:n.replace});if(r.shortCircuited)return;f=r.pendingActionData,y=r.pendingActionError,s=t({state:"loading",location:o},n.submission),g=new Request(g.url,{signal:g.signal})}let{shortCircuited:b,loaderData:D,errors:R}=await async function(e,a,o,n,i,s,l,c,u){let h=n;if(!h){h=t({state:"loading",location:a,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},i)}let f=i||s?i||s:h.formMethod&&h.formAction&&h.formData&&h.formEncType?{formMethod:h.formMethod,formAction:h.formAction,formData:h.formData,formEncType:h.formEncType}:void 0,p=d||m,[y,g]=Q(r.history,x,o,f,a,O,T,_,J,p,v,c,u);if(Ue((e=>!(o&&o.some((t=>t.route.id===e)))||y&&y.some((t=>t.route.id===e)))),0===y.length&&0===g.length){let e=Me();return oe(a,t({matches:o,loaderData:{},errors:u||null},c?{actionData:c}:{},e?{fetchers:new Map(x.fetchers)}:{})),{shortCircuited:!0}}if(!j){g.forEach((e=>{let t=x.fetchers.get(e.key),r={state:"loading",data:t&&t.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0};x.fetchers.set(e.key,r)}));let e=c||x.actionData;te(t({navigation:h},e?0===Object.keys(e).length?{actionData:null}:{actionData:e}:{},g.length>0?{fetchers:new Map(x.fetchers)}:{}))}H=++z,g.forEach((e=>{e.controller&&I.set(e.key,e.controller)}));let b=()=>g.forEach((e=>Pe(e.key)));L&&L.signal.addEventListener("abort",b);let{results:w,loaderResults:D,fetcherResults:E}=await ye(x.matches,o,y,g,e);if(e.signal.aborted)return{shortCircuited:!0};L&&L.signal.removeEventListener("abort",b);g.forEach((e=>I.delete(e.key)));let R=ue(w);if(R)return await ve(x,R,{replace:l}),{shortCircuited:!0};let{loaderData:A,errors:P}=ie(x,o,y,D,u,g,E,X);X.forEach(((e,t)=>{e.subscribe((r=>{(r||e.done)&&X.delete(t)}))}));let S=Me(),M=Le(H),k=S||M||g.length>0;return t({loaderData:A,errors:P},k?{fetchers:new Map(x.fetchers)}:{})}(g,o,l,s,n&&n.submission,n&&n.fetcherSubmission,n&&n.replace,f,y);b||(L=null,oe(o,t({matches:l},f?{actionData:f}:{},{loaderData:D,errors:R})))}function he(e){return x.fetchers.get(e)||W}async function ve(n,l,c){let{submission:d,fetcherSubmission:u,replace:h}=void 0===c?{}:c;l.revalidate&&(O=!0);let f=s(n.location,l.location,{_isRedirect:!0});if(o(f,"Expected a location on the redirect navigation"),K.test(l.location)&&i){let e=r.history.createURL(l.location),t=null==R(e.pathname,v);if(a.location.origin!==e.origin||t)return void(h?a.location.replace(l.location):a.location.assign(l.location))}L=null;let p=!0===h?e.Action.Replace:e.Action.Push,{formMethod:m,formAction:y,formEncType:g,formData:b}=n.navigation;!d&&!u&&m&&y&&b&&g&&(d={formMethod:m,formAction:y,formEncType:g,formData:b});let w=d||u;$.has(l.status)&&w&&we(w.formMethod)?await ne(p,f,{submission:t({},w,{formAction:l.location}),preventScrollReset:U}):await ne(p,f,{overrideNavigation:{state:"loading",location:f,formMethod:d?d.formMethod:void 0,formAction:d?d.formAction:void 0,formEncType:d?d.formEncType:void 0,formData:d?d.formData:void 0},fetcherSubmission:u,preventScrollReset:U})}async function ye(e,t,a,o,n){let i=await Promise.all([...a.map((e=>re("loader",n,e,t,h,c,v))),...o.map((e=>{if(e.matches&&e.match&&e.controller)return re("loader",ae(r.history,e.path,e.controller.signal),e.match,e.matches,h,c,v);return{type:u.error,error:de(404,{pathname:e.path})}}))]),s=i.slice(0,a.length),l=i.slice(a.length);return await Promise.all([De(e,a,s,s.map((()=>n.signal)),!1,x.loaderData),De(e,o.map((e=>e.match)),l,o.map((e=>e.controller?e.controller.signal:null)),!0)]),{results:i,loaderResults:s,fetcherResults:l}}function ge(){O=!0,T.push(...Ue()),J.forEach(((e,t)=>{I.has(t)&&(_.push(t),Pe(t))}))}function be(e,t,r){let a=le(x.matches,t);Re(e),te({errors:{[a.route.id]:r},fetchers:new Map(x.fetchers)})}function Re(e){let t=x.fetchers.get(e);!I.has(e)||t&&"loading"===t.state&&B.has(e)||Pe(e),J.delete(e),B.delete(e),q.delete(e),x.fetchers.delete(e)}function Pe(e){let t=I.get(e);o(t,"Expected fetch controller: "+e),t.abort(),I.delete(e)}function Se(e){for(let t of e){let e={state:"idle",data:he(t).data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0};x.fetchers.set(t,e)}}function Me(){let e=[],t=!1;for(let r of q){let a=x.fetchers.get(r);o(a,"Expected fetcher: "+r),"loading"===a.state&&(q.delete(r),e.push(r),t=!0)}return Se(e),t}function Le(e){let t=[];for(let[r,a]of B)if(a<e){let e=x.fetchers.get(r);o(e,"Expected fetcher: "+r),"loading"===e.state&&(Pe(r),B.delete(r),t.push(r))}return Se(t),t.length>0}function ke(e){x.blockers.delete(e),Z.delete(e)}function xe(e,t){let r=x.blockers.get(e)||F;o("unblocked"===r.state&&"blocked"===t.state||"blocked"===r.state&&"blocked"===t.state||"blocked"===r.state&&"proceeding"===t.state||"blocked"===r.state&&"unblocked"===t.state||"proceeding"===r.state&&"unblocked"===t.state,"Invalid blocker state transition: "+r.state+" -> "+t.state),x.blockers.set(e,t),te({blockers:new Map(x.blockers)})}function Ce(e){let{currentLocation:t,nextLocation:r,historyAction:a}=e;if(0===Z.size)return;Z.size>1&&n(!1,"A router only supports one blocker at a time");let o=Array.from(Z.entries()),[i,s]=o[o.length-1],l=x.blockers.get(i);return l&&"proceeding"===l.state?void 0:s({currentLocation:t,nextLocation:r,historyAction:a})?i:void 0}function Ue(e){let t=[];return X.forEach(((r,a)=>{e&&!e(a)||(r.cancel(),t.push(a),X.delete(a))})),t}function je(e,t){if(D){return D(e,t.map((e=>function(e,t){let{route:r,pathname:a,params:o}=e;return{id:r.id,pathname:a,params:o,data:t[r.id],handle:r.handle}}(e,x.loaderData))))||e.key}return e.key}function Oe(e,t){if(w){let r=je(e,t),a=w[r];if("number"==typeof a)return a}return null}return M={get basename(){return v},get state(){return x},get routes(){return m},initialize:function(){return g=r.history.listen((e=>{let{action:t,location:a,delta:o}=e;if(ee)return void(ee=!1);n(0===Z.size||null!=o,"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.");let i=Ce({currentLocation:x.location,nextLocation:a,historyAction:t});return i&&null!=o?(ee=!0,r.history.go(-1*o),void xe(i,{state:"blocked",location:a,proceed(){xe(i,{state:"proceeding",proceed:void 0,reset:void 0,location:a}),r.history.go(o)},reset(){ke(i),te({blockers:new Map(M.state.blockers)})}})):ne(t,a)})),x.initialized||ne(e.Action.Pop,x.location),M},subscribe:function(e){return b.add(e),()=>b.delete(e)},enableScrollRestoration:function(e,t,r){if(w=e,E=t,D=r||null,!A&&x.navigation===N){A=!0;let e=Oe(x.location,x.matches);null!=e&&te({restoreScrollPosition:e})}return()=>{w=null,E=null,D=null}},navigate:async function a(o,n){if("number"==typeof o)return void r.history.go(o);let i=V(x.location,x.matches,v,y.v7_prependBasename,o,null==n?void 0:n.fromRouteId,null==n?void 0:n.relative),{path:l,submission:c,error:d}=G(y.v7_normalizeFormMethod,!1,i,n),u=x.location,h=s(x.location,l,n&&n.state);h=t({},h,r.history.encodeLocation(h));let f=n&&null!=n.replace?n.replace:void 0,p=e.Action.Push;!0===f?p=e.Action.Replace:!1===f||null!=c&&we(c.formMethod)&&c.formAction===x.location.pathname+x.location.search&&(p=e.Action.Replace);let m=n&&"preventScrollReset"in n?!0===n.preventScrollReset:void 0,g=Ce({currentLocation:u,nextLocation:h,historyAction:p});if(!g)return await ne(p,h,{submission:c,pendingError:d,preventScrollReset:m,replace:n&&n.replace});xe(g,{state:"blocked",location:h,proceed(){xe(g,{state:"proceeding",proceed:void 0,reset:void 0,location:h}),a(o,n)},reset(){ke(g),te({blockers:new Map(x.blockers)})}})},fetch:function(e,a,n,i){if(l)throw new Error("router.fetch() was called during the server render, but it shouldn't be. You are likely calling a useFetcher() method in the body of your component. Try moving it to a useEffect or a callback.");I.has(e)&&Pe(e);let s=d||m,u=V(x.location,x.matches,v,y.v7_prependBasename,n,a,null==i?void 0:i.relative),f=p(s,u,v);if(!f)return void be(e,a,de(404,{pathname:u}));let{path:g,submission:b}=G(y.v7_normalizeFormMethod,!0,u,i),w=Ae(f,g);U=!0===(i&&i.preventScrollReset),b&&we(b.formMethod)?async function(e,a,n,i,s,l){if(ge(),J.delete(e),!i.route.action&&!i.route.lazy){let t=de(405,{method:l.formMethod,pathname:n,routeId:a});return void be(e,a,t)}let u=x.fetchers.get(e),f=t({state:"submitting"},l,{data:u&&u.data});x.fetchers.set(e,f),te({fetchers:new Map(x.fetchers)});let y=new AbortController,g=ae(r.history,n,y.signal,l);I.set(e,y);let b=await re("action",g,i,s,h,c,v);if(g.signal.aborted)return void(I.get(e)===y&&I.delete(e));if(me(b)){I.delete(e),q.add(e);let r=t({state:"loading"},l,{data:void 0});return x.fetchers.set(e,r),te({fetchers:new Map(x.fetchers)}),ve(x,b,{fetcherSubmission:l})}if(pe(b))return void be(e,a,b.error);if(fe(b))throw de(400,{type:"defer-action"});let w=x.navigation.location||x.location,D=ae(r.history,w,y.signal),E=d||m,R="idle"!==x.navigation.state?p(E,x.navigation.location,v):x.matches;o(R,"Didn't find any matches after fetcher action");let A=++z;B.set(e,A);let P=t({state:"loading",data:b.data},l);x.fetchers.set(e,P);let[S,M]=Q(r.history,x,R,l,w,O,T,_,J,E,v,{[i.route.id]:b.data},void 0);M.filter((t=>t.key!==e)).forEach((e=>{let t=e.key,r=x.fetchers.get(t),a={state:"loading",data:r&&r.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0};x.fetchers.set(t,a),e.controller&&I.set(t,e.controller)})),te({fetchers:new Map(x.fetchers)});let k=()=>M.forEach((e=>Pe(e.key)));y.signal.addEventListener("abort",k);let{results:U,loaderResults:j,fetcherResults:$}=await ye(x.matches,R,S,M,D);if(y.signal.aborted)return;y.signal.removeEventListener("abort",k),B.delete(e),I.delete(e),M.forEach((e=>I.delete(e.key)));let N=ue(U);if(N)return ve(x,N);let{loaderData:W,errors:F}=ie(x,x.matches,S,j,void 0,M,$,X);if(x.fetchers.has(e)){let t={state:"idle",data:b.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0};x.fetchers.set(e,t)}let K=Le(A);"loading"===x.navigation.state&&A>H?(o(C,"Expected pending action"),L&&L.abort(),oe(x.navigation.location,{matches:R,loaderData:W,errors:F,fetchers:new Map(x.fetchers)})):(te(t({errors:F,loaderData:se(x.loaderData,W,R,F)},K||M.length>0?{fetchers:new Map(x.fetchers)}:{})),O=!1)}(e,a,g,w,f,b):(J.set(e,{routeId:a,path:g}),async function(e,a,n,i,s,l){let d=x.fetchers.get(e),u=t({state:"loading",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0},l,{data:d&&d.data});x.fetchers.set(e,u),te({fetchers:new Map(x.fetchers)});let f=new AbortController,p=ae(r.history,n,f.signal);I.set(e,f);let m=await re("loader",p,i,s,h,c,v);fe(m)&&(m=await Ee(m,p.signal,!0)||m);I.get(e)===f&&I.delete(e);if(p.signal.aborted)return;if(me(m))return q.add(e),void await ve(x,m);if(pe(m)){let t=le(x.matches,a);return x.fetchers.delete(e),void te({fetchers:new Map(x.fetchers),errors:{[t.route.id]:m.error}})}o(!fe(m),"Unhandled fetcher deferred data");let y={state:"idle",data:m.data,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0};x.fetchers.set(e,y),te({fetchers:new Map(x.fetchers)})}(e,a,g,w,f,b))},revalidate:function(){ge(),te({revalidation:"loading"}),"submitting"!==x.navigation.state&&("idle"!==x.navigation.state?ne(C||x.historyAction,x.navigation.location,{overrideNavigation:x.navigation}):ne(x.historyAction,x.location,{startUninterruptedRevalidation:!0}))},createHref:e=>r.history.createHref(e),encodeLocation:e=>r.history.encodeLocation(e),getFetcher:he,deleteFetcher:Re,dispose:function(){g&&g(),b.clear(),L&&L.abort(),x.fetchers.forEach(((e,t)=>Re(t))),x.blockers.forEach(((e,t)=>ke(t)))},getBlocker:function(e,t){let r=x.blockers.get(e)||F;return Z.get(e)!==t&&Z.set(e,t),r},deleteBlocker:ke,_internalFetchControllers:I,_internalActiveDeferreds:X,_internalSetRoutes:function(e){h={},d=f(e,c,void 0,h)}},M},e.createStaticHandler=function(e,r){o(e.length>0,"You must provide a non-empty routes array to createStaticHandler");let a,n={},i=(r?r.basename:null)||"/";if(null!=r&&r.mapRouteProperties)a=r.mapRouteProperties;else if(null!=r&&r.detectErrorBoundary){let e=r.detectErrorBoundary;a=t=>({hasErrorBoundary:e(t)})}else a=Y;let c=f(e,a,void 0,n);async function d(e,r,s,l,c){o(e.signal,"query()/queryRoute() requests must contain an AbortController signal");try{if(we(e.method.toLowerCase())){let o=await async function(e,r,o,s,l){let c;if(o.route.action||o.route.lazy){if(c=await re("action",e,o,r,n,a,i,!0,l,s),e.signal.aborted){throw new Error((l?"queryRoute":"query")+"() call aborted")}}else{let t=de(405,{method:e.method,pathname:new URL(e.url).pathname,routeId:o.route.id});if(l)throw t;c={type:u.error,error:t}}if(me(c))throw new Response(null,{status:c.status,headers:{Location:c.location}});if(fe(c)){let e=de(400,{type:"defer-action"});if(l)throw e;c={type:u.error,error:e}}if(l){if(pe(c))throw c.error;return{matches:[o],loaderData:{},actionData:{[o.route.id]:c.data},errors:null,statusCode:200,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}if(pe(c)){let a=le(r,o.route.id);return t({},await h(e,r,s,void 0,{[a.route.id]:c.error}),{statusCode:_(c.error)?c.error.status:500,actionData:null,actionHeaders:t({},c.headers?{[o.route.id]:c.headers}:{})})}let d=new Request(e.url,{headers:e.headers,redirect:e.redirect,signal:e.signal});return t({},await h(d,r,s),c.statusCode?{statusCode:c.statusCode}:{},{actionData:{[o.route.id]:c.data},actionHeaders:t({},c.headers?{[o.route.id]:c.headers}:{})})}(e,s,c||Ae(s,r),l,null!=c);return o}let o=await h(e,s,l,c);return ye(o)?o:t({},o,{actionData:null,actionHeaders:{}})}catch(e){if((d=e)&&ye(d.response)&&(d.type===u.data||u.error)){if(e.type===u.error&&!ge(e.response))throw e.response;return e.response}if(ge(e))return e;throw e}var d}async function h(e,r,o,s,l){let c=null!=s;if(c&&(null==s||!s.route.loader)&&(null==s||!s.route.lazy))throw de(400,{method:e.method,pathname:new URL(e.url).pathname,routeId:null==s?void 0:s.route.id});let d=(s?[s]:X(r,Object.keys(l||{})[0])).filter((e=>e.route.loader||e.route.lazy));if(0===d.length)return{matches:r,loaderData:r.reduce(((e,t)=>Object.assign(e,{[t.route.id]:null})),{}),errors:l||null,statusCode:200,loaderHeaders:{},activeDeferreds:null};let u=await Promise.all([...d.map((t=>re("loader",e,t,r,n,a,i,!0,c,o)))]);if(e.signal.aborted){throw new Error((c?"queryRoute":"query")+"() call aborted")}let h=new Map,f=ne(r,d,u,l,h),p=new Set(d.map((e=>e.route.id)));return r.forEach((e=>{p.has(e.route.id)||(f.loaderData[e.route.id]=null)})),t({},f,{matches:r,activeDeferreds:h.size>0?Object.fromEntries(h.entries()):null})}return{dataRoutes:c,query:async function(e,r){let{requestContext:a}=void 0===r?{}:r,o=new URL(e.url),n=e.method,u=s("",l(o),null,"default"),h=p(c,u,i);if(!be(n)&&"HEAD"!==n){let e=de(405,{method:n}),{matches:t,route:r}=ce(c);return{basename:i,location:u,matches:t,loaderData:{},actionData:null,errors:{[r.id]:e},statusCode:e.status,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}if(!h){let e=de(404,{pathname:u.pathname}),{matches:t,route:r}=ce(c);return{basename:i,location:u,matches:t,loaderData:{},actionData:null,errors:{[r.id]:e},statusCode:e.status,loaderHeaders:{},actionHeaders:{},activeDeferreds:null}}let f=await d(e,u,h,a);return ye(f)?f:t({location:u,basename:i},f)},queryRoute:async function(e,t){let{routeId:r,requestContext:a}=void 0===t?{}:t,o=new URL(e.url),n=e.method,u=s("",l(o),null,"default"),h=p(c,u,i);if(!be(n)&&"HEAD"!==n&&"OPTIONS"!==n)throw de(405,{method:n});if(!h)throw de(404,{pathname:u.pathname});let f=r?h.find((e=>e.route.id===r)):Ae(h,u);if(r&&!f)throw de(403,{pathname:u.pathname,routeId:r});if(!f)throw de(404,{pathname:u.pathname});let m=await d(e,u,h,a,f);if(ye(m))return m;let v=m.errors?Object.values(m.errors)[0]:void 0;if(void 0!==v)throw v;if(m.actionData)return Object.values(m.actionData)[0];if(m.loaderData){var y;let e=Object.values(m.loaderData)[0];return null!=(y=m.activeDeferreds)&&y[f.route.id]&&(e[J]=m.activeDeferreds[f.route.id]),e}}}},e.defer=function(e,t){return void 0===t&&(t={}),new j(e,"number"==typeof t?{status:t}:t)},e.generatePath=function(e,t){void 0===t&&(t={});let r=e;return r.endsWith("*")&&"*"!==r&&!r.endsWith("/*")&&(n(!1,'Route path "'+r+'" will be treated as if it were "'+r.replace(/\*$/,"/*")+'" because the `*` character must always follow a `/` in the pattern. To get rid of this warning, please change the route path to "'+r.replace(/\*$/,"/*")+'".'),r=r.replace(/\*$/,"/*")),(r.startsWith("/")?"/":"")+r.split(/\/+/).map(((e,r,a)=>{if(r===a.length-1&&"*"===e){return t["*"]}const n=e.match(/^:(\w+)(\??)$/);if(n){const[,e,r]=n;let a=t[e];return"?"===r?null==a?"":a:(null==a&&o(!1,'Missing ":'+e+'" param'),a)}return e.replace(/\?$/g,"")})).filter((e=>!!e)).join("/")},e.getStaticContextFromError=function(e,r,a){return t({},r,{statusCode:500,errors:{[r._deepestRenderedBoundaryId||e[0].id]:a}})},e.getToPathname=function(e){return""===e||""===e.pathname?"/":"string"==typeof e?c(e).pathname:e.pathname},e.isDeferredData=ve,e.isRouteErrorResponse=_,e.joinPaths=L,e.json=function(e,r){void 0===r&&(r={});let a="number"==typeof r?{status:r}:r,o=new Headers(a.headers);return o.has("Content-Type")||o.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(e),t({},a,{headers:o}))},e.matchPath=D,e.matchRoutes=p,e.normalizePathname=k,e.parsePath=c,e.redirect=function(e,r){void 0===r&&(r=302);let a=r;"number"==typeof a?a={status:a}:void 0===a.status&&(a.status=302);let o=new Headers(a.headers);return o.set("Location",e),new Response(null,t({},a,{headers:o}))},e.resolvePath=A,e.resolveTo=M,e.stripBasename=R,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=router.umd.min.js.map |
@@ -53,4 +53,21 @@ import type { Location, Path, To } from "./history"; | ||
export declare type DataResult = SuccessResult | DeferredResult | RedirectResult | ErrorResult; | ||
export declare type MutationFormMethod = "post" | "put" | "patch" | "delete"; | ||
export declare type FormMethod = "get" | MutationFormMethod; | ||
declare type LowerCaseFormMethod = "get" | "post" | "put" | "patch" | "delete"; | ||
declare type UpperCaseFormMethod = Uppercase<LowerCaseFormMethod>; | ||
/** | ||
* Users can specify either lowercase or uppercase form methods on <Form>, | ||
* useSubmit(), <fetcher.Form>, etc. | ||
*/ | ||
export declare type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod; | ||
/** | ||
* Active navigation/fetcher form methods are exposed in lowercase on the | ||
* RouterState | ||
*/ | ||
export declare type FormMethod = LowerCaseFormMethod; | ||
export declare type MutationFormMethod = Exclude<FormMethod, "get">; | ||
/** | ||
* In v7, active navigation/fetcher form methods are exposed in uppercase on the | ||
* RouterState. This is to align with the normalization done via fetch(). | ||
*/ | ||
export declare type V7_FormMethod = UpperCaseFormMethod; | ||
export declare type V7_MutationFormMethod = Exclude<V7_FormMethod, "GET">; | ||
export declare type FormEncType = "application/x-www-form-urlencoded" | "multipart/form-data"; | ||
@@ -63,3 +80,3 @@ /** | ||
export interface Submission { | ||
formMethod: FormMethod; | ||
formMethod: FormMethod | V7_FormMethod; | ||
formAction: string; | ||
@@ -79,3 +96,2 @@ formEncType: FormEncType; | ||
} | ||
declare type DataFunctionReturnValue = Promise<Response> | Response | Promise<any> | any; | ||
/** | ||
@@ -92,6 +108,12 @@ * Arguments passed to loader functions | ||
/** | ||
* Loaders and actions can return anything except `undefined` (`null` is a | ||
* valid return value if there is no data to return). Responses are preferred | ||
* and will ease any future migration to Remix | ||
*/ | ||
declare type DataFunctionValue = Response | NonNullable<unknown> | null; | ||
/** | ||
* Route loader function signature | ||
*/ | ||
export interface LoaderFunction { | ||
(args: LoaderFunctionArgs): DataFunctionReturnValue; | ||
(args: LoaderFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue; | ||
} | ||
@@ -102,47 +124,5 @@ /** | ||
export interface ActionFunction { | ||
(args: ActionFunctionArgs): DataFunctionReturnValue; | ||
(args: ActionFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue; | ||
} | ||
/** | ||
* @private | ||
* Arguments passed to route loader/action functions when middleware is enabled. | ||
*/ | ||
interface DataFunctionArgsWithMiddleware { | ||
request: Request; | ||
params: Params; | ||
context: MiddlewareContext; | ||
} | ||
/** | ||
* Arguments passed to middleware functions when middleware is enabled | ||
*/ | ||
export interface MiddlewareFunctionArgs extends DataFunctionArgsWithMiddleware { | ||
} | ||
/** | ||
* Route loader function signature when middleware is enabled | ||
*/ | ||
export interface MiddlewareFunction { | ||
(args: MiddlewareFunctionArgs): DataFunctionReturnValue; | ||
} | ||
/** | ||
* Arguments passed to loader functions when middleware is enabled | ||
*/ | ||
export interface LoaderFunctionArgsWithMiddleware extends DataFunctionArgsWithMiddleware { | ||
} | ||
/** | ||
* Route loader function signature when middleware is enabled | ||
*/ | ||
export interface LoaderFunctionWithMiddleware { | ||
(args: LoaderFunctionArgsWithMiddleware): DataFunctionReturnValue; | ||
} | ||
/** | ||
* Arguments passed to action functions when middleware is enabled | ||
*/ | ||
export interface ActionFunctionArgsWithMiddleware extends DataFunctionArgsWithMiddleware { | ||
} | ||
/** | ||
* Route action function signature when middleware is enabled | ||
*/ | ||
export interface ActionFunctionWithMiddleware { | ||
(args: ActionFunctionArgsWithMiddleware): DataFunctionReturnValue; | ||
} | ||
/** | ||
* Route shouldRevalidate function signature. This runs after any submission | ||
@@ -169,2 +149,34 @@ * (navigation or fetcher), so we flatten the navigation/fetcher submission | ||
/** | ||
* Function provided by the framework-aware layers to set `hasErrorBoundary` | ||
* from the framework-aware `errorElement` prop | ||
* | ||
* @deprecated Use `mapRouteProperties` instead | ||
*/ | ||
export interface DetectErrorBoundaryFunction { | ||
(route: AgnosticRouteObject): boolean; | ||
} | ||
/** | ||
* Function provided by the framework-aware layers to set any framework-specific | ||
* properties from framework-agnostic properties | ||
*/ | ||
export interface MapRoutePropertiesFunction { | ||
(route: AgnosticRouteObject): { | ||
hasErrorBoundary: boolean; | ||
} & Record<string, any>; | ||
} | ||
/** | ||
* Keys we cannot change from within a lazy() function. We spread all other keys | ||
* onto the route. Either they're meaningful to the router, or they'll get | ||
* ignored. | ||
*/ | ||
export declare type ImmutableRouteKey = "lazy" | "caseSensitive" | "path" | "id" | "index" | "children"; | ||
export declare const immutableRouteKeys: Set<ImmutableRouteKey>; | ||
/** | ||
* lazy() function to load a route definition, which can add non-matching | ||
* related properties to a route | ||
*/ | ||
export interface LazyRouteFunction<R extends AgnosticRouteObject> { | ||
(): Promise<Omit<R, ImmutableRouteKey>>; | ||
} | ||
/** | ||
* Base RouteObject with common props shared by all types of routes | ||
@@ -176,8 +188,8 @@ */ | ||
id?: string; | ||
middleware?: MiddlewareFunction; | ||
loader?: LoaderFunction | LoaderFunctionWithMiddleware; | ||
action?: ActionFunction | ActionFunctionWithMiddleware; | ||
loader?: LoaderFunction; | ||
action?: ActionFunction; | ||
hasErrorBoundary?: boolean; | ||
shouldRevalidate?: ShouldRevalidateFunction; | ||
handle?: any; | ||
lazy?: LazyRouteFunction<AgnosticBaseRouteObject>; | ||
}; | ||
@@ -214,2 +226,3 @@ /** | ||
export declare type AgnosticDataRouteObject = AgnosticDataIndexRouteObject | AgnosticDataNonIndexRouteObject; | ||
export declare type RouteManifest = Record<string, AgnosticDataRouteObject | undefined>; | ||
declare type _PathParam<Path extends string> = Path extends `${infer L}/${infer R}` ? _PathParam<L> | _PathParam<R> : Path extends `:${infer Param}` ? Param extends `${infer Optional}?` ? Optional : Param : never; | ||
@@ -225,3 +238,3 @@ /** | ||
*/ | ||
declare type PathParam<Path extends string> = Path extends "*" ? "*" : Path extends `${infer Rest}/*` ? "*" | _PathParam<Rest> : _PathParam<Path>; | ||
declare type PathParam<Path extends string> = Path extends "*" | "/*" ? "*" : Path extends `${infer Rest}/*` ? "*" | _PathParam<Rest> : _PathParam<Path>; | ||
export declare type ParamParseKey<Segment extends string> = [ | ||
@@ -259,3 +272,3 @@ PathParam<Segment> | ||
} | ||
export declare function convertRoutesToDataRoutes(routes: AgnosticRouteObject[], parentPath?: number[], allIds?: Set<string>): AgnosticDataRouteObject[]; | ||
export declare function convertRoutesToDataRoutes(routes: AgnosticRouteObject[], mapRouteProperties: MapRoutePropertiesFunction, parentPath?: number[], manifest?: RouteManifest): AgnosticDataRouteObject[]; | ||
/** | ||
@@ -328,6 +341,2 @@ * Matches the given routes to a location and returns the match data. | ||
/** | ||
* @private | ||
*/ | ||
export declare function warning(cond: any, message: string): void; | ||
/** | ||
* Returns a resolved path object relative to the given pathname. | ||
@@ -444,50 +453,2 @@ * | ||
export declare function isRouteErrorResponse(error: any): error is ErrorResponse; | ||
/** | ||
* Context object passed through middleware functions and into action/loaders. | ||
* | ||
* Supports only key/value for now, eventually will be enhanced | ||
*/ | ||
export interface MiddlewareContext { | ||
/** | ||
* Retrieve a value from context | ||
*/ | ||
get<T>(key: MiddlewareContextInstance<T>): T; | ||
/** | ||
* Set a value from context | ||
*/ | ||
set<T>(key: MiddlewareContextInstance<T>, value: T): void; | ||
/** | ||
* Call any child middlewares and the destination loader/action | ||
*/ | ||
next: () => DataFunctionReturnValue; | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Return the entries - needed so we can copy values from the serverMiddleware | ||
* context into route-specific contexts | ||
*/ | ||
entries(): IterableIterator<[MiddlewareContextInstance<unknown>, unknown]>; | ||
} | ||
/** | ||
* Generic class to "hold" a default middleware value and the generic type so | ||
* we can enforce typings on middleware.get/set | ||
*/ | ||
export declare class MiddlewareContextInstance<T> { | ||
private defaultValue; | ||
constructor(defaultValue?: T); | ||
getDefaultValue(): T; | ||
} | ||
/** | ||
* Create a middleware context that can be used as a "key" to set/get middleware | ||
* values in a strongly-typed fashion | ||
*/ | ||
export declare function createMiddlewareContext<T extends unknown>(defaultValue?: T): MiddlewareContextInstance<T>; | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Create a middleware "context" to store values and provide a next() hook | ||
*/ | ||
export declare function createMiddlewareStore(initialMiddlewareContext?: MiddlewareContext): MiddlewareContext; | ||
export {}; |
@@ -484,3 +484,3 @@ //////////////////////////////////////////////////////////////////////////////// | ||
function warning(cond: any, message: string) { | ||
export function warning(cond: any, message: string) { | ||
if (!cond) { | ||
@@ -638,2 +638,9 @@ // eslint-disable-next-line no-console | ||
} catch (error) { | ||
// If the exception is because `state` can't be serialized, let that throw | ||
// outwards just like a replace call would so the dev knows the cause | ||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps | ||
// https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal | ||
if (error instanceof DOMException && error.name === "DataCloneError") { | ||
throw error; | ||
} | ||
// They are going to lose state here, but there is no real | ||
@@ -640,0 +647,0 @@ // way to warn them about it since the page will refresh... |
21
index.ts
export type { | ||
ActionFunction, | ||
ActionFunctionArgs, | ||
ActionFunctionWithMiddleware, | ||
ActionFunctionArgsWithMiddleware, | ||
AgnosticDataIndexRouteObject, | ||
@@ -14,13 +12,10 @@ AgnosticDataNonIndexRouteObject, | ||
AgnosticRouteObject, | ||
LazyRouteFunction, | ||
TrackedPromise, | ||
FormEncType, | ||
FormMethod, | ||
HTMLFormMethod, | ||
JsonFunction, | ||
LoaderFunction, | ||
LoaderFunctionArgs, | ||
LoaderFunctionWithMiddleware, | ||
LoaderFunctionArgsWithMiddleware, | ||
MiddlewareContext, | ||
MiddlewareFunction, | ||
MiddlewareFunctionArgs, | ||
ParamParseKey, | ||
@@ -32,3 +27,3 @@ Params, | ||
ShouldRevalidateFunction, | ||
Submission, | ||
V7_FormMethod, | ||
} from "./utils"; | ||
@@ -39,3 +34,2 @@ | ||
ErrorResponse, | ||
createMiddlewareContext, | ||
defer, | ||
@@ -54,3 +48,2 @@ generatePath, | ||
stripBasename, | ||
warning, | ||
} from "./utils"; | ||
@@ -78,3 +71,2 @@ | ||
createMemoryHistory, | ||
invariant, | ||
parsePath, | ||
@@ -93,2 +85,3 @@ } from "./history"; | ||
/** @internal */ | ||
export type { RouteManifest as UNSAFE_RouteManifest } from "./utils"; | ||
export { | ||
@@ -98,3 +91,7 @@ DeferredData as UNSAFE_DeferredData, | ||
getPathContributingMatches as UNSAFE_getPathContributingMatches, | ||
createMiddlewareStore as UNSAFE_createMiddlewareStore, | ||
} from "./utils"; | ||
export { | ||
invariant as UNSAFE_invariant, | ||
warning as UNSAFE_warning, | ||
} from "./history"; |
MIT License | ||
Copyright (c) React Training 2015-2019 | ||
Copyright (c) Remix Software 2020-2022 | ||
Copyright (c) React Training LLC 2015-2019 | ||
Copyright (c) Remix Software Inc. 2020-2021 | ||
Copyright (c) Shopify Inc. 2022-2023 | ||
@@ -6,0 +7,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
{ | ||
"name": "@remix-run/router", | ||
"version": "0.0.0-experimental-48058118", | ||
"version": "0.0.0-experimental-5f08b33f", | ||
"description": "Nested/Data-driven/Framework-agnostic Routing", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -5,3 +5,3 @@ # Remix Router | ||
If you're using React Router, you should never `import` anything directly from the `@remix-run/router` or `react-router` packages, but you should have everything you need in either `react-router-dom` or `react-router-native`. Both of those packages re-export everything from `@remix-run/router` and `react-router`. | ||
If you're using React Router, you should never `import` anything directly from the `@remix-run/router` - you should have everything you need in `react-router-dom` (or `react-router`/`react-router-native` if you're not rendering in the browser). All of those packages should re-export everything you would otherwise need from `@remix-run/router`. | ||
@@ -20,7 +20,19 @@ > **Warning** | ||
let router = createRouter({ | ||
// Routes array | ||
routes: , | ||
// History instance | ||
history, | ||
}).initialize() | ||
// Required properties | ||
routes: [{ | ||
path: '/', | ||
loader: ({ request, params }) => { /* ... */ }, | ||
children: [{ | ||
path: 'home', | ||
loader: ({ request, params }) => { /* ... */ }, | ||
}] | ||
}, | ||
history: createBrowserHistory(), | ||
// Optional properties | ||
basename, // Base path | ||
mapRouteProperties, // Map framework-agnostic routes to framework-aware routes | ||
future, // Future flags | ||
hydrationData, // Hydration data if using server-side-rendering | ||
}).initialize(); | ||
``` | ||
@@ -83,2 +95,7 @@ | ||
}); | ||
// Relative routing from a source routeId | ||
router.navigate("../../somewhere", { | ||
fromRouteId: "active-route-id", | ||
}); | ||
``` | ||
@@ -107,2 +124,11 @@ | ||
### Future Flags | ||
We use _Future Flags_ in the router to help us introduce breaking changes in an opt-in fashion ahead of major releases. Please check out the [blog post][future-flags-post] and [React Router Docs][api-development-strategy] for more information on this process. The currently available future flags in `@remix-run/router` are: | ||
| Flag | Description | | ||
| ------------------------ | ------------------------------------------------------------------------- | | ||
| `v7_normalizeFormMethod` | Normalize `useNavigation().formMethod` to be an uppercase HTTP Method | | ||
| `v7_prependBasename` | Prepend the `basename` to incoming `router.navigate`/`router.fetch` paths | | ||
[react-router]: https://reactrouter.com | ||
@@ -112,1 +138,3 @@ [remix]: https://remix.run | ||
[remix-routers-repo]: https://github.com/brophdawg11/remix-routers | ||
[api-development-strategy]: https://reactrouter.com/en/main/guides/api-development-strategy | ||
[future-flags-post]: https://remix.run/blog/future-flags |
370
utils.ts
import type { Location, Path, To } from "./history"; | ||
import { invariant, parsePath } from "./history"; | ||
import { warning, invariant, parsePath } from "./history"; | ||
@@ -66,5 +66,25 @@ /** | ||
export type MutationFormMethod = "post" | "put" | "patch" | "delete"; | ||
export type FormMethod = "get" | MutationFormMethod; | ||
type LowerCaseFormMethod = "get" | "post" | "put" | "patch" | "delete"; | ||
type UpperCaseFormMethod = Uppercase<LowerCaseFormMethod>; | ||
/** | ||
* Users can specify either lowercase or uppercase form methods on <Form>, | ||
* useSubmit(), <fetcher.Form>, etc. | ||
*/ | ||
export type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod; | ||
/** | ||
* Active navigation/fetcher form methods are exposed in lowercase on the | ||
* RouterState | ||
*/ | ||
export type FormMethod = LowerCaseFormMethod; | ||
export type MutationFormMethod = Exclude<FormMethod, "get">; | ||
/** | ||
* In v7, active navigation/fetcher form methods are exposed in uppercase on the | ||
* RouterState. This is to align with the normalization done via fetch(). | ||
*/ | ||
export type V7_FormMethod = UpperCaseFormMethod; | ||
export type V7_MutationFormMethod = Exclude<V7_FormMethod, "GET">; | ||
export type FormEncType = | ||
@@ -80,3 +100,3 @@ | "application/x-www-form-urlencoded" | ||
export interface Submission { | ||
formMethod: FormMethod; | ||
formMethod: FormMethod | V7_FormMethod; | ||
formAction: string; | ||
@@ -98,8 +118,2 @@ formEncType: FormEncType; | ||
type DataFunctionReturnValue = | ||
| Promise<Response> | ||
| Response | ||
| Promise<any> | ||
| any; | ||
/** | ||
@@ -116,6 +130,13 @@ * Arguments passed to loader functions | ||
/** | ||
* Loaders and actions can return anything except `undefined` (`null` is a | ||
* valid return value if there is no data to return). Responses are preferred | ||
* and will ease any future migration to Remix | ||
*/ | ||
type DataFunctionValue = Response | NonNullable<unknown> | null; | ||
/** | ||
* Route loader function signature | ||
*/ | ||
export interface LoaderFunction { | ||
(args: LoaderFunctionArgs): DataFunctionReturnValue; | ||
(args: LoaderFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue; | ||
} | ||
@@ -127,55 +148,6 @@ | ||
export interface ActionFunction { | ||
(args: ActionFunctionArgs): DataFunctionReturnValue; | ||
(args: ActionFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue; | ||
} | ||
/** | ||
* @private | ||
* Arguments passed to route loader/action functions when middleware is enabled. | ||
*/ | ||
interface DataFunctionArgsWithMiddleware { | ||
request: Request; | ||
params: Params; | ||
context: MiddlewareContext; | ||
} | ||
/** | ||
* Arguments passed to middleware functions when middleware is enabled | ||
*/ | ||
export interface MiddlewareFunctionArgs | ||
extends DataFunctionArgsWithMiddleware {} | ||
/** | ||
* Route loader function signature when middleware is enabled | ||
*/ | ||
export interface MiddlewareFunction { | ||
(args: MiddlewareFunctionArgs): DataFunctionReturnValue; | ||
} | ||
/** | ||
* Arguments passed to loader functions when middleware is enabled | ||
*/ | ||
export interface LoaderFunctionArgsWithMiddleware | ||
extends DataFunctionArgsWithMiddleware {} | ||
/** | ||
* Route loader function signature when middleware is enabled | ||
*/ | ||
export interface LoaderFunctionWithMiddleware { | ||
(args: LoaderFunctionArgsWithMiddleware): DataFunctionReturnValue; | ||
} | ||
/** | ||
* Arguments passed to action functions when middleware is enabled | ||
*/ | ||
export interface ActionFunctionArgsWithMiddleware | ||
extends DataFunctionArgsWithMiddleware {} | ||
/** | ||
* Route action function signature when middleware is enabled | ||
*/ | ||
export interface ActionFunctionWithMiddleware { | ||
(args: ActionFunctionArgsWithMiddleware): DataFunctionReturnValue; | ||
} | ||
/** | ||
* Route shouldRevalidate function signature. This runs after any submission | ||
@@ -203,2 +175,52 @@ * (navigation or fetcher), so we flatten the navigation/fetcher submission | ||
/** | ||
* Function provided by the framework-aware layers to set `hasErrorBoundary` | ||
* from the framework-aware `errorElement` prop | ||
* | ||
* @deprecated Use `mapRouteProperties` instead | ||
*/ | ||
export interface DetectErrorBoundaryFunction { | ||
(route: AgnosticRouteObject): boolean; | ||
} | ||
/** | ||
* Function provided by the framework-aware layers to set any framework-specific | ||
* properties from framework-agnostic properties | ||
*/ | ||
export interface MapRoutePropertiesFunction { | ||
(route: AgnosticRouteObject): { | ||
hasErrorBoundary: boolean; | ||
} & Record<string, any>; | ||
} | ||
/** | ||
* Keys we cannot change from within a lazy() function. We spread all other keys | ||
* onto the route. Either they're meaningful to the router, or they'll get | ||
* ignored. | ||
*/ | ||
export type ImmutableRouteKey = | ||
| "lazy" | ||
| "caseSensitive" | ||
| "path" | ||
| "id" | ||
| "index" | ||
| "children"; | ||
export const immutableRouteKeys = new Set<ImmutableRouteKey>([ | ||
"lazy", | ||
"caseSensitive", | ||
"path", | ||
"id", | ||
"index", | ||
"children", | ||
]); | ||
/** | ||
* lazy() function to load a route definition, which can add non-matching | ||
* related properties to a route | ||
*/ | ||
export interface LazyRouteFunction<R extends AgnosticRouteObject> { | ||
(): Promise<Omit<R, ImmutableRouteKey>>; | ||
} | ||
/** | ||
* Base RouteObject with common props shared by all types of routes | ||
@@ -210,8 +232,8 @@ */ | ||
id?: string; | ||
middleware?: MiddlewareFunction; | ||
loader?: LoaderFunction | LoaderFunctionWithMiddleware; | ||
action?: ActionFunction | ActionFunctionWithMiddleware; | ||
loader?: LoaderFunction; | ||
action?: ActionFunction; | ||
hasErrorBoundary?: boolean; | ||
shouldRevalidate?: ShouldRevalidateFunction; | ||
handle?: any; | ||
lazy?: LazyRouteFunction<AgnosticBaseRouteObject>; | ||
}; | ||
@@ -259,2 +281,4 @@ | ||
export type RouteManifest = Record<string, AgnosticDataRouteObject | undefined>; | ||
// Recursive helper for finding path parameters in the absence of wildcards | ||
@@ -284,3 +308,3 @@ type _PathParam<Path extends string> = | ||
// check if path is just a wildcard | ||
Path extends "*" | ||
Path extends "*" | "/*" | ||
? "*" | ||
@@ -345,4 +369,5 @@ : // look for wildcard at the end of the path | ||
routes: AgnosticRouteObject[], | ||
mapRouteProperties: MapRoutePropertiesFunction, | ||
parentPath: number[] = [], | ||
allIds: Set<string> = new Set<string>() | ||
manifest: RouteManifest = {} | ||
): AgnosticDataRouteObject[] { | ||
@@ -357,10 +382,14 @@ return routes.map((route, index) => { | ||
invariant( | ||
!allIds.has(id), | ||
!manifest[id], | ||
`Found a route id collision on id "${id}". Route ` + | ||
"id's must be globally unique within Data Router usages" | ||
); | ||
allIds.add(id); | ||
if (isIndexRoute(route)) { | ||
let indexRoute: AgnosticDataIndexRouteObject = { ...route, id }; | ||
let indexRoute: AgnosticDataIndexRouteObject = { | ||
...route, | ||
...mapRouteProperties(route), | ||
id, | ||
}; | ||
manifest[id] = indexRoute; | ||
return indexRoute; | ||
@@ -370,7 +399,17 @@ } else { | ||
...route, | ||
...mapRouteProperties(route), | ||
id, | ||
children: route.children | ||
? convertRoutesToDataRoutes(route.children, treePath, allIds) | ||
: undefined, | ||
children: undefined, | ||
}; | ||
manifest[id] = pathOrLayoutRoute; | ||
if (route.children) { | ||
pathOrLayoutRoute.children = convertRoutesToDataRoutes( | ||
route.children, | ||
mapRouteProperties, | ||
treePath, | ||
manifest | ||
); | ||
} | ||
return pathOrLayoutRoute; | ||
@@ -692,3 +731,3 @@ } | ||
): string { | ||
let path = originalPath; | ||
let path: string = originalPath; | ||
if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) { | ||
@@ -705,45 +744,42 @@ warning( | ||
return ( | ||
path | ||
.replace( | ||
/^:(\w+)(\??)/g, | ||
(_, key: PathParam<Path>, optional: string | undefined) => { | ||
let param = params[key]; | ||
if (optional === "?") { | ||
return param == null ? "" : param; | ||
} | ||
if (param == null) { | ||
invariant(false, `Missing ":${key}" param`); | ||
} | ||
return param; | ||
// ensure `/` is added at the beginning if the path is absolute | ||
const prefix = path.startsWith("/") ? "/" : ""; | ||
const segments = path | ||
.split(/\/+/) | ||
.map((segment, index, array) => { | ||
const isLastSegment = index === array.length - 1; | ||
// only apply the splat if it's the last segment | ||
if (isLastSegment && segment === "*") { | ||
const star = "*" as PathParam<Path>; | ||
const starParam = params[star]; | ||
// Apply the splat | ||
return starParam; | ||
} | ||
const keyMatch = segment.match(/^:(\w+)(\??)$/); | ||
if (keyMatch) { | ||
const [, key, optional] = keyMatch; | ||
let param = params[key as PathParam<Path>]; | ||
if (optional === "?") { | ||
return param == null ? "" : param; | ||
} | ||
) | ||
.replace( | ||
/\/:(\w+)(\??)/g, | ||
(_, key: PathParam<Path>, optional: string | undefined) => { | ||
let param = params[key]; | ||
if (optional === "?") { | ||
return param == null ? "" : `/${param}`; | ||
} | ||
if (param == null) { | ||
invariant(false, `Missing ":${key}" param`); | ||
} | ||
return `/${param}`; | ||
if (param == null) { | ||
invariant(false, `Missing ":${key}" param`); | ||
} | ||
) | ||
return param; | ||
} | ||
// Remove any optional markers from optional static segments | ||
.replace(/\?/g, "") | ||
.replace(/(\/?)\*/, (_, prefix, __, str) => { | ||
const star = "*" as PathParam<Path>; | ||
return segment.replace(/\?$/g, ""); | ||
}) | ||
// Remove empty segments | ||
.filter((segment) => !!segment); | ||
if (params[star] == null) { | ||
// If no splat was provided, trim the trailing slash _unless_ it's | ||
// the entire path | ||
return str === "/*" ? "/" : ""; | ||
} | ||
// Apply the splat | ||
return `${prefix}${params[star]}`; | ||
}) | ||
); | ||
return prefix + segments.join("/"); | ||
} | ||
@@ -965,22 +1001,2 @@ | ||
/** | ||
* @private | ||
*/ | ||
export function warning(cond: any, message: string): void { | ||
if (!cond) { | ||
// eslint-disable-next-line no-console | ||
if (typeof console !== "undefined") console.warn(message); | ||
try { | ||
// Welcome to debugging @remix-run/router! | ||
// | ||
// This error is thrown as a convenience so you can more easily | ||
// find the source for a warning that appears in the console by | ||
// enabling "pause on exceptions" in your JavaScript debugger. | ||
throw new Error(message); | ||
// eslint-disable-next-line no-empty | ||
} catch (e) {} | ||
} | ||
} | ||
/** | ||
* Returns a resolved path object relative to the given pathname. | ||
@@ -1485,91 +1501,1 @@ * | ||
} | ||
/** | ||
* Context object passed through middleware functions and into action/loaders. | ||
* | ||
* Supports only key/value for now, eventually will be enhanced | ||
*/ | ||
export interface MiddlewareContext { | ||
/** | ||
* Retrieve a value from context | ||
*/ | ||
get<T>(key: MiddlewareContextInstance<T>): T; | ||
/** | ||
* Set a value from context | ||
*/ | ||
set<T>(key: MiddlewareContextInstance<T>, value: T): void; | ||
/** | ||
* Call any child middlewares and the destination loader/action | ||
*/ | ||
next: () => DataFunctionReturnValue; | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Return the entries - needed so we can copy values from the serverMiddleware | ||
* context into route-specific contexts | ||
*/ | ||
entries(): IterableIterator<[MiddlewareContextInstance<unknown>, unknown]>; | ||
} | ||
/** | ||
* Generic class to "hold" a default middleware value and the generic type so | ||
* we can enforce typings on middleware.get/set | ||
*/ | ||
export class MiddlewareContextInstance<T> { | ||
private defaultValue: T | undefined; | ||
constructor(defaultValue?: T) { | ||
if (typeof defaultValue !== "undefined") { | ||
this.defaultValue = defaultValue; | ||
} | ||
} | ||
getDefaultValue(): T { | ||
if (typeof this.defaultValue === "undefined") { | ||
throw new Error("Unable to find a value in the middleware context"); | ||
} | ||
return this.defaultValue; | ||
} | ||
} | ||
/** | ||
* Create a middleware context that can be used as a "key" to set/get middleware | ||
* values in a strongly-typed fashion | ||
*/ | ||
export function createMiddlewareContext<T extends unknown>( | ||
defaultValue?: T | ||
): MiddlewareContextInstance<T> { | ||
return new MiddlewareContextInstance<T>(defaultValue); | ||
} | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Create a middleware "context" to store values and provide a next() hook | ||
*/ | ||
export function createMiddlewareStore( | ||
initialMiddlewareContext?: MiddlewareContext | ||
) { | ||
let store = new Map(initialMiddlewareContext?.entries()); | ||
let middlewareContext: MiddlewareContext = { | ||
get<T>(k: MiddlewareContextInstance<T>) { | ||
if (store.has(k)) { | ||
return store.get(k) as T; | ||
} | ||
return k.getDefaultValue(); | ||
}, | ||
set<T>(k: MiddlewareContextInstance<T>, v: T) { | ||
if (typeof v === "undefined") { | ||
throw new Error( | ||
"You cannot set an undefined value in the middleware context" | ||
); | ||
} | ||
store.set(k, v); | ||
}, | ||
next: () => {}, | ||
entries: () => store.entries(), | ||
}; | ||
return middlewareContext; | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
2054056
7.19%19090
9.99%136
25.93%