You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					1331 lines
				
				45 KiB
			
		
		
			
		
	
	
					1331 lines
				
				45 KiB
			| 
											3 years ago
										 | /** | ||
|  |  * React Router v6.6.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 | ||
|  |  */ | ||
|  | import { invariant, joinPaths, matchPath, UNSAFE_getPathContributingMatches, warning, resolveTo, parsePath, matchRoutes, Action, isRouteErrorResponse, createMemoryHistory, stripBasename, AbortedDeferredError, createRouter } from '@remix-run/router'; | ||
|  | export { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, resolvePath } from '@remix-run/router'; | ||
|  | import * as React from 'react'; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Copyright (c) Facebook, Inc. and its affiliates. | ||
|  |  * | ||
|  |  * This source code is licensed under the MIT license found in the | ||
|  |  * LICENSE file in the root directory of this source tree. | ||
|  |  */ | ||
|  | /** | ||
|  |  * inlined Object.is polyfill to avoid requiring consumers ship their own | ||
|  |  * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function isPolyfill(x, y) { | ||
|  |   return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
 | ||
|  |   ; | ||
|  | } | ||
|  | 
 | ||
|  | const is = typeof Object.is === "function" ? Object.is : isPolyfill; // Intentionally not using named imports because Rollup uses dynamic
 | ||
|  | // dispatch for CommonJS interop named imports.
 | ||
|  | 
 | ||
|  | const { | ||
|  |   useState, | ||
|  |   useEffect, | ||
|  |   useLayoutEffect, | ||
|  |   useDebugValue | ||
|  | } = React; | ||
|  | let didWarnOld18Alpha = false; | ||
|  | let didWarnUncachedGetSnapshot = false; // Disclaimer: This shim breaks many of the rules of React, and only works
 | ||
|  | // because of a very particular set of implementation details and assumptions
 | ||
|  | // -- change any one of them and it will break. The most important assumption
 | ||
|  | // is that updates are always synchronous, because concurrent rendering is
 | ||
|  | // only available in versions of React that also have a built-in
 | ||
|  | // useSyncExternalStore API. And we only use this shim when the built-in API
 | ||
|  | // does not exist.
 | ||
|  | //
 | ||
|  | // Do not assume that the clever hacks used by this hook also work in general.
 | ||
|  | // The point of this shim is to replace the need for hacks by other libraries.
 | ||
|  | 
 | ||
|  | function useSyncExternalStore$2(subscribe, getSnapshot, // Note: The shim does not use getServerSnapshot, because pre-18 versions of
 | ||
|  | // React do not expose a way to check if we're hydrating. So users of the shim
 | ||
|  | // will need to track that themselves and return the correct value
 | ||
|  | // from `getSnapshot`.
 | ||
|  | getServerSnapshot) { | ||
|  |   { | ||
|  |     if (!didWarnOld18Alpha) { | ||
|  |       if ("startTransition" in React) { | ||
|  |         didWarnOld18Alpha = true; | ||
|  |         console.error("You are using an outdated, pre-release alpha of React 18 that " + "does not support useSyncExternalStore. The " + "use-sync-external-store shim will not work correctly. Upgrade " + "to a newer pre-release."); | ||
|  |       } | ||
|  |     } | ||
|  |   } // Read the current snapshot from the store on every render. Again, this
 | ||
|  |   // breaks the rules of React, and only works here because of specific
 | ||
|  |   // implementation details, most importantly that updates are
 | ||
|  |   // always synchronous.
 | ||
|  | 
 | ||
|  | 
 | ||
|  |   const value = getSnapshot(); | ||
|  | 
 | ||
|  |   { | ||
|  |     if (!didWarnUncachedGetSnapshot) { | ||
|  |       const cachedValue = getSnapshot(); | ||
|  | 
 | ||
|  |       if (!is(value, cachedValue)) { | ||
|  |         console.error("The result of getSnapshot should be cached to avoid an infinite loop"); | ||
|  |         didWarnUncachedGetSnapshot = true; | ||
|  |       } | ||
|  |     } | ||
|  |   } // Because updates are synchronous, we don't queue them. Instead we force a
 | ||
|  |   // re-render whenever the subscribed state changes by updating an some
 | ||
|  |   // arbitrary useState hook. Then, during render, we call getSnapshot to read
 | ||
|  |   // the current value.
 | ||
|  |   //
 | ||
|  |   // Because we don't actually use the state returned by the useState hook, we
 | ||
|  |   // can save a bit of memory by storing other stuff in that slot.
 | ||
|  |   //
 | ||
|  |   // To implement the early bailout, we need to track some things on a mutable
 | ||
|  |   // object. Usually, we would put that in a useRef hook, but we can stash it in
 | ||
|  |   // our useState hook instead.
 | ||
|  |   //
 | ||
|  |   // To force a re-render, we call forceUpdate({inst}). That works because the
 | ||
|  |   // new object always fails an equality check.
 | ||
|  | 
 | ||
|  | 
 | ||
|  |   const [{ | ||
|  |     inst | ||
|  |   }, forceUpdate] = useState({ | ||
|  |     inst: { | ||
|  |       value, | ||
|  |       getSnapshot | ||
|  |     } | ||
|  |   }); // Track the latest getSnapshot function with a ref. This needs to be updated
 | ||
|  |   // in the layout phase so we can access it during the tearing check that
 | ||
|  |   // happens on subscribe.
 | ||
|  | 
 | ||
|  |   useLayoutEffect(() => { | ||
|  |     inst.value = value; | ||
|  |     inst.getSnapshot = getSnapshot; // Whenever getSnapshot or subscribe changes, we need to check in the
 | ||
|  |     // commit phase if there was an interleaved mutation. In concurrent mode
 | ||
|  |     // this can happen all the time, but even in synchronous mode, an earlier
 | ||
|  |     // effect may have mutated the store.
 | ||
|  | 
 | ||
|  |     if (checkIfSnapshotChanged(inst)) { | ||
|  |       // Force a re-render.
 | ||
|  |       forceUpdate({ | ||
|  |         inst | ||
|  |       }); | ||
|  |     } // eslint-disable-next-line react-hooks/exhaustive-deps
 | ||
|  | 
 | ||
|  |   }, [subscribe, value, getSnapshot]); | ||
|  |   useEffect(() => { | ||
|  |     // Check for changes right before subscribing. Subsequent changes will be
 | ||
|  |     // detected in the subscription handler.
 | ||
|  |     if (checkIfSnapshotChanged(inst)) { | ||
|  |       // Force a re-render.
 | ||
|  |       forceUpdate({ | ||
|  |         inst | ||
|  |       }); | ||
|  |     } | ||
|  | 
 | ||
|  |     const handleStoreChange = () => { | ||
|  |       // TODO: Because there is no cross-renderer API for batching updates, it's
 | ||
|  |       // up to the consumer of this library to wrap their subscription event
 | ||
|  |       // with unstable_batchedUpdates. Should we try to detect when this isn't
 | ||
|  |       // the case and print a warning in development?
 | ||
|  |       // The store changed. Check if the snapshot changed since the last time we
 | ||
|  |       // read from the store.
 | ||
|  |       if (checkIfSnapshotChanged(inst)) { | ||
|  |         // Force a re-render.
 | ||
|  |         forceUpdate({ | ||
|  |           inst | ||
|  |         }); | ||
|  |       } | ||
|  |     }; // Subscribe to the store and return a clean-up function.
 | ||
|  | 
 | ||
|  | 
 | ||
|  |     return subscribe(handleStoreChange); // eslint-disable-next-line react-hooks/exhaustive-deps
 | ||
|  |   }, [subscribe]); | ||
|  |   useDebugValue(value); | ||
|  |   return value; | ||
|  | } | ||
|  | 
 | ||
|  | function checkIfSnapshotChanged(inst) { | ||
|  |   const latestGetSnapshot = inst.getSnapshot; | ||
|  |   const prevValue = inst.value; | ||
|  | 
 | ||
|  |   try { | ||
|  |     const nextValue = latestGetSnapshot(); | ||
|  |     return !is(prevValue, nextValue); | ||
|  |   } catch (error) { | ||
|  |     return true; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Copyright (c) Facebook, Inc. and its affiliates. | ||
|  |  * | ||
|  |  * This source code is licensed under the MIT license found in the | ||
|  |  * LICENSE file in the root directory of this source tree. | ||
|  |  * | ||
|  |  * @flow | ||
|  |  */ | ||
|  | function useSyncExternalStore$1(subscribe, getSnapshot, getServerSnapshot) { | ||
|  |   // Note: The shim does not use getServerSnapshot, because pre-18 versions of
 | ||
|  |   // React do not expose a way to check if we're hydrating. So users of the shim
 | ||
|  |   // will need to track that themselves and return the correct value
 | ||
|  |   // from `getSnapshot`.
 | ||
|  |   return getSnapshot(); | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Inlined into the react-router repo since use-sync-external-store does not | ||
|  |  * provide a UMD-compatible package, so we need this to be able to distribute | ||
|  |  * UMD react-router bundles | ||
|  |  */ | ||
|  | const canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"); | ||
|  | const isServerEnvironment = !canUseDOM; | ||
|  | const shim = isServerEnvironment ? useSyncExternalStore$1 : useSyncExternalStore$2; | ||
|  | const useSyncExternalStore = "useSyncExternalStore" in React ? (module => module.useSyncExternalStore)(React) : shim; | ||
|  | 
 | ||
|  | const DataStaticRouterContext = /*#__PURE__*/React.createContext(null); | ||
|  | 
 | ||
|  | { | ||
|  |   DataStaticRouterContext.displayName = "DataStaticRouterContext"; | ||
|  | } | ||
|  | 
 | ||
|  | const DataRouterContext = /*#__PURE__*/React.createContext(null); | ||
|  | 
 | ||
|  | { | ||
|  |   DataRouterContext.displayName = "DataRouter"; | ||
|  | } | ||
|  | 
 | ||
|  | const DataRouterStateContext = /*#__PURE__*/React.createContext(null); | ||
|  | 
 | ||
|  | { | ||
|  |   DataRouterStateContext.displayName = "DataRouterState"; | ||
|  | } | ||
|  | 
 | ||
|  | const AwaitContext = /*#__PURE__*/React.createContext(null); | ||
|  | 
 | ||
|  | { | ||
|  |   AwaitContext.displayName = "Await"; | ||
|  | } | ||
|  | 
 | ||
|  | const NavigationContext = /*#__PURE__*/React.createContext(null); | ||
|  | 
 | ||
|  | { | ||
|  |   NavigationContext.displayName = "Navigation"; | ||
|  | } | ||
|  | 
 | ||
|  | const LocationContext = /*#__PURE__*/React.createContext(null); | ||
|  | 
 | ||
|  | { | ||
|  |   LocationContext.displayName = "Location"; | ||
|  | } | ||
|  | 
 | ||
|  | const RouteContext = /*#__PURE__*/React.createContext({ | ||
|  |   outlet: null, | ||
|  |   matches: [] | ||
|  | }); | ||
|  | 
 | ||
|  | { | ||
|  |   RouteContext.displayName = "Route"; | ||
|  | } | ||
|  | 
 | ||
|  | const RouteErrorContext = /*#__PURE__*/React.createContext(null); | ||
|  | 
 | ||
|  | { | ||
|  |   RouteErrorContext.displayName = "RouteError"; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the full href for the given "to" value. This is useful for building | ||
|  |  * custom links that are also accessible and preserve right-click behavior. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-href
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useHref(to, { | ||
|  |   relative | ||
|  | } = {}) { | ||
|  |   !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
 | ||
|  |   // router loaded. We can help them understand how to avoid that.
 | ||
|  |   `useHref() may be used only in the context of a <Router> component.`)  : void 0; | ||
|  |   let { | ||
|  |     basename, | ||
|  |     navigator | ||
|  |   } = React.useContext(NavigationContext); | ||
|  |   let { | ||
|  |     hash, | ||
|  |     pathname, | ||
|  |     search | ||
|  |   } = useResolvedPath(to, { | ||
|  |     relative | ||
|  |   }); | ||
|  |   let joinedPathname = pathname; // If we're operating within a basename, prepend it to the pathname prior
 | ||
|  |   // to creating the href.  If this is a root navigation, then just use the raw
 | ||
|  |   // basename which allows the basename to have full control over the presence
 | ||
|  |   // of a trailing slash on root links
 | ||
|  | 
 | ||
|  |   if (basename !== "/") { | ||
|  |     joinedPathname = pathname === "/" ? basename : joinPaths([basename, pathname]); | ||
|  |   } | ||
|  | 
 | ||
|  |   return navigator.createHref({ | ||
|  |     pathname: joinedPathname, | ||
|  |     search, | ||
|  |     hash | ||
|  |   }); | ||
|  | } | ||
|  | /** | ||
|  |  * Returns true if this component is a descendant of a <Router>. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-in-router-context
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useInRouterContext() { | ||
|  |   return React.useContext(LocationContext) != null; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the current location object, which represents the current URL in web | ||
|  |  * browsers. | ||
|  |  * | ||
|  |  * Note: If you're using this it may mean you're doing some of your own | ||
|  |  * "routing" in your app, and we'd like to know what your use case is. We may | ||
|  |  * be able to provide something higher-level to better suit your needs. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-location
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useLocation() { | ||
|  |   !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
 | ||
|  |   // router loaded. We can help them understand how to avoid that.
 | ||
|  |   `useLocation() may be used only in the context of a <Router> component.`)  : void 0; | ||
|  |   return React.useContext(LocationContext).location; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the current navigation action which describes how the router came to | ||
|  |  * the current location, either by a pop, push, or replace on the history stack. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-navigation-type
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useNavigationType() { | ||
|  |   return React.useContext(LocationContext).navigationType; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns a PathMatch object if the given pattern matches the current URL. | ||
|  |  * This is useful for components that need to know "active" state, e.g. | ||
|  |  * <NavLink>. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-match
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useMatch(pattern) { | ||
|  |   !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
 | ||
|  |   // router loaded. We can help them understand how to avoid that.
 | ||
|  |   `useMatch() may be used only in the context of a <Router> component.`)  : void 0; | ||
|  |   let { | ||
|  |     pathname | ||
|  |   } = useLocation(); | ||
|  |   return React.useMemo(() => matchPath(pattern, pathname), [pathname, pattern]); | ||
|  | } | ||
|  | /** | ||
|  |  * Returns an imperative method for changing the location. Used by <Link>s, but | ||
|  |  * may also be used by other elements to change the location. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-navigate
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useNavigate() { | ||
|  |   !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
 | ||
|  |   // router loaded. We can help them understand how to avoid that.
 | ||
|  |   `useNavigate() may be used only in the context of a <Router> component.`)  : void 0; | ||
|  |   let { | ||
|  |     basename, | ||
|  |     navigator | ||
|  |   } = React.useContext(NavigationContext); | ||
|  |   let { | ||
|  |     matches | ||
|  |   } = React.useContext(RouteContext); | ||
|  |   let { | ||
|  |     pathname: locationPathname | ||
|  |   } = useLocation(); | ||
|  |   let routePathnamesJson = JSON.stringify(UNSAFE_getPathContributingMatches(matches).map(match => match.pathnameBase)); | ||
|  |   let activeRef = React.useRef(false); | ||
|  |   React.useEffect(() => { | ||
|  |     activeRef.current = true; | ||
|  |   }); | ||
|  |   let navigate = React.useCallback((to, options = {}) => { | ||
|  |     warning(activeRef.current, `You should call navigate() in a React.useEffect(), not when ` + `your component is first rendered.`) ; | ||
|  |     if (!activeRef.current) return; | ||
|  | 
 | ||
|  |     if (typeof to === "number") { | ||
|  |       navigator.go(to); | ||
|  |       return; | ||
|  |     } | ||
|  | 
 | ||
|  |     let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === "path"); // If we're operating within a basename, prepend it to the pathname prior
 | ||
|  |     // to handing off to history.  If this is a root navigation, then we
 | ||
|  |     // navigate to the raw basename which allows the basename to have full
 | ||
|  |     // control over the presence of a trailing slash on root links
 | ||
|  | 
 | ||
|  |     if (basename !== "/") { | ||
|  |       path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]); | ||
|  |     } | ||
|  | 
 | ||
|  |     (!!options.replace ? navigator.replace : navigator.push)(path, options.state, options); | ||
|  |   }, [basename, navigator, routePathnamesJson, locationPathname]); | ||
|  |   return navigate; | ||
|  | } | ||
|  | const OutletContext = /*#__PURE__*/React.createContext(null); | ||
|  | /** | ||
|  |  * Returns the context (if provided) for the child route at this level of the route | ||
|  |  * hierarchy. | ||
|  |  * @see https://reactrouter.com/hooks/use-outlet-context
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useOutletContext() { | ||
|  |   return React.useContext(OutletContext); | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the element for the child route at this level of the route | ||
|  |  * hierarchy. Used internally by <Outlet> to render child routes. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-outlet
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useOutlet(context) { | ||
|  |   let outlet = React.useContext(RouteContext).outlet; | ||
|  | 
 | ||
|  |   if (outlet) { | ||
|  |     return /*#__PURE__*/React.createElement(OutletContext.Provider, { | ||
|  |       value: context | ||
|  |     }, outlet); | ||
|  |   } | ||
|  | 
 | ||
|  |   return outlet; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns an object of key/value pairs of the dynamic params from the current | ||
|  |  * URL that were matched by the route path. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-params
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useParams() { | ||
|  |   let { | ||
|  |     matches | ||
|  |   } = React.useContext(RouteContext); | ||
|  |   let routeMatch = matches[matches.length - 1]; | ||
|  |   return routeMatch ? routeMatch.params : {}; | ||
|  | } | ||
|  | /** | ||
|  |  * Resolves the pathname of the given `to` value against the current location. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-resolved-path
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useResolvedPath(to, { | ||
|  |   relative | ||
|  | } = {}) { | ||
|  |   let { | ||
|  |     matches | ||
|  |   } = React.useContext(RouteContext); | ||
|  |   let { | ||
|  |     pathname: locationPathname | ||
|  |   } = useLocation(); | ||
|  |   let routePathnamesJson = JSON.stringify(UNSAFE_getPathContributingMatches(matches).map(match => match.pathnameBase)); | ||
|  |   return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [to, routePathnamesJson, locationPathname, relative]); | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the element of the route that matched the current location, prepared | ||
|  |  * with the correct context to render the remainder of the route tree. Route | ||
|  |  * elements in the tree must render an <Outlet> to render their child route's | ||
|  |  * element. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/hooks/use-routes
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function useRoutes(routes, locationArg) { | ||
|  |   !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
 | ||
|  |   // router loaded. We can help them understand how to avoid that.
 | ||
|  |   `useRoutes() may be used only in the context of a <Router> component.`)  : void 0; | ||
|  |   let { | ||
|  |     navigator | ||
|  |   } = React.useContext(NavigationContext); | ||
|  |   let dataRouterStateContext = React.useContext(DataRouterStateContext); | ||
|  |   let { | ||
|  |     matches: parentMatches | ||
|  |   } = React.useContext(RouteContext); | ||
|  |   let routeMatch = parentMatches[parentMatches.length - 1]; | ||
|  |   let parentParams = routeMatch ? routeMatch.params : {}; | ||
|  |   let parentPathname = routeMatch ? routeMatch.pathname : "/"; | ||
|  |   let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/"; | ||
|  |   let parentRoute = routeMatch && routeMatch.route; | ||
|  | 
 | ||
|  |   { | ||
|  |     // You won't get a warning about 2 different <Routes> under a <Route>
 | ||
|  |     // without a trailing *, but this is a best-effort warning anyway since we
 | ||
|  |     // cannot even give the warning unless they land at the parent route.
 | ||
|  |     //
 | ||
|  |     // Example:
 | ||
|  |     //
 | ||
|  |     // <Routes>
 | ||
|  |     //   {/* This route path MUST end with /* because otherwise
 | ||
|  |     //       it will never match /blog/post/123 */}
 | ||
|  |     //   <Route path="blog" element={<Blog />} />
 | ||
|  |     //   <Route path="blog/feed" element={<BlogFeed />} />
 | ||
|  |     // </Routes>
 | ||
|  |     //
 | ||
|  |     // function Blog() {
 | ||
|  |     //   return (
 | ||
|  |     //     <Routes>
 | ||
|  |     //       <Route path="post/:id" element={<Post />} />
 | ||
|  |     //     </Routes>
 | ||
|  |     //   );
 | ||
|  |     // }
 | ||
|  |     let parentPath = parentRoute && parentRoute.path || ""; | ||
|  |     warningOnce(parentPathname, !parentRoute || parentPath.endsWith("*"), `You rendered descendant <Routes> (or called \`useRoutes()\`) at ` + `"${parentPathname}" (under <Route path="${parentPath}">) but the ` + `parent route path has no trailing "*". This means if you navigate ` + `deeper, the parent won't match anymore and therefore the child ` + `routes will never render.\n\n` + `Please change the parent <Route path="${parentPath}"> to <Route ` + `path="${parentPath === "/" ? "*" : `${parentPath}/*`}">.`); | ||
|  |   } | ||
|  | 
 | ||
|  |   let locationFromContext = useLocation(); | ||
|  |   let location; | ||
|  | 
 | ||
|  |   if (locationArg) { | ||
|  |     let parsedLocationArg = typeof locationArg === "string" ? parsePath(locationArg) : locationArg; | ||
|  |     !(parentPathnameBase === "/" || parsedLocationArg.pathname?.startsWith(parentPathnameBase)) ? invariant(false, `When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, ` + `the location pathname must begin with the portion of the URL pathname that was ` + `matched by all parent routes. The current pathname base is "${parentPathnameBase}" ` + `but pathname "${parsedLocationArg.pathname}" was given in the \`location\` prop.`)  : void 0; | ||
|  |     location = parsedLocationArg; | ||
|  |   } else { | ||
|  |     location = locationFromContext; | ||
|  |   } | ||
|  | 
 | ||
|  |   let pathname = location.pathname || "/"; | ||
|  |   let remainingPathname = parentPathnameBase === "/" ? pathname : pathname.slice(parentPathnameBase.length) || "/"; | ||
|  |   let matches = matchRoutes(routes, { | ||
|  |     pathname: remainingPathname | ||
|  |   }); | ||
|  | 
 | ||
|  |   { | ||
|  |     warning(parentRoute || matches != null, `No routes matched location "${location.pathname}${location.search}${location.hash}" `) ; | ||
|  |     warning(matches == null || matches[matches.length - 1].route.element !== undefined, `Matched leaf route at location "${location.pathname}${location.search}${location.hash}" does not have an element. ` + `This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`) ; | ||
|  |   } | ||
|  | 
 | ||
|  |   let renderedMatches = _renderMatches(matches && matches.map(match => Object.assign({}, match, { | ||
|  |     params: Object.assign({}, parentParams, match.params), | ||
|  |     pathname: joinPaths([parentPathnameBase, // Re-encode pathnames that were decoded inside matchRoutes
 | ||
|  |     navigator.encodeLocation ? navigator.encodeLocation(match.pathname).pathname : match.pathname]), | ||
|  |     pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([parentPathnameBase, // Re-encode pathnames that were decoded inside matchRoutes
 | ||
|  |     navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase]) | ||
|  |   })), parentMatches, dataRouterStateContext || undefined); // When a user passes in a `locationArg`, the associated routes need to
 | ||
|  |   // be wrapped in a new `LocationContext.Provider` in order for `useLocation`
 | ||
|  |   // to use the scoped location instead of the global location.
 | ||
|  | 
 | ||
|  | 
 | ||
|  |   if (locationArg && renderedMatches) { | ||
|  |     return /*#__PURE__*/React.createElement(LocationContext.Provider, { | ||
|  |       value: { | ||
|  |         location: { | ||
|  |           pathname: "/", | ||
|  |           search: "", | ||
|  |           hash: "", | ||
|  |           state: null, | ||
|  |           key: "default", | ||
|  |           ...location | ||
|  |         }, | ||
|  |         navigationType: Action.Pop | ||
|  |       } | ||
|  |     }, renderedMatches); | ||
|  |   } | ||
|  | 
 | ||
|  |   return renderedMatches; | ||
|  | } | ||
|  | 
 | ||
|  | function DefaultErrorElement() { | ||
|  |   let error = useRouteError(); | ||
|  |   let message = isRouteErrorResponse(error) ? `${error.status} ${error.statusText}` : error instanceof Error ? error.message : JSON.stringify(error); | ||
|  |   let stack = error instanceof Error ? error.stack : null; | ||
|  |   let lightgrey = "rgba(200,200,200, 0.5)"; | ||
|  |   let preStyles = { | ||
|  |     padding: "0.5rem", | ||
|  |     backgroundColor: lightgrey | ||
|  |   }; | ||
|  |   let codeStyles = { | ||
|  |     padding: "2px 4px", | ||
|  |     backgroundColor: lightgrey | ||
|  |   }; | ||
|  |   return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h2", null, "Unhandled Thrown Error!"), /*#__PURE__*/React.createElement("h3", { | ||
|  |     style: { | ||
|  |       fontStyle: "italic" | ||
|  |     } | ||
|  |   }, message), stack ? /*#__PURE__*/React.createElement("pre", { | ||
|  |     style: preStyles | ||
|  |   }, stack) : null, /*#__PURE__*/React.createElement("p", null, "\uD83D\uDCBF Hey developer \uD83D\uDC4B"), /*#__PURE__*/React.createElement("p", null, "You can provide a way better UX than this when your app throws errors by providing your own\u00A0", /*#__PURE__*/React.createElement("code", { | ||
|  |     style: codeStyles | ||
|  |   }, "errorElement"), " props on\u00A0", /*#__PURE__*/React.createElement("code", { | ||
|  |     style: codeStyles | ||
|  |   }, "<Route>"))); | ||
|  | } | ||
|  | 
 | ||
|  | class RenderErrorBoundary extends React.Component { | ||
|  |   constructor(props) { | ||
|  |     super(props); | ||
|  |     this.state = { | ||
|  |       location: props.location, | ||
|  |       error: props.error | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   static getDerivedStateFromError(error) { | ||
|  |     return { | ||
|  |       error: error | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   static getDerivedStateFromProps(props, state) { | ||
|  |     // When we get into an error state, the user will likely click "back" to the
 | ||
|  |     // previous page that didn't have an error. Because this wraps the entire
 | ||
|  |     // application, that will have no effect--the error page continues to display.
 | ||
|  |     // This gives us a mechanism to recover from the error when the location changes.
 | ||
|  |     //
 | ||
|  |     // Whether we're in an error state or not, we update the location in state
 | ||
|  |     // so that when we are in an error state, it gets reset when a new location
 | ||
|  |     // comes in and the user recovers from the error.
 | ||
|  |     if (state.location !== props.location) { | ||
|  |       return { | ||
|  |         error: props.error, | ||
|  |         location: props.location | ||
|  |       }; | ||
|  |     } // If we're not changing locations, preserve the location but still surface
 | ||
|  |     // any new errors that may come through. We retain the existing error, we do
 | ||
|  |     // this because the error provided from the app state may be cleared without
 | ||
|  |     // the location changing.
 | ||
|  | 
 | ||
|  | 
 | ||
|  |     return { | ||
|  |       error: props.error || state.error, | ||
|  |       location: state.location | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   componentDidCatch(error, errorInfo) { | ||
|  |     console.error("React Router caught the following error during render", error, errorInfo); | ||
|  |   } | ||
|  | 
 | ||
|  |   render() { | ||
|  |     return this.state.error ? /*#__PURE__*/React.createElement(RouteContext.Provider, { | ||
|  |       value: this.props.routeContext | ||
|  |     }, /*#__PURE__*/React.createElement(RouteErrorContext.Provider, { | ||
|  |       value: this.state.error, | ||
|  |       children: this.props.component | ||
|  |     })) : this.props.children; | ||
|  |   } | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | function RenderedRoute({ | ||
|  |   routeContext, | ||
|  |   match, | ||
|  |   children | ||
|  | }) { | ||
|  |   let dataStaticRouterContext = React.useContext(DataStaticRouterContext); // Track how deep we got in our render pass to emulate SSR componentDidCatch
 | ||
|  |   // in a DataStaticRouter
 | ||
|  | 
 | ||
|  |   if (dataStaticRouterContext && match.route.errorElement) { | ||
|  |     dataStaticRouterContext._deepestRenderedBoundaryId = match.route.id; | ||
|  |   } | ||
|  | 
 | ||
|  |   return /*#__PURE__*/React.createElement(RouteContext.Provider, { | ||
|  |     value: routeContext | ||
|  |   }, children); | ||
|  | } | ||
|  | 
 | ||
|  | function _renderMatches(matches, parentMatches = [], dataRouterState) { | ||
|  |   if (matches == null) { | ||
|  |     if (dataRouterState?.errors) { | ||
|  |       // Don't bail if we have data router errors so we can render them in the
 | ||
|  |       // boundary.  Use the pre-matched (or shimmed) matches
 | ||
|  |       matches = dataRouterState.matches; | ||
|  |     } else { | ||
|  |       return null; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   let renderedMatches = matches; // If we have data errors, trim matches to the highest error boundary
 | ||
|  | 
 | ||
|  |   let errors = dataRouterState?.errors; | ||
|  | 
 | ||
|  |   if (errors != null) { | ||
|  |     let errorIndex = renderedMatches.findIndex(m => m.route.id && errors?.[m.route.id]); | ||
|  |     !(errorIndex >= 0) ? invariant(false, `Could not find a matching route for the current errors: ${errors}`)  : void 0; | ||
|  |     renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1)); | ||
|  |   } | ||
|  | 
 | ||
|  |   return renderedMatches.reduceRight((outlet, match, index) => { | ||
|  |     let error = match.route.id ? errors?.[match.route.id] : null; // Only data routers handle errors
 | ||
|  | 
 | ||
|  |     let errorElement = dataRouterState ? match.route.errorElement || /*#__PURE__*/React.createElement(DefaultErrorElement, null) : null; | ||
|  |     let matches = parentMatches.concat(renderedMatches.slice(0, index + 1)); | ||
|  | 
 | ||
|  |     let getChildren = () => /*#__PURE__*/React.createElement(RenderedRoute, { | ||
|  |       match: match, | ||
|  |       routeContext: { | ||
|  |         outlet, | ||
|  |         matches | ||
|  |       } | ||
|  |     }, error ? errorElement : match.route.element !== undefined ? match.route.element : outlet); // Only wrap in an error boundary within data router usages when we have an
 | ||
|  |     // errorElement on this route.  Otherwise let it bubble up to an ancestor
 | ||
|  |     // errorElement
 | ||
|  | 
 | ||
|  | 
 | ||
|  |     return dataRouterState && (match.route.errorElement || index === 0) ? /*#__PURE__*/React.createElement(RenderErrorBoundary, { | ||
|  |       location: dataRouterState.location, | ||
|  |       component: errorElement, | ||
|  |       error: error, | ||
|  |       children: getChildren(), | ||
|  |       routeContext: { | ||
|  |         outlet: null, | ||
|  |         matches | ||
|  |       } | ||
|  |     }) : getChildren(); | ||
|  |   }, null); | ||
|  | } | ||
|  | var DataRouterHook; | ||
|  | 
 | ||
|  | (function (DataRouterHook) { | ||
|  |   DataRouterHook["UseRevalidator"] = "useRevalidator"; | ||
|  | })(DataRouterHook || (DataRouterHook = {})); | ||
|  | 
 | ||
|  | var DataRouterStateHook; | ||
|  | 
 | ||
|  | (function (DataRouterStateHook) { | ||
|  |   DataRouterStateHook["UseLoaderData"] = "useLoaderData"; | ||
|  |   DataRouterStateHook["UseActionData"] = "useActionData"; | ||
|  |   DataRouterStateHook["UseRouteError"] = "useRouteError"; | ||
|  |   DataRouterStateHook["UseNavigation"] = "useNavigation"; | ||
|  |   DataRouterStateHook["UseRouteLoaderData"] = "useRouteLoaderData"; | ||
|  |   DataRouterStateHook["UseMatches"] = "useMatches"; | ||
|  |   DataRouterStateHook["UseRevalidator"] = "useRevalidator"; | ||
|  | })(DataRouterStateHook || (DataRouterStateHook = {})); | ||
|  | 
 | ||
|  | function getDataRouterConsoleError(hookName) { | ||
|  |   return `${hookName} must be used within a data router.  See https://reactrouter.com/routers/picking-a-router.`; | ||
|  | } | ||
|  | 
 | ||
|  | function useDataRouterContext(hookName) { | ||
|  |   let ctx = React.useContext(DataRouterContext); | ||
|  |   !ctx ? invariant(false, getDataRouterConsoleError(hookName))  : void 0; | ||
|  |   return ctx; | ||
|  | } | ||
|  | 
 | ||
|  | function useDataRouterState(hookName) { | ||
|  |   let state = React.useContext(DataRouterStateContext); | ||
|  |   !state ? invariant(false, getDataRouterConsoleError(hookName))  : void 0; | ||
|  |   return state; | ||
|  | } | ||
|  | 
 | ||
|  | function useRouteContext(hookName) { | ||
|  |   let route = React.useContext(RouteContext); | ||
|  |   !route ? invariant(false, getDataRouterConsoleError(hookName))  : void 0; | ||
|  |   return route; | ||
|  | } | ||
|  | 
 | ||
|  | function useCurrentRouteId(hookName) { | ||
|  |   let route = useRouteContext(hookName); | ||
|  |   let thisRoute = route.matches[route.matches.length - 1]; | ||
|  |   !thisRoute.route.id ? invariant(false, `${hookName} can only be used on routes that contain a unique "id"`)  : void 0; | ||
|  |   return thisRoute.route.id; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the current navigation, defaulting to an "idle" navigation when | ||
|  |  * no navigation is in progress | ||
|  |  */ | ||
|  | 
 | ||
|  | 
 | ||
|  | function useNavigation() { | ||
|  |   let state = useDataRouterState(DataRouterStateHook.UseNavigation); | ||
|  |   return state.navigation; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns a revalidate function for manually triggering revalidation, as well | ||
|  |  * as the current state of any manual revalidations | ||
|  |  */ | ||
|  | 
 | ||
|  | function useRevalidator() { | ||
|  |   let dataRouterContext = useDataRouterContext(DataRouterHook.UseRevalidator); | ||
|  |   let state = useDataRouterState(DataRouterStateHook.UseRevalidator); | ||
|  |   return { | ||
|  |     revalidate: dataRouterContext.router.revalidate, | ||
|  |     state: state.revalidation | ||
|  |   }; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the active route matches, useful for accessing loaderData for | ||
|  |  * parent/child routes or the route "handle" property | ||
|  |  */ | ||
|  | 
 | ||
|  | function useMatches() { | ||
|  |   let { | ||
|  |     matches, | ||
|  |     loaderData | ||
|  |   } = useDataRouterState(DataRouterStateHook.UseMatches); | ||
|  |   return React.useMemo(() => matches.map(match => { | ||
|  |     let { | ||
|  |       pathname, | ||
|  |       params | ||
|  |     } = match; // Note: This structure matches that created by createUseMatchesMatch
 | ||
|  |     // in the @remix-run/router , so if you change this please also change
 | ||
|  |     // that :)  Eventually we'll DRY this up
 | ||
|  | 
 | ||
|  |     return { | ||
|  |       id: match.route.id, | ||
|  |       pathname, | ||
|  |       params, | ||
|  |       data: loaderData[match.route.id], | ||
|  |       handle: match.route.handle | ||
|  |     }; | ||
|  |   }), [matches, loaderData]); | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the loader data for the nearest ancestor Route loader | ||
|  |  */ | ||
|  | 
 | ||
|  | function useLoaderData() { | ||
|  |   let state = useDataRouterState(DataRouterStateHook.UseLoaderData); | ||
|  |   let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData); | ||
|  | 
 | ||
|  |   if (state.errors && state.errors[routeId] != null) { | ||
|  |     console.error(`You cannot \`useLoaderData\` in an errorElement (routeId: ${routeId})`); | ||
|  |     return undefined; | ||
|  |   } | ||
|  | 
 | ||
|  |   return state.loaderData[routeId]; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the loaderData for the given routeId | ||
|  |  */ | ||
|  | 
 | ||
|  | function useRouteLoaderData(routeId) { | ||
|  |   let state = useDataRouterState(DataRouterStateHook.UseRouteLoaderData); | ||
|  |   return state.loaderData[routeId]; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the action data for the nearest ancestor Route action | ||
|  |  */ | ||
|  | 
 | ||
|  | function useActionData() { | ||
|  |   let state = useDataRouterState(DataRouterStateHook.UseActionData); | ||
|  |   let route = React.useContext(RouteContext); | ||
|  |   !route ? invariant(false, `useActionData must be used inside a RouteContext`)  : void 0; | ||
|  |   return Object.values(state?.actionData || {})[0]; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the nearest ancestor Route error, which could be a loader/action | ||
|  |  * error or a render error.  This is intended to be called from your | ||
|  |  * errorElement to display a proper error message. | ||
|  |  */ | ||
|  | 
 | ||
|  | function useRouteError() { | ||
|  |   let error = React.useContext(RouteErrorContext); | ||
|  |   let state = useDataRouterState(DataRouterStateHook.UseRouteError); | ||
|  |   let routeId = useCurrentRouteId(DataRouterStateHook.UseRouteError); // If this was a render error, we put it in a RouteError context inside
 | ||
|  |   // of RenderErrorBoundary
 | ||
|  | 
 | ||
|  |   if (error) { | ||
|  |     return error; | ||
|  |   } // Otherwise look for errors from our data router state
 | ||
|  | 
 | ||
|  | 
 | ||
|  |   return state.errors?.[routeId]; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the happy-path data from the nearest ancestor <Await /> value | ||
|  |  */ | ||
|  | 
 | ||
|  | function useAsyncValue() { | ||
|  |   let value = React.useContext(AwaitContext); | ||
|  |   return value?._data; | ||
|  | } | ||
|  | /** | ||
|  |  * Returns the error from the nearest ancestor <Await /> value | ||
|  |  */ | ||
|  | 
 | ||
|  | function useAsyncError() { | ||
|  |   let value = React.useContext(AwaitContext); | ||
|  |   return value?._error; | ||
|  | } | ||
|  | const alreadyWarned = {}; | ||
|  | 
 | ||
|  | function warningOnce(key, cond, message) { | ||
|  |   if (!cond && !alreadyWarned[key]) { | ||
|  |     alreadyWarned[key] = true; | ||
|  |     warning(false, message) ; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Given a Remix Router instance, render the appropriate UI | ||
|  |  */ | ||
|  | 
 | ||
|  | function RouterProvider({ | ||
|  |   fallbackElement, | ||
|  |   router | ||
|  | }) { | ||
|  |   // Sync router state to our component state to force re-renders
 | ||
|  |   let state = useSyncExternalStore(router.subscribe, () => router.state, // We have to provide this so React@18 doesn't complain during hydration,
 | ||
|  |   // but we pass our serialized hydration data into the router so state here
 | ||
|  |   // is already synced with what the server saw
 | ||
|  |   () => router.state); | ||
|  |   let navigator = React.useMemo(() => { | ||
|  |     return { | ||
|  |       createHref: router.createHref, | ||
|  |       encodeLocation: router.encodeLocation, | ||
|  |       go: n => router.navigate(n), | ||
|  |       push: (to, state, opts) => router.navigate(to, { | ||
|  |         state, | ||
|  |         preventScrollReset: opts?.preventScrollReset | ||
|  |       }), | ||
|  |       replace: (to, state, opts) => router.navigate(to, { | ||
|  |         replace: true, | ||
|  |         state, | ||
|  |         preventScrollReset: opts?.preventScrollReset | ||
|  |       }) | ||
|  |     }; | ||
|  |   }, [router]); | ||
|  |   let basename = router.basename || "/"; | ||
|  |   return /*#__PURE__*/React.createElement(DataRouterContext.Provider, { | ||
|  |     value: { | ||
|  |       router, | ||
|  |       navigator, | ||
|  |       static: false, | ||
|  |       // Do we need this?
 | ||
|  |       basename | ||
|  |     } | ||
|  |   }, /*#__PURE__*/React.createElement(DataRouterStateContext.Provider, { | ||
|  |     value: state | ||
|  |   }, /*#__PURE__*/React.createElement(Router, { | ||
|  |     basename: router.basename, | ||
|  |     location: router.state.location, | ||
|  |     navigationType: router.state.historyAction, | ||
|  |     navigator: navigator | ||
|  |   }, router.state.initialized ? /*#__PURE__*/React.createElement(Routes, null) : fallbackElement))); | ||
|  | } | ||
|  | /** | ||
|  |  * A <Router> that stores all entries in memory. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/router-components/memory-router
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function MemoryRouter({ | ||
|  |   basename, | ||
|  |   children, | ||
|  |   initialEntries, | ||
|  |   initialIndex | ||
|  | }) { | ||
|  |   let historyRef = React.useRef(); | ||
|  | 
 | ||
|  |   if (historyRef.current == null) { | ||
|  |     historyRef.current = createMemoryHistory({ | ||
|  |       initialEntries, | ||
|  |       initialIndex, | ||
|  |       v5Compat: true | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   let history = historyRef.current; | ||
|  |   let [state, setState] = React.useState({ | ||
|  |     action: history.action, | ||
|  |     location: history.location | ||
|  |   }); | ||
|  |   React.useLayoutEffect(() => history.listen(setState), [history]); | ||
|  |   return /*#__PURE__*/React.createElement(Router, { | ||
|  |     basename: basename, | ||
|  |     children: children, | ||
|  |     location: state.location, | ||
|  |     navigationType: state.action, | ||
|  |     navigator: history | ||
|  |   }); | ||
|  | } | ||
|  | /** | ||
|  |  * Changes the current location. | ||
|  |  * | ||
|  |  * Note: This API is mostly useful in React.Component subclasses that are not | ||
|  |  * able to use hooks. In functional components, we recommend you use the | ||
|  |  * `useNavigate` hook instead. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/components/navigate
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function Navigate({ | ||
|  |   to, | ||
|  |   replace, | ||
|  |   state, | ||
|  |   relative | ||
|  | }) { | ||
|  |   !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of
 | ||
|  |   // the router loaded. We can help them understand how to avoid that.
 | ||
|  |   `<Navigate> may be used only in the context of a <Router> component.`)  : void 0; | ||
|  |   warning(!React.useContext(NavigationContext).static, `<Navigate> must not be used on the initial render in a <StaticRouter>. ` + `This is a no-op, but you should modify your code so the <Navigate> is ` + `only ever rendered in response to some user interaction or state change.`) ; | ||
|  |   let dataRouterState = React.useContext(DataRouterStateContext); | ||
|  |   let navigate = useNavigate(); | ||
|  |   React.useEffect(() => { | ||
|  |     // Avoid kicking off multiple navigations if we're in the middle of a
 | ||
|  |     // data-router navigation, since components get re-rendered when we enter
 | ||
|  |     // a submitting/loading state
 | ||
|  |     if (dataRouterState && dataRouterState.navigation.state !== "idle") { | ||
|  |       return; | ||
|  |     } | ||
|  | 
 | ||
|  |     navigate(to, { | ||
|  |       replace, | ||
|  |       state, | ||
|  |       relative | ||
|  |     }); | ||
|  |   }); | ||
|  |   return null; | ||
|  | } | ||
|  | /** | ||
|  |  * Renders the child route's element, if there is one. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/components/outlet
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function Outlet(props) { | ||
|  |   return useOutlet(props.context); | ||
|  | } | ||
|  | /** | ||
|  |  * Declares an element that should be rendered at a certain URL path. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/components/route
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function Route(_props) { | ||
|  |   invariant(false, `A <Route> is only ever to be used as the child of <Routes> element, ` + `never rendered directly. Please wrap your <Route> in a <Routes>.`)  ; | ||
|  | } | ||
|  | /** | ||
|  |  * Provides location context for the rest of the app. | ||
|  |  * | ||
|  |  * Note: You usually won't render a <Router> directly. Instead, you'll render a | ||
|  |  * router that is more specific to your environment such as a <BrowserRouter> | ||
|  |  * in web browsers or a <StaticRouter> for server rendering. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/router-components/router
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function Router({ | ||
|  |   basename: basenameProp = "/", | ||
|  |   children = null, | ||
|  |   location: locationProp, | ||
|  |   navigationType = Action.Pop, | ||
|  |   navigator, | ||
|  |   static: staticProp = false | ||
|  | }) { | ||
|  |   !!useInRouterContext() ? invariant(false, `You cannot render a <Router> inside another <Router>.` + ` You should never have more than one in your app.`)  : void 0; // Preserve trailing slashes on basename, so we can let the user control
 | ||
|  |   // the enforcement of trailing slashes throughout the app
 | ||
|  | 
 | ||
|  |   let basename = basenameProp.replace(/^\/*/, "/"); | ||
|  |   let navigationContext = React.useMemo(() => ({ | ||
|  |     basename, | ||
|  |     navigator, | ||
|  |     static: staticProp | ||
|  |   }), [basename, navigator, staticProp]); | ||
|  | 
 | ||
|  |   if (typeof locationProp === "string") { | ||
|  |     locationProp = parsePath(locationProp); | ||
|  |   } | ||
|  | 
 | ||
|  |   let { | ||
|  |     pathname = "/", | ||
|  |     search = "", | ||
|  |     hash = "", | ||
|  |     state = null, | ||
|  |     key = "default" | ||
|  |   } = locationProp; | ||
|  |   let location = React.useMemo(() => { | ||
|  |     let trailingPathname = stripBasename(pathname, basename); | ||
|  | 
 | ||
|  |     if (trailingPathname == null) { | ||
|  |       return null; | ||
|  |     } | ||
|  | 
 | ||
|  |     return { | ||
|  |       pathname: trailingPathname, | ||
|  |       search, | ||
|  |       hash, | ||
|  |       state, | ||
|  |       key | ||
|  |     }; | ||
|  |   }, [basename, pathname, search, hash, state, key]); | ||
|  |   warning(location != null, `<Router basename="${basename}"> is not able to match the URL ` + `"${pathname}${search}${hash}" because it does not start with the ` + `basename, so the <Router> won't render anything.`) ; | ||
|  | 
 | ||
|  |   if (location == null) { | ||
|  |     return null; | ||
|  |   } | ||
|  | 
 | ||
|  |   return /*#__PURE__*/React.createElement(NavigationContext.Provider, { | ||
|  |     value: navigationContext | ||
|  |   }, /*#__PURE__*/React.createElement(LocationContext.Provider, { | ||
|  |     children: children, | ||
|  |     value: { | ||
|  |       location, | ||
|  |       navigationType | ||
|  |     } | ||
|  |   })); | ||
|  | } | ||
|  | /** | ||
|  |  * A container for a nested tree of <Route> elements that renders the branch | ||
|  |  * that best matches the current location. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/components/routes
 | ||
|  |  */ | ||
|  | 
 | ||
|  | function Routes({ | ||
|  |   children, | ||
|  |   location | ||
|  | }) { | ||
|  |   let dataRouterContext = React.useContext(DataRouterContext); // When in a DataRouterContext _without_ children, we use the router routes
 | ||
|  |   // directly.  If we have children, then we're in a descendant tree and we
 | ||
|  |   // need to use child routes.
 | ||
|  | 
 | ||
|  |   let routes = dataRouterContext && !children ? dataRouterContext.router.routes : createRoutesFromChildren(children); | ||
|  |   return useRoutes(routes, location); | ||
|  | } | ||
|  | /** | ||
|  |  * Component to use for rendering lazily loaded data from returning defer() | ||
|  |  * in a loader function | ||
|  |  */ | ||
|  | 
 | ||
|  | function Await({ | ||
|  |   children, | ||
|  |   errorElement, | ||
|  |   resolve | ||
|  | }) { | ||
|  |   return /*#__PURE__*/React.createElement(AwaitErrorBoundary, { | ||
|  |     resolve: resolve, | ||
|  |     errorElement: errorElement | ||
|  |   }, /*#__PURE__*/React.createElement(ResolveAwait, null, children)); | ||
|  | } | ||
|  | var AwaitRenderStatus; | ||
|  | 
 | ||
|  | (function (AwaitRenderStatus) { | ||
|  |   AwaitRenderStatus[AwaitRenderStatus["pending"] = 0] = "pending"; | ||
|  |   AwaitRenderStatus[AwaitRenderStatus["success"] = 1] = "success"; | ||
|  |   AwaitRenderStatus[AwaitRenderStatus["error"] = 2] = "error"; | ||
|  | })(AwaitRenderStatus || (AwaitRenderStatus = {})); | ||
|  | 
 | ||
|  | const neverSettledPromise = new Promise(() => {}); | ||
|  | 
 | ||
|  | class AwaitErrorBoundary extends React.Component { | ||
|  |   constructor(props) { | ||
|  |     super(props); | ||
|  |     this.state = { | ||
|  |       error: null | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   static getDerivedStateFromError(error) { | ||
|  |     return { | ||
|  |       error | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   componentDidCatch(error, errorInfo) { | ||
|  |     console.error("<Await> caught the following error during render", error, errorInfo); | ||
|  |   } | ||
|  | 
 | ||
|  |   render() { | ||
|  |     let { | ||
|  |       children, | ||
|  |       errorElement, | ||
|  |       resolve | ||
|  |     } = this.props; | ||
|  |     let promise = null; | ||
|  |     let status = AwaitRenderStatus.pending; | ||
|  | 
 | ||
|  |     if (!(resolve instanceof Promise)) { | ||
|  |       // Didn't get a promise - provide as a resolved promise
 | ||
|  |       status = AwaitRenderStatus.success; | ||
|  |       promise = Promise.resolve(); | ||
|  |       Object.defineProperty(promise, "_tracked", { | ||
|  |         get: () => true | ||
|  |       }); | ||
|  |       Object.defineProperty(promise, "_data", { | ||
|  |         get: () => resolve | ||
|  |       }); | ||
|  |     } else if (this.state.error) { | ||
|  |       // Caught a render error, provide it as a rejected promise
 | ||
|  |       status = AwaitRenderStatus.error; | ||
|  |       let renderError = this.state.error; | ||
|  |       promise = Promise.reject().catch(() => {}); // Avoid unhandled rejection warnings
 | ||
|  | 
 | ||
|  |       Object.defineProperty(promise, "_tracked", { | ||
|  |         get: () => true | ||
|  |       }); | ||
|  |       Object.defineProperty(promise, "_error", { | ||
|  |         get: () => renderError | ||
|  |       }); | ||
|  |     } else if (resolve._tracked) { | ||
|  |       // Already tracked promise - check contents
 | ||
|  |       promise = resolve; | ||
|  |       status = promise._error !== undefined ? AwaitRenderStatus.error : promise._data !== undefined ? AwaitRenderStatus.success : AwaitRenderStatus.pending; | ||
|  |     } else { | ||
|  |       // Raw (untracked) promise - track it
 | ||
|  |       status = AwaitRenderStatus.pending; | ||
|  |       Object.defineProperty(resolve, "_tracked", { | ||
|  |         get: () => true | ||
|  |       }); | ||
|  |       promise = resolve.then(data => Object.defineProperty(resolve, "_data", { | ||
|  |         get: () => data | ||
|  |       }), error => Object.defineProperty(resolve, "_error", { | ||
|  |         get: () => error | ||
|  |       })); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (status === AwaitRenderStatus.error && promise._error instanceof AbortedDeferredError) { | ||
|  |       // Freeze the UI by throwing a never resolved promise
 | ||
|  |       throw neverSettledPromise; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (status === AwaitRenderStatus.error && !errorElement) { | ||
|  |       // No errorElement, throw to the nearest route-level error boundary
 | ||
|  |       throw promise._error; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (status === AwaitRenderStatus.error) { | ||
|  |       // Render via our errorElement
 | ||
|  |       return /*#__PURE__*/React.createElement(AwaitContext.Provider, { | ||
|  |         value: promise, | ||
|  |         children: errorElement | ||
|  |       }); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (status === AwaitRenderStatus.success) { | ||
|  |       // Render children with resolved value
 | ||
|  |       return /*#__PURE__*/React.createElement(AwaitContext.Provider, { | ||
|  |         value: promise, | ||
|  |         children: children | ||
|  |       }); | ||
|  |     } // Throw to the suspense boundary
 | ||
|  | 
 | ||
|  | 
 | ||
|  |     throw promise; | ||
|  |   } | ||
|  | 
 | ||
|  | } | ||
|  | /** | ||
|  |  * @private | ||
|  |  * Indirection to leverage useAsyncValue for a render-prop API on <Await> | ||
|  |  */ | ||
|  | 
 | ||
|  | 
 | ||
|  | function ResolveAwait({ | ||
|  |   children | ||
|  | }) { | ||
|  |   let data = useAsyncValue(); | ||
|  | 
 | ||
|  |   if (typeof children === "function") { | ||
|  |     return children(data); | ||
|  |   } | ||
|  | 
 | ||
|  |   return /*#__PURE__*/React.createElement(React.Fragment, null, children); | ||
|  | } ///////////////////////////////////////////////////////////////////////////////
 | ||
|  | // UTILS
 | ||
|  | ///////////////////////////////////////////////////////////////////////////////
 | ||
|  | 
 | ||
|  | /** | ||
|  |  * Creates a route config from a React "children" object, which is usually | ||
|  |  * either a `<Route>` element or an array of them. Used internally by | ||
|  |  * `<Routes>` to create a route config from its children. | ||
|  |  * | ||
|  |  * @see https://reactrouter.com/utils/create-routes-from-children
 | ||
|  |  */ | ||
|  | 
 | ||
|  | 
 | ||
|  | function createRoutesFromChildren(children, parentPath = []) { | ||
|  |   let routes = []; | ||
|  |   React.Children.forEach(children, (element, index) => { | ||
|  |     if (! /*#__PURE__*/React.isValidElement(element)) { | ||
|  |       // Ignore non-elements. This allows people to more easily inline
 | ||
|  |       // conditionals in their route config.
 | ||
|  |       return; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (element.type === React.Fragment) { | ||
|  |       // Transparently support React.Fragment and its children.
 | ||
|  |       routes.push.apply(routes, createRoutesFromChildren(element.props.children, parentPath)); | ||
|  |       return; | ||
|  |     } | ||
|  | 
 | ||
|  |     !(element.type === Route) ? invariant(false, `[${typeof element.type === "string" ? element.type : element.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`)  : void 0; | ||
|  |     !(!element.props.index || !element.props.children) ? invariant(false, "An index route cannot have child routes.")  : void 0; | ||
|  |     let treePath = [...parentPath, index]; | ||
|  |     let route = { | ||
|  |       id: element.props.id || treePath.join("-"), | ||
|  |       caseSensitive: element.props.caseSensitive, | ||
|  |       element: element.props.element, | ||
|  |       index: element.props.index, | ||
|  |       path: element.props.path, | ||
|  |       loader: element.props.loader, | ||
|  |       action: element.props.action, | ||
|  |       errorElement: element.props.errorElement, | ||
|  |       hasErrorBoundary: element.props.errorElement != null, | ||
|  |       shouldRevalidate: element.props.shouldRevalidate, | ||
|  |       handle: element.props.handle | ||
|  |     }; | ||
|  | 
 | ||
|  |     if (element.props.children) { | ||
|  |       route.children = createRoutesFromChildren(element.props.children, treePath); | ||
|  |     } | ||
|  | 
 | ||
|  |     routes.push(route); | ||
|  |   }); | ||
|  |   return routes; | ||
|  | } | ||
|  | /** | ||
|  |  * Renders the result of `matchRoutes()` into a React element. | ||
|  |  */ | ||
|  | 
 | ||
|  | function renderMatches(matches) { | ||
|  |   return _renderMatches(matches); | ||
|  | } | ||
|  | /** | ||
|  |  * @private | ||
|  |  * Walk the route tree and add hasErrorBoundary if it's not provided, so that | ||
|  |  * users providing manual route arrays can just specify errorElement | ||
|  |  */ | ||
|  | 
 | ||
|  | function enhanceManualRouteObjects(routes) { | ||
|  |   return routes.map(route => { | ||
|  |     let routeClone = { ...route | ||
|  |     }; | ||
|  | 
 | ||
|  |     if (routeClone.hasErrorBoundary == null) { | ||
|  |       routeClone.hasErrorBoundary = routeClone.errorElement != null; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (routeClone.children) { | ||
|  |       routeClone.children = enhanceManualRouteObjects(routeClone.children); | ||
|  |     } | ||
|  | 
 | ||
|  |     return routeClone; | ||
|  |   }); | ||
|  | } | ||
|  | 
 | ||
|  | function createMemoryRouter(routes, opts) { | ||
|  |   return createRouter({ | ||
|  |     basename: opts?.basename, | ||
|  |     history: createMemoryHistory({ | ||
|  |       initialEntries: opts?.initialEntries, | ||
|  |       initialIndex: opts?.initialIndex | ||
|  |     }), | ||
|  |     hydrationData: opts?.hydrationData, | ||
|  |     routes: enhanceManualRouteObjects(routes) | ||
|  |   }).initialize(); | ||
|  | } ///////////////////////////////////////////////////////////////////////////////
 | ||
|  | 
 | ||
|  | export { Await, MemoryRouter, Navigate, Outlet, Route, Router, RouterProvider, Routes, DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, DataStaticRouterContext as UNSAFE_DataStaticRouterContext, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RouteContext as UNSAFE_RouteContext, enhanceManualRouteObjects as UNSAFE_enhanceManualRouteObjects, createMemoryRouter, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, renderMatches, useActionData, useAsyncError, useAsyncValue, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes }; | ||
|  | //# sourceMappingURL=react-router.development.js.map
 |