() => matchRoutes(router2.routes, page, router2.basename), [router2.routes, page, router2.basename] ); if (!matches) { return null; } return React9.createElement(PrefetchPageLinksImpl, { page, matches, ...dataLinkProps }); } function useKeyedPrefetchLinks(matches) { let { manifest, routeModules } = useFrameworkContext(); let [keyedPrefetchLinks, setKeyedPrefetchLinks] = React9.useState([]); React9.useEffect(() => { let interrupted = false; void getKeyedPrefetchLinks(matches, manifest, routeModules).then( (links) => { if (!interrupted) { setKeyedPrefetchLinks(links); } } ); return () => { interrupted = true; }; }, [matches, manifest, routeModules]); return keyedPrefetchLinks; } function PrefetchPageLinksImpl({ page, matches: nextMatches, ...linkProps }) { let location = useLocation(); let { manifest, routeModules } = useFrameworkContext(); let { basename } = useDataRouterContext2(); let { loaderData, matches } = useDataRouterStateContext(); let newMatchesForData = React9.useMemo( () => getNewMatchesForLinks( page, nextMatches, matches, manifest, location, "data" ), [page, nextMatches, matches, manifest, location] ); let newMatchesForAssets = React9.useMemo( () => getNewMatchesForLinks( page, nextMatches, matches, manifest, location, "assets" ), [page, nextMatches, matches, manifest, location] ); let dataHrefs = React9.useMemo(() => { if (page === location.pathname + location.search + location.hash) { return []; } let routesParams = /* @__PURE__ */ new Set(); let foundOptOutRoute = false; nextMatches.forEach((m) => { let manifestRoute = manifest.routes[m.route.id]; if (!manifestRoute || !manifestRoute.hasLoader) { return; } if (!newMatchesForData.some((m2) => m2.route.id === m.route.id) && m.route.id in loaderData && routeModules[m.route.id]?.shouldRevalidate) { foundOptOutRoute = true; } else if (manifestRoute.hasClientLoader) { foundOptOutRoute = true; } else { routesParams.add(m.route.id); } }); if (routesParams.size === 0) { return []; } let url = singleFetchUrl(page, basename); if (foundOptOutRoute && routesParams.size > 0) { url.searchParams.set( "_routes", nextMatches.filter((m) => routesParams.has(m.route.id)).map((m) => m.route.id).join(",") ); } return [url.pathname + url.search]; }, [ basename, loaderData, location, manifest, newMatchesForData, nextMatches, page, routeModules ]); let moduleHrefs = React9.useMemo( () => getModuleLinkHrefs(newMatchesForAssets, manifest), [newMatchesForAssets, manifest] ); let keyedPrefetchLinks = useKeyedPrefetchLinks(newMatchesForAssets); return React9.createElement(React9.Fragment, null, dataHrefs.map((href2) => React9.createElement("link", { key: href2, rel: "prefetch", as: "fetch", href: href2, ...linkProps })), moduleHrefs.map((href2) => React9.createElement("link", { key: href2, rel: "modulepreload", href: href2, ...linkProps })), keyedPrefetchLinks.map(({ key, link }) => ( // these don't spread `linkProps` because they are full link descriptors // already with their own props React9.createElement("link", { key, ...link }) ))); } function Meta() { let { isSpaMode, routeModules } = useFrameworkContext(); let { errors, matches: routerMatches, loaderData } = useDataRouterStateContext(); let location = useLocation(); let _matches = getActiveMatches(routerMatches, errors, isSpaMode); let error = null; if (errors) { error = errors[_matches[_matches.length - 1].route.id]; } let meta = []; let leafMeta = null; let matches = []; for (let i = 0; i < _matches.length; i++) { let _match = _matches[i]; let routeId = _match.route.id; let data2 = loaderData[routeId]; let params = _match.params; let routeModule = routeModules[routeId]; let routeMeta = []; let match = { id: routeId, data: data2, meta: [], params: _match.params, pathname: _match.pathname, handle: _match.route.handle, error }; matches[i] = match; if (routeModule?.meta) { routeMeta = typeof routeModule.meta === "function" ? routeModule.meta({ data: data2, params, location, matches, error }) : Array.isArray(routeModule.meta) ? [...routeModule.meta] : routeModule.meta; } else if (leafMeta) { routeMeta = [...leafMeta]; } routeMeta = routeMeta || []; if (!Array.isArray(routeMeta)) { throw new Error( "The route at " + _match.route.path + " returns an invalid value. All route meta functions must return an array of meta objects.\n\nTo reference the meta function API, see https://remix.run/route/meta" ); } match.meta = routeMeta; matches[i] = match; meta = [...routeMeta]; leafMeta = meta; } return React9.createElement(React9.Fragment, null, meta.flat().map((metaProps) => { if (!metaProps) { return null; } if ("tagName" in metaProps) { let { tagName, ...rest } = metaProps; if (!isValidMetaTag(tagName)) { console.warn( `A meta object uses an invalid tagName: ${tagName}. Expected either 'link' or 'meta'` ); return null; } let Comp = tagName; return React9.createElement(Comp, { key: JSON.stringify(rest), ...rest }); } if ("title" in metaProps) { return React9.createElement("title", { key: "title" }, String(metaProps.title)); } if ("charset" in metaProps) { metaProps.charSet ?? (metaProps.charSet = metaProps.charset); delete metaProps.charset; } if ("charSet" in metaProps && metaProps.charSet != null) { return typeof metaProps.charSet === "string" ? React9.createElement("meta", { key: "charSet", charSet: metaProps.charSet }) : null; } if ("script:ld+json" in metaProps) { try { let json = JSON.stringify(metaProps["script:ld+json"]); return React9.createElement( "script", { key: `script:ld+json:${json}`, type: "application/ld+json", dangerouslySetInnerHTML: { __html: json } } ); } catch (err) { return null; } } return React9.createElement("meta", { key: JSON.stringify(metaProps), ...metaProps }); })); } function isValidMetaTag(tagName) { return typeof tagName === "string" && /^(meta|link)$/.test(tagName); } var isHydrated = false; function Scripts(props) { let { manifest, serverHandoffString, isSpaMode, ssr, renderMeta } = useFrameworkContext(); let { router: router2, static: isStatic, staticContext } = useDataRouterContext2(); let { matches: routerMatches } = useDataRouterStateContext(); let enableFogOfWar = isFogOfWarEnabled(ssr); if (renderMeta) { renderMeta.didRenderScripts = true; } let matches = getActiveMatches(routerMatches, null, isSpaMode); React9.useEffect(() => { isHydrated = true; }, []); let initialScripts = React9.useMemo(() => { let streamScript = "window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());"; let contextScript = staticContext ? `window.__reactRouterContext = ${serverHandoffString};${streamScript}` : " "; let routeModulesScript = !isStatic ? " " : `${manifest.hmr?.runtime ? `import ${JSON.stringify(manifest.hmr.runtime)};` : ""}${!enableFogOfWar ? `import ${JSON.stringify(manifest.url)}` : ""}; ${matches.map((match, routeIndex) => { let routeVarName = `route${routeIndex}`; let manifestEntry = manifest.routes[match.route.id]; invariant2(manifestEntry, `Route ${match.route.id} not found in manifest`); let { clientActionModule, clientLoaderModule, hydrateFallbackModule, module } = manifestEntry; let chunks = [ ...clientActionModule ? [ { module: clientActionModule, varName: `${routeVarName}_clientAction` } ] : [], ...clientLoaderModule ? [ { module: clientLoaderModule, varName: `${routeVarName}_clientLoader` } ] : [], ...hydrateFallbackModule ? [ { module: hydrateFallbackModule, varName: `${routeVarName}_HydrateFallback` } ] : [], { module, varName: `${routeVarName}_main` } ]; if (chunks.length === 1) { return `import * as ${routeVarName} from ${JSON.stringify(module)};`; } let chunkImportsSnippet = chunks.map((chunk) => `import * as ${chunk.varName} from "${chunk.module}";`).join("\n"); let mergedChunksSnippet = `const ${routeVarName} = {${chunks.map((chunk) => `...${chunk.varName}`).join(",")}};`; return [chunkImportsSnippet, mergedChunksSnippet].join("\n"); }).join("\n")} ${enableFogOfWar ? ( // Inline a minimal manifest with the SSR matches `window.__reactRouterManifest = ${JSON.stringify( getPartialManifest(manifest, router2), null, 2 )};` ) : ""} window.__reactRouterRouteModules = {${matches.map((match, index) => `${JSON.stringify(match.route.id)}:route${index}`).join(",")}}; import(${JSON.stringify(manifest.entry.module)});`; return React9.createElement(React9.Fragment, null, React9.createElement( "script", { ...props, suppressHydrationWarning: true, dangerouslySetInnerHTML: createHtml(contextScript), type: void 0 } ), React9.createElement( "script", { ...props, suppressHydrationWarning: true, dangerouslySetInnerHTML: createHtml(routeModulesScript), type: "module", async: true } )); }, []); let preloads = isHydrated ? [] : manifest.entry.imports.concat( getModuleLinkHrefs(matches, manifest, { includeHydrateFallback: true }) ); return isHydrated ? null : React9.createElement(React9.Fragment, null, !enableFogOfWar ? React9.createElement( "link", { rel: "modulepreload", href: manifest.url, crossOrigin: props.crossOrigin } ) : null, React9.createElement( "link", { rel: "modulepreload", href: manifest.entry.module, crossOrigin: props.crossOrigin } ), dedupe(preloads).map((path) => React9.createElement( "link", { key: path, rel: "modulepreload", href: path, crossOrigin: props.crossOrigin } )), initialScripts); } function dedupe(array) { return [...new Set(array)]; } function mergeRefs(...refs) { return (value) => { refs.forEach((ref) => { if (typeof ref === "function") { ref(value); } else if (ref != null) { ref.current = value; } }); }; } var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"; try { if (isBrowser) { window.__reactRouterVersion = "7.3.0"; } } catch (e) { } function createBrowserRouter(routes, opts) { return createRouter({ basename: opts?.basename, unstable_getContext: opts?.unstable_getContext, future: opts?.future, history: createBrowserHistory({ window: opts?.window }), hydrationData: opts?.hydrationData || parseHydrationData(), routes, mapRouteProperties, dataStrategy: opts?.dataStrategy, patchRoutesOnNavigation: opts?.patchRoutesOnNavigation, window: opts?.window }).initialize(); } function createHashRouter(routes, opts) { return createRouter({ basename: opts?.basename, unstable_getContext: opts?.unstable_getContext, future: opts?.future, history: createHashHistory({ window: opts?.window }), hydrationData: opts?.hydrationData || parseHydrationData(), routes, mapRouteProperties, dataStrategy: opts?.dataStrategy, patchRoutesOnNavigation: opts?.patchRoutesOnNavigation, window: opts?.window }).initialize(); } function parseHydrationData() { let state = window?.__staticRouterHydrationData; if (state && state.errors) { state = { ...state, errors: deserializeErrors(state.errors) }; } return state; } function deserializeErrors(errors) { if (!errors) return null; let entries = Object.entries(errors); let serialized = {}; for (let [key, val] of entries) { if (val && val.__type === "RouteErrorResponse") { serialized[key] = new ErrorResponseImpl( val.status, val.statusText, val.data, val.internal === true ); } else if (val && val.__type === "Error") { if (val.__subType) { let ErrorConstructor = window[val.__subType]; if (typeof ErrorConstructor === "function") { try { let error = new ErrorConstructor(val.message); error.stack = ""; serialized[key] = error; } catch (e) { } } } if (serialized[key] == null) { let error = new Error(val.message); error.stack = ""; serialized[key] = error; } } else { serialized[key] = val; } } return serialized; } function BrowserRouter({ basename, children, window: window2 }) { let historyRef = React10.useRef(); if (historyRef.current == null) { historyRef.current = createBrowserHistory({ window: window2, v5Compat: true }); } let history = historyRef.current; let [state, setStateImpl] = React10.useState({ action: history.action, location: history.location }); let setState = React10.useCallback( (newState) => { React10.startTransition(() => setStateImpl(newState)); }, [setStateImpl] ); React10.useLayoutEffect(() => history.listen(setState), [history, setState]); return React10.createElement( Router, { basename, children, location: state.location, navigationType: state.action, navigator: history } ); } function HashRouter({ basename, children, window: window2 }) { let historyRef = React10.useRef(); if (historyRef.current == null) { historyRef.current = createHashHistory({ window: window2, v5Compat: true }); } let history = historyRef.current; let [state, setStateImpl] = React10.useState({ action: history.action, location: history.location }); let setState = React10.useCallback( (newState) => { React10.startTransition(() => setStateImpl(newState)); }, [setStateImpl] ); React10.useLayoutEffect(() => history.listen(setState), [history, setState]); return React10.createElement( Router, { basename, children, location: state.location, navigationType: state.action, navigator: history } ); } function HistoryRouter({ basename, children, history }) { let [state, setStateImpl] = React10.useState({ action: history.action, location: history.location }); let setState = React10.useCallback( (newState) => { React10.startTransition(() => setStateImpl(newState)); }, [setStateImpl] ); React10.useLayoutEffect(() => history.listen(setState), [history, setState]); return React10.createElement( Router, { basename, children, location: state.location, navigationType: state.action, navigator: history } ); } HistoryRouter.displayName = "unstable_HistoryRouter"; var ABSOLUTE_URL_REGEX2 = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; var Link = React10.forwardRef( function LinkWithRef({ onClick, discover = "render", prefetch = "none", relative, reloadDocument, replace: replace2, state, target, to, preventScrollReset, viewTransition, ...rest }, forwardedRef) { let { basename } = React10.useContext(NavigationContext); let isAbsolute = typeof to === "string" && ABSOLUTE_URL_REGEX2.test(to); let absoluteHref; let isExternal = false; if (typeof to === "string" && isAbsolute) { absoluteHref = to; if (isBrowser) { try { let currentUrl = new URL(window.location.href); let targetUrl = to.startsWith("//") ? new URL(currentUrl.protocol + to) : new URL(to); let path = stripBasename(targetUrl.pathname, basename); if (targetUrl.origin === currentUrl.origin && path != null) { to = path + targetUrl.search + targetUrl.hash; } else { isExternal = true; } } catch (e) { warning( false, ` contains an invalid URL which will probably break when clicked - please update to a valid URL path.` ); } } } let href2 = useHref(to, { relative }); let [shouldPrefetch, prefetchRef, prefetchHandlers] = usePrefetchBehavior( prefetch, rest ); let internalOnClick = useLinkClickHandler(to, { replace: replace2, state, target, preventScrollReset, relative, viewTransition }); function handleClick(event) { if (onClick) onClick(event); if (!event.defaultPrevented) { internalOnClick(event); } } let link = ( // eslint-disable-next-line jsx-a11y/anchor-has-content React10.createElement( "a", { ...rest, ...prefetchHandlers, href: absoluteHref || href2, onClick: isExternal || reloadDocument ? onClick : handleClick, ref: mergeRefs(forwardedRef, prefetchRef), target, "data-discover": !isAbsolute && discover === "render" ? "true" : void 0 } ) ); return shouldPrefetch && !isAbsolute ? React10.createElement(React10.Fragment, null, link, React10.createElement(PrefetchPageLinks, { page: href2 })) : link; } ); Link.displayName = "Link"; var NavLink = React10.forwardRef( function NavLinkWithRef({ "aria-current": ariaCurrentProp = "page", caseSensitive = false, className: classNameProp = "", end = false, style: styleProp, to, viewTransition, children, ...rest }, ref) { let path = useResolvedPath(to, { relative: rest.relative }); let location = useLocation(); let routerState = React10.useContext(DataRouterStateContext); let { navigator: navigator2, basename } = React10.useContext(NavigationContext); let isTransitioning = routerState != null && // Conditional usage is OK here because the usage of a data router is static // eslint-disable-next-line react-hooks/rules-of-hooks useViewTransitionState(path) && viewTransition === true; let toPathname = navigator2.encodeLocation ? navigator2.encodeLocation(path).pathname : path.pathname; let locationPathname = location.pathname; let nextLocationPathname = routerState && routerState.navigation && routerState.navigation.location ? routerState.navigation.location.pathname : null; if (!caseSensitive) { locationPathname = locationPathname.toLowerCase(); nextLocationPathname = nextLocationPathname ? nextLocationPathname.toLowerCase() : null; toPathname = toPathname.toLowerCase(); } if (nextLocationPathname && basename) { nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname; } const endSlashPosition = toPathname !== "/" && toPathname.endsWith("/") ? toPathname.length - 1 : toPathname.length; let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === "/"; let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(toPathname.length) === "/"); let renderProps = { isActive, isPending, isTransitioning }; let ariaCurrent = isActive ? ariaCurrentProp : void 0; let className; if (typeof classNameProp === "function") { className = classNameProp(renderProps); } else { className = [ classNameProp, isActive ? "active" : null, isPending ? "pending" : null, isTransitioning ? "transitioning" : null ].filter(Boolean).join(" "); } let style = typeof styleProp === "function" ? styleProp(renderProps) : styleProp; return React10.createElement( Link, { ...rest, "aria-current": ariaCurrent, className, ref, style, to, viewTransition }, typeof children === "function" ? children(renderProps) : children ); } ); NavLink.displayName = "NavLink"; var Form = React10.forwardRef( ({ discover = "render", fetcherKey, navigate, reloadDocument, replace: replace2, state, method = defaultMethod, action, onSubmit, relative, preventScrollReset, viewTransition, ...props }, forwardedRef) => { let submit = useSubmit(); let formAction = useFormAction(action, { relative }); let formMethod = method.toLowerCase() === "get" ? "get" : "post"; let isAbsolute = typeof action === "string" && ABSOLUTE_URL_REGEX2.test(action); let submitHandler = (event) => { onSubmit && onSubmit(event); if (event.defaultPrevented) return; event.preventDefault(); let submitter = event.nativeEvent.submitter; let submitMethod = submitter?.getAttribute("formmethod") || method; submit(submitter || event.currentTarget, { fetcherKey, method: submitMethod, navigate, replace: replace2, state, relative, preventScrollReset, viewTransition }); }; return React10.createElement( "form", { ref: forwardedRef, method: formMethod, action: formAction, onSubmit: reloadDocument ? onSubmit : submitHandler, ...props, "data-discover": !isAbsolute && discover === "render" ? "true" : void 0 } ); } ); Form.displayName = "Form"; function ScrollRestoration({ getKey, storageKey, ...props }) { let remixContext = React10.useContext(FrameworkContext); let { basename } = React10.useContext(NavigationContext); let location = useLocation(); let matches = useMatches(); useScrollRestoration({ getKey, storageKey }); let ssrKey = React10.useMemo( () => { if (!remixContext || !getKey) return null; let userKey = getScrollRestorationKey( location, matches, basename, getKey ); return userKey !== location.key ? userKey : null; }, // Nah, we only need this the first time for the SSR render // eslint-disable-next-line react-hooks/exhaustive-deps [] ); if (!remixContext || remixContext.isSpaMode) { return null; } let restoreScroll = ((storageKey2, restoreKey) => { if (!window.history.state || !window.history.state.key) { let key = Math.random().toString(32).slice(2); window.history.replaceState({ key }, ""); } try { let positions = JSON.parse(sessionStorage.getItem(storageKey2) || "{}"); let storedY = positions[restoreKey || window.history.state.key]; if (typeof storedY === "number") { window.scrollTo(0, storedY); } } catch (error) { console.error(error); sessionStorage.removeItem(storageKey2); } }).toString(); return React10.createElement( "script", { ...props, suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: `(${restoreScroll})(${JSON.stringify( storageKey || SCROLL_RESTORATION_STORAGE_KEY )}, ${JSON.stringify(ssrKey)})` } } ); } ScrollRestoration.displayName = "ScrollRestoration"; function getDataRouterConsoleError2(hookName) { return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`; } function useDataRouterContext3(hookName) { let ctx = React10.useContext(DataRouterContext); invariant(ctx, getDataRouterConsoleError2(hookName)); return ctx; } function useDataRouterState2(hookName) { let state = React10.useContext(DataRouterStateContext); invariant(state, getDataRouterConsoleError2(hookName)); return state; } function useLinkClickHandler(to, { target, replace: replaceProp, state, preventScrollReset, relative, viewTransition } = {}) { let navigate = useNavigate(); let location = useLocation(); let path = useResolvedPath(to, { relative }); return React10.useCallback( (event) => { if (shouldProcessLinkClick(event, target)) { event.preventDefault(); let replace2 = replaceProp !== void 0 ? replaceProp : createPath(location) === createPath(path); navigate(to, { replace: replace2, state, preventScrollReset, relative, viewTransition }); } }, [ location, navigate, path, replaceProp, state, target, to, preventScrollReset, relative, viewTransition ] ); } function useSearchParams(defaultInit) { warning( typeof URLSearchParams !== "undefined", `You cannot use the \`useSearchParams\` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.` ); let defaultSearchParamsRef = React10.useRef(createSearchParams(defaultInit)); let hasSetSearchParamsRef = React10.useRef(false); let location = useLocation(); let searchParams = React10.useMemo( () => ( // Only merge in the defaults if we haven't yet called setSearchParams. // Once we call that we want those to take precedence, otherwise you can't // remove a param with setSearchParams({}) if it has an initial value getSearchParamsForLocation( location.search, hasSetSearchParamsRef.current ? null : defaultSearchParamsRef.current ) ), [location.search] ); let navigate = useNavigate(); let setSearchParams = React10.useCallback( (nextInit, navigateOptions) => { const newSearchParams = createSearchParams( typeof nextInit === "function" ? nextInit(searchParams) : nextInit ); hasSetSearchParamsRef.current = true; navigate("?" + newSearchParams, navigateOptions); }, [navigate, searchParams] ); return [searchParams, setSearchParams]; } var fetcherId = 0; var getUniqueFetcherId = () => `__${String(++fetcherId)}__`; function useSubmit() { let { router: router2 } = useDataRouterContext3( "useSubmit" /* UseSubmit */ ); let { basename } = React10.useContext(NavigationContext); let currentRouteId = useRouteId(); return React10.useCallback( async (target, options = {}) => { let { action, method, encType, formData, body } = getFormSubmissionInfo( target, basename ); if (options.navigate === false) { let key = options.fetcherKey || getUniqueFetcherId(); await router2.fetch(key, currentRouteId, options.action || action, { preventScrollReset: options.preventScrollReset, formData, body, formMethod: options.method || method, formEncType: options.encType || encType, flushSync: options.flushSync }); } else { await router2.navigate(options.action || action, { preventScrollReset: options.preventScrollReset, formData, body, formMethod: options.method || method, formEncType: options.encType || encType, replace: options.replace, state: options.state, fromRouteId: currentRouteId, flushSync: options.flushSync, viewTransition: options.viewTransition }); } }, [router2, basename, currentRouteId] ); } function useFormAction(action, { relative } = {}) { let { basename } = React10.useContext(NavigationContext); let routeContext = React10.useContext(RouteContext); invariant(routeContext, "useFormAction must be used inside a RouteContext"); let [match] = routeContext.matches.slice(-1); let path = { ...useResolvedPath(action ? action : ".", { relative }) }; let location = useLocation(); if (action == null) { path.search = location.search; let params = new URLSearchParams(path.search); let indexValues = params.getAll("index"); let hasNakedIndexParam = indexValues.some((v) => v === ""); if (hasNakedIndexParam) { params.delete("index"); indexValues.filter((v) => v).forEach((v) => params.append("index", v)); let qs = params.toString(); path.search = qs ? `?${qs}` : ""; } } if ((!action || action === ".") && match.route.index) { path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index"; } if (basename !== "/") { path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]); } return createPath(path); } function useFetcher({ key } = {}) { let { router: router2 } = useDataRouterContext3( "useFetcher" /* UseFetcher */ ); let state = useDataRouterState2( "useFetcher" /* UseFetcher */ ); let fetcherData = React10.useContext(FetchersContext); let route = React10.useContext(RouteContext); let routeId = route.matches[route.matches.length - 1]?.route.id; invariant(fetcherData, `useFetcher must be used inside a FetchersContext`); invariant(route, `useFetcher must be used inside a RouteContext`); invariant( routeId != null, `useFetcher can only be used on routes that contain a unique "id"` ); let defaultKey = React10.useId(); let [fetcherKey, setFetcherKey] = React10.useState(key || defaultKey); if (key && key !== fetcherKey) { setFetcherKey(key); } React10.useEffect(() => { router2.getFetcher(fetcherKey); return () => router2.deleteFetcher(fetcherKey); }, [router2, fetcherKey]); let load = React10.useCallback( async (href2, opts) => { invariant(routeId, "No routeId available for fetcher.load()"); await router2.fetch(fetcherKey, routeId, href2, opts); }, [fetcherKey, routeId, router2] ); let submitImpl = useSubmit(); let submit = React10.useCallback( async (target, opts) => { await submitImpl(target, { ...opts, navigate: false, fetcherKey }); }, [fetcherKey, submitImpl] ); let FetcherForm = React10.useMemo(() => { let FetcherForm2 = React10.forwardRef( (props, ref) => { return React10.createElement(Form, { ...props, navigate: false, fetcherKey, ref }); } ); FetcherForm2.displayName = "fetcher.Form"; return FetcherForm2; }, [fetcherKey]); let fetcher = state.fetchers.get(fetcherKey) || IDLE_FETCHER; let data2 = fetcherData.get(fetcherKey); let fetcherWithComponents = React10.useMemo( () => ({ Form: FetcherForm, submit, load, ...fetcher, data: data2 }), [FetcherForm, submit, load, fetcher, data2] ); return fetcherWithComponents; } function useFetchers() { let state = useDataRouterState2( "useFetchers" /* UseFetchers */ ); return Array.from(state.fetchers.entries()).map(([key, fetcher]) => ({ ...fetcher, key })); } var SCROLL_RESTORATION_STORAGE_KEY = "react-router-scroll-positions"; var savedScrollPositions = {}; function getScrollRestorationKey(location, matches, basename, getKey) { let key = null; if (getKey) { if (basename !== "/") { key = getKey( { ...location, pathname: stripBasename(location.pathname, basename) || location.pathname }, matches ); } else { key = getKey(location, matches); } } if (key == null) { key = location.key; } return key; } function useScrollRestoration({ getKey, storageKey } = {}) { let { router: router2 } = useDataRouterContext3( "useScrollRestoration" /* UseScrollRestoration */ ); let { restoreScrollPosition, preventScrollReset } = useDataRouterState2( "useScrollRestoration" /* UseScrollRestoration */ ); let { basename } = React10.useContext(NavigationContext); let location = useLocation(); let matches = useMatches(); let navigation = useNavigation(); React10.useEffect(() => { window.history.scrollRestoration = "manual"; return () => { window.history.scrollRestoration = "auto"; }; }, []); usePageHide( React10.useCallback(() => { if (navigation.state === "idle") { let key = getScrollRestorationKey(location, matches, basename, getKey); savedScrollPositions[key] = window.scrollY; } try { sessionStorage.setItem( storageKey || SCROLL_RESTORATION_STORAGE_KEY, JSON.stringify(savedScrollPositions) ); } catch (error) { warning( false, `Failed to save scroll positions in sessionStorage, will not work properly (${error}).` ); } window.history.scrollRestoration = "auto"; }, [navigation.state, getKey, basename, location, matches, storageKey]) ); if (typeof document !== "undefined") { React10.useLayoutEffect(() => { try { let sessionPositions = sessionStorage.getItem( storageKey || SCROLL_RESTORATION_STORAGE_KEY ); if (sessionPositions) { savedScrollPositions = JSON.parse(sessionPositions); } } catch (e) { } }, [storageKey]); React10.useLayoutEffect(() => { let disableScrollRestoration = router2?.enableScrollRestoration( savedScrollPositions, () => window.scrollY, getKey ? (location2, matches2) => getScrollRestorationKey(location2, matches2, basename, getKey) : void 0 ); return () => disableScrollRestoration && disableScrollRestoration(); }, [router2, basename, getKey]); React10.useLayoutEffect(() => { if (restoreScrollPosition === false) { return; } if (typeof restoreScrollPosition === "number") { window.scrollTo(0, restoreScrollPosition); return; } if (location.hash) { let el = document.getElementById( decodeURIComponent(location.hash.slice(1)) ); if (el) { el.scrollIntoView(); return; } } if (preventScrollReset === true) { return; } window.scrollTo(0, 0); }, [location, restoreScrollPosition, preventScrollReset]); } } function useBeforeUnload(callback, options) { let { capture } = options || {}; React10.useEffect(() => { let opts = capture != null ? { capture } : void 0; window.addEventListener("beforeunload", callback, opts); return () => { window.removeEventListener("beforeunload", callback, opts); }; }, [callback, capture]); } function usePageHide(callback, options) { let { capture } = options || {}; React10.useEffect(() => { let opts = capture != null ? { capture } : void 0; window.addEventListener("pagehide", callback, opts); return () => { window.removeEventListener("pagehide", callback, opts); }; }, [callback, capture]); } function usePrompt({ when, message }) { let blocker = useBlocker(when); React10.useEffect(() => { if (blocker.state === "blocked") { let proceed = window.confirm(message); if (proceed) { setTimeout(blocker.proceed, 0); } else { blocker.reset(); } } }, [blocker, message]); React10.useEffect(() => { if (blocker.state === "blocked" && !when) { blocker.reset(); } }, [blocker, when]); } function useViewTransitionState(to, opts = {}) { let vtContext = React10.useContext(ViewTransitionContext); invariant( vtContext != null, "`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?" ); let { basename } = useDataRouterContext3( "useViewTransitionState" /* useViewTransitionState */ ); let path = useResolvedPath(to, { relative: opts.relative }); if (!vtContext.isTransitioning) { return false; } let currentPath = stripBasename(vtContext.currentLocation.pathname, basename) || vtContext.currentLocation.pathname; let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname; return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null; } function StaticRouter({ basename, children, location: locationProp = "/" }) { if (typeof locationProp === "string") { locationProp = parsePath(locationProp); } let action = "POP"; let location = { pathname: locationProp.pathname || "/", search: locationProp.search || "", hash: locationProp.hash || "", state: locationProp.state != null ? locationProp.state : null, key: locationProp.key || "default" }; let staticNavigator = getStatelessNavigator(); return React11.createElement( Router, { basename, children, location, navigationType: action, navigator: staticNavigator, static: true } ); } function StaticRouterProvider({ context, router: router2, hydrate: hydrate2 = true, nonce }) { invariant( router2 && context, "You must provide `router` and `context` to " ); let dataRouterContext = { router: router2, navigator: getStatelessNavigator(), static: true, staticContext: context, basename: context.basename || "/" }; let fetchersContext = /* @__PURE__ */ new Map(); let hydrateScript = ""; if (hydrate2 !== false) { let data2 = { loaderData: context.loaderData, actionData: context.actionData, errors: serializeErrors(context.errors) }; let json = htmlEscape(JSON.stringify(JSON.stringify(data2))); hydrateScript = `window.__staticRouterHydrationData = JSON.parse(${json});`; } let { state } = dataRouterContext.router; return React11.createElement(React11.Fragment, null, React11.createElement(DataRouterContext.Provider, { value: dataRouterContext }, React11.createElement(DataRouterStateContext.Provider, { value: state }, React11.createElement(FetchersContext.Provider, { value: fetchersContext }, React11.createElement(ViewTransitionContext.Provider, { value: { isTransitioning: false } }, React11.createElement( Router, { basename: dataRouterContext.basename, location: state.location, navigationType: state.historyAction, navigator: dataRouterContext.navigator, static: dataRouterContext.static }, React11.createElement( DataRoutes2, { routes: router2.routes, future: router2.future, state } ) ))))), hydrateScript ? React11.createElement( "script", { suppressHydrationWarning: true, nonce, dangerouslySetInnerHTML: { __html: hydrateScript } } ) : null); } function DataRoutes2({ routes, future, state }) { return useRoutesImpl(routes, void 0, state, future); } function serializeErrors(errors) { if (!errors) return null; let entries = Object.entries(errors); let serialized = {}; for (let [key, val] of entries) { if (isRouteErrorResponse(val)) { serialized[key] = { ...val, __type: "RouteErrorResponse" }; } else if (val instanceof Error) { serialized[key] = { message: val.message, __type: "Error", // If this is a subclass (i.e., ReferenceError), send up the type so we // can re-create the same type during hydration. ...val.name !== "Error" ? { __subType: val.name } : {} }; } else { serialized[key] = val; } } return serialized; } function getStatelessNavigator() { return { createHref, encodeLocation, push(to) { throw new Error( `You cannot use navigator.push() on the server because it is a stateless environment. This error was probably triggered when you did a \`navigate(${JSON.stringify(to)})\` somewhere in your app.` ); }, replace(to) { throw new Error( `You cannot use navigator.replace() on the server because it is a stateless environment. This error was probably triggered when you did a \`navigate(${JSON.stringify(to)}, { replace: true })\` somewhere in your app.` ); }, go(delta) { throw new Error( `You cannot use navigator.go() on the server because it is a stateless environment. This error was probably triggered when you did a \`navigate(${delta})\` somewhere in your app.` ); }, back() { throw new Error( `You cannot use navigator.back() on the server because it is a stateless environment.` ); }, forward() { throw new Error( `You cannot use navigator.forward() on the server because it is a stateless environment.` ); } }; } function createStaticHandler2(routes, opts) { return createStaticHandler(routes, { ...opts, mapRouteProperties }); } function createStaticRouter(routes, context, opts = {}) { let manifest = {}; let dataRoutes = convertRoutesToDataRoutes( routes, mapRouteProperties, void 0, manifest ); let matches = context.matches.map((match) => { let route = manifest[match.route.id] || match.route; return { ...match, route }; }); let msg = (method) => `You cannot use router.${method}() on the server because it is a stateless environment`; return { get basename() { return context.basename; }, get future() { return { unstable_middleware: false, ...opts?.future }; }, get state() { return { historyAction: "POP", location: context.location, matches, loaderData: context.loaderData, actionData: context.actionData, errors: context.errors, initialized: true, navigation: IDLE_NAVIGATION, restoreScrollPosition: null, preventScrollReset: false, revalidation: "idle", fetchers: /* @__PURE__ */ new Map(), blockers: /* @__PURE__ */ new Map() }; }, get routes() { return dataRoutes; }, get window() { return void 0; }, initialize() { throw msg("initialize"); }, subscribe() { throw msg("subscribe"); }, enableScrollRestoration() { throw msg("enableScrollRestoration"); }, navigate() { throw msg("navigate"); }, fetch() { throw msg("fetch"); }, revalidate() { throw msg("revalidate"); }, createHref, encodeLocation, getFetcher() { return IDLE_FETCHER; }, deleteFetcher() { throw msg("deleteFetcher"); }, dispose() { throw msg("dispose"); }, getBlocker() { return IDLE_BLOCKER; }, deleteBlocker() { throw msg("deleteBlocker"); }, patchRoutes() { throw msg("patchRoutes"); }, _internalFetchControllers: /* @__PURE__ */ new Map(), _internalSetRoutes() { throw msg("_internalSetRoutes"); } }; } function createHref(to) { return typeof to === "string" ? to : createPath(to); } function encodeLocation(to) { let href2 = typeof to === "string" ? to : createPath(to); href2 = href2.replace(/ $/, "%20"); let encoded = ABSOLUTE_URL_REGEX3.test(href2) ? new URL(href2) : new URL(href2, "http://localhost"); return { pathname: encoded.pathname, search: encoded.search, hash: encoded.hash }; } var ABSOLUTE_URL_REGEX3 = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; var ESCAPE_LOOKUP2 = { "&": "\\u0026", ">": "\\u003e", "<": "\\u003c", "\u2028": "\\u2028", "\u2029": "\\u2029" }; var ESCAPE_REGEX2 = /[&><\u2028\u2029]/g; function htmlEscape(str) { return str.replace(ESCAPE_REGEX2, (match) => ESCAPE_LOOKUP2[match]); } function ServerRouter({ context, url, nonce }) { if (typeof url === "string") { url = new URL(url); } let { manifest, routeModules, criticalCss, serverHandoffString } = context; let routes = createServerRoutes( manifest.routes, routeModules, context.future, context.isSpaMode ); context.staticHandlerContext.loaderData = { ...context.staticHandlerContext.loaderData }; for (let match of context.staticHandlerContext.matches) { let routeId = match.route.id; let route = routeModules[routeId]; let manifestRoute = context.manifest.routes[routeId]; if (route && manifestRoute && shouldHydrateRouteLoader(manifestRoute, route, context.isSpaMode) && (route.HydrateFallback || !manifestRoute.hasLoader)) { delete context.staticHandlerContext.loaderData[routeId]; } } let router2 = createStaticRouter(routes, context.staticHandlerContext); return React12.createElement(React12.Fragment, null, React12.createElement( FrameworkContext.Provider, { value: { manifest, routeModules, criticalCss, serverHandoffString, future: context.future, ssr: context.ssr, isSpaMode: context.isSpaMode, serializeError: context.serializeError, renderMeta: context.renderMeta } }, React12.createElement(RemixErrorBoundary, { location: router2.state.location }, React12.createElement( StaticRouterProvider, { router: router2, context: context.staticHandlerContext, hydrate: false } )) ), context.serverHandoffStream ? React12.createElement(React12.Suspense, null, React12.createElement( StreamTransfer, { context, identifier: 0, reader: context.serverHandoffStream.getReader(), textDecoder: new TextDecoder(), nonce } )) : null); } function createRoutesStub(routes, unstable_getContext) { return function RoutesTestStub({ initialEntries, initialIndex, hydrationData, future }) { let routerRef = React13.useRef(); let remixContextRef = React13.useRef(); if (routerRef.current == null) { remixContextRef.current = { future: { unstable_middleware: future?.unstable_middleware === true }, manifest: { routes: {}, entry: { imports: [], module: "" }, url: "", version: "" }, routeModules: {}, ssr: false, isSpaMode: false }; let patched = processRoutes( // @ts-expect-error `StubRouteObject` is stricter about `loader`/`action` // types compared to `AgnosticRouteObject` convertRoutesToDataRoutes(routes, (r) => r), remixContextRef.current.manifest, remixContextRef.current.routeModules ); routerRef.current = createMemoryRouter(patched, { unstable_getContext, initialEntries, initialIndex, hydrationData }); } return React13.createElement(FrameworkContext.Provider, { value: remixContextRef.current }, React13.createElement(RouterProvider, { router: routerRef.current })); }; } function processRoutes(routes, manifest, routeModules, parentId) { return routes.map((route) => { if (!route.id) { throw new Error( "Expected a route.id in @remix-run/testing processRoutes() function" ); } let newRoute = { id: route.id, path: route.path, index: route.index, Component: route.Component, HydrateFallback: route.HydrateFallback, ErrorBoundary: route.ErrorBoundary, action: route.action, loader: route.loader, handle: route.handle, shouldRevalidate: route.shouldRevalidate }; let entryRoute = { id: route.id, path: route.path, index: route.index, parentId, hasAction: route.action != null, hasLoader: route.loader != null, // When testing routes, you should just be stubbing loader/action, not // trying to re-implement the full loader/clientLoader/SSR/hydration flow. // That is better tested via E2E tests. hasClientAction: false, hasClientLoader: false, hasErrorBoundary: route.ErrorBoundary != null, // any need for these? module: "build/stub-path-to-module.js", clientActionModule: void 0, clientLoaderModule: void 0, hydrateFallbackModule: void 0 }; manifest.routes[newRoute.id] = entryRoute; routeModules[route.id] = { default: route.Component || Outlet, ErrorBoundary: route.ErrorBoundary || void 0, handle: route.handle, links: route.links, meta: route.meta, shouldRevalidate: route.shouldRevalidate }; if (route.children) { newRoute.children = processRoutes( route.children, manifest, routeModules, newRoute.id ); } return newRoute; }); } var encoder = new TextEncoder(); var sign = async (value, secret) => { let data2 = encoder.encode(value); let key = await createKey2(secret, ["sign"]); let signature = await crypto.subtle.sign("HMAC", key, data2); let hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace( /=+$/, "" ); return value + "." + hash; }; var unsign = async (cookie, secret) => { let index = cookie.lastIndexOf("."); let value = cookie.slice(0, index); let hash = cookie.slice(index + 1); let data2 = encoder.encode(value); let key = await createKey2(secret, ["verify"]); let signature = byteStringToUint8Array(atob(hash)); let valid = await crypto.subtle.verify("HMAC", key, signature, data2); return valid ? value : false; }; var createKey2 = async (secret, usages) => crypto.subtle.importKey( "raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, usages ); function byteStringToUint8Array(byteString) { let array = new Uint8Array(byteString.length); for (let i = 0; i < byteString.length; i++) { array[i] = byteString.charCodeAt(i); } return array; } var createCookie = (name, cookieOptions = {}) => { let { secrets = [], ...options } = { path: "/", sameSite: "lax", ...cookieOptions }; warnOnceAboutExpiresCookie(name, options.expires); return { get name() { return name; }, get isSigned() { return secrets.length > 0; }, get expires() { return typeof options.maxAge !== "undefined" ? new Date(Date.now() + options.maxAge * 1e3) : options.expires; }, async parse(cookieHeader, parseOptions) { if (!cookieHeader) return null; let cookies = (0, import_cookie.parse)(cookieHeader, { ...options, ...parseOptions }); if (name in cookies) { let value = cookies[name]; if (typeof value === "string" && value !== "") { let decoded = await decodeCookieValue(value, secrets); return decoded; } else { return ""; } } else { return null; } }, async serialize(value, serializeOptions) { return (0, import_cookie.serialize)( name, value === "" ? "" : await encodeCookieValue(value, secrets), { ...options, ...serializeOptions } ); } }; }; var isCookie = (object) => { return object != null && typeof object.name === "string" && typeof object.isSigned === "boolean" && typeof object.parse === "function" && typeof object.serialize === "function"; }; async function encodeCookieValue(value, secrets) { let encoded = encodeData(value); if (secrets.length > 0) { encoded = await sign(encoded, secrets[0]); } return encoded; } async function decodeCookieValue(value, secrets) { if (secrets.length > 0) { for (let secret of secrets) { let unsignedValue = await unsign(value, secret); if (unsignedValue !== false) { return decodeData(unsignedValue); } } return null; } return decodeData(value); } function encodeData(value) { return btoa(myUnescape(encodeURIComponent(JSON.stringify(value)))); } function decodeData(value) { try { return JSON.parse(decodeURIComponent(myEscape(atob(value)))); } catch (error) { return {}; } } function myEscape(value) { let str = value.toString(); let result = ""; let index = 0; let chr, code; while (index < str.length) { chr = str.charAt(index++); if (/[\w*+\-./@]/.exec(chr)) { result += chr; } else { code = chr.charCodeAt(0); if (code < 256) { result += "%" + hex(code, 2); } else { result += "%u" + hex(code, 4).toUpperCase(); } } } return result; } function hex(code, length) { let result = code.toString(16); while (result.length < length) result = "0" + result; return result; } function myUnescape(value) { let str = value.toString(); let result = ""; let index = 0; let chr, part; while (index < str.length) { chr = str.charAt(index++); if (chr === "%") { if (str.charAt(index) === "u") { part = str.slice(index + 1, index + 5); if (/^[\da-f]{4}$/i.exec(part)) { result += String.fromCharCode(parseInt(part, 16)); index += 5; continue; } } else { part = str.slice(index, index + 2); if (/^[\da-f]{2}$/i.exec(part)) { result += String.fromCharCode(parseInt(part, 16)); index += 2; continue; } } } result += chr; } return result; } function warnOnceAboutExpiresCookie(name, expires) { warnOnce( !expires, `The "${name}" cookie has an "expires" property set. This will cause the expires value to not be updated when the session is committed. Instead, you should set the expires value when serializing the cookie. You can use \`commitSession(session, { expires })\` if using a session storage object, or \`cookie.serialize("value", { expires })\` if you're using the cookie directly.` ); } function createEntryRouteModules(manifest) { return Object.keys(manifest).reduce((memo2, routeId) => { let route = manifest[routeId]; if (route) { memo2[routeId] = route.module; } return memo2; }, {}); } var ServerMode = ((ServerMode2) => { ServerMode2["Development"] = "development"; ServerMode2["Production"] = "production"; ServerMode2["Test"] = "test"; return ServerMode2; })(ServerMode || {}); function isServerMode(value) { return value === "development" || value === "production" || value === "test"; } function sanitizeError(error, serverMode) { if (error instanceof Error && serverMode !== "development") { let sanitized = new Error("Unexpected Server Error"); sanitized.stack = void 0; return sanitized; } return error; } function sanitizeErrors(errors, serverMode) { return Object.entries(errors).reduce((acc, [routeId, error]) => { return Object.assign(acc, { [routeId]: sanitizeError(error, serverMode) }); }, {}); } function serializeError(error, serverMode) { let sanitized = sanitizeError(error, serverMode); return { message: sanitized.message, stack: sanitized.stack }; } function serializeErrors2(errors, serverMode) { if (!errors) return null; let entries = Object.entries(errors); let serialized = {}; for (let [key, val] of entries) { if (isRouteErrorResponse(val)) { serialized[key] = { ...val, __type: "RouteErrorResponse" }; } else if (val instanceof Error) { let sanitized = sanitizeError(val, serverMode); serialized[key] = { message: sanitized.message, stack: sanitized.stack, __type: "Error", // If this is a subclass (i.e., ReferenceError), send up the type so we // can re-create the same type during hydration. This will only apply // in dev mode since all production errors are sanitized to normal // Error instances ...sanitized.name !== "Error" ? { __subType: sanitized.name } : {} }; } else { serialized[key] = val; } } return serialized; } function matchServerRoutes(routes, pathname, basename) { let matches = matchRoutes( routes, pathname, basename ); if (!matches) return null; return matches.map((match) => ({ params: match.params, pathname: match.pathname, route: match.route })); } async function callRouteHandler(handler, args) { let result = await handler({ request: stripRoutesParam(stripIndexParam2(args.request)), params: args.params, context: args.context }); if (isDataWithResponseInit(result) && result.init && result.init.status && isRedirectStatusCode(result.init.status)) { throw new Response(null, result.init); } return result; } function stripIndexParam2(request) { let url = new URL(request.url); let indexValues = url.searchParams.getAll("index"); url.searchParams.delete("index"); let indexValuesToKeep = []; for (let indexValue of indexValues) { if (indexValue) { indexValuesToKeep.push(indexValue); } } for (let toKeep of indexValuesToKeep) { url.searchParams.append("index", toKeep); } let init = { method: request.method, body: request.body, headers: request.headers, signal: request.signal }; if (init.body) { init.duplex = "half"; } return new Request(url.href, init); } function stripRoutesParam(request) { let url = new URL(request.url); url.searchParams.delete("_routes"); let init = { method: request.method, body: request.body, headers: request.headers, signal: request.signal }; if (init.body) { init.duplex = "half"; } return new Request(url.href, init); } function invariant3(value, message) { if (value === false || value === null || typeof value === "undefined") { console.error( "The following error is a bug in React Router; please open an issue! https://github.com/remix-run/react-router/issues/new/choose" ); throw new Error(message); } } function groupRoutesByParentId2(manifest) { let routes = {}; Object.values(manifest).forEach((route) => { if (route) { let parentId = route.parentId || ""; if (!routes[parentId]) { routes[parentId] = []; } routes[parentId].push(route); } }); return routes; } function createRoutes(manifest, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) { return (routesByParentId[parentId] || []).map((route) => ({ ...route, children: createRoutes(manifest, route.id, routesByParentId) })); } function createStaticHandlerDataRoutes(manifest, future, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) { return (routesByParentId[parentId] || []).map((route) => { let commonRoute = { // Always include root due to default boundaries hasErrorBoundary: route.id === "root" || route.module.ErrorBoundary != null, id: route.id, path: route.path, unstable_middleware: route.module.unstable_middleware, // Need to use RR's version in the param typed here to permit the optional // context even though we know it'll always be provided in remix loader: route.module.loader ? async (args) => { if (args.request.headers.has("X-React-Router-Prerender-Data")) { const preRenderedData = args.request.headers.get( "X-React-Router-Prerender-Data" ); let encoded = preRenderedData ? decodeURI(preRenderedData) : preRenderedData; invariant3(encoded, "Missing prerendered data for route"); let uint8array = new TextEncoder().encode(encoded); let stream = new ReadableStream({ start(controller) { controller.enqueue(uint8array); controller.close(); } }); let decoded = await decodeViaTurboStream(stream, global); let data2 = decoded.value; invariant3( data2 && route.id in data2, "Unable to decode prerendered data" ); let result = data2[route.id]; invariant3("data" in result, "Unable to process prerendered data"); return result.data; } let val = await callRouteHandler(route.module.loader, args); return val; } : void 0, action: route.module.action ? (args) => callRouteHandler(route.module.action, args) : void 0, handle: route.module.handle }; return route.index ? { index: true, ...commonRoute } : { caseSensitive: route.caseSensitive, children: createStaticHandlerDataRoutes( manifest, future, route.id, routesByParentId ), ...commonRoute }; }); } var ESCAPE_LOOKUP3 = { "&": "\\u0026", ">": "\\u003e", "<": "\\u003c", "\u2028": "\\u2028", "\u2029": "\\u2029" }; var ESCAPE_REGE