` easier if relative routing would _replace_ the current splat:
+
+ ```jsx
+
+
+ } />
+ } />
+
+
+ ```
+
+ Any paths like `/dashboard`, `/dashboard/team`, `/dashboard/projects` will match the `Dashboard` route. The dashboard component itself can then render nested ``:
+
+ ```jsx
+ function Dashboard() {
+ return (
+
+
Dashboard
+
+ Dashboard Home
+ Team
+ Projects
+
+
+
+ } />
+ } />
+ } />
+
+
+ );
+ }
+ ```
+
+ Now, all links and route paths are relative to the router above them. This makes code splitting and compartmentalizing your app really easy. You could render the `Dashboard` as its own independent app, or embed it into your large app without making any changes to it.
+
+ **The Problem**
+
+ The problem is that this concept of ignoring part of a path breaks a lot of other assumptions in React Router - namely that `"."` always means the current location pathname for that route. When we ignore the splat portion, we start getting invalid paths when using `"."`:
+
+ ```jsx
+ // If we are on URL /dashboard/team, and we want to link to /dashboard/team:
+ function DashboardTeam() {
+ // ❌ This is broken and results in
+ return A broken link to the Current URL;
+
+ // ✅ This is fixed but super unintuitive since we're already at /dashboard/team!
+ return A broken link to the Current URL;
+ }
+ ```
+
+ We've also introduced an issue that we can no longer move our `DashboardTeam` component around our route hierarchy easily - since it behaves differently if we're underneath a non-splat route, such as `/dashboard/:widget`. Now, our `"."` links will, properly point to ourself _inclusive of the dynamic param value_ so behavior will break from it's corresponding usage in a `/dashboard/*` route.
+
+ Even worse, consider a nested splat route configuration:
+
+ ```jsx
+
+
+
+ } />
+
+
+
+ ```
+
+ Now, a ` ` and a ` ` inside the `Dashboard` component go to the same place! That is definitely not correct!
+
+ Another common issue arose in Data Routers (and Remix) where any `;
+ },
+ },
+ ],
+ });
+ ```
+
+ This is just a compounded issue from the above because the default location for a `Form` to submit to is itself (`"."`) - and if we ignore the splat portion, that now resolves to the parent route.
+
+ **The Solution**
+ If you are leveraging this behavior, it's recommended to enable the future flag, move your splat to it's own route, and leverage `../` for any links to "sibling" pages:
+
+ ```jsx
+
+
+
+ } />
+
+
+
+
+ function Dashboard() {
+ return (
+
+
Dashboard
+
+ Dashboard Home
+ Team
+ Projects
+
+
+
+ } />
+ } />
+ } />
+
+
+ );
+ }
+ ```
+
+ This way, `.` means "the full current pathname for my route" in all cases (including static, dynamic, and splat routes) and `..` always means "my parents pathname".
+
+### Patch Changes
+
+- Catch and bubble errors thrown when trying to unwrap responses from `loader`/`action` functions ([#11061](https://github.com/remix-run/react-router/pull/11061))
+- Fix `relative="path"` issue when rendering `Link`/`NavLink` outside of matched routes ([#11062](https://github.com/remix-run/react-router/pull/11062))
+
+## 1.13.1
+
+### Patch Changes
+
+- Revert the `useResolvedPath` fix for splat routes due to a large number of applications that were relying on the buggy behavior (see https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329). We plan to re-introduce this fix behind a future flag in the next minor version. ([#11078](https://github.com/remix-run/react-router/pull/11078))
+
+## 1.13.0
+
+### Minor Changes
+
+- Export the `PathParam` type from the public API ([#10719](https://github.com/remix-run/react-router/pull/10719))
+
+### Patch Changes
+
+- Fix bug with `resolveTo` in splat routes ([#11045](https://github.com/remix-run/react-router/pull/11045))
+ - This is a follow up to [#10983](https://github.com/remix-run/react-router/pull/10983) to handle the few other code paths using `getPathContributingMatches`
+ - This removes the `UNSAFE_getPathContributingMatches` export from `@remix-run/router` since we no longer need this in the `react-router`/`react-router-dom` layers
+- Do not revalidate unmounted fetchers when `v7_fetcherPersist` is enabled ([#11044](https://github.com/remix-run/react-router/pull/11044))
+
+## 1.12.0
+
+### Minor Changes
+
+- Add `unstable_flushSync` option to `router.navigate` and `router.fetch` to tell the React Router layer to opt-out of `React.startTransition` and into `ReactDOM.flushSync` for state updates ([#11005](https://github.com/remix-run/react-router/pull/11005))
+
+### Patch Changes
+
+- Fix `relative="path"` bug where relative path calculations started from the full location pathname, instead of from the current contextual route pathname. ([#11006](https://github.com/remix-run/react-router/pull/11006))
+
+ ```jsx
+
+ }>
+
+
+ ;
+
+ function Component() {
+ return (
+ <>
+ {/* This is now correctly relative to /a/b, not /a/b/c */}
+
+
+ >
+ );
+ }
+ ```
+
+## 1.11.0
+
+### Minor Changes
+
+- Add a new `future.v7_fetcherPersist` flag to the `@remix-run/router` to change the persistence behavior of fetchers when `router.deleteFetcher` is called. Instead of being immediately cleaned up, fetchers will persist until they return to an `idle` state ([RFC](https://github.com/remix-run/remix/discussions/7698)) ([#10962](https://github.com/remix-run/react-router/pull/10962))
+
+ - This is sort of a long-standing bug fix as the `useFetchers()` API was always supposed to only reflect **in-flight** fetcher information for pending/optimistic UI -- it was not intended to reflect fetcher data or hang onto fetchers after they returned to an `idle` state
+ - Keep an eye out for the following specific behavioral changes when opting into this flag and check your app for compatibility:
+ - Fetchers that complete _while still mounted_ will no longer appear in `useFetchers()`. They served effectively no purpose in there since you can access the data via `useFetcher().data`).
+ - Fetchers that previously unmounted _while in-flight_ will not be immediately aborted and will instead be cleaned up once they return to an `idle` state. They will remain exposed via `useFetchers` while in-flight so you can still access pending/optimistic data after unmount.
+
+- When `v7_fetcherPersist` is enabled, the router now performs ref-counting on fetcher keys via `getFetcher`/`deleteFetcher` so it knows when a given fetcher is totally unmounted from the UI ([#10977](https://github.com/remix-run/react-router/pull/10977))
+
+ - Once a fetcher has been totally unmounted, we can ignore post-processing of a persisted fetcher result such as a redirect or an error
+ - The router will also pass a new `deletedFetchers` array to the subscriber callbacks so that the UI layer can remove associated fetcher data
+
+- Add support for optional path segments in `matchPath` ([#10768](https://github.com/remix-run/react-router/pull/10768))
+
+### Patch Changes
+
+- Fix `router.getFetcher`/`router.deleteFetcher` type definitions which incorrectly specified `key` as an optional parameter ([#10960](https://github.com/remix-run/react-router/pull/10960))
+
+## 1.10.0
+
+### Minor Changes
+
+- Add experimental support for the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/ViewTransition) by allowing users to opt-into view transitions on navigations via the new `unstable_viewTransition` option to `router.navigate` ([#10916](https://github.com/remix-run/react-router/pull/10916))
+
+### Patch Changes
+
+- Allow 404 detection to leverage root route error boundary if path contains a URL segment ([#10852](https://github.com/remix-run/react-router/pull/10852))
+- Fix `ErrorResponse` type to avoid leaking internal field ([#10876](https://github.com/remix-run/react-router/pull/10876))
+
+## 1.9.0
+
+### Minor Changes
+
+- In order to move towards stricter TypeScript support in the future, we're aiming to replace current usages of `any` with `unknown` on exposed typings for user-provided data. To do this in Remix v2 without introducing breaking changes in React Router v6, we have added generics to a number of shared types. These continue to default to `any` in React Router and are overridden with `unknown` in Remix. In React Router v7 we plan to move these to `unknown` as a breaking change. ([#10843](https://github.com/remix-run/react-router/pull/10843))
+ - `Location` now accepts a generic for the `location.state` value
+ - `ActionFunctionArgs`/`ActionFunction`/`LoaderFunctionArgs`/`LoaderFunction` now accept a generic for the `context` parameter (only used in SSR usages via `createStaticHandler`)
+ - The return type of `useMatches` (now exported as `UIMatch`) accepts generics for `match.data` and `match.handle` - both of which were already set to `unknown`
+- Move the `@private` class export `ErrorResponse` to an `UNSAFE_ErrorResponseImpl` export since it is an implementation detail and there should be no construction of `ErrorResponse` instances in userland. This frees us up to export a `type ErrorResponse` which correlates to an instance of the class via `InstanceType`. Userland code should only ever be using `ErrorResponse` as a type and should be type-narrowing via `isRouteErrorResponse`. ([#10811](https://github.com/remix-run/react-router/pull/10811))
+- Export `ShouldRevalidateFunctionArgs` interface ([#10797](https://github.com/remix-run/react-router/pull/10797))
+- Removed private/internal APIs only required for the Remix v1 backwards compatibility layer and no longer needed in Remix v2 (`_isFetchActionRedirect`, `_hasFetcherDoneAnything`) ([#10715](https://github.com/remix-run/react-router/pull/10715))
+
+### Patch Changes
+
+- Add method/url to error message on aborted `query`/`queryRoute` calls ([#10793](https://github.com/remix-run/react-router/pull/10793))
+- Fix a race-condition with loader/action-thrown errors on `route.lazy` routes ([#10778](https://github.com/remix-run/react-router/pull/10778))
+- Fix type for `actionResult` on the arguments object passed to `shouldRevalidate` ([#10779](https://github.com/remix-run/react-router/pull/10779))
+
+## 1.8.0
+
+### Minor Changes
+
+- Add's a new `redirectDocument()` function which allows users to specify that a redirect from a `loader`/`action` should trigger a document reload (via `window.location`) instead of attempting to navigate to the redirected location via React Router ([#10705](https://github.com/remix-run/react-router/pull/10705))
+
+### Patch Changes
+
+- Fix an issue in `queryRoute` that was not always identifying thrown `Response` instances ([#10717](https://github.com/remix-run/react-router/pull/10717))
+- Ensure hash history always includes a leading slash on hash pathnames ([#10753](https://github.com/remix-run/react-router/pull/10753))
+
+## 1.7.2
+
+### Patch Changes
+
+- Trigger an error if a `defer` promise resolves/rejects with `undefined` in order to match the behavior of loaders and actions which must return a value or `null` ([#10690](https://github.com/remix-run/react-router/pull/10690))
+- Properly handle fetcher redirects interrupted by normal navigations ([#10674](https://github.com/remix-run/react-router/pull/10674), [#10709](https://github.com/remix-run/react-router/pull/10709))
+- Initial-load fetchers should not automatically revalidate on GET navigations ([#10688](https://github.com/remix-run/react-router/pull/10688))
+- Enhance the return type of `Route.lazy` to prohibit returning an empty object ([#10634](https://github.com/remix-run/react-router/pull/10634))
+
+## 1.7.1
+
+### Patch Changes
+
+- Fix issues with reused blockers on subsequent navigations ([#10656](https://github.com/remix-run/react-router/pull/10656))
+
+## 1.7.0
+
+### Minor Changes
+
+- Add support for `application/json` and `text/plain` encodings for `router.navigate`/`router.fetch` submissions. To leverage these encodings, pass your data in a `body` parameter and specify the desired `formEncType`: ([#10413](https://github.com/remix-run/react-router/pull/10413))
+
+ ```js
+ // By default, the encoding is "application/x-www-form-urlencoded"
+ router.navigate("/", {
+ formMethod: "post",
+ body: { key: "value" },
+ });
+
+ async function action({ request }) {
+ // await request.formData() => FormData instance with entry [key=value]
+ }
+ ```
+
+ ```js
+ // Pass `formEncType` to opt-into a different encoding (json)
+ router.navigate("/", {
+ formMethod: "post",
+ formEncType: "application/json",
+ body: { key: "value" },
+ });
+
+ async function action({ request }) {
+ // await request.json() => { key: "value" }
+ }
+ ```
+
+ ```js
+ // Pass `formEncType` to opt-into a different encoding (text)
+ router.navigate("/", {
+ formMethod: "post",
+ formEncType: "text/plain",
+ body: "Text submission",
+ });
+
+ async function action({ request }) {
+ // await request.text() => "Text submission"
+ }
+ ```
+
+### Patch Changes
+
+- Call `window.history.pushState/replaceState` before updating React Router state (instead of after) so that `window.location` matches `useLocation` during synchronous React 17 rendering ([#10448](https://github.com/remix-run/react-router/pull/10448))
+ - ⚠️ However, generally apps should not be relying on `window.location` and should always reference `useLocation` when possible, as `window.location` will not be in sync 100% of the time (due to `popstate` events, concurrent mode, etc.)
+- Strip `basename` from the `location` provided to `` to match the `useLocation` behavior ([#10550](https://github.com/remix-run/react-router/pull/10550))
+- Avoid calling `shouldRevalidate` for fetchers that have not yet completed a data load ([#10623](https://github.com/remix-run/react-router/pull/10623))
+- Fix `unstable_useBlocker` key issues in `StrictMode` ([#10573](https://github.com/remix-run/react-router/pull/10573))
+- Upgrade `typescript` to 5.1 ([#10581](https://github.com/remix-run/react-router/pull/10581))
+
+## 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(
+ }>
+ } />
+ import("./a")} />
+ import("./b")} />
+
+ );
+ ```
+
+ 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 (
+ <>
+ You made it!
+ {data}
+ >
+ );
+ }
+
+ // Export an `ErrorBoundary` directly instead of needing to create a React Element from it
+ export function ErrorBoundary() {
+ let error = useRouteError();
+ return isRouteErrorResponse(error) ? (
+
+ {error.status} {error.statusText}
+
+ ) : (
+ {error.message || error}
+ );
+ }
+ ```
+
+ 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
+
+### Patch Changes
+
+- Fixes 2 separate issues for revalidating fetcher `shouldRevalidate` calls ([#9948](https://github.com/remix-run/react-router/pull/9948))
+ - The `shouldRevalidate` function was only being called for _explicit_ revalidation scenarios (after a mutation, manual `useRevalidator` call, or an `X-Remix-Revalidate` header used for cookie setting in Remix). It was not properly being called on _implicit_ revalidation scenarios that also apply to navigation `loader` revalidation, such as a change in search params or clicking a link for the page we're already on. It's now correctly called in those additional scenarios.
+ - The parameters being passed were incorrect and inconsistent with one another since the `current*`/`next*` parameters reflected the static `fetcher.load` URL (and thus were identical). Instead, they should have reflected the the navigation that triggered the revalidation (as the `form*` parameters did). These parameters now correctly reflect the triggering navigation.
+- Respect `preventScrollReset` on `` ([#9963](https://github.com/remix-run/react-router/pull/9963))
+- Do not short circuit on hash change only mutation submissions ([#9944](https://github.com/remix-run/react-router/pull/9944))
+- Remove `instanceof` check from `isRouteErrorResponse` to avoid bundling issues on the server ([#9930](https://github.com/remix-run/react-router/pull/9930))
+- Fix navigation for hash routers on manual URL changes ([#9980](https://github.com/remix-run/react-router/pull/9980))
+- Detect when a `defer` call only contains critical data and remove the `AbortController` ([#9965](https://github.com/remix-run/react-router/pull/9965))
+- Send the name as the value when url-encoding `File` `FormData` entries ([#9867](https://github.com/remix-run/react-router/pull/9867))
+
+## 1.3.0
+
+### Minor Changes
+
+- Added support for navigation blocking APIs ([#9709](https://github.com/remix-run/react-router/pull/9709))
+- Expose deferred information from `createStaticHandler` ([#9760](https://github.com/remix-run/react-router/pull/9760))
+
+### Patch Changes
+
+- Improved absolute redirect url detection in actions/loaders ([#9829](https://github.com/remix-run/react-router/pull/9829))
+- Fix URL creation with memory histories ([#9814](https://github.com/remix-run/react-router/pull/9814))
+- Fix `generatePath` when optional params are present ([#9764](https://github.com/remix-run/react-router/pull/9764))
+- Fix scroll reset if a submission redirects ([#9886](https://github.com/remix-run/react-router/pull/9886))
+- Fix 404 bug with same-origin absolute redirects ([#9913](https://github.com/remix-run/react-router/pull/9913))
+- Support `OPTIONS` requests in `staticHandler.queryRoute` ([#9914](https://github.com/remix-run/react-router/pull/9914))
+
+## 1.2.1
+
+### Patch Changes
+
+- Include submission info in `shouldRevalidate` on action redirects ([#9777](https://github.com/remix-run/react-router/pull/9777), [#9782](https://github.com/remix-run/react-router/pull/9782))
+- Reset `actionData` on action redirect to current location ([#9772](https://github.com/remix-run/react-router/pull/9772))
+
+## 1.2.0
+
+### Minor Changes
+
+- Remove `unstable_` prefix from `createStaticHandler`/`createStaticRouter`/`StaticRouterProvider` ([#9738](https://github.com/remix-run/react-router/pull/9738))
+
+### Patch Changes
+
+- Fix explicit `replace` on submissions and `PUSH` on submission to new paths ([#9734](https://github.com/remix-run/react-router/pull/9734))
+- Fix a few bugs where loader/action data wasn't properly cleared on errors ([#9735](https://github.com/remix-run/react-router/pull/9735))
+- Prevent `useLoaderData` usage in `errorElement` ([#9735](https://github.com/remix-run/react-router/pull/9735))
+- Skip initial scroll restoration for SSR apps with `hydrationData` ([#9664](https://github.com/remix-run/react-router/pull/9664))
+
+## 1.1.0
+
+This release introduces support for [Optional Route Segments](https://github.com/remix-run/react-router/issues/9546). Now, adding a `?` to the end of any path segment will make that entire segment optional. This works for both static segments and dynamic parameters.
+
+**Optional Params Examples**
+
+- Path `lang?/about` will match:
+ - `/:lang/about`
+ - `/about`
+- Path `/multistep/:widget1?/widget2?/widget3?` will match:
+ - `/multistep`
+ - `/multistep/:widget1`
+ - `/multistep/:widget1/:widget2`
+ - `/multistep/:widget1/:widget2/:widget3`
+
+**Optional Static Segment Example**
+
+- Path `/home?` will match:
+ - `/`
+ - `/home`
+- Path `/fr?/about` will match:
+ - `/about`
+ - `/fr/about`
+
+### Minor Changes
+
+- Allows optional routes and optional static segments ([#9650](https://github.com/remix-run/react-router/pull/9650))
+
+### Patch Changes
+
+- Stop incorrectly matching on partial named parameters, i.e. ``, to align with how splat parameters work. If you were previously relying on this behavior then it's recommended to extract the static portion of the path at the `useParams` call site: ([#9506](https://github.com/remix-run/react-router/pull/9506))
+
+```jsx
+// Old behavior at URL /prefix-123
+ }>
+
+function Comp() {
+ let params = useParams(); // { id: '123' }
+ let id = params.id; // "123"
+ ...
+}
+
+// New behavior at URL /prefix-123
+ }>
+
+function Comp() {
+ let params = useParams(); // { id: 'prefix-123' }
+ let id = params.id.replace(/^prefix-/, ''); // "123"
+ ...
+}
+```
+
+- Persist `headers` on `loader` `request`'s after SSR document `action` request ([#9721](https://github.com/remix-run/react-router/pull/9721))
+- Fix requests sent to revalidating loaders so they reflect a GET request ([#9660](https://github.com/remix-run/react-router/pull/9660))
+- Fix issue with deeply nested optional segments ([#9727](https://github.com/remix-run/react-router/pull/9727))
+- GET forms now expose a submission on the loading navigation ([#9695](https://github.com/remix-run/react-router/pull/9695))
+- Fix error boundary tracking for multiple errors bubbling to the same boundary ([#9702](https://github.com/remix-run/react-router/pull/9702))
+
+## 1.0.5
+
+### Patch Changes
+
+- Fix requests sent to revalidating loaders so they reflect a `GET` request ([#9680](https://github.com/remix-run/react-router/pull/9680))
+- Remove `instanceof Response` checks in favor of `isResponse` ([#9690](https://github.com/remix-run/react-router/pull/9690))
+- Fix `URL` creation in Cloudflare Pages or other non-browser-environments ([#9682](https://github.com/remix-run/react-router/pull/9682), [#9689](https://github.com/remix-run/react-router/pull/9689))
+- Add `requestContext` support to static handler `query`/`queryRoute` ([#9696](https://github.com/remix-run/react-router/pull/9696))
+ - Note that the unstable API of `queryRoute(path, routeId)` has been changed to `queryRoute(path, { routeId, requestContext })`
+
+## 1.0.4
+
+### Patch Changes
+
+- Throw an error if an `action`/`loader` function returns `undefined` as revalidations need to know whether the loader has previously been executed. `undefined` also causes issues during SSR stringification for hydration. You should always ensure you `loader`/`action` returns a value, and you may return `null` if you don't wish to return anything. ([#9511](https://github.com/remix-run/react-router/pull/9511))
+- Properly handle redirects to external domains ([#9590](https://github.com/remix-run/react-router/pull/9590), [#9654](https://github.com/remix-run/react-router/pull/9654))
+- Preserve the HTTP method on 307/308 redirects ([#9597](https://github.com/remix-run/react-router/pull/9597))
+- Support `basename` in static data routers ([#9591](https://github.com/remix-run/react-router/pull/9591))
+- Enhanced `ErrorResponse` bodies to contain more descriptive text in internal 403/404/405 scenarios
+
+## 1.0.3
+
+### Patch Changes
+
+- Fix hrefs generated when using `createHashRouter` ([#9409](https://github.com/remix-run/react-router/pull/9409))
+- fix encoding/matching issues with special chars ([#9477](https://github.com/remix-run/react-router/pull/9477), [#9496](https://github.com/remix-run/react-router/pull/9496))
+- Support `basename` and relative routing in `loader`/`action` redirects ([#9447](https://github.com/remix-run/react-router/pull/9447))
+- Ignore pathless layout routes when looking for proper submission `action` function ([#9455](https://github.com/remix-run/react-router/pull/9455))
+- properly support `index` routes with a `path` in `useResolvedPath` ([#9486](https://github.com/remix-run/react-router/pull/9486))
+- Add UMD build for `@remix-run/router` ([#9446](https://github.com/remix-run/react-router/pull/9446))
+- fix `createURL` in local file execution in Firefox ([#9464](https://github.com/remix-run/react-router/pull/9464))
+- Updates to `unstable_createStaticHandler` for incorporating into Remix ([#9482](https://github.com/remix-run/react-router/pull/9482), [#9465](https://github.com/remix-run/react-router/pull/9465))
+
+## 1.0.2
+
+### Patch Changes
+
+- Reset `actionData` after a successful action redirect ([#9334](https://github.com/remix-run/react-router/pull/9334))
+- Update `matchPath` to avoid false positives on dash-separated segments ([#9300](https://github.com/remix-run/react-router/pull/9300))
+- If an index route has children, it will result in a runtime error. We have strengthened our `RouteObject`/`RouteProps` types to surface the error in TypeScript. ([#9366](https://github.com/remix-run/react-router/pull/9366))
+
+## 1.0.1
+
+### Patch Changes
+
+- Preserve state from `initialEntries` ([#9288](https://github.com/remix-run/react-router/pull/9288))
+- Preserve `?index` for fetcher get submissions to index routes ([#9312](https://github.com/remix-run/react-router/pull/9312))
+
+## 1.0.0
+
+This is the first stable release of `@remix-run/router`, which provides all the underlying routing and data loading/mutation logic for `react-router`. You should _not_ be using this package directly unless you are authoring a routing library similar to `react-router`.
+
+For an overview of the features provided by `react-router`, we recommend you go check out the [docs][rr-docs], especially the [feature overview][rr-feature-overview] and the [tutorial][rr-tutorial].
+
+For an overview of the features provided by `@remix-run/router`, please check out the [`README`][remix-router-readme].
+
+[rr-docs]: https://reactrouter.com
+[rr-feature-overview]: https://reactrouter.com/start/overview
+[rr-tutorial]: https://reactrouter.com/start/tutorial
+[remix-router-readme]: https://github.com/remix-run/react-router/blob/main/packages/router/README.md
diff --git a/node_modules/@remix-run/router/LICENSE.md b/node_modules/@remix-run/router/LICENSE.md
new file mode 100644
index 0000000..7d0a32c
--- /dev/null
+++ b/node_modules/@remix-run/router/LICENSE.md
@@ -0,0 +1,23 @@
+MIT License
+
+Copyright (c) React Training LLC 2015-2019
+Copyright (c) Remix Software Inc. 2020-2021
+Copyright (c) Shopify Inc. 2022-2023
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/node_modules/@remix-run/router/README.md b/node_modules/@remix-run/router/README.md
new file mode 100644
index 0000000..1c8536d
--- /dev/null
+++ b/node_modules/@remix-run/router/README.md
@@ -0,0 +1,135 @@
+# Remix Router
+
+The `@remix-run/router` package is a framework-agnostic routing package (sometimes referred to as a browser-emulator) that serves as the heart of [React Router][react-router] and [Remix][remix] and provides all the core functionality for routing coupled with data loading and data mutations. It comes with built-in handling of errors, race-conditions, interruptions, cancellations, lazy-loading data, and much, much more.
+
+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`.
+
+> [!WARNING]
+>
+> This router is a low-level package intended to be consumed by UI layer routing libraries. You should very likely not be using this package directly unless you are authoring a routing library such as [`react-router-dom`][react-router-repo] or one of it's other [UI ports][remix-routers-repo].
+
+## API
+
+A Router instance can be created using `createRouter`:
+
+```js
+// Create and initialize a router. "initialize" contains all side effects
+// including history listeners and kicking off the initial data fetch
+let router = createRouter({
+ // 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();
+```
+
+Internally, the Router represents the state in an object of the following format, which is available through `router.state`. You can also register a subscriber of the signature `(state: RouterState) => void` to execute when the state updates via `router.subscribe()`;
+
+```ts
+interface RouterState {
+ // False during the initial data load, true once we have our initial data
+ initialized: boolean;
+ // The `history` action of the most recently completed navigation
+ historyAction: Action;
+ // The current location of the router. During a navigation this reflects
+ // the "old" location and is updated upon completion of the navigation
+ location: Location;
+ // The current set of route matches
+ matches: DataRouteMatch[];
+ // The state of the current navigation
+ navigation: Navigation;
+ // The state of any in-progress router.revalidate() calls
+ revalidation: RevalidationState;
+ // Data from the loaders for the current matches
+ loaderData: RouteData;
+ // Data from the action for the current matches
+ actionData: RouteData | null;
+ // Errors thrown from loaders/actions for the current matches
+ errors: RouteData | null;
+ // Map of all active fetchers
+ fetchers: Map;
+ // Scroll position to restore to for the active Location, false if we
+ // should not restore, or null if we don't have a saved position
+ // Note: must be enabled via router.enableScrollRestoration()
+ restoreScrollPosition: number | false | null;
+ // Proxied `preventScrollReset` value passed to router.navigate()
+ preventScrollReset: boolean;
+}
+```
+
+### Navigations
+
+All navigations are done through the `router.navigate` API which is overloaded to support different types of navigations:
+
+```js
+// Link navigation (pushes onto the history stack by default)
+router.navigate("/page");
+
+// Link navigation (replacing the history stack)
+router.navigate("/page", { replace: true });
+
+// Pop navigation (moving backward/forward in the history stack)
+router.navigate(-1);
+
+// Form submission navigation
+let formData = new FormData();
+formData.append(key, value);
+router.navigate("/page", {
+ formMethod: "post",
+ formData,
+});
+
+// Relative routing from a source routeId
+router.navigate("../../somewhere", {
+ fromRouteId: "active-route-id",
+});
+```
+
+### Fetchers
+
+Fetchers are a mechanism to call loaders/actions without triggering a navigation, and are done through the `router.fetch()` API. All fetch calls require a unique key to identify the fetcher.
+
+```js
+// Execute the loader for /page
+router.fetch("key", "/page");
+
+// Submit to the action for /page
+let formData = new FormData();
+formData.append(key, value);
+router.fetch("key", "/page", {
+ formMethod: "post",
+ formData,
+});
+```
+
+### Revalidation
+
+By default, active loaders will revalidate after any navigation or fetcher mutation. If you need to kick off a revalidation for other use-cases, you can use `router.revalidate()` to re-execute all active loaders.
+
+### 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
+[remix]: https://remix.run
+[react-router-repo]: https://github.com/remix-run/react-router
+[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
diff --git a/node_modules/@remix-run/router/dist/history.d.ts b/node_modules/@remix-run/router/dist/history.d.ts
new file mode 100644
index 0000000..bda6722
--- /dev/null
+++ b/node_modules/@remix-run/router/dist/history.d.ts
@@ -0,0 +1,250 @@
+/**
+ * Actions represent the type of change to a location value.
+ */
+export declare enum Action {
+ /**
+ * A POP indicates a change to an arbitrary index in the history stack, such
+ * as a back or forward navigation. It does not describe the direction of the
+ * navigation, only that the current index changed.
+ *
+ * Note: This is the default action for newly created history objects.
+ */
+ Pop = "POP",
+ /**
+ * A PUSH indicates a new entry being added to the history stack, such as when
+ * a link is clicked and a new page loads. When this happens, all subsequent
+ * entries in the stack are lost.
+ */
+ Push = "PUSH",
+ /**
+ * A REPLACE indicates the entry at the current index in the history stack
+ * being replaced by a new one.
+ */
+ Replace = "REPLACE"
+}
+/**
+ * The pathname, search, and hash values of a URL.
+ */
+export interface Path {
+ /**
+ * A URL pathname, beginning with a /.
+ */
+ pathname: string;
+ /**
+ * A URL search string, beginning with a ?.
+ */
+ search: string;
+ /**
+ * A URL fragment identifier, beginning with a #.
+ */
+ hash: string;
+}
+/**
+ * An entry in a history stack. A location contains information about the
+ * URL path, as well as possibly some arbitrary state and a key.
+ */
+export interface Location extends Path {
+ /**
+ * A value of arbitrary data associated with this location.
+ */
+ state: State;
+ /**
+ * A unique string associated with this location. May be used to safely store
+ * and retrieve data in some other storage API, like `localStorage`.
+ *
+ * Note: This value is always "default" on the initial location.
+ */
+ key: string;
+}
+/**
+ * A change to the current location.
+ */
+export interface Update {
+ /**
+ * The action that triggered the change.
+ */
+ action: Action;
+ /**
+ * The new location.
+ */
+ location: Location;
+ /**
+ * The delta between this location and the former location in the history stack
+ */
+ delta: number | null;
+}
+/**
+ * A function that receives notifications about location changes.
+ */
+export interface Listener {
+ (update: Update): void;
+}
+/**
+ * Describes a location that is the destination of some navigation, either via
+ * `history.push` or `history.replace`. This may be either a URL or the pieces
+ * of a URL path.
+ */
+export type To = string | Partial;
+/**
+ * A history is an interface to the navigation stack. The history serves as the
+ * source of truth for the current location, as well as provides a set of
+ * methods that may be used to change it.
+ *
+ * It is similar to the DOM's `window.history` object, but with a smaller, more
+ * focused API.
+ */
+export interface History {
+ /**
+ * The last action that modified the current location. This will always be
+ * Action.Pop when a history instance is first created. This value is mutable.
+ */
+ readonly action: Action;
+ /**
+ * The current location. This value is mutable.
+ */
+ readonly location: Location;
+ /**
+ * Returns a valid href for the given `to` value that may be used as
+ * the value of an attribute.
+ *
+ * @param to - The destination URL
+ */
+ createHref(to: To): string;
+ /**
+ * Returns a URL for the given `to` value
+ *
+ * @param to - The destination URL
+ */
+ createURL(to: To): URL;
+ /**
+ * Encode a location the same way window.history would do (no-op for memory
+ * history) so we ensure our PUSH/REPLACE navigations for data routers
+ * behave the same as POP
+ *
+ * @param to Unencoded path
+ */
+ encodeLocation(to: To): Path;
+ /**
+ * Pushes a new location onto the history stack, increasing its length by one.
+ * If there were any entries in the stack after the current one, they are
+ * lost.
+ *
+ * @param to - The new URL
+ * @param state - Data to associate with the new location
+ */
+ push(to: To, state?: any): void;
+ /**
+ * Replaces the current location in the history stack with a new one. The
+ * location that was replaced will no longer be available.
+ *
+ * @param to - The new URL
+ * @param state - Data to associate with the new location
+ */
+ replace(to: To, state?: any): void;
+ /**
+ * Navigates `n` entries backward/forward in the history stack relative to the
+ * current index. For example, a "back" navigation would use go(-1).
+ *
+ * @param delta - The delta in the stack index
+ */
+ go(delta: number): void;
+ /**
+ * Sets up a listener that will be called whenever the current location
+ * changes.
+ *
+ * @param listener - A function that will be called when the location changes
+ * @returns unlisten - A function that may be used to stop listening
+ */
+ listen(listener: Listener): () => void;
+}
+/**
+ * A user-supplied object that describes a location. Used when providing
+ * entries to `createMemoryHistory` via its `initialEntries` option.
+ */
+export type InitialEntry = string | Partial;
+export type MemoryHistoryOptions = {
+ initialEntries?: InitialEntry[];
+ initialIndex?: number;
+ v5Compat?: boolean;
+};
+/**
+ * A memory history stores locations in memory. This is useful in stateful
+ * environments where there is no web browser, such as node tests or React
+ * Native.
+ */
+export interface MemoryHistory extends History {
+ /**
+ * The current index in the history stack.
+ */
+ readonly index: number;
+}
+/**
+ * Memory history stores the current location in memory. It is designed for use
+ * in stateful non-browser environments like tests and React Native.
+ */
+export declare function createMemoryHistory(options?: MemoryHistoryOptions): MemoryHistory;
+/**
+ * A browser history stores the current location in regular URLs in a web
+ * browser environment. This is the standard for most web apps and provides the
+ * cleanest URLs the browser's address bar.
+ *
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory
+ */
+export interface BrowserHistory extends UrlHistory {
+}
+export type BrowserHistoryOptions = UrlHistoryOptions;
+/**
+ * Browser history stores the location in regular URLs. This is the standard for
+ * most web apps, but it requires some configuration on the server to ensure you
+ * serve the same app at multiple URLs.
+ *
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory
+ */
+export declare function createBrowserHistory(options?: BrowserHistoryOptions): BrowserHistory;
+/**
+ * A hash history stores the current location in the fragment identifier portion
+ * of the URL in a web browser environment.
+ *
+ * This is ideal for apps that do not control the server for some reason
+ * (because the fragment identifier is never sent to the server), including some
+ * shared hosting environments that do not provide fine-grained controls over
+ * which pages are served at which URLs.
+ *
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory
+ */
+export interface HashHistory extends UrlHistory {
+}
+export type HashHistoryOptions = UrlHistoryOptions;
+/**
+ * Hash history stores the location in window.location.hash. This makes it ideal
+ * for situations where you don't want to send the location to the server for
+ * some reason, either because you do cannot configure it or the URL space is
+ * reserved for something else.
+ *
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory
+ */
+export declare function createHashHistory(options?: HashHistoryOptions): HashHistory;
+/**
+ * @private
+ */
+export declare function invariant(value: boolean, message?: string): asserts value;
+export declare function invariant(value: T | null | undefined, message?: string): asserts value is T;
+export declare function warning(cond: any, message: string): void;
+/**
+ * Creates a Location object with a unique key from the given Path
+ */
+export declare function createLocation(current: string | Location, to: To, state?: any, key?: string): Readonly;
+/**
+ * Creates a string URL path from the given pathname, search, and hash components.
+ */
+export declare function createPath({ pathname, search, hash, }: Partial): string;
+/**
+ * Parses a string URL path into its separate pathname, search, and hash components.
+ */
+export declare function parsePath(path: string): Partial;
+export interface UrlHistory extends History {
+}
+export type UrlHistoryOptions = {
+ window?: Window;
+ v5Compat?: boolean;
+};
diff --git a/node_modules/@remix-run/router/dist/index.d.ts b/node_modules/@remix-run/router/dist/index.d.ts
new file mode 100644
index 0000000..78479d0
--- /dev/null
+++ b/node_modules/@remix-run/router/dist/index.d.ts
@@ -0,0 +1,9 @@
+export type { ActionFunction, ActionFunctionArgs, AgnosticDataIndexRouteObject, AgnosticDataNonIndexRouteObject, AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticIndexRouteObject, AgnosticNonIndexRouteObject, AgnosticRouteMatch, AgnosticRouteObject, ErrorResponse, FormEncType, FormMethod, HTMLFormMethod, JsonFunction, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, ParamParseKey, Params, PathMatch, PathParam, PathPattern, RedirectFunction, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, TrackedPromise, UIMatch, V7_FormMethod, } from "./utils";
+export { AbortedDeferredError, defer, generatePath, getToPathname, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, redirect, redirectDocument, resolvePath, resolveTo, stripBasename, } from "./utils";
+export type { BrowserHistory, BrowserHistoryOptions, HashHistory, HashHistoryOptions, History, InitialEntry, Location, MemoryHistory, MemoryHistoryOptions, Path, To, } from "./history";
+export { Action, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, parsePath, } from "./history";
+export * from "./router";
+/** @internal */
+export type { RouteManifest as UNSAFE_RouteManifest } from "./utils";
+export { DeferredData as UNSAFE_DeferredData, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, getResolveToMatches as UNSAFE_getResolveToMatches, } from "./utils";
+export { invariant as UNSAFE_invariant, warning as UNSAFE_warning, } from "./history";
diff --git a/node_modules/@remix-run/router/dist/router.cjs.js b/node_modules/@remix-run/router/dist/router.cjs.js
new file mode 100644
index 0000000..d5d7f8a
--- /dev/null
+++ b/node_modules/@remix-run/router/dist/router.cjs.js
@@ -0,0 +1,4836 @@
+/**
+ * @remix-run/router v1.14.1
+ *
+ * Copyright (c) Remix Software Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE.md file in the root directory of this source tree.
+ *
+ * @license MIT
+ */
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+function _extends() {
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
+ for (var i = 1; i < arguments.length; i++) {
+ var source = arguments[i];
+ for (var key in source) {
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
+ target[key] = source[key];
+ }
+ }
+ }
+ return target;
+ };
+ return _extends.apply(this, arguments);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//#region Types and Constants
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Actions represent the type of change to a location value.
+ */
+let Action = /*#__PURE__*/function (Action) {
+ Action["Pop"] = "POP";
+ Action["Push"] = "PUSH";
+ Action["Replace"] = "REPLACE";
+ return Action;
+}({});
+
+/**
+ * The pathname, search, and hash values of a URL.
+ */
+
+// TODO: (v7) Change the Location generic default from `any` to `unknown` and
+// remove Remix `useLocation` wrapper.
+/**
+ * An entry in a history stack. A location contains information about the
+ * URL path, as well as possibly some arbitrary state and a key.
+ */
+/**
+ * A change to the current location.
+ */
+/**
+ * A function that receives notifications about location changes.
+ */
+/**
+ * Describes a location that is the destination of some navigation, either via
+ * `history.push` or `history.replace`. This may be either a URL or the pieces
+ * of a URL path.
+ */
+/**
+ * A history is an interface to the navigation stack. The history serves as the
+ * source of truth for the current location, as well as provides a set of
+ * methods that may be used to change it.
+ *
+ * It is similar to the DOM's `window.history` object, but with a smaller, more
+ * focused API.
+ */
+const PopStateEventType = "popstate";
+//#endregion
+
+////////////////////////////////////////////////////////////////////////////////
+//#region Memory History
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A user-supplied object that describes a location. Used when providing
+ * entries to `createMemoryHistory` via its `initialEntries` option.
+ */
+/**
+ * A memory history stores locations in memory. This is useful in stateful
+ * environments where there is no web browser, such as node tests or React
+ * Native.
+ */
+/**
+ * Memory history stores the current location in memory. It is designed for use
+ * in stateful non-browser environments like tests and React Native.
+ */
+function createMemoryHistory(options) {
+ if (options === void 0) {
+ options = {};
+ }
+ let {
+ initialEntries = ["/"],
+ initialIndex,
+ v5Compat = false
+ } = options;
+ let entries; // Declare so we can access from createMemoryLocation
+ entries = initialEntries.map((entry, index) => createMemoryLocation(entry, typeof entry === "string" ? null : entry.state, index === 0 ? "default" : undefined));
+ let index = clampIndex(initialIndex == null ? entries.length - 1 : initialIndex);
+ let action = Action.Pop;
+ let listener = null;
+ function clampIndex(n) {
+ return Math.min(Math.max(n, 0), entries.length - 1);
+ }
+ function getCurrentLocation() {
+ return entries[index];
+ }
+ function createMemoryLocation(to, state, key) {
+ if (state === void 0) {
+ state = null;
+ }
+ let location = createLocation(entries ? getCurrentLocation().pathname : "/", to, state, key);
+ warning(location.pathname.charAt(0) === "/", "relative pathnames are not supported in memory history: " + JSON.stringify(to));
+ return location;
+ }
+ function createHref(to) {
+ return typeof to === "string" ? to : createPath(to);
+ }
+ let history = {
+ get index() {
+ return index;
+ },
+ get action() {
+ return action;
+ },
+ get location() {
+ return getCurrentLocation();
+ },
+ createHref,
+ createURL(to) {
+ return new URL(createHref(to), "http://localhost");
+ },
+ encodeLocation(to) {
+ let path = typeof to === "string" ? parsePath(to) : to;
+ return {
+ pathname: path.pathname || "",
+ search: path.search || "",
+ hash: path.hash || ""
+ };
+ },
+ push(to, state) {
+ action = Action.Push;
+ let nextLocation = createMemoryLocation(to, state);
+ index += 1;
+ entries.splice(index, entries.length, nextLocation);
+ if (v5Compat && listener) {
+ listener({
+ action,
+ location: nextLocation,
+ delta: 1
+ });
+ }
+ },
+ replace(to, state) {
+ action = Action.Replace;
+ let nextLocation = createMemoryLocation(to, state);
+ entries[index] = nextLocation;
+ if (v5Compat && listener) {
+ listener({
+ action,
+ location: nextLocation,
+ delta: 0
+ });
+ }
+ },
+ go(delta) {
+ action = Action.Pop;
+ let nextIndex = clampIndex(index + delta);
+ let nextLocation = entries[nextIndex];
+ index = nextIndex;
+ if (listener) {
+ listener({
+ action,
+ location: nextLocation,
+ delta
+ });
+ }
+ },
+ listen(fn) {
+ listener = fn;
+ return () => {
+ listener = null;
+ };
+ }
+ };
+ return history;
+}
+//#endregion
+
+////////////////////////////////////////////////////////////////////////////////
+//#region Browser History
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A browser history stores the current location in regular URLs in a web
+ * browser environment. This is the standard for most web apps and provides the
+ * cleanest URLs the browser's address bar.
+ *
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#browserhistory
+ */
+/**
+ * Browser history stores the location in regular URLs. This is the standard for
+ * most web apps, but it requires some configuration on the server to ensure you
+ * serve the same app at multiple URLs.
+ *
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory
+ */
+function createBrowserHistory(options) {
+ if (options === void 0) {
+ options = {};
+ }
+ function createBrowserLocation(window, globalHistory) {
+ let {
+ pathname,
+ search,
+ hash
+ } = window.location;
+ return createLocation("", {
+ pathname,
+ search,
+ hash
+ },
+ // state defaults to `null` because `window.history.state` does
+ globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || "default");
+ }
+ function createBrowserHref(window, to) {
+ return typeof to === "string" ? to : createPath(to);
+ }
+ return getUrlBasedHistory(createBrowserLocation, createBrowserHref, null, options);
+}
+//#endregion
+
+////////////////////////////////////////////////////////////////////////////////
+//#region Hash History
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A hash history stores the current location in the fragment identifier portion
+ * of the URL in a web browser environment.
+ *
+ * This is ideal for apps that do not control the server for some reason
+ * (because the fragment identifier is never sent to the server), including some
+ * shared hosting environments that do not provide fine-grained controls over
+ * which pages are served at which URLs.
+ *
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#hashhistory
+ */
+/**
+ * Hash history stores the location in window.location.hash. This makes it ideal
+ * for situations where you don't want to send the location to the server for
+ * some reason, either because you do cannot configure it or the URL space is
+ * reserved for something else.
+ *
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory
+ */
+function createHashHistory(options) {
+ if (options === void 0) {
+ options = {};
+ }
+ function createHashLocation(window, globalHistory) {
+ let {
+ pathname = "/",
+ search = "",
+ hash = ""
+ } = parsePath(window.location.hash.substr(1));
+
+ // Hash URL should always have a leading / just like window.location.pathname
+ // does, so if an app ends up at a route like /#something then we add a
+ // leading slash so all of our path-matching behaves the same as if it would
+ // in a browser router. This is particularly important when there exists a
+ // root splat route () since that matches internally against
+ // "/*" and we'd expect /#something to 404 in a hash router app.
+ if (!pathname.startsWith("/") && !pathname.startsWith(".")) {
+ pathname = "/" + pathname;
+ }
+ return createLocation("", {
+ pathname,
+ search,
+ hash
+ },
+ // state defaults to `null` because `window.history.state` does
+ globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || "default");
+ }
+ function createHashHref(window, to) {
+ let base = window.document.querySelector("base");
+ let href = "";
+ if (base && base.getAttribute("href")) {
+ let url = window.location.href;
+ let hashIndex = url.indexOf("#");
+ href = hashIndex === -1 ? url : url.slice(0, hashIndex);
+ }
+ return href + "#" + (typeof to === "string" ? to : createPath(to));
+ }
+ function validateHashLocation(location, to) {
+ warning(location.pathname.charAt(0) === "/", "relative pathnames are not supported in hash history.push(" + JSON.stringify(to) + ")");
+ }
+ return getUrlBasedHistory(createHashLocation, createHashHref, validateHashLocation, options);
+}
+//#endregion
+
+////////////////////////////////////////////////////////////////////////////////
+//#region UTILS
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @private
+ */
+function invariant(value, message) {
+ if (value === false || value === null || typeof value === "undefined") {
+ throw new Error(message);
+ }
+}
+function warning(cond, message) {
+ if (!cond) {
+ // eslint-disable-next-line no-console
+ if (typeof console !== "undefined") console.warn(message);
+ try {
+ // Welcome to debugging history!
+ //
+ // 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) {}
+ }
+}
+function createKey() {
+ return Math.random().toString(36).substr(2, 8);
+}
+
+/**
+ * For browser-based histories, we combine the state and key into an object
+ */
+function getHistoryState(location, index) {
+ return {
+ usr: location.state,
+ key: location.key,
+ idx: index
+ };
+}
+
+/**
+ * Creates a Location object with a unique key from the given Path
+ */
+function createLocation(current, to, state, key) {
+ if (state === void 0) {
+ state = null;
+ }
+ let location = _extends({
+ pathname: typeof current === "string" ? current : current.pathname,
+ search: "",
+ hash: ""
+ }, typeof to === "string" ? parsePath(to) : to, {
+ state,
+ // TODO: This could be cleaned up. push/replace should probably just take
+ // full Locations now and avoid the need to run through this flow at all
+ // But that's a pretty big refactor to the current test suite so going to
+ // keep as is for the time being and just let any incoming keys take precedence
+ key: to && to.key || key || createKey()
+ });
+ return location;
+}
+
+/**
+ * Creates a string URL path from the given pathname, search, and hash components.
+ */
+function createPath(_ref) {
+ let {
+ pathname = "/",
+ search = "",
+ hash = ""
+ } = _ref;
+ if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search;
+ if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
+ return pathname;
+}
+
+/**
+ * Parses a string URL path into its separate pathname, search, and hash components.
+ */
+function parsePath(path) {
+ let parsedPath = {};
+ if (path) {
+ let hashIndex = path.indexOf("#");
+ if (hashIndex >= 0) {
+ parsedPath.hash = path.substr(hashIndex);
+ path = path.substr(0, hashIndex);
+ }
+ let searchIndex = path.indexOf("?");
+ if (searchIndex >= 0) {
+ parsedPath.search = path.substr(searchIndex);
+ path = path.substr(0, searchIndex);
+ }
+ if (path) {
+ parsedPath.pathname = path;
+ }
+ }
+ return parsedPath;
+}
+function getUrlBasedHistory(getLocation, createHref, validateLocation, options) {
+ if (options === void 0) {
+ options = {};
+ }
+ let {
+ window = document.defaultView,
+ v5Compat = false
+ } = options;
+ let globalHistory = window.history;
+ let action = Action.Pop;
+ let listener = null;
+ let index = getIndex();
+ // Index should only be null when we initialize. If not, it's because the
+ // user called history.pushState or history.replaceState directly, in which
+ // case we should log a warning as it will result in bugs.
+ if (index == null) {
+ index = 0;
+ globalHistory.replaceState(_extends({}, globalHistory.state, {
+ idx: index
+ }), "");
+ }
+ function getIndex() {
+ let state = globalHistory.state || {
+ idx: null
+ };
+ return state.idx;
+ }
+ function handlePop() {
+ action = Action.Pop;
+ let nextIndex = getIndex();
+ let delta = nextIndex == null ? null : nextIndex - index;
+ index = nextIndex;
+ if (listener) {
+ listener({
+ action,
+ location: history.location,
+ delta
+ });
+ }
+ }
+ function push(to, state) {
+ action = Action.Push;
+ let location = createLocation(history.location, to, state);
+ if (validateLocation) validateLocation(location, to);
+ index = getIndex() + 1;
+ let historyState = getHistoryState(location, index);
+ let url = history.createHref(location);
+
+ // try...catch because iOS limits us to 100 pushState calls :/
+ try {
+ globalHistory.pushState(historyState, "", url);
+ } 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
+ // way to warn them about it since the page will refresh...
+ window.location.assign(url);
+ }
+ if (v5Compat && listener) {
+ listener({
+ action,
+ location: history.location,
+ delta: 1
+ });
+ }
+ }
+ function replace(to, state) {
+ action = Action.Replace;
+ let location = createLocation(history.location, to, state);
+ if (validateLocation) validateLocation(location, to);
+ index = getIndex();
+ let historyState = getHistoryState(location, index);
+ let url = history.createHref(location);
+ globalHistory.replaceState(historyState, "", url);
+ if (v5Compat && listener) {
+ listener({
+ action,
+ location: history.location,
+ delta: 0
+ });
+ }
+ }
+ function createURL(to) {
+ // window.location.origin is "null" (the literal string value) in Firefox
+ // under certain conditions, notably when serving from a local HTML file
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297
+ let base = window.location.origin !== "null" ? window.location.origin : window.location.href;
+ let href = typeof to === "string" ? to : createPath(to);
+ invariant(base, "No window.location.(origin|href) available to create URL for href: " + href);
+ return new URL(href, base);
+ }
+ let history = {
+ get action() {
+ return action;
+ },
+ get location() {
+ return getLocation(window, globalHistory);
+ },
+ listen(fn) {
+ if (listener) {
+ throw new Error("A history only accepts one active listener");
+ }
+ window.addEventListener(PopStateEventType, handlePop);
+ listener = fn;
+ return () => {
+ window.removeEventListener(PopStateEventType, handlePop);
+ listener = null;
+ };
+ },
+ createHref(to) {
+ return createHref(window, to);
+ },
+ createURL,
+ encodeLocation(to) {
+ // Encode a Location the same way window.location would
+ let url = createURL(to);
+ return {
+ pathname: url.pathname,
+ search: url.search,
+ hash: url.hash
+ };
+ },
+ push,
+ replace,
+ go(n) {
+ return globalHistory.go(n);
+ }
+ };
+ return history;
+}
+
+//#endregion
+
+/**
+ * Map of routeId -> data returned from a loader/action/error
+ */
+
+let ResultType = /*#__PURE__*/function (ResultType) {
+ ResultType["data"] = "data";
+ ResultType["deferred"] = "deferred";
+ ResultType["redirect"] = "redirect";
+ ResultType["error"] = "error";
+ return ResultType;
+}({});
+
+/**
+ * Successful result from a loader or action
+ */
+
+/**
+ * Successful defer() result from a loader or action
+ */
+
+/**
+ * Redirect result from a loader or action
+ */
+
+/**
+ * Unsuccessful result from a loader or action
+ */
+
+/**
+ * Result from a loader or action - potentially successful or unsuccessful
+ */
+
+/**
+ * Users can specify either lowercase or uppercase form methods on `