UNPKG

328 kBJavaScriptView Raw
1"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
2 * react-router v7.13.1
3 *
4 * Copyright (c) Remix Software Inc.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE.md file in the root directory of this source tree.
8 *
9 * @license MIT
10 */
11var __typeError = (msg) => {
12 throw TypeError(msg);
13};
14var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
15var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
16var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
17
18// lib/router/history.ts
19var Action = /* @__PURE__ */ ((Action2) => {
20 Action2["Pop"] = "POP";
21 Action2["Push"] = "PUSH";
22 Action2["Replace"] = "REPLACE";
23 return Action2;
24})(Action || {});
25var PopStateEventType = "popstate";
26function isLocation(obj) {
27 return typeof obj === "object" && obj != null && "pathname" in obj && "search" in obj && "hash" in obj && "state" in obj && "key" in obj;
28}
29function createMemoryHistory(options = {}) {
30 let { initialEntries = ["/"], initialIndex, v5Compat = false } = options;
31 let entries;
32 entries = initialEntries.map(
33 (entry, index2) => createMemoryLocation(
34 entry,
35 typeof entry === "string" ? null : entry.state,
36 index2 === 0 ? "default" : void 0,
37 typeof entry === "string" ? void 0 : entry.unstable_mask
38 )
39 );
40 let index = clampIndex(
41 initialIndex == null ? entries.length - 1 : initialIndex
42 );
43 let action = "POP" /* Pop */;
44 let listener = null;
45 function clampIndex(n) {
46 return Math.min(Math.max(n, 0), entries.length - 1);
47 }
48 function getCurrentLocation() {
49 return entries[index];
50 }
51 function createMemoryLocation(to, state = null, key, unstable_mask) {
52 let location = createLocation(
53 entries ? getCurrentLocation().pathname : "/",
54 to,
55 state,
56 key,
57 unstable_mask
58 );
59 warning(
60 location.pathname.charAt(0) === "/",
61 `relative pathnames are not supported in memory history: ${JSON.stringify(
62 to
63 )}`
64 );
65 return location;
66 }
67 function createHref(to) {
68 return typeof to === "string" ? to : createPath(to);
69 }
70 let history = {
71 get index() {
72 return index;
73 },
74 get action() {
75 return action;
76 },
77 get location() {
78 return getCurrentLocation();
79 },
80 createHref,
81 createURL(to) {
82 return new URL(createHref(to), "http://localhost");
83 },
84 encodeLocation(to) {
85 let path = typeof to === "string" ? parsePath(to) : to;
86 return {
87 pathname: path.pathname || "",
88 search: path.search || "",
89 hash: path.hash || ""
90 };
91 },
92 push(to, state) {
93 action = "PUSH" /* Push */;
94 let nextLocation = isLocation(to) ? to : createMemoryLocation(to, state);
95 index += 1;
96 entries.splice(index, entries.length, nextLocation);
97 if (v5Compat && listener) {
98 listener({ action, location: nextLocation, delta: 1 });
99 }
100 },
101 replace(to, state) {
102 action = "REPLACE" /* Replace */;
103 let nextLocation = isLocation(to) ? to : createMemoryLocation(to, state);
104 entries[index] = nextLocation;
105 if (v5Compat && listener) {
106 listener({ action, location: nextLocation, delta: 0 });
107 }
108 },
109 go(delta) {
110 action = "POP" /* Pop */;
111 let nextIndex = clampIndex(index + delta);
112 let nextLocation = entries[nextIndex];
113 index = nextIndex;
114 if (listener) {
115 listener({ action, location: nextLocation, delta });
116 }
117 },
118 listen(fn) {
119 listener = fn;
120 return () => {
121 listener = null;
122 };
123 }
124 };
125 return history;
126}
127function createBrowserHistory(options = {}) {
128 function createBrowserLocation(window2, globalHistory) {
129 let maskedLocation = _optionalChain([globalHistory, 'access', _2 => _2.state, 'optionalAccess', _3 => _3.masked]);
130 let { pathname, search, hash } = maskedLocation || window2.location;
131 return createLocation(
132 "",
133 { pathname, search, hash },
134 // state defaults to `null` because `window.history.state` does
135 globalHistory.state && globalHistory.state.usr || null,
136 globalHistory.state && globalHistory.state.key || "default",
137 maskedLocation ? {
138 pathname: window2.location.pathname,
139 search: window2.location.search,
140 hash: window2.location.hash
141 } : void 0
142 );
143 }
144 function createBrowserHref(window2, to) {
145 return typeof to === "string" ? to : createPath(to);
146 }
147 return getUrlBasedHistory(
148 createBrowserLocation,
149 createBrowserHref,
150 null,
151 options
152 );
153}
154function createHashHistory(options = {}) {
155 function createHashLocation(window2, globalHistory) {
156 let {
157 pathname = "/",
158 search = "",
159 hash = ""
160 } = parsePath(window2.location.hash.substring(1));
161 if (!pathname.startsWith("/") && !pathname.startsWith(".")) {
162 pathname = "/" + pathname;
163 }
164 return createLocation(
165 "",
166 { pathname, search, hash },
167 // state defaults to `null` because `window.history.state` does
168 globalHistory.state && globalHistory.state.usr || null,
169 globalHistory.state && globalHistory.state.key || "default"
170 );
171 }
172 function createHashHref(window2, to) {
173 let base = window2.document.querySelector("base");
174 let href = "";
175 if (base && base.getAttribute("href")) {
176 let url = window2.location.href;
177 let hashIndex = url.indexOf("#");
178 href = hashIndex === -1 ? url : url.slice(0, hashIndex);
179 }
180 return href + "#" + (typeof to === "string" ? to : createPath(to));
181 }
182 function validateHashLocation(location, to) {
183 warning(
184 location.pathname.charAt(0) === "/",
185 `relative pathnames are not supported in hash history.push(${JSON.stringify(
186 to
187 )})`
188 );
189 }
190 return getUrlBasedHistory(
191 createHashLocation,
192 createHashHref,
193 validateHashLocation,
194 options
195 );
196}
197function invariant(value, message) {
198 if (value === false || value === null || typeof value === "undefined") {
199 throw new Error(message);
200 }
201}
202function warning(cond, message) {
203 if (!cond) {
204 if (typeof console !== "undefined") console.warn(message);
205 try {
206 throw new Error(message);
207 } catch (e) {
208 }
209 }
210}
211function createKey() {
212 return Math.random().toString(36).substring(2, 10);
213}
214function getHistoryState(location, index) {
215 return {
216 usr: location.state,
217 key: location.key,
218 idx: index,
219 masked: location.unstable_mask ? {
220 pathname: location.pathname,
221 search: location.search,
222 hash: location.hash
223 } : void 0
224 };
225}
226function createLocation(current, to, state = null, key, unstable_mask) {
227 let location = {
228 pathname: typeof current === "string" ? current : current.pathname,
229 search: "",
230 hash: "",
231 ...typeof to === "string" ? parsePath(to) : to,
232 state,
233 // TODO: This could be cleaned up. push/replace should probably just take
234 // full Locations now and avoid the need to run through this flow at all
235 // But that's a pretty big refactor to the current test suite so going to
236 // keep as is for the time being and just let any incoming keys take precedence
237 key: to && to.key || key || createKey(),
238 unstable_mask
239 };
240 return location;
241}
242function createPath({
243 pathname = "/",
244 search = "",
245 hash = ""
246}) {
247 if (search && search !== "?")
248 pathname += search.charAt(0) === "?" ? search : "?" + search;
249 if (hash && hash !== "#")
250 pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
251 return pathname;
252}
253function parsePath(path) {
254 let parsedPath = {};
255 if (path) {
256 let hashIndex = path.indexOf("#");
257 if (hashIndex >= 0) {
258 parsedPath.hash = path.substring(hashIndex);
259 path = path.substring(0, hashIndex);
260 }
261 let searchIndex = path.indexOf("?");
262 if (searchIndex >= 0) {
263 parsedPath.search = path.substring(searchIndex);
264 path = path.substring(0, searchIndex);
265 }
266 if (path) {
267 parsedPath.pathname = path;
268 }
269 }
270 return parsedPath;
271}
272function getUrlBasedHistory(getLocation, createHref, validateLocation, options = {}) {
273 let { window: window2 = document.defaultView, v5Compat = false } = options;
274 let globalHistory = window2.history;
275 let action = "POP" /* Pop */;
276 let listener = null;
277 let index = getIndex();
278 if (index == null) {
279 index = 0;
280 globalHistory.replaceState({ ...globalHistory.state, idx: index }, "");
281 }
282 function getIndex() {
283 let state = globalHistory.state || { idx: null };
284 return state.idx;
285 }
286 function handlePop() {
287 action = "POP" /* Pop */;
288 let nextIndex = getIndex();
289 let delta = nextIndex == null ? null : nextIndex - index;
290 index = nextIndex;
291 if (listener) {
292 listener({ action, location: history.location, delta });
293 }
294 }
295 function push(to, state) {
296 action = "PUSH" /* Push */;
297 let location = isLocation(to) ? to : createLocation(history.location, to, state);
298 if (validateLocation) validateLocation(location, to);
299 index = getIndex() + 1;
300 let historyState = getHistoryState(location, index);
301 let url = history.createHref(location.unstable_mask || location);
302 try {
303 globalHistory.pushState(historyState, "", url);
304 } catch (error) {
305 if (error instanceof DOMException && error.name === "DataCloneError") {
306 throw error;
307 }
308 window2.location.assign(url);
309 }
310 if (v5Compat && listener) {
311 listener({ action, location: history.location, delta: 1 });
312 }
313 }
314 function replace2(to, state) {
315 action = "REPLACE" /* Replace */;
316 let location = isLocation(to) ? to : createLocation(history.location, to, state);
317 if (validateLocation) validateLocation(location, to);
318 index = getIndex();
319 let historyState = getHistoryState(location, index);
320 let url = history.createHref(location.unstable_mask || location);
321 globalHistory.replaceState(historyState, "", url);
322 if (v5Compat && listener) {
323 listener({ action, location: history.location, delta: 0 });
324 }
325 }
326 function createURL(to) {
327 return createBrowserURLImpl(to);
328 }
329 let history = {
330 get action() {
331 return action;
332 },
333 get location() {
334 return getLocation(window2, globalHistory);
335 },
336 listen(fn) {
337 if (listener) {
338 throw new Error("A history only accepts one active listener");
339 }
340 window2.addEventListener(PopStateEventType, handlePop);
341 listener = fn;
342 return () => {
343 window2.removeEventListener(PopStateEventType, handlePop);
344 listener = null;
345 };
346 },
347 createHref(to) {
348 return createHref(window2, to);
349 },
350 createURL,
351 encodeLocation(to) {
352 let url = createURL(to);
353 return {
354 pathname: url.pathname,
355 search: url.search,
356 hash: url.hash
357 };
358 },
359 push,
360 replace: replace2,
361 go(n) {
362 return globalHistory.go(n);
363 }
364 };
365 return history;
366}
367function createBrowserURLImpl(to, isAbsolute = false) {
368 let base = "http://localhost";
369 if (typeof window !== "undefined") {
370 base = window.location.origin !== "null" ? window.location.origin : window.location.href;
371 }
372 invariant(base, "No window.location.(origin|href) available to create URL");
373 let href = typeof to === "string" ? to : createPath(to);
374 href = href.replace(/ $/, "%20");
375 if (!isAbsolute && href.startsWith("//")) {
376 href = base + href;
377 }
378 return new URL(href, base);
379}
380
381// lib/router/utils.ts
382function createContext(defaultValue) {
383 return { defaultValue };
384}
385var _map;
386var RouterContextProvider = class {
387 /**
388 * Create a new `RouterContextProvider` instance
389 * @param init An optional initial context map to populate the provider with
390 */
391 constructor(init) {
392 __privateAdd(this, _map, /* @__PURE__ */ new Map());
393 if (init) {
394 for (let [context, value] of init) {
395 this.set(context, value);
396 }
397 }
398 }
399 /**
400 * Access a value from the context. If no value has been set for the context,
401 * it will return the context's `defaultValue` if provided, or throw an error
402 * if no `defaultValue` was set.
403 * @param context The context to get the value for
404 * @returns The value for the context, or the context's `defaultValue` if no
405 * value was set
406 */
407 get(context) {
408 if (__privateGet(this, _map).has(context)) {
409 return __privateGet(this, _map).get(context);
410 }
411 if (context.defaultValue !== void 0) {
412 return context.defaultValue;
413 }
414 throw new Error("No value found for context");
415 }
416 /**
417 * Set a value for the context. If the context already has a value set, this
418 * will overwrite it.
419 *
420 * @param context The context to set the value for
421 * @param value The value to set for the context
422 * @returns {void}
423 */
424 set(context, value) {
425 __privateGet(this, _map).set(context, value);
426 }
427};
428_map = new WeakMap();
429var unsupportedLazyRouteObjectKeys = /* @__PURE__ */ new Set([
430 "lazy",
431 "caseSensitive",
432 "path",
433 "id",
434 "index",
435 "children"
436]);
437function isUnsupportedLazyRouteObjectKey(key) {
438 return unsupportedLazyRouteObjectKeys.has(
439 key
440 );
441}
442var unsupportedLazyRouteFunctionKeys = /* @__PURE__ */ new Set([
443 "lazy",
444 "caseSensitive",
445 "path",
446 "id",
447 "index",
448 "middleware",
449 "children"
450]);
451function isUnsupportedLazyRouteFunctionKey(key) {
452 return unsupportedLazyRouteFunctionKeys.has(
453 key
454 );
455}
456function isIndexRoute(route) {
457 return route.index === true;
458}
459function convertRoutesToDataRoutes(routes, mapRouteProperties2, parentPath = [], manifest = {}, allowInPlaceMutations = false) {
460 return routes.map((route, index) => {
461 let treePath = [...parentPath, String(index)];
462 let id = typeof route.id === "string" ? route.id : treePath.join("-");
463 invariant(
464 route.index !== true || !route.children,
465 `Cannot specify children on an index route`
466 );
467 invariant(
468 allowInPlaceMutations || !manifest[id],
469 `Found a route id collision on id "${id}". Route id's must be globally unique within Data Router usages`
470 );
471 if (isIndexRoute(route)) {
472 let indexRoute = {
473 ...route,
474 id
475 };
476 manifest[id] = mergeRouteUpdates(
477 indexRoute,
478 mapRouteProperties2(indexRoute)
479 );
480 return indexRoute;
481 } else {
482 let pathOrLayoutRoute = {
483 ...route,
484 id,
485 children: void 0
486 };
487 manifest[id] = mergeRouteUpdates(
488 pathOrLayoutRoute,
489 mapRouteProperties2(pathOrLayoutRoute)
490 );
491 if (route.children) {
492 pathOrLayoutRoute.children = convertRoutesToDataRoutes(
493 route.children,
494 mapRouteProperties2,
495 treePath,
496 manifest,
497 allowInPlaceMutations
498 );
499 }
500 return pathOrLayoutRoute;
501 }
502 });
503}
504function mergeRouteUpdates(route, updates) {
505 return Object.assign(route, {
506 ...updates,
507 ...typeof updates.lazy === "object" && updates.lazy != null ? {
508 lazy: {
509 ...route.lazy,
510 ...updates.lazy
511 }
512 } : {}
513 });
514}
515function matchRoutes(routes, locationArg, basename = "/") {
516 return matchRoutesImpl(routes, locationArg, basename, false);
517}
518function matchRoutesImpl(routes, locationArg, basename, allowPartial) {
519 let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
520 let pathname = stripBasename(location.pathname || "/", basename);
521 if (pathname == null) {
522 return null;
523 }
524 let branches = flattenRoutes(routes);
525 rankRouteBranches(branches);
526 let matches = null;
527 for (let i = 0; matches == null && i < branches.length; ++i) {
528 let decoded = decodePath(pathname);
529 matches = matchRouteBranch(
530 branches[i],
531 decoded,
532 allowPartial
533 );
534 }
535 return matches;
536}
537function convertRouteMatchToUiMatch(match, loaderData) {
538 let { route, pathname, params } = match;
539 return {
540 id: route.id,
541 pathname,
542 params,
543 data: loaderData[route.id],
544 loaderData: loaderData[route.id],
545 handle: route.handle
546 };
547}
548function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "", _hasParentOptionalSegments = false) {
549 let flattenRoute = (route, index, hasParentOptionalSegments = _hasParentOptionalSegments, relativePath) => {
550 let meta = {
551 relativePath: relativePath === void 0 ? route.path || "" : relativePath,
552 caseSensitive: route.caseSensitive === true,
553 childrenIndex: index,
554 route
555 };
556 if (meta.relativePath.startsWith("/")) {
557 if (!meta.relativePath.startsWith(parentPath) && hasParentOptionalSegments) {
558 return;
559 }
560 invariant(
561 meta.relativePath.startsWith(parentPath),
562 `Absolute route path "${meta.relativePath}" nested under path "${parentPath}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`
563 );
564 meta.relativePath = meta.relativePath.slice(parentPath.length);
565 }
566 let path = joinPaths([parentPath, meta.relativePath]);
567 let routesMeta = parentsMeta.concat(meta);
568 if (route.children && route.children.length > 0) {
569 invariant(
570 // Our types know better, but runtime JS may not!
571 // @ts-expect-error
572 route.index !== true,
573 `Index routes must not have child routes. Please remove all child routes from route path "${path}".`
574 );
575 flattenRoutes(
576 route.children,
577 branches,
578 routesMeta,
579 path,
580 hasParentOptionalSegments
581 );
582 }
583 if (route.path == null && !route.index) {
584 return;
585 }
586 branches.push({
587 path,
588 score: computeScore(path, route.index),
589 routesMeta
590 });
591 };
592 routes.forEach((route, index) => {
593 if (route.path === "" || !_optionalChain([route, 'access', _4 => _4.path, 'optionalAccess', _5 => _5.includes, 'call', _6 => _6("?")])) {
594 flattenRoute(route, index);
595 } else {
596 for (let exploded of explodeOptionalSegments(route.path)) {
597 flattenRoute(route, index, true, exploded);
598 }
599 }
600 });
601 return branches;
602}
603function explodeOptionalSegments(path) {
604 let segments = path.split("/");
605 if (segments.length === 0) return [];
606 let [first, ...rest] = segments;
607 let isOptional = first.endsWith("?");
608 let required = first.replace(/\?$/, "");
609 if (rest.length === 0) {
610 return isOptional ? [required, ""] : [required];
611 }
612 let restExploded = explodeOptionalSegments(rest.join("/"));
613 let result = [];
614 result.push(
615 ...restExploded.map(
616 (subpath) => subpath === "" ? required : [required, subpath].join("/")
617 )
618 );
619 if (isOptional) {
620 result.push(...restExploded);
621 }
622 return result.map(
623 (exploded) => path.startsWith("/") && exploded === "" ? "/" : exploded
624 );
625}
626function rankRouteBranches(branches) {
627 branches.sort(
628 (a, b) => a.score !== b.score ? b.score - a.score : compareIndexes(
629 a.routesMeta.map((meta) => meta.childrenIndex),
630 b.routesMeta.map((meta) => meta.childrenIndex)
631 )
632 );
633}
634var paramRe = /^:[\w-]+$/;
635var dynamicSegmentValue = 3;
636var indexRouteValue = 2;
637var emptySegmentValue = 1;
638var staticSegmentValue = 10;
639var splatPenalty = -2;
640var isSplat = (s) => s === "*";
641function computeScore(path, index) {
642 let segments = path.split("/");
643 let initialScore = segments.length;
644 if (segments.some(isSplat)) {
645 initialScore += splatPenalty;
646 }
647 if (index) {
648 initialScore += indexRouteValue;
649 }
650 return segments.filter((s) => !isSplat(s)).reduce(
651 (score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue),
652 initialScore
653 );
654}
655function compareIndexes(a, b) {
656 let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);
657 return siblings ? (
658 // If two routes are siblings, we should try to match the earlier sibling
659 // first. This allows people to have fine-grained control over the matching
660 // behavior by simply putting routes with identical paths in the order they
661 // want them tried.
662 a[a.length - 1] - b[b.length - 1]
663 ) : (
664 // Otherwise, it doesn't really make sense to rank non-siblings by index,
665 // so they sort equally.
666 0
667 );
668}
669function matchRouteBranch(branch, pathname, allowPartial = false) {
670 let { routesMeta } = branch;
671 let matchedParams = {};
672 let matchedPathname = "/";
673 let matches = [];
674 for (let i = 0; i < routesMeta.length; ++i) {
675 let meta = routesMeta[i];
676 let end = i === routesMeta.length - 1;
677 let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
678 let match = matchPath(
679 { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },
680 remainingPathname
681 );
682 let route = meta.route;
683 if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) {
684 match = matchPath(
685 {
686 path: meta.relativePath,
687 caseSensitive: meta.caseSensitive,
688 end: false
689 },
690 remainingPathname
691 );
692 }
693 if (!match) {
694 return null;
695 }
696 Object.assign(matchedParams, match.params);
697 matches.push({
698 // TODO: Can this as be avoided?
699 params: matchedParams,
700 pathname: joinPaths([matchedPathname, match.pathname]),
701 pathnameBase: normalizePathname(
702 joinPaths([matchedPathname, match.pathnameBase])
703 ),
704 route
705 });
706 if (match.pathnameBase !== "/") {
707 matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
708 }
709 }
710 return matches;
711}
712function generatePath(originalPath, params = {}) {
713 let path = originalPath;
714 if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) {
715 warning(
716 false,
717 `Route path "${path}" will be treated as if it were "${path.replace(/\*$/, "/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${path.replace(/\*$/, "/*")}".`
718 );
719 path = path.replace(/\*$/, "/*");
720 }
721 const prefix = path.startsWith("/") ? "/" : "";
722 const stringify2 = (p) => p == null ? "" : typeof p === "string" ? p : String(p);
723 const segments = path.split(/\/+/).map((segment, index, array) => {
724 const isLastSegment = index === array.length - 1;
725 if (isLastSegment && segment === "*") {
726 const star = "*";
727 return stringify2(params[star]);
728 }
729 const keyMatch = segment.match(/^:([\w-]+)(\??)(.*)/);
730 if (keyMatch) {
731 const [, key, optional, suffix] = keyMatch;
732 let param = params[key];
733 invariant(optional === "?" || param != null, `Missing ":${key}" param`);
734 return encodeURIComponent(stringify2(param)) + suffix;
735 }
736 return segment.replace(/\?$/g, "");
737 }).filter((segment) => !!segment);
738 return prefix + segments.join("/");
739}
740function matchPath(pattern, pathname) {
741 if (typeof pattern === "string") {
742 pattern = { path: pattern, caseSensitive: false, end: true };
743 }
744 let [matcher, compiledParams] = compilePath(
745 pattern.path,
746 pattern.caseSensitive,
747 pattern.end
748 );
749 let match = pathname.match(matcher);
750 if (!match) return null;
751 let matchedPathname = match[0];
752 let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
753 let captureGroups = match.slice(1);
754 let params = compiledParams.reduce(
755 (memo2, { paramName, isOptional }, index) => {
756 if (paramName === "*") {
757 let splatValue = captureGroups[index] || "";
758 pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
759 }
760 const value = captureGroups[index];
761 if (isOptional && !value) {
762 memo2[paramName] = void 0;
763 } else {
764 memo2[paramName] = (value || "").replace(/%2F/g, "/");
765 }
766 return memo2;
767 },
768 {}
769 );
770 return {
771 params,
772 pathname: matchedPathname,
773 pathnameBase,
774 pattern
775 };
776}
777function compilePath(path, caseSensitive = false, end = true) {
778 warning(
779 path === "*" || !path.endsWith("*") || path.endsWith("/*"),
780 `Route path "${path}" will be treated as if it were "${path.replace(/\*$/, "/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${path.replace(/\*$/, "/*")}".`
781 );
782 let params = [];
783 let regexpSource = "^" + path.replace(/\/*\*?$/, "").replace(/^\/*/, "/").replace(/[\\.*+^${}|()[\]]/g, "\\$&").replace(
784 /\/:([\w-]+)(\?)?/g,
785 (match, paramName, isOptional, index, str) => {
786 params.push({ paramName, isOptional: isOptional != null });
787 if (isOptional) {
788 let nextChar = str.charAt(index + match.length);
789 if (nextChar && nextChar !== "/") {
790 return "/([^\\/]*)";
791 }
792 return "(?:/([^\\/]*))?";
793 }
794 return "/([^\\/]+)";
795 }
796 ).replace(/\/([\w-]+)\?(\/|$)/g, "(/$1)?$2");
797 if (path.endsWith("*")) {
798 params.push({ paramName: "*" });
799 regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
800 } else if (end) {
801 regexpSource += "\\/*$";
802 } else if (path !== "" && path !== "/") {
803 regexpSource += "(?:(?=\\/|$))";
804 } else {
805 }
806 let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i");
807 return [matcher, params];
808}
809function decodePath(value) {
810 try {
811 return value.split("/").map((v) => decodeURIComponent(v).replace(/\//g, "%2F")).join("/");
812 } catch (error) {
813 warning(
814 false,
815 `The URL path "${value}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${error}).`
816 );
817 return value;
818 }
819}
820function stripBasename(pathname, basename) {
821 if (basename === "/") return pathname;
822 if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
823 return null;
824 }
825 let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length;
826 let nextChar = pathname.charAt(startIndex);
827 if (nextChar && nextChar !== "/") {
828 return null;
829 }
830 return pathname.slice(startIndex) || "/";
831}
832function prependBasename({
833 basename,
834 pathname
835}) {
836 return pathname === "/" ? basename : joinPaths([basename, pathname]);
837}
838var ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
839var isAbsoluteUrl = (url) => ABSOLUTE_URL_REGEX.test(url);
840function resolvePath(to, fromPathname = "/") {
841 let {
842 pathname: toPathname,
843 search = "",
844 hash = ""
845 } = typeof to === "string" ? parsePath(to) : to;
846 let pathname;
847 if (toPathname) {
848 toPathname = toPathname.replace(/\/\/+/g, "/");
849 if (toPathname.startsWith("/")) {
850 pathname = resolvePathname(toPathname.substring(1), "/");
851 } else {
852 pathname = resolvePathname(toPathname, fromPathname);
853 }
854 } else {
855 pathname = fromPathname;
856 }
857 return {
858 pathname,
859 search: normalizeSearch(search),
860 hash: normalizeHash(hash)
861 };
862}
863function resolvePathname(relativePath, fromPathname) {
864 let segments = fromPathname.replace(/\/+$/, "").split("/");
865 let relativeSegments = relativePath.split("/");
866 relativeSegments.forEach((segment) => {
867 if (segment === "..") {
868 if (segments.length > 1) segments.pop();
869 } else if (segment !== ".") {
870 segments.push(segment);
871 }
872 });
873 return segments.length > 1 ? segments.join("/") : "/";
874}
875function getInvalidPathError(char, field, dest, path) {
876 return `Cannot include a '${char}' character in a manually specified \`to.${field}\` field [${JSON.stringify(
877 path
878 )}]. Please separate it out to the \`to.${dest}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`;
879}
880function getPathContributingMatches(matches) {
881 return matches.filter(
882 (match, index) => index === 0 || match.route.path && match.route.path.length > 0
883 );
884}
885function getResolveToMatches(matches) {
886 let pathMatches = getPathContributingMatches(matches);
887 return pathMatches.map(
888 (match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase
889 );
890}
891function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) {
892 let to;
893 if (typeof toArg === "string") {
894 to = parsePath(toArg);
895 } else {
896 to = { ...toArg };
897 invariant(
898 !to.pathname || !to.pathname.includes("?"),
899 getInvalidPathError("?", "pathname", "search", to)
900 );
901 invariant(
902 !to.pathname || !to.pathname.includes("#"),
903 getInvalidPathError("#", "pathname", "hash", to)
904 );
905 invariant(
906 !to.search || !to.search.includes("#"),
907 getInvalidPathError("#", "search", "hash", to)
908 );
909 }
910 let isEmptyPath = toArg === "" || to.pathname === "";
911 let toPathname = isEmptyPath ? "/" : to.pathname;
912 let from;
913 if (toPathname == null) {
914 from = locationPathname;
915 } else {
916 let routePathnameIndex = routePathnames.length - 1;
917 if (!isPathRelative && toPathname.startsWith("..")) {
918 let toSegments = toPathname.split("/");
919 while (toSegments[0] === "..") {
920 toSegments.shift();
921 routePathnameIndex -= 1;
922 }
923 to.pathname = toSegments.join("/");
924 }
925 from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
926 }
927 let path = resolvePath(to, from);
928 let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/");
929 let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/");
930 if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {
931 path.pathname += "/";
932 }
933 return path;
934}
935var joinPaths = (paths) => paths.join("/").replace(/\/\/+/g, "/");
936var normalizePathname = (pathname) => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
937var normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
938var normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
939var DataWithResponseInit = class {
940 constructor(data2, init) {
941 this.type = "DataWithResponseInit";
942 this.data = data2;
943 this.init = init || null;
944 }
945};
946function data(data2, init) {
947 return new DataWithResponseInit(
948 data2,
949 typeof init === "number" ? { status: init } : init
950 );
951}
952var redirect = (url, init = 302) => {
953 let responseInit = init;
954 if (typeof responseInit === "number") {
955 responseInit = { status: responseInit };
956 } else if (typeof responseInit.status === "undefined") {
957 responseInit.status = 302;
958 }
959 let headers = new Headers(responseInit.headers);
960 headers.set("Location", url);
961 return new Response(null, { ...responseInit, headers });
962};
963var redirectDocument = (url, init) => {
964 let response = redirect(url, init);
965 response.headers.set("X-Remix-Reload-Document", "true");
966 return response;
967};
968var replace = (url, init) => {
969 let response = redirect(url, init);
970 response.headers.set("X-Remix-Replace", "true");
971 return response;
972};
973var ErrorResponseImpl = class {
974 constructor(status, statusText, data2, internal = false) {
975 this.status = status;
976 this.statusText = statusText || "";
977 this.internal = internal;
978 if (data2 instanceof Error) {
979 this.data = data2.toString();
980 this.error = data2;
981 } else {
982 this.data = data2;
983 }
984 }
985};
986function isRouteErrorResponse(error) {
987 return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error;
988}
989function getRoutePattern(matches) {
990 return matches.map((m) => m.route.path).filter(Boolean).join("/").replace(/\/\/*/g, "/") || "/";
991}
992var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
993function parseToInfo(_to, basename) {
994 let to = _to;
995 if (typeof to !== "string" || !ABSOLUTE_URL_REGEX.test(to)) {
996 return {
997 absoluteURL: void 0,
998 isExternal: false,
999 to
1000 };
1001 }
1002 let absoluteURL = to;
1003 let isExternal = false;
1004 if (isBrowser) {
1005 try {
1006 let currentUrl = new URL(window.location.href);
1007 let targetUrl = to.startsWith("//") ? new URL(currentUrl.protocol + to) : new URL(to);
1008 let path = stripBasename(targetUrl.pathname, basename);
1009 if (targetUrl.origin === currentUrl.origin && path != null) {
1010 to = path + targetUrl.search + targetUrl.hash;
1011 } else {
1012 isExternal = true;
1013 }
1014 } catch (e) {
1015 warning(
1016 false,
1017 `<Link to="${to}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`
1018 );
1019 }
1020 }
1021 return {
1022 absoluteURL,
1023 isExternal,
1024 to
1025 };
1026}
1027
1028// lib/router/instrumentation.ts
1029var UninstrumentedSymbol = Symbol("Uninstrumented");
1030function getRouteInstrumentationUpdates(fns, route) {
1031 let aggregated = {
1032 lazy: [],
1033 "lazy.loader": [],
1034 "lazy.action": [],
1035 "lazy.middleware": [],
1036 middleware: [],
1037 loader: [],
1038 action: []
1039 };
1040 fns.forEach(
1041 (fn) => fn({
1042 id: route.id,
1043 index: route.index,
1044 path: route.path,
1045 instrument(i) {
1046 let keys = Object.keys(aggregated);
1047 for (let key of keys) {
1048 if (i[key]) {
1049 aggregated[key].push(i[key]);
1050 }
1051 }
1052 }
1053 })
1054 );
1055 let updates = {};
1056 if (typeof route.lazy === "function" && aggregated.lazy.length > 0) {
1057 let instrumented = wrapImpl(aggregated.lazy, route.lazy, () => void 0);
1058 if (instrumented) {
1059 updates.lazy = instrumented;
1060 }
1061 }
1062 if (typeof route.lazy === "object") {
1063 let lazyObject = route.lazy;
1064 ["middleware", "loader", "action"].forEach((key) => {
1065 let lazyFn = lazyObject[key];
1066 let instrumentations = aggregated[`lazy.${key}`];
1067 if (typeof lazyFn === "function" && instrumentations.length > 0) {
1068 let instrumented = wrapImpl(instrumentations, lazyFn, () => void 0);
1069 if (instrumented) {
1070 updates.lazy = Object.assign(updates.lazy || {}, {
1071 [key]: instrumented
1072 });
1073 }
1074 }
1075 });
1076 }
1077 ["loader", "action"].forEach((key) => {
1078 let handler = route[key];
1079 if (typeof handler === "function" && aggregated[key].length > 0) {
1080 let original = _nullishCoalesce(handler[UninstrumentedSymbol], () => ( handler));
1081 let instrumented = wrapImpl(
1082 aggregated[key],
1083 original,
1084 (...args) => getHandlerInfo(args[0])
1085 );
1086 if (instrumented) {
1087 if (key === "loader" && original.hydrate === true) {
1088 instrumented.hydrate = true;
1089 }
1090 instrumented[UninstrumentedSymbol] = original;
1091 updates[key] = instrumented;
1092 }
1093 }
1094 });
1095 if (route.middleware && route.middleware.length > 0 && aggregated.middleware.length > 0) {
1096 updates.middleware = route.middleware.map((middleware) => {
1097 let original = _nullishCoalesce(middleware[UninstrumentedSymbol], () => ( middleware));
1098 let instrumented = wrapImpl(
1099 aggregated.middleware,
1100 original,
1101 (...args) => getHandlerInfo(args[0])
1102 );
1103 if (instrumented) {
1104 instrumented[UninstrumentedSymbol] = original;
1105 return instrumented;
1106 }
1107 return middleware;
1108 });
1109 }
1110 return updates;
1111}
1112function instrumentClientSideRouter(router, fns) {
1113 let aggregated = {
1114 navigate: [],
1115 fetch: []
1116 };
1117 fns.forEach(
1118 (fn) => fn({
1119 instrument(i) {
1120 let keys = Object.keys(i);
1121 for (let key of keys) {
1122 if (i[key]) {
1123 aggregated[key].push(i[key]);
1124 }
1125 }
1126 }
1127 })
1128 );
1129 if (aggregated.navigate.length > 0) {
1130 let navigate = _nullishCoalesce(router.navigate[UninstrumentedSymbol], () => ( router.navigate));
1131 let instrumentedNavigate = wrapImpl(
1132 aggregated.navigate,
1133 navigate,
1134 (...args) => {
1135 let [to, opts] = args;
1136 return {
1137 to: typeof to === "number" || typeof to === "string" ? to : to ? createPath(to) : ".",
1138 ...getRouterInfo(router, _nullishCoalesce(opts, () => ( {})))
1139 };
1140 }
1141 );
1142 if (instrumentedNavigate) {
1143 instrumentedNavigate[UninstrumentedSymbol] = navigate;
1144 router.navigate = instrumentedNavigate;
1145 }
1146 }
1147 if (aggregated.fetch.length > 0) {
1148 let fetch2 = _nullishCoalesce(router.fetch[UninstrumentedSymbol], () => ( router.fetch));
1149 let instrumentedFetch = wrapImpl(aggregated.fetch, fetch2, (...args) => {
1150 let [key, , href, opts] = args;
1151 return {
1152 href: _nullishCoalesce(href, () => ( ".")),
1153 fetcherKey: key,
1154 ...getRouterInfo(router, _nullishCoalesce(opts, () => ( {})))
1155 };
1156 });
1157 if (instrumentedFetch) {
1158 instrumentedFetch[UninstrumentedSymbol] = fetch2;
1159 router.fetch = instrumentedFetch;
1160 }
1161 }
1162 return router;
1163}
1164function instrumentHandler(handler, fns) {
1165 let aggregated = {
1166 request: []
1167 };
1168 fns.forEach(
1169 (fn) => fn({
1170 instrument(i) {
1171 let keys = Object.keys(i);
1172 for (let key of keys) {
1173 if (i[key]) {
1174 aggregated[key].push(i[key]);
1175 }
1176 }
1177 }
1178 })
1179 );
1180 let instrumentedHandler = handler;
1181 if (aggregated.request.length > 0) {
1182 instrumentedHandler = wrapImpl(aggregated.request, handler, (...args) => {
1183 let [request, context] = args;
1184 return {
1185 request: getReadonlyRequest(request),
1186 context: context != null ? getReadonlyContext(context) : context
1187 };
1188 });
1189 }
1190 return instrumentedHandler;
1191}
1192function wrapImpl(impls, handler, getInfo) {
1193 if (impls.length === 0) {
1194 return null;
1195 }
1196 return async (...args) => {
1197 let result = await recurseRight(
1198 impls,
1199 getInfo(...args),
1200 () => handler(...args),
1201 impls.length - 1
1202 );
1203 if (result.type === "error") {
1204 throw result.value;
1205 }
1206 return result.value;
1207 };
1208}
1209async function recurseRight(impls, info, handler, index) {
1210 let impl = impls[index];
1211 let result;
1212 if (!impl) {
1213 try {
1214 let value = await handler();
1215 result = { type: "success", value };
1216 } catch (e) {
1217 result = { type: "error", value: e };
1218 }
1219 } else {
1220 let handlerPromise = void 0;
1221 let callHandler = async () => {
1222 if (handlerPromise) {
1223 console.error("You cannot call instrumented handlers more than once");
1224 } else {
1225 handlerPromise = recurseRight(impls, info, handler, index - 1);
1226 }
1227 result = await handlerPromise;
1228 invariant(result, "Expected a result");
1229 if (result.type === "error" && result.value instanceof Error) {
1230 return { status: "error", error: result.value };
1231 }
1232 return { status: "success", error: void 0 };
1233 };
1234 try {
1235 await impl(callHandler, info);
1236 } catch (e) {
1237 console.error("An instrumentation function threw an error:", e);
1238 }
1239 if (!handlerPromise) {
1240 await callHandler();
1241 }
1242 await handlerPromise;
1243 }
1244 if (result) {
1245 return result;
1246 }
1247 return {
1248 type: "error",
1249 value: new Error("No result assigned in instrumentation chain.")
1250 };
1251}
1252function getHandlerInfo(args) {
1253 let { request, context, params, unstable_pattern } = args;
1254 return {
1255 request: getReadonlyRequest(request),
1256 params: { ...params },
1257 unstable_pattern,
1258 context: getReadonlyContext(context)
1259 };
1260}
1261function getRouterInfo(router, opts) {
1262 return {
1263 currentUrl: createPath(router.state.location),
1264 ..."formMethod" in opts ? { formMethod: opts.formMethod } : {},
1265 ..."formEncType" in opts ? { formEncType: opts.formEncType } : {},
1266 ..."formData" in opts ? { formData: opts.formData } : {},
1267 ..."body" in opts ? { body: opts.body } : {}
1268 };
1269}
1270function getReadonlyRequest(request) {
1271 return {
1272 method: request.method,
1273 url: request.url,
1274 headers: {
1275 get: (...args) => request.headers.get(...args)
1276 }
1277 };
1278}
1279function getReadonlyContext(context) {
1280 if (isPlainObject(context)) {
1281 let frozen = { ...context };
1282 Object.freeze(frozen);
1283 return frozen;
1284 } else {
1285 return {
1286 get: (ctx) => context.get(ctx)
1287 };
1288 }
1289}
1290var objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
1291function isPlainObject(thing) {
1292 if (thing === null || typeof thing !== "object") {
1293 return false;
1294 }
1295 const proto = Object.getPrototypeOf(thing);
1296 return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames;
1297}
1298
1299// lib/router/router.ts
1300var validMutationMethodsArr = [
1301 "POST",
1302 "PUT",
1303 "PATCH",
1304 "DELETE"
1305];
1306var validMutationMethods = new Set(
1307 validMutationMethodsArr
1308);
1309var validRequestMethodsArr = [
1310 "GET",
1311 ...validMutationMethodsArr
1312];
1313var validRequestMethods = new Set(validRequestMethodsArr);
1314var redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
1315var redirectPreserveMethodStatusCodes = /* @__PURE__ */ new Set([307, 308]);
1316var IDLE_NAVIGATION = {
1317 state: "idle",
1318 location: void 0,
1319 formMethod: void 0,
1320 formAction: void 0,
1321 formEncType: void 0,
1322 formData: void 0,
1323 json: void 0,
1324 text: void 0
1325};
1326var IDLE_FETCHER = {
1327 state: "idle",
1328 data: void 0,
1329 formMethod: void 0,
1330 formAction: void 0,
1331 formEncType: void 0,
1332 formData: void 0,
1333 json: void 0,
1334 text: void 0
1335};
1336var IDLE_BLOCKER = {
1337 state: "unblocked",
1338 proceed: void 0,
1339 reset: void 0,
1340 location: void 0
1341};
1342var defaultMapRouteProperties = (route) => ({
1343 hasErrorBoundary: Boolean(route.hasErrorBoundary)
1344});
1345var TRANSITIONS_STORAGE_KEY = "remix-router-transitions";
1346var ResetLoaderDataSymbol = Symbol("ResetLoaderData");
1347function createRouter(init) {
1348 const routerWindow = init.window ? init.window : typeof window !== "undefined" ? window : void 0;
1349 const isBrowser2 = typeof routerWindow !== "undefined" && typeof routerWindow.document !== "undefined" && typeof routerWindow.document.createElement !== "undefined";
1350 invariant(
1351 init.routes.length > 0,
1352 "You must provide a non-empty routes array to createRouter"
1353 );
1354 let hydrationRouteProperties2 = init.hydrationRouteProperties || [];
1355 let _mapRouteProperties = init.mapRouteProperties || defaultMapRouteProperties;
1356 let mapRouteProperties2 = _mapRouteProperties;
1357 if (init.unstable_instrumentations) {
1358 let instrumentations = init.unstable_instrumentations;
1359 mapRouteProperties2 = (route) => {
1360 return {
1361 ..._mapRouteProperties(route),
1362 ...getRouteInstrumentationUpdates(
1363 instrumentations.map((i) => i.route).filter(Boolean),
1364 route
1365 )
1366 };
1367 };
1368 }
1369 let manifest = {};
1370 let dataRoutes = convertRoutesToDataRoutes(
1371 init.routes,
1372 mapRouteProperties2,
1373 void 0,
1374 manifest
1375 );
1376 let inFlightDataRoutes;
1377 let basename = init.basename || "/";
1378 if (!basename.startsWith("/")) {
1379 basename = `/${basename}`;
1380 }
1381 let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware;
1382 let future = {
1383 ...init.future
1384 };
1385 let unlistenHistory = null;
1386 let subscribers = /* @__PURE__ */ new Set();
1387 let savedScrollPositions = null;
1388 let getScrollRestorationKey = null;
1389 let getScrollPosition = null;
1390 let initialScrollRestored = init.hydrationData != null;
1391 let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);
1392 let initialMatchesIsFOW = false;
1393 let initialErrors = null;
1394 let initialized;
1395 let renderFallback;
1396 if (initialMatches == null && !init.patchRoutesOnNavigation) {
1397 let error = getInternalRouterError(404, {
1398 pathname: init.history.location.pathname
1399 });
1400 let { matches, route } = getShortCircuitMatches(dataRoutes);
1401 initialized = true;
1402 renderFallback = !initialized;
1403 initialMatches = matches;
1404 initialErrors = { [route.id]: error };
1405 } else {
1406 if (initialMatches && !init.hydrationData) {
1407 let fogOfWar = checkFogOfWar(
1408 initialMatches,
1409 dataRoutes,
1410 init.history.location.pathname
1411 );
1412 if (fogOfWar.active) {
1413 initialMatches = null;
1414 }
1415 }
1416 if (!initialMatches) {
1417 initialized = false;
1418 renderFallback = !initialized;
1419 initialMatches = [];
1420 let fogOfWar = checkFogOfWar(
1421 null,
1422 dataRoutes,
1423 init.history.location.pathname
1424 );
1425 if (fogOfWar.active && fogOfWar.matches) {
1426 initialMatchesIsFOW = true;
1427 initialMatches = fogOfWar.matches;
1428 }
1429 } else if (initialMatches.some((m) => m.route.lazy)) {
1430 initialized = false;
1431 renderFallback = !initialized;
1432 } else if (!initialMatches.some((m) => routeHasLoaderOrMiddleware(m.route))) {
1433 initialized = true;
1434 renderFallback = !initialized;
1435 } else {
1436 let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;
1437 let errors = init.hydrationData ? init.hydrationData.errors : null;
1438 let relevantMatches = initialMatches;
1439 if (errors) {
1440 let idx = initialMatches.findIndex(
1441 (m) => errors[m.route.id] !== void 0
1442 );
1443 relevantMatches = relevantMatches.slice(0, idx + 1);
1444 }
1445 renderFallback = false;
1446 initialized = relevantMatches.every((m) => {
1447 let status = getRouteHydrationStatus(m.route, loaderData, errors);
1448 renderFallback = renderFallback || status.renderFallback;
1449 return !status.shouldLoad;
1450 });
1451 }
1452 }
1453 let router;
1454 let state = {
1455 historyAction: init.history.action,
1456 location: init.history.location,
1457 matches: initialMatches,
1458 initialized,
1459 renderFallback,
1460 navigation: IDLE_NAVIGATION,
1461 // Don't restore on initial updateState() if we were SSR'd
1462 restoreScrollPosition: init.hydrationData != null ? false : null,
1463 preventScrollReset: false,
1464 revalidation: "idle",
1465 loaderData: init.hydrationData && init.hydrationData.loaderData || {},
1466 actionData: init.hydrationData && init.hydrationData.actionData || null,
1467 errors: init.hydrationData && init.hydrationData.errors || initialErrors,
1468 fetchers: /* @__PURE__ */ new Map(),
1469 blockers: /* @__PURE__ */ new Map()
1470 };
1471 let pendingAction = "POP" /* Pop */;
1472 let pendingPopstateNavigationDfd = null;
1473 let pendingPreventScrollReset = false;
1474 let pendingNavigationController;
1475 let pendingViewTransitionEnabled = false;
1476 let appliedViewTransitions = /* @__PURE__ */ new Map();
1477 let removePageHideEventListener = null;
1478 let isUninterruptedRevalidation = false;
1479 let isRevalidationRequired = false;
1480 let cancelledFetcherLoads = /* @__PURE__ */ new Set();
1481 let fetchControllers = /* @__PURE__ */ new Map();
1482 let incrementingLoadId = 0;
1483 let pendingNavigationLoadId = -1;
1484 let fetchReloadIds = /* @__PURE__ */ new Map();
1485 let fetchRedirectIds = /* @__PURE__ */ new Set();
1486 let fetchLoadMatches = /* @__PURE__ */ new Map();
1487 let activeFetchers = /* @__PURE__ */ new Map();
1488 let fetchersQueuedForDeletion = /* @__PURE__ */ new Set();
1489 let blockerFunctions = /* @__PURE__ */ new Map();
1490 let unblockBlockerHistoryUpdate = void 0;
1491 let pendingRevalidationDfd = null;
1492 function initialize() {
1493 unlistenHistory = init.history.listen(
1494 ({ action: historyAction, location, delta }) => {
1495 if (unblockBlockerHistoryUpdate) {
1496 unblockBlockerHistoryUpdate();
1497 unblockBlockerHistoryUpdate = void 0;
1498 return;
1499 }
1500 warning(
1501 blockerFunctions.size === 0 || delta != null,
1502 "You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL."
1503 );
1504 let blockerKey = shouldBlockNavigation({
1505 currentLocation: state.location,
1506 nextLocation: location,
1507 historyAction
1508 });
1509 if (blockerKey && delta != null) {
1510 let nextHistoryUpdatePromise = new Promise((resolve) => {
1511 unblockBlockerHistoryUpdate = resolve;
1512 });
1513 init.history.go(delta * -1);
1514 updateBlocker(blockerKey, {
1515 state: "blocked",
1516 location,
1517 proceed() {
1518 updateBlocker(blockerKey, {
1519 state: "proceeding",
1520 proceed: void 0,
1521 reset: void 0,
1522 location
1523 });
1524 nextHistoryUpdatePromise.then(() => init.history.go(delta));
1525 },
1526 reset() {
1527 let blockers = new Map(state.blockers);
1528 blockers.set(blockerKey, IDLE_BLOCKER);
1529 updateState({ blockers });
1530 }
1531 });
1532 _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _7 => _7.resolve, 'call', _8 => _8()]);
1533 pendingPopstateNavigationDfd = null;
1534 return;
1535 }
1536 return startNavigation(historyAction, location);
1537 }
1538 );
1539 if (isBrowser2) {
1540 restoreAppliedTransitions(routerWindow, appliedViewTransitions);
1541 let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions);
1542 routerWindow.addEventListener("pagehide", _saveAppliedTransitions);
1543 removePageHideEventListener = () => routerWindow.removeEventListener("pagehide", _saveAppliedTransitions);
1544 }
1545 if (!state.initialized) {
1546 startNavigation("POP" /* Pop */, state.location, {
1547 initialHydration: true
1548 });
1549 }
1550 return router;
1551 }
1552 function dispose() {
1553 if (unlistenHistory) {
1554 unlistenHistory();
1555 }
1556 if (removePageHideEventListener) {
1557 removePageHideEventListener();
1558 }
1559 subscribers.clear();
1560 pendingNavigationController && pendingNavigationController.abort();
1561 state.fetchers.forEach((_, key) => deleteFetcher(key));
1562 state.blockers.forEach((_, key) => deleteBlocker(key));
1563 }
1564 function subscribe(fn) {
1565 subscribers.add(fn);
1566 return () => subscribers.delete(fn);
1567 }
1568 function updateState(newState, opts = {}) {
1569 if (newState.matches) {
1570 newState.matches = newState.matches.map((m) => {
1571 let route = manifest[m.route.id];
1572 let matchRoute = m.route;
1573 if (matchRoute.element !== route.element || matchRoute.errorElement !== route.errorElement || matchRoute.hydrateFallbackElement !== route.hydrateFallbackElement) {
1574 return {
1575 ...m,
1576 route
1577 };
1578 }
1579 return m;
1580 });
1581 }
1582 state = {
1583 ...state,
1584 ...newState
1585 };
1586 let unmountedFetchers = [];
1587 let mountedFetchers = [];
1588 state.fetchers.forEach((fetcher, key) => {
1589 if (fetcher.state === "idle") {
1590 if (fetchersQueuedForDeletion.has(key)) {
1591 unmountedFetchers.push(key);
1592 } else {
1593 mountedFetchers.push(key);
1594 }
1595 }
1596 });
1597 fetchersQueuedForDeletion.forEach((key) => {
1598 if (!state.fetchers.has(key) && !fetchControllers.has(key)) {
1599 unmountedFetchers.push(key);
1600 }
1601 });
1602 [...subscribers].forEach(
1603 (subscriber) => subscriber(state, {
1604 deletedFetchers: unmountedFetchers,
1605 newErrors: _nullishCoalesce(newState.errors, () => ( null)),
1606 viewTransitionOpts: opts.viewTransitionOpts,
1607 flushSync: opts.flushSync === true
1608 })
1609 );
1610 unmountedFetchers.forEach((key) => deleteFetcher(key));
1611 mountedFetchers.forEach((key) => state.fetchers.delete(key));
1612 }
1613 function completeNavigation(location, newState, { flushSync } = {}) {
1614 let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === "loading" && _optionalChain([location, 'access', _9 => _9.state, 'optionalAccess', _10 => _10._isRedirect]) !== true;
1615 let actionData;
1616 if (newState.actionData) {
1617 if (Object.keys(newState.actionData).length > 0) {
1618 actionData = newState.actionData;
1619 } else {
1620 actionData = null;
1621 }
1622 } else if (isActionReload) {
1623 actionData = state.actionData;
1624 } else {
1625 actionData = null;
1626 }
1627 let loaderData = newState.loaderData ? mergeLoaderData(
1628 state.loaderData,
1629 newState.loaderData,
1630 newState.matches || [],
1631 newState.errors
1632 ) : state.loaderData;
1633 let blockers = state.blockers;
1634 if (blockers.size > 0) {
1635 blockers = new Map(blockers);
1636 blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));
1637 }
1638 let restoreScrollPosition = isUninterruptedRevalidation ? false : getSavedScrollPosition(location, newState.matches || state.matches);
1639 let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && _optionalChain([location, 'access', _11 => _11.state, 'optionalAccess', _12 => _12._isRedirect]) !== true;
1640 if (inFlightDataRoutes) {
1641 dataRoutes = inFlightDataRoutes;
1642 inFlightDataRoutes = void 0;
1643 }
1644 if (isUninterruptedRevalidation) {
1645 } else if (pendingAction === "POP" /* Pop */) {
1646 } else if (pendingAction === "PUSH" /* Push */) {
1647 init.history.push(location, location.state);
1648 } else if (pendingAction === "REPLACE" /* Replace */) {
1649 init.history.replace(location, location.state);
1650 }
1651 let viewTransitionOpts;
1652 if (pendingAction === "POP" /* Pop */) {
1653 let priorPaths = appliedViewTransitions.get(state.location.pathname);
1654 if (priorPaths && priorPaths.has(location.pathname)) {
1655 viewTransitionOpts = {
1656 currentLocation: state.location,
1657 nextLocation: location
1658 };
1659 } else if (appliedViewTransitions.has(location.pathname)) {
1660 viewTransitionOpts = {
1661 currentLocation: location,
1662 nextLocation: state.location
1663 };
1664 }
1665 } else if (pendingViewTransitionEnabled) {
1666 let toPaths = appliedViewTransitions.get(state.location.pathname);
1667 if (toPaths) {
1668 toPaths.add(location.pathname);
1669 } else {
1670 toPaths = /* @__PURE__ */ new Set([location.pathname]);
1671 appliedViewTransitions.set(state.location.pathname, toPaths);
1672 }
1673 viewTransitionOpts = {
1674 currentLocation: state.location,
1675 nextLocation: location
1676 };
1677 }
1678 updateState(
1679 {
1680 ...newState,
1681 // matches, errors, fetchers go through as-is
1682 actionData,
1683 loaderData,
1684 historyAction: pendingAction,
1685 location,
1686 initialized: true,
1687 renderFallback: false,
1688 navigation: IDLE_NAVIGATION,
1689 revalidation: "idle",
1690 restoreScrollPosition,
1691 preventScrollReset,
1692 blockers
1693 },
1694 {
1695 viewTransitionOpts,
1696 flushSync: flushSync === true
1697 }
1698 );
1699 pendingAction = "POP" /* Pop */;
1700 pendingPreventScrollReset = false;
1701 pendingViewTransitionEnabled = false;
1702 isUninterruptedRevalidation = false;
1703 isRevalidationRequired = false;
1704 _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _13 => _13.resolve, 'call', _14 => _14()]);
1705 pendingPopstateNavigationDfd = null;
1706 _optionalChain([pendingRevalidationDfd, 'optionalAccess', _15 => _15.resolve, 'call', _16 => _16()]);
1707 pendingRevalidationDfd = null;
1708 }
1709 async function navigate(to, opts) {
1710 _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _17 => _17.resolve, 'call', _18 => _18()]);
1711 pendingPopstateNavigationDfd = null;
1712 if (typeof to === "number") {
1713 if (!pendingPopstateNavigationDfd) {
1714 pendingPopstateNavigationDfd = createDeferred();
1715 }
1716 let promise = pendingPopstateNavigationDfd.promise;
1717 init.history.go(to);
1718 return promise;
1719 }
1720 let normalizedPath = normalizeTo(
1721 state.location,
1722 state.matches,
1723 basename,
1724 to,
1725 _optionalChain([opts, 'optionalAccess', _19 => _19.fromRouteId]),
1726 _optionalChain([opts, 'optionalAccess', _20 => _20.relative])
1727 );
1728 let { path, submission, error } = normalizeNavigateOptions(
1729 false,
1730 normalizedPath,
1731 opts
1732 );
1733 let maskPath;
1734 if (_optionalChain([opts, 'optionalAccess', _21 => _21.unstable_mask])) {
1735 let partialPath = typeof opts.unstable_mask === "string" ? parsePath(opts.unstable_mask) : {
1736 ...state.location.unstable_mask,
1737 ...opts.unstable_mask
1738 };
1739 maskPath = {
1740 pathname: "",
1741 search: "",
1742 hash: "",
1743 ...partialPath
1744 };
1745 }
1746 let currentLocation = state.location;
1747 let nextLocation = createLocation(
1748 currentLocation,
1749 path,
1750 opts && opts.state,
1751 void 0,
1752 maskPath
1753 );
1754 nextLocation = {
1755 ...nextLocation,
1756 ...init.history.encodeLocation(nextLocation)
1757 };
1758 let userReplace = opts && opts.replace != null ? opts.replace : void 0;
1759 let historyAction = "PUSH" /* Push */;
1760 if (userReplace === true) {
1761 historyAction = "REPLACE" /* Replace */;
1762 } else if (userReplace === false) {
1763 } else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) {
1764 historyAction = "REPLACE" /* Replace */;
1765 }
1766 let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : void 0;
1767 let flushSync = (opts && opts.flushSync) === true;
1768 let blockerKey = shouldBlockNavigation({
1769 currentLocation,
1770 nextLocation,
1771 historyAction
1772 });
1773 if (blockerKey) {
1774 updateBlocker(blockerKey, {
1775 state: "blocked",
1776 location: nextLocation,
1777 proceed() {
1778 updateBlocker(blockerKey, {
1779 state: "proceeding",
1780 proceed: void 0,
1781 reset: void 0,
1782 location: nextLocation
1783 });
1784 navigate(to, opts);
1785 },
1786 reset() {
1787 let blockers = new Map(state.blockers);
1788 blockers.set(blockerKey, IDLE_BLOCKER);
1789 updateState({ blockers });
1790 }
1791 });
1792 return;
1793 }
1794 await startNavigation(historyAction, nextLocation, {
1795 submission,
1796 // Send through the formData serialization error if we have one so we can
1797 // render at the right error boundary after we match routes
1798 pendingError: error,
1799 preventScrollReset,
1800 replace: opts && opts.replace,
1801 enableViewTransition: opts && opts.viewTransition,
1802 flushSync,
1803 callSiteDefaultShouldRevalidate: opts && opts.unstable_defaultShouldRevalidate
1804 });
1805 }
1806 function revalidate() {
1807 if (!pendingRevalidationDfd) {
1808 pendingRevalidationDfd = createDeferred();
1809 }
1810 interruptActiveLoads();
1811 updateState({ revalidation: "loading" });
1812 let promise = pendingRevalidationDfd.promise;
1813 if (state.navigation.state === "submitting") {
1814 return promise;
1815 }
1816 if (state.navigation.state === "idle") {
1817 startNavigation(state.historyAction, state.location, {
1818 startUninterruptedRevalidation: true
1819 });
1820 return promise;
1821 }
1822 startNavigation(
1823 pendingAction || state.historyAction,
1824 state.navigation.location,
1825 {
1826 overrideNavigation: state.navigation,
1827 // Proxy through any rending view transition
1828 enableViewTransition: pendingViewTransitionEnabled === true
1829 }
1830 );
1831 return promise;
1832 }
1833 async function startNavigation(historyAction, location, opts) {
1834 pendingNavigationController && pendingNavigationController.abort();
1835 pendingNavigationController = null;
1836 pendingAction = historyAction;
1837 isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true;
1838 saveScrollPosition(state.location, state.matches);
1839 pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
1840 pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;
1841 let routesToUse = inFlightDataRoutes || dataRoutes;
1842 let loadingNavigation = opts && opts.overrideNavigation;
1843 let matches = _optionalChain([opts, 'optionalAccess', _22 => _22.initialHydration]) && state.matches && state.matches.length > 0 && !initialMatchesIsFOW ? (
1844 // `matchRoutes()` has already been called if we're in here via `router.initialize()`
1845 state.matches
1846 ) : matchRoutes(routesToUse, location, basename);
1847 let flushSync = (opts && opts.flushSync) === true;
1848 if (matches && state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) {
1849 completeNavigation(location, { matches }, { flushSync });
1850 return;
1851 }
1852 let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);
1853 if (fogOfWar.active && fogOfWar.matches) {
1854 matches = fogOfWar.matches;
1855 }
1856 if (!matches) {
1857 let { error, notFoundMatches, route } = handleNavigational404(
1858 location.pathname
1859 );
1860 completeNavigation(
1861 location,
1862 {
1863 matches: notFoundMatches,
1864 loaderData: {},
1865 errors: {
1866 [route.id]: error
1867 }
1868 },
1869 { flushSync }
1870 );
1871 return;
1872 }
1873 pendingNavigationController = new AbortController();
1874 let request = createClientSideRequest(
1875 init.history,
1876 location,
1877 pendingNavigationController.signal,
1878 opts && opts.submission
1879 );
1880 let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider();
1881 let pendingActionResult;
1882 if (opts && opts.pendingError) {
1883 pendingActionResult = [
1884 findNearestBoundary(matches).route.id,
1885 { type: "error" /* error */, error: opts.pendingError }
1886 ];
1887 } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) {
1888 let actionResult = await handleAction(
1889 request,
1890 location,
1891 opts.submission,
1892 matches,
1893 scopedContext,
1894 fogOfWar.active,
1895 opts && opts.initialHydration === true,
1896 { replace: opts.replace, flushSync }
1897 );
1898 if (actionResult.shortCircuited) {
1899 return;
1900 }
1901 if (actionResult.pendingActionResult) {
1902 let [routeId, result] = actionResult.pendingActionResult;
1903 if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) {
1904 pendingNavigationController = null;
1905 completeNavigation(location, {
1906 matches: actionResult.matches,
1907 loaderData: {},
1908 errors: {
1909 [routeId]: result.error
1910 }
1911 });
1912 return;
1913 }
1914 }
1915 matches = actionResult.matches || matches;
1916 pendingActionResult = actionResult.pendingActionResult;
1917 loadingNavigation = getLoadingNavigation(location, opts.submission);
1918 flushSync = false;
1919 fogOfWar.active = false;
1920 request = createClientSideRequest(
1921 init.history,
1922 request.url,
1923 request.signal
1924 );
1925 }
1926 let {
1927 shortCircuited,
1928 matches: updatedMatches,
1929 loaderData,
1930 errors
1931 } = await handleLoaders(
1932 request,
1933 location,
1934 matches,
1935 scopedContext,
1936 fogOfWar.active,
1937 loadingNavigation,
1938 opts && opts.submission,
1939 opts && opts.fetcherSubmission,
1940 opts && opts.replace,
1941 opts && opts.initialHydration === true,
1942 flushSync,
1943 pendingActionResult,
1944 opts && opts.callSiteDefaultShouldRevalidate
1945 );
1946 if (shortCircuited) {
1947 return;
1948 }
1949 pendingNavigationController = null;
1950 completeNavigation(location, {
1951 matches: updatedMatches || matches,
1952 ...getActionDataForCommit(pendingActionResult),
1953 loaderData,
1954 errors
1955 });
1956 }
1957 async function handleAction(request, location, submission, matches, scopedContext, isFogOfWar, initialHydration, opts = {}) {
1958 interruptActiveLoads();
1959 let navigation = getSubmittingNavigation(location, submission);
1960 updateState({ navigation }, { flushSync: opts.flushSync === true });
1961 if (isFogOfWar) {
1962 let discoverResult = await discoverRoutes(
1963 matches,
1964 location.pathname,
1965 request.signal
1966 );
1967 if (discoverResult.type === "aborted") {
1968 return { shortCircuited: true };
1969 } else if (discoverResult.type === "error") {
1970 if (discoverResult.partialMatches.length === 0) {
1971 let { matches: matches2, route } = getShortCircuitMatches(dataRoutes);
1972 return {
1973 matches: matches2,
1974 pendingActionResult: [
1975 route.id,
1976 {
1977 type: "error" /* error */,
1978 error: discoverResult.error
1979 }
1980 ]
1981 };
1982 }
1983 let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;
1984 return {
1985 matches: discoverResult.partialMatches,
1986 pendingActionResult: [
1987 boundaryId,
1988 {
1989 type: "error" /* error */,
1990 error: discoverResult.error
1991 }
1992 ]
1993 };
1994 } else if (!discoverResult.matches) {
1995 let { notFoundMatches, error, route } = handleNavigational404(
1996 location.pathname
1997 );
1998 return {
1999 matches: notFoundMatches,
2000 pendingActionResult: [
2001 route.id,
2002 {
2003 type: "error" /* error */,
2004 error
2005 }
2006 ]
2007 };
2008 } else {
2009 matches = discoverResult.matches;
2010 }
2011 }
2012 let result;
2013 let actionMatch = getTargetMatch(matches, location);
2014 if (!actionMatch.route.action && !actionMatch.route.lazy) {
2015 result = {
2016 type: "error" /* error */,
2017 error: getInternalRouterError(405, {
2018 method: request.method,
2019 pathname: location.pathname,
2020 routeId: actionMatch.route.id
2021 })
2022 };
2023 } else {
2024 let dsMatches = getTargetedDataStrategyMatches(
2025 mapRouteProperties2,
2026 manifest,
2027 request,
2028 matches,
2029 actionMatch,
2030 initialHydration ? [] : hydrationRouteProperties2,
2031 scopedContext
2032 );
2033 let results = await callDataStrategy(
2034 request,
2035 dsMatches,
2036 scopedContext,
2037 null
2038 );
2039 result = results[actionMatch.route.id];
2040 if (!result) {
2041 for (let match of matches) {
2042 if (results[match.route.id]) {
2043 result = results[match.route.id];
2044 break;
2045 }
2046 }
2047 }
2048 if (request.signal.aborted) {
2049 return { shortCircuited: true };
2050 }
2051 }
2052 if (isRedirectResult(result)) {
2053 let replace2;
2054 if (opts && opts.replace != null) {
2055 replace2 = opts.replace;
2056 } else {
2057 let location2 = normalizeRedirectLocation(
2058 result.response.headers.get("Location"),
2059 new URL(request.url),
2060 basename,
2061 init.history
2062 );
2063 replace2 = location2 === state.location.pathname + state.location.search;
2064 }
2065 await startRedirectNavigation(request, result, true, {
2066 submission,
2067 replace: replace2
2068 });
2069 return { shortCircuited: true };
2070 }
2071 if (isErrorResult(result)) {
2072 let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);
2073 if ((opts && opts.replace) !== true) {
2074 pendingAction = "PUSH" /* Push */;
2075 }
2076 return {
2077 matches,
2078 pendingActionResult: [
2079 boundaryMatch.route.id,
2080 result,
2081 actionMatch.route.id
2082 ]
2083 };
2084 }
2085 return {
2086 matches,
2087 pendingActionResult: [actionMatch.route.id, result]
2088 };
2089 }
2090 async function handleLoaders(request, location, matches, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync, pendingActionResult, callSiteDefaultShouldRevalidate) {
2091 let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);
2092 let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);
2093 let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration;
2094 if (isFogOfWar) {
2095 if (shouldUpdateNavigationState) {
2096 let actionData = getUpdatedActionData(pendingActionResult);
2097 updateState(
2098 {
2099 navigation: loadingNavigation,
2100 ...actionData !== void 0 ? { actionData } : {}
2101 },
2102 {
2103 flushSync
2104 }
2105 );
2106 }
2107 let discoverResult = await discoverRoutes(
2108 matches,
2109 location.pathname,
2110 request.signal
2111 );
2112 if (discoverResult.type === "aborted") {
2113 return { shortCircuited: true };
2114 } else if (discoverResult.type === "error") {
2115 if (discoverResult.partialMatches.length === 0) {
2116 let { matches: matches2, route } = getShortCircuitMatches(dataRoutes);
2117 return {
2118 matches: matches2,
2119 loaderData: {},
2120 errors: {
2121 [route.id]: discoverResult.error
2122 }
2123 };
2124 }
2125 let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;
2126 return {
2127 matches: discoverResult.partialMatches,
2128 loaderData: {},
2129 errors: {
2130 [boundaryId]: discoverResult.error
2131 }
2132 };
2133 } else if (!discoverResult.matches) {
2134 let { error, notFoundMatches, route } = handleNavigational404(
2135 location.pathname
2136 );
2137 return {
2138 matches: notFoundMatches,
2139 loaderData: {},
2140 errors: {
2141 [route.id]: error
2142 }
2143 };
2144 } else {
2145 matches = discoverResult.matches;
2146 }
2147 }
2148 let routesToUse = inFlightDataRoutes || dataRoutes;
2149 let { dsMatches, revalidatingFetchers } = getMatchesToLoad(
2150 request,
2151 scopedContext,
2152 mapRouteProperties2,
2153 manifest,
2154 init.history,
2155 state,
2156 matches,
2157 activeSubmission,
2158 location,
2159 initialHydration ? [] : hydrationRouteProperties2,
2160 initialHydration === true,
2161 isRevalidationRequired,
2162 cancelledFetcherLoads,
2163 fetchersQueuedForDeletion,
2164 fetchLoadMatches,
2165 fetchRedirectIds,
2166 routesToUse,
2167 basename,
2168 init.patchRoutesOnNavigation != null,
2169 pendingActionResult,
2170 callSiteDefaultShouldRevalidate
2171 );
2172 pendingNavigationLoadId = ++incrementingLoadId;
2173 if (!init.dataStrategy && !dsMatches.some((m) => m.shouldLoad) && !dsMatches.some(
2174 (m) => m.route.middleware && m.route.middleware.length > 0
2175 ) && revalidatingFetchers.length === 0) {
2176 let updatedFetchers2 = markFetchRedirectsDone();
2177 completeNavigation(
2178 location,
2179 {
2180 matches,
2181 loaderData: {},
2182 // Commit pending error if we're short circuiting
2183 errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { [pendingActionResult[0]]: pendingActionResult[1].error } : null,
2184 ...getActionDataForCommit(pendingActionResult),
2185 ...updatedFetchers2 ? { fetchers: new Map(state.fetchers) } : {}
2186 },
2187 { flushSync }
2188 );
2189 return { shortCircuited: true };
2190 }
2191 if (shouldUpdateNavigationState) {
2192 let updates = {};
2193 if (!isFogOfWar) {
2194 updates.navigation = loadingNavigation;
2195 let actionData = getUpdatedActionData(pendingActionResult);
2196 if (actionData !== void 0) {
2197 updates.actionData = actionData;
2198 }
2199 }
2200 if (revalidatingFetchers.length > 0) {
2201 updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers);
2202 }
2203 updateState(updates, { flushSync });
2204 }
2205 revalidatingFetchers.forEach((rf) => {
2206 abortFetcher(rf.key);
2207 if (rf.controller) {
2208 fetchControllers.set(rf.key, rf.controller);
2209 }
2210 });
2211 let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((f) => abortFetcher(f.key));
2212 if (pendingNavigationController) {
2213 pendingNavigationController.signal.addEventListener(
2214 "abort",
2215 abortPendingFetchRevalidations
2216 );
2217 }
2218 let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
2219 dsMatches,
2220 revalidatingFetchers,
2221 request,
2222 scopedContext
2223 );
2224 if (request.signal.aborted) {
2225 return { shortCircuited: true };
2226 }
2227 if (pendingNavigationController) {
2228 pendingNavigationController.signal.removeEventListener(
2229 "abort",
2230 abortPendingFetchRevalidations
2231 );
2232 }
2233 revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));
2234 let redirect2 = findRedirect(loaderResults);
2235 if (redirect2) {
2236 await startRedirectNavigation(request, redirect2.result, true, {
2237 replace: replace2
2238 });
2239 return { shortCircuited: true };
2240 }
2241 redirect2 = findRedirect(fetcherResults);
2242 if (redirect2) {
2243 fetchRedirectIds.add(redirect2.key);
2244 await startRedirectNavigation(request, redirect2.result, true, {
2245 replace: replace2
2246 });
2247 return { shortCircuited: true };
2248 }
2249 let { loaderData, errors } = processLoaderData(
2250 state,
2251 matches,
2252 loaderResults,
2253 pendingActionResult,
2254 revalidatingFetchers,
2255 fetcherResults
2256 );
2257 if (initialHydration && state.errors) {
2258 errors = { ...state.errors, ...errors };
2259 }
2260 let updatedFetchers = markFetchRedirectsDone();
2261 let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);
2262 let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;
2263 return {
2264 matches,
2265 loaderData,
2266 errors,
2267 ...shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {}
2268 };
2269 }
2270 function getUpdatedActionData(pendingActionResult) {
2271 if (pendingActionResult && !isErrorResult(pendingActionResult[1])) {
2272 return {
2273 [pendingActionResult[0]]: pendingActionResult[1].data
2274 };
2275 } else if (state.actionData) {
2276 if (Object.keys(state.actionData).length === 0) {
2277 return null;
2278 } else {
2279 return state.actionData;
2280 }
2281 }
2282 }
2283 function getUpdatedRevalidatingFetchers(revalidatingFetchers) {
2284 revalidatingFetchers.forEach((rf) => {
2285 let fetcher = state.fetchers.get(rf.key);
2286 let revalidatingFetcher = getLoadingFetcher(
2287 void 0,
2288 fetcher ? fetcher.data : void 0
2289 );
2290 state.fetchers.set(rf.key, revalidatingFetcher);
2291 });
2292 return new Map(state.fetchers);
2293 }
2294 async function fetch2(key, routeId, href, opts) {
2295 abortFetcher(key);
2296 let flushSync = (opts && opts.flushSync) === true;
2297 let routesToUse = inFlightDataRoutes || dataRoutes;
2298 let normalizedPath = normalizeTo(
2299 state.location,
2300 state.matches,
2301 basename,
2302 href,
2303 routeId,
2304 _optionalChain([opts, 'optionalAccess', _23 => _23.relative])
2305 );
2306 let matches = matchRoutes(routesToUse, normalizedPath, basename);
2307 let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath);
2308 if (fogOfWar.active && fogOfWar.matches) {
2309 matches = fogOfWar.matches;
2310 }
2311 if (!matches) {
2312 setFetcherError(
2313 key,
2314 routeId,
2315 getInternalRouterError(404, { pathname: normalizedPath }),
2316 { flushSync }
2317 );
2318 return;
2319 }
2320 let { path, submission, error } = normalizeNavigateOptions(
2321 true,
2322 normalizedPath,
2323 opts
2324 );
2325 if (error) {
2326 setFetcherError(key, routeId, error, { flushSync });
2327 return;
2328 }
2329 let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider();
2330 let preventScrollReset = (opts && opts.preventScrollReset) === true;
2331 if (submission && isMutationMethod(submission.formMethod)) {
2332 await handleFetcherAction(
2333 key,
2334 routeId,
2335 path,
2336 matches,
2337 scopedContext,
2338 fogOfWar.active,
2339 flushSync,
2340 preventScrollReset,
2341 submission,
2342 opts && opts.unstable_defaultShouldRevalidate
2343 );
2344 return;
2345 }
2346 fetchLoadMatches.set(key, { routeId, path });
2347 await handleFetcherLoader(
2348 key,
2349 routeId,
2350 path,
2351 matches,
2352 scopedContext,
2353 fogOfWar.active,
2354 flushSync,
2355 preventScrollReset,
2356 submission
2357 );
2358 }
2359 async function handleFetcherAction(key, routeId, path, requestMatches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission, callSiteDefaultShouldRevalidate) {
2360 interruptActiveLoads();
2361 fetchLoadMatches.delete(key);
2362 let existingFetcher = state.fetchers.get(key);
2363 updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {
2364 flushSync
2365 });
2366 let abortController = new AbortController();
2367 let fetchRequest = createClientSideRequest(
2368 init.history,
2369 path,
2370 abortController.signal,
2371 submission
2372 );
2373 if (isFogOfWar) {
2374 let discoverResult = await discoverRoutes(
2375 requestMatches,
2376 new URL(fetchRequest.url).pathname,
2377 fetchRequest.signal,
2378 key
2379 );
2380 if (discoverResult.type === "aborted") {
2381 return;
2382 } else if (discoverResult.type === "error") {
2383 setFetcherError(key, routeId, discoverResult.error, { flushSync });
2384 return;
2385 } else if (!discoverResult.matches) {
2386 setFetcherError(
2387 key,
2388 routeId,
2389 getInternalRouterError(404, { pathname: path }),
2390 { flushSync }
2391 );
2392 return;
2393 } else {
2394 requestMatches = discoverResult.matches;
2395 }
2396 }
2397 let match = getTargetMatch(requestMatches, path);
2398 if (!match.route.action && !match.route.lazy) {
2399 let error = getInternalRouterError(405, {
2400 method: submission.formMethod,
2401 pathname: path,
2402 routeId
2403 });
2404 setFetcherError(key, routeId, error, { flushSync });
2405 return;
2406 }
2407 fetchControllers.set(key, abortController);
2408 let originatingLoadId = incrementingLoadId;
2409 let fetchMatches = getTargetedDataStrategyMatches(
2410 mapRouteProperties2,
2411 manifest,
2412 fetchRequest,
2413 requestMatches,
2414 match,
2415 hydrationRouteProperties2,
2416 scopedContext
2417 );
2418 let actionResults = await callDataStrategy(
2419 fetchRequest,
2420 fetchMatches,
2421 scopedContext,
2422 key
2423 );
2424 let actionResult = actionResults[match.route.id];
2425 if (!actionResult) {
2426 for (let match2 of fetchMatches) {
2427 if (actionResults[match2.route.id]) {
2428 actionResult = actionResults[match2.route.id];
2429 break;
2430 }
2431 }
2432 }
2433 if (fetchRequest.signal.aborted) {
2434 if (fetchControllers.get(key) === abortController) {
2435 fetchControllers.delete(key);
2436 }
2437 return;
2438 }
2439 if (fetchersQueuedForDeletion.has(key)) {
2440 if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {
2441 updateFetcherState(key, getDoneFetcher(void 0));
2442 return;
2443 }
2444 } else {
2445 if (isRedirectResult(actionResult)) {
2446 fetchControllers.delete(key);
2447 if (pendingNavigationLoadId > originatingLoadId) {
2448 updateFetcherState(key, getDoneFetcher(void 0));
2449 return;
2450 } else {
2451 fetchRedirectIds.add(key);
2452 updateFetcherState(key, getLoadingFetcher(submission));
2453 return startRedirectNavigation(fetchRequest, actionResult, false, {
2454 fetcherSubmission: submission,
2455 preventScrollReset
2456 });
2457 }
2458 }
2459 if (isErrorResult(actionResult)) {
2460 setFetcherError(key, routeId, actionResult.error);
2461 return;
2462 }
2463 }
2464 let nextLocation = state.navigation.location || state.location;
2465 let revalidationRequest = createClientSideRequest(
2466 init.history,
2467 nextLocation,
2468 abortController.signal
2469 );
2470 let routesToUse = inFlightDataRoutes || dataRoutes;
2471 let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches;
2472 invariant(matches, "Didn't find any matches after fetcher action");
2473 let loadId = ++incrementingLoadId;
2474 fetchReloadIds.set(key, loadId);
2475 let loadFetcher = getLoadingFetcher(submission, actionResult.data);
2476 state.fetchers.set(key, loadFetcher);
2477 let { dsMatches, revalidatingFetchers } = getMatchesToLoad(
2478 revalidationRequest,
2479 scopedContext,
2480 mapRouteProperties2,
2481 manifest,
2482 init.history,
2483 state,
2484 matches,
2485 submission,
2486 nextLocation,
2487 hydrationRouteProperties2,
2488 false,
2489 isRevalidationRequired,
2490 cancelledFetcherLoads,
2491 fetchersQueuedForDeletion,
2492 fetchLoadMatches,
2493 fetchRedirectIds,
2494 routesToUse,
2495 basename,
2496 init.patchRoutesOnNavigation != null,
2497 [match.route.id, actionResult],
2498 callSiteDefaultShouldRevalidate
2499 );
2500 revalidatingFetchers.filter((rf) => rf.key !== key).forEach((rf) => {
2501 let staleKey = rf.key;
2502 let existingFetcher2 = state.fetchers.get(staleKey);
2503 let revalidatingFetcher = getLoadingFetcher(
2504 void 0,
2505 existingFetcher2 ? existingFetcher2.data : void 0
2506 );
2507 state.fetchers.set(staleKey, revalidatingFetcher);
2508 abortFetcher(staleKey);
2509 if (rf.controller) {
2510 fetchControllers.set(staleKey, rf.controller);
2511 }
2512 });
2513 updateState({ fetchers: new Map(state.fetchers) });
2514 let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));
2515 abortController.signal.addEventListener(
2516 "abort",
2517 abortPendingFetchRevalidations
2518 );
2519 let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
2520 dsMatches,
2521 revalidatingFetchers,
2522 revalidationRequest,
2523 scopedContext
2524 );
2525 if (abortController.signal.aborted) {
2526 return;
2527 }
2528 abortController.signal.removeEventListener(
2529 "abort",
2530 abortPendingFetchRevalidations
2531 );
2532 fetchReloadIds.delete(key);
2533 fetchControllers.delete(key);
2534 revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key));
2535 if (state.fetchers.has(key)) {
2536 let doneFetcher = getDoneFetcher(actionResult.data);
2537 state.fetchers.set(key, doneFetcher);
2538 }
2539 let redirect2 = findRedirect(loaderResults);
2540 if (redirect2) {
2541 return startRedirectNavigation(
2542 revalidationRequest,
2543 redirect2.result,
2544 false,
2545 { preventScrollReset }
2546 );
2547 }
2548 redirect2 = findRedirect(fetcherResults);
2549 if (redirect2) {
2550 fetchRedirectIds.add(redirect2.key);
2551 return startRedirectNavigation(
2552 revalidationRequest,
2553 redirect2.result,
2554 false,
2555 { preventScrollReset }
2556 );
2557 }
2558 let { loaderData, errors } = processLoaderData(
2559 state,
2560 matches,
2561 loaderResults,
2562 void 0,
2563 revalidatingFetchers,
2564 fetcherResults
2565 );
2566 abortStaleFetchLoads(loadId);
2567 if (state.navigation.state === "loading" && loadId > pendingNavigationLoadId) {
2568 invariant(pendingAction, "Expected pending action");
2569 pendingNavigationController && pendingNavigationController.abort();
2570 completeNavigation(state.navigation.location, {
2571 matches,
2572 loaderData,
2573 errors,
2574 fetchers: new Map(state.fetchers)
2575 });
2576 } else {
2577 updateState({
2578 errors,
2579 loaderData: mergeLoaderData(
2580 state.loaderData,
2581 loaderData,
2582 matches,
2583 errors
2584 ),
2585 fetchers: new Map(state.fetchers)
2586 });
2587 isRevalidationRequired = false;
2588 }
2589 }
2590 async function handleFetcherLoader(key, routeId, path, matches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) {
2591 let existingFetcher = state.fetchers.get(key);
2592 updateFetcherState(
2593 key,
2594 getLoadingFetcher(
2595 submission,
2596 existingFetcher ? existingFetcher.data : void 0
2597 ),
2598 { flushSync }
2599 );
2600 let abortController = new AbortController();
2601 let fetchRequest = createClientSideRequest(
2602 init.history,
2603 path,
2604 abortController.signal
2605 );
2606 if (isFogOfWar) {
2607 let discoverResult = await discoverRoutes(
2608 matches,
2609 new URL(fetchRequest.url).pathname,
2610 fetchRequest.signal,
2611 key
2612 );
2613 if (discoverResult.type === "aborted") {
2614 return;
2615 } else if (discoverResult.type === "error") {
2616 setFetcherError(key, routeId, discoverResult.error, { flushSync });
2617 return;
2618 } else if (!discoverResult.matches) {
2619 setFetcherError(
2620 key,
2621 routeId,
2622 getInternalRouterError(404, { pathname: path }),
2623 { flushSync }
2624 );
2625 return;
2626 } else {
2627 matches = discoverResult.matches;
2628 }
2629 }
2630 let match = getTargetMatch(matches, path);
2631 fetchControllers.set(key, abortController);
2632 let originatingLoadId = incrementingLoadId;
2633 let dsMatches = getTargetedDataStrategyMatches(
2634 mapRouteProperties2,
2635 manifest,
2636 fetchRequest,
2637 matches,
2638 match,
2639 hydrationRouteProperties2,
2640 scopedContext
2641 );
2642 let results = await callDataStrategy(
2643 fetchRequest,
2644 dsMatches,
2645 scopedContext,
2646 key
2647 );
2648 let result = results[match.route.id];
2649 if (fetchControllers.get(key) === abortController) {
2650 fetchControllers.delete(key);
2651 }
2652 if (fetchRequest.signal.aborted) {
2653 return;
2654 }
2655 if (fetchersQueuedForDeletion.has(key)) {
2656 updateFetcherState(key, getDoneFetcher(void 0));
2657 return;
2658 }
2659 if (isRedirectResult(result)) {
2660 if (pendingNavigationLoadId > originatingLoadId) {
2661 updateFetcherState(key, getDoneFetcher(void 0));
2662 return;
2663 } else {
2664 fetchRedirectIds.add(key);
2665 await startRedirectNavigation(fetchRequest, result, false, {
2666 preventScrollReset
2667 });
2668 return;
2669 }
2670 }
2671 if (isErrorResult(result)) {
2672 setFetcherError(key, routeId, result.error);
2673 return;
2674 }
2675 updateFetcherState(key, getDoneFetcher(result.data));
2676 }
2677 async function startRedirectNavigation(request, redirect2, isNavigation, {
2678 submission,
2679 fetcherSubmission,
2680 preventScrollReset,
2681 replace: replace2
2682 } = {}) {
2683 if (!isNavigation) {
2684 _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _24 => _24.resolve, 'call', _25 => _25()]);
2685 pendingPopstateNavigationDfd = null;
2686 }
2687 if (redirect2.response.headers.has("X-Remix-Revalidate")) {
2688 isRevalidationRequired = true;
2689 }
2690 let location = redirect2.response.headers.get("Location");
2691 invariant(location, "Expected a Location header on the redirect Response");
2692 location = normalizeRedirectLocation(
2693 location,
2694 new URL(request.url),
2695 basename,
2696 init.history
2697 );
2698 let redirectLocation = createLocation(state.location, location, {
2699 _isRedirect: true
2700 });
2701 if (isBrowser2) {
2702 let isDocumentReload = false;
2703 if (redirect2.response.headers.has("X-Remix-Reload-Document")) {
2704 isDocumentReload = true;
2705 } else if (isAbsoluteUrl(location)) {
2706 const url = createBrowserURLImpl(location, true);
2707 isDocumentReload = // Hard reload if it's an absolute URL to a new origin
2708 url.origin !== routerWindow.location.origin || // Hard reload if it's an absolute URL that does not match our basename
2709 stripBasename(url.pathname, basename) == null;
2710 }
2711 if (isDocumentReload) {
2712 if (replace2) {
2713 routerWindow.location.replace(location);
2714 } else {
2715 routerWindow.location.assign(location);
2716 }
2717 return;
2718 }
2719 }
2720 pendingNavigationController = null;
2721 let redirectNavigationType = replace2 === true || redirect2.response.headers.has("X-Remix-Replace") ? "REPLACE" /* Replace */ : "PUSH" /* Push */;
2722 let { formMethod, formAction, formEncType } = state.navigation;
2723 if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) {
2724 submission = getSubmissionFromNavigation(state.navigation);
2725 }
2726 let activeSubmission = submission || fetcherSubmission;
2727 if (redirectPreserveMethodStatusCodes.has(redirect2.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) {
2728 await startNavigation(redirectNavigationType, redirectLocation, {
2729 submission: {
2730 ...activeSubmission,
2731 formAction: location
2732 },
2733 // Preserve these flags across redirects
2734 preventScrollReset: preventScrollReset || pendingPreventScrollReset,
2735 enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0
2736 });
2737 } else {
2738 let overrideNavigation = getLoadingNavigation(
2739 redirectLocation,
2740 submission
2741 );
2742 await startNavigation(redirectNavigationType, redirectLocation, {
2743 overrideNavigation,
2744 // Send fetcher submissions through for shouldRevalidate
2745 fetcherSubmission,
2746 // Preserve these flags across redirects
2747 preventScrollReset: preventScrollReset || pendingPreventScrollReset,
2748 enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0
2749 });
2750 }
2751 }
2752 async function callDataStrategy(request, matches, scopedContext, fetcherKey) {
2753 let results;
2754 let dataResults = {};
2755 try {
2756 results = await callDataStrategyImpl(
2757 dataStrategyImpl,
2758 request,
2759 matches,
2760 fetcherKey,
2761 scopedContext,
2762 false
2763 );
2764 } catch (e) {
2765 matches.filter((m) => m.shouldLoad).forEach((m) => {
2766 dataResults[m.route.id] = {
2767 type: "error" /* error */,
2768 error: e
2769 };
2770 });
2771 return dataResults;
2772 }
2773 if (request.signal.aborted) {
2774 return dataResults;
2775 }
2776 if (!isMutationMethod(request.method)) {
2777 for (let match of matches) {
2778 if (_optionalChain([results, 'access', _26 => _26[match.route.id], 'optionalAccess', _27 => _27.type]) === "error" /* error */) {
2779 break;
2780 }
2781 if (!results.hasOwnProperty(match.route.id) && !state.loaderData.hasOwnProperty(match.route.id) && (!state.errors || !state.errors.hasOwnProperty(match.route.id)) && match.shouldCallHandler()) {
2782 results[match.route.id] = {
2783 type: "error" /* error */,
2784 result: new Error(
2785 `No result returned from dataStrategy for route ${match.route.id}`
2786 )
2787 };
2788 }
2789 }
2790 }
2791 for (let [routeId, result] of Object.entries(results)) {
2792 if (isRedirectDataStrategyResult(result)) {
2793 let response = result.result;
2794 dataResults[routeId] = {
2795 type: "redirect" /* redirect */,
2796 response: normalizeRelativeRoutingRedirectResponse(
2797 response,
2798 request,
2799 routeId,
2800 matches,
2801 basename
2802 )
2803 };
2804 } else {
2805 dataResults[routeId] = await convertDataStrategyResultToDataResult(result);
2806 }
2807 }
2808 return dataResults;
2809 }
2810 async function callLoadersAndMaybeResolveData(matches, fetchersToLoad, request, scopedContext) {
2811 let loaderResultsPromise = callDataStrategy(
2812 request,
2813 matches,
2814 scopedContext,
2815 null
2816 );
2817 let fetcherResultsPromise = Promise.all(
2818 fetchersToLoad.map(async (f) => {
2819 if (f.matches && f.match && f.request && f.controller) {
2820 let results = await callDataStrategy(
2821 f.request,
2822 f.matches,
2823 scopedContext,
2824 f.key
2825 );
2826 let result = results[f.match.route.id];
2827 return { [f.key]: result };
2828 } else {
2829 return Promise.resolve({
2830 [f.key]: {
2831 type: "error" /* error */,
2832 error: getInternalRouterError(404, {
2833 pathname: f.path
2834 })
2835 }
2836 });
2837 }
2838 })
2839 );
2840 let loaderResults = await loaderResultsPromise;
2841 let fetcherResults = (await fetcherResultsPromise).reduce(
2842 (acc, r) => Object.assign(acc, r),
2843 {}
2844 );
2845 return {
2846 loaderResults,
2847 fetcherResults
2848 };
2849 }
2850 function interruptActiveLoads() {
2851 isRevalidationRequired = true;
2852 fetchLoadMatches.forEach((_, key) => {
2853 if (fetchControllers.has(key)) {
2854 cancelledFetcherLoads.add(key);
2855 }
2856 abortFetcher(key);
2857 });
2858 }
2859 function updateFetcherState(key, fetcher, opts = {}) {
2860 state.fetchers.set(key, fetcher);
2861 updateState(
2862 { fetchers: new Map(state.fetchers) },
2863 { flushSync: (opts && opts.flushSync) === true }
2864 );
2865 }
2866 function setFetcherError(key, routeId, error, opts = {}) {
2867 let boundaryMatch = findNearestBoundary(state.matches, routeId);
2868 deleteFetcher(key);
2869 updateState(
2870 {
2871 errors: {
2872 [boundaryMatch.route.id]: error
2873 },
2874 fetchers: new Map(state.fetchers)
2875 },
2876 { flushSync: (opts && opts.flushSync) === true }
2877 );
2878 }
2879 function getFetcher(key) {
2880 activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);
2881 if (fetchersQueuedForDeletion.has(key)) {
2882 fetchersQueuedForDeletion.delete(key);
2883 }
2884 return state.fetchers.get(key) || IDLE_FETCHER;
2885 }
2886 function resetFetcher(key, opts) {
2887 abortFetcher(key, _optionalChain([opts, 'optionalAccess', _28 => _28.reason]));
2888 updateFetcherState(key, getDoneFetcher(null));
2889 }
2890 function deleteFetcher(key) {
2891 let fetcher = state.fetchers.get(key);
2892 if (fetchControllers.has(key) && !(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key))) {
2893 abortFetcher(key);
2894 }
2895 fetchLoadMatches.delete(key);
2896 fetchReloadIds.delete(key);
2897 fetchRedirectIds.delete(key);
2898 fetchersQueuedForDeletion.delete(key);
2899 cancelledFetcherLoads.delete(key);
2900 state.fetchers.delete(key);
2901 }
2902 function queueFetcherForDeletion(key) {
2903 let count = (activeFetchers.get(key) || 0) - 1;
2904 if (count <= 0) {
2905 activeFetchers.delete(key);
2906 fetchersQueuedForDeletion.add(key);
2907 } else {
2908 activeFetchers.set(key, count);
2909 }
2910 updateState({ fetchers: new Map(state.fetchers) });
2911 }
2912 function abortFetcher(key, reason) {
2913 let controller = fetchControllers.get(key);
2914 if (controller) {
2915 controller.abort(reason);
2916 fetchControllers.delete(key);
2917 }
2918 }
2919 function markFetchersDone(keys) {
2920 for (let key of keys) {
2921 let fetcher = getFetcher(key);
2922 let doneFetcher = getDoneFetcher(fetcher.data);
2923 state.fetchers.set(key, doneFetcher);
2924 }
2925 }
2926 function markFetchRedirectsDone() {
2927 let doneKeys = [];
2928 let updatedFetchers = false;
2929 for (let key of fetchRedirectIds) {
2930 let fetcher = state.fetchers.get(key);
2931 invariant(fetcher, `Expected fetcher: ${key}`);
2932 if (fetcher.state === "loading") {
2933 fetchRedirectIds.delete(key);
2934 doneKeys.push(key);
2935 updatedFetchers = true;
2936 }
2937 }
2938 markFetchersDone(doneKeys);
2939 return updatedFetchers;
2940 }
2941 function abortStaleFetchLoads(landedId) {
2942 let yeetedKeys = [];
2943 for (let [key, id] of fetchReloadIds) {
2944 if (id < landedId) {
2945 let fetcher = state.fetchers.get(key);
2946 invariant(fetcher, `Expected fetcher: ${key}`);
2947 if (fetcher.state === "loading") {
2948 abortFetcher(key);
2949 fetchReloadIds.delete(key);
2950 yeetedKeys.push(key);
2951 }
2952 }
2953 }
2954 markFetchersDone(yeetedKeys);
2955 return yeetedKeys.length > 0;
2956 }
2957 function getBlocker(key, fn) {
2958 let blocker = state.blockers.get(key) || IDLE_BLOCKER;
2959 if (blockerFunctions.get(key) !== fn) {
2960 blockerFunctions.set(key, fn);
2961 }
2962 return blocker;
2963 }
2964 function deleteBlocker(key) {
2965 state.blockers.delete(key);
2966 blockerFunctions.delete(key);
2967 }
2968 function updateBlocker(key, newBlocker) {
2969 let blocker = state.blockers.get(key) || IDLE_BLOCKER;
2970 invariant(
2971 blocker.state === "unblocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "proceeding" || blocker.state === "blocked" && newBlocker.state === "unblocked" || blocker.state === "proceeding" && newBlocker.state === "unblocked",
2972 `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}`
2973 );
2974 let blockers = new Map(state.blockers);
2975 blockers.set(key, newBlocker);
2976 updateState({ blockers });
2977 }
2978 function shouldBlockNavigation({
2979 currentLocation,
2980 nextLocation,
2981 historyAction
2982 }) {
2983 if (blockerFunctions.size === 0) {
2984 return;
2985 }
2986 if (blockerFunctions.size > 1) {
2987 warning(false, "A router only supports one blocker at a time");
2988 }
2989 let entries = Array.from(blockerFunctions.entries());
2990 let [blockerKey, blockerFunction] = entries[entries.length - 1];
2991 let blocker = state.blockers.get(blockerKey);
2992 if (blocker && blocker.state === "proceeding") {
2993 return;
2994 }
2995 if (blockerFunction({ currentLocation, nextLocation, historyAction })) {
2996 return blockerKey;
2997 }
2998 }
2999 function handleNavigational404(pathname) {
3000 let error = getInternalRouterError(404, { pathname });
3001 let routesToUse = inFlightDataRoutes || dataRoutes;
3002 let { matches, route } = getShortCircuitMatches(routesToUse);
3003 return { notFoundMatches: matches, route, error };
3004 }
3005 function enableScrollRestoration(positions, getPosition, getKey) {
3006 savedScrollPositions = positions;
3007 getScrollPosition = getPosition;
3008 getScrollRestorationKey = getKey || null;
3009 if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {
3010 initialScrollRestored = true;
3011 let y = getSavedScrollPosition(state.location, state.matches);
3012 if (y != null) {
3013 updateState({ restoreScrollPosition: y });
3014 }
3015 }
3016 return () => {
3017 savedScrollPositions = null;
3018 getScrollPosition = null;
3019 getScrollRestorationKey = null;
3020 };
3021 }
3022 function getScrollKey(location, matches) {
3023 if (getScrollRestorationKey) {
3024 let key = getScrollRestorationKey(
3025 location,
3026 matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData))
3027 );
3028 return key || location.key;
3029 }
3030 return location.key;
3031 }
3032 function saveScrollPosition(location, matches) {
3033 if (savedScrollPositions && getScrollPosition) {
3034 let key = getScrollKey(location, matches);
3035 savedScrollPositions[key] = getScrollPosition();
3036 }
3037 }
3038 function getSavedScrollPosition(location, matches) {
3039 if (savedScrollPositions) {
3040 let key = getScrollKey(location, matches);
3041 let y = savedScrollPositions[key];
3042 if (typeof y === "number") {
3043 return y;
3044 }
3045 }
3046 return null;
3047 }
3048 function checkFogOfWar(matches, routesToUse, pathname) {
3049 if (init.patchRoutesOnNavigation) {
3050 if (!matches) {
3051 let fogMatches = matchRoutesImpl(
3052 routesToUse,
3053 pathname,
3054 basename,
3055 true
3056 );
3057 return { active: true, matches: fogMatches || [] };
3058 } else {
3059 if (Object.keys(matches[0].params).length > 0) {
3060 let partialMatches = matchRoutesImpl(
3061 routesToUse,
3062 pathname,
3063 basename,
3064 true
3065 );
3066 return { active: true, matches: partialMatches };
3067 }
3068 }
3069 }
3070 return { active: false, matches: null };
3071 }
3072 async function discoverRoutes(matches, pathname, signal, fetcherKey) {
3073 if (!init.patchRoutesOnNavigation) {
3074 return { type: "success", matches };
3075 }
3076 let partialMatches = matches;
3077 while (true) {
3078 let isNonHMR = inFlightDataRoutes == null;
3079 let routesToUse = inFlightDataRoutes || dataRoutes;
3080 let localManifest = manifest;
3081 try {
3082 await init.patchRoutesOnNavigation({
3083 signal,
3084 path: pathname,
3085 matches: partialMatches,
3086 fetcherKey,
3087 patch: (routeId, children) => {
3088 if (signal.aborted) return;
3089 patchRoutesImpl(
3090 routeId,
3091 children,
3092 routesToUse,
3093 localManifest,
3094 mapRouteProperties2,
3095 false
3096 );
3097 }
3098 });
3099 } catch (e) {
3100 return { type: "error", error: e, partialMatches };
3101 } finally {
3102 if (isNonHMR && !signal.aborted) {
3103 dataRoutes = [...dataRoutes];
3104 }
3105 }
3106 if (signal.aborted) {
3107 return { type: "aborted" };
3108 }
3109 let newMatches = matchRoutes(routesToUse, pathname, basename);
3110 let newPartialMatches = null;
3111 if (newMatches) {
3112 if (Object.keys(newMatches[0].params).length === 0) {
3113 return { type: "success", matches: newMatches };
3114 } else {
3115 newPartialMatches = matchRoutesImpl(
3116 routesToUse,
3117 pathname,
3118 basename,
3119 true
3120 );
3121 let matchedDeeper = newPartialMatches && partialMatches.length < newPartialMatches.length && compareMatches(
3122 partialMatches,
3123 newPartialMatches.slice(0, partialMatches.length)
3124 );
3125 if (!matchedDeeper) {
3126 return { type: "success", matches: newMatches };
3127 }
3128 }
3129 }
3130 if (!newPartialMatches) {
3131 newPartialMatches = matchRoutesImpl(
3132 routesToUse,
3133 pathname,
3134 basename,
3135 true
3136 );
3137 }
3138 if (!newPartialMatches || compareMatches(partialMatches, newPartialMatches)) {
3139 return { type: "success", matches: null };
3140 }
3141 partialMatches = newPartialMatches;
3142 }
3143 }
3144 function compareMatches(a, b) {
3145 return a.length === b.length && a.every((m, i) => m.route.id === b[i].route.id);
3146 }
3147 function _internalSetRoutes(newRoutes) {
3148 manifest = {};
3149 inFlightDataRoutes = convertRoutesToDataRoutes(
3150 newRoutes,
3151 mapRouteProperties2,
3152 void 0,
3153 manifest
3154 );
3155 }
3156 function patchRoutes(routeId, children, unstable_allowElementMutations = false) {
3157 let isNonHMR = inFlightDataRoutes == null;
3158 let routesToUse = inFlightDataRoutes || dataRoutes;
3159 patchRoutesImpl(
3160 routeId,
3161 children,
3162 routesToUse,
3163 manifest,
3164 mapRouteProperties2,
3165 unstable_allowElementMutations
3166 );
3167 if (isNonHMR) {
3168 dataRoutes = [...dataRoutes];
3169 updateState({});
3170 }
3171 }
3172 router = {
3173 get basename() {
3174 return basename;
3175 },
3176 get future() {
3177 return future;
3178 },
3179 get state() {
3180 return state;
3181 },
3182 get routes() {
3183 return dataRoutes;
3184 },
3185 get window() {
3186 return routerWindow;
3187 },
3188 initialize,
3189 subscribe,
3190 enableScrollRestoration,
3191 navigate,
3192 fetch: fetch2,
3193 revalidate,
3194 // Passthrough to history-aware createHref used by useHref so we get proper
3195 // hash-aware URLs in DOM paths
3196 createHref: (to) => init.history.createHref(to),
3197 encodeLocation: (to) => init.history.encodeLocation(to),
3198 getFetcher,
3199 resetFetcher,
3200 deleteFetcher: queueFetcherForDeletion,
3201 dispose,
3202 getBlocker,
3203 deleteBlocker,
3204 patchRoutes,
3205 _internalFetchControllers: fetchControllers,
3206 // TODO: Remove setRoutes, it's temporary to avoid dealing with
3207 // updating the tree while validating the update algorithm.
3208 _internalSetRoutes,
3209 _internalSetStateDoNotUseOrYouWillBreakYourApp(newState) {
3210 updateState(newState);
3211 }
3212 };
3213 if (init.unstable_instrumentations) {
3214 router = instrumentClientSideRouter(
3215 router,
3216 init.unstable_instrumentations.map((i) => i.router).filter(Boolean)
3217 );
3218 }
3219 return router;
3220}
3221function createStaticHandler(routes, opts) {
3222 invariant(
3223 routes.length > 0,
3224 "You must provide a non-empty routes array to createStaticHandler"
3225 );
3226 let manifest = {};
3227 let basename = (opts ? opts.basename : null) || "/";
3228 let _mapRouteProperties = _optionalChain([opts, 'optionalAccess', _29 => _29.mapRouteProperties]) || defaultMapRouteProperties;
3229 let mapRouteProperties2 = _mapRouteProperties;
3230 if (_optionalChain([opts, 'optionalAccess', _30 => _30.unstable_instrumentations])) {
3231 let instrumentations = opts.unstable_instrumentations;
3232 mapRouteProperties2 = (route) => {
3233 return {
3234 ..._mapRouteProperties(route),
3235 ...getRouteInstrumentationUpdates(
3236 instrumentations.map((i) => i.route).filter(Boolean),
3237 route
3238 )
3239 };
3240 };
3241 }
3242 let dataRoutes = convertRoutesToDataRoutes(
3243 routes,
3244 mapRouteProperties2,
3245 void 0,
3246 manifest
3247 );
3248 async function query(request, {
3249 requestContext,
3250 filterMatchesToLoad,
3251 skipLoaderErrorBubbling,
3252 skipRevalidation,
3253 dataStrategy,
3254 generateMiddlewareResponse
3255 } = {}) {
3256 let url = new URL(request.url);
3257 let method = request.method;
3258 let location = createLocation("", createPath(url), null, "default");
3259 let matches = matchRoutes(dataRoutes, location, basename);
3260 requestContext = requestContext != null ? requestContext : new RouterContextProvider();
3261 if (!isValidMethod(method) && method !== "HEAD") {
3262 let error = getInternalRouterError(405, { method });
3263 let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes);
3264 let staticContext = {
3265 basename,
3266 location,
3267 matches: methodNotAllowedMatches,
3268 loaderData: {},
3269 actionData: null,
3270 errors: {
3271 [route.id]: error
3272 },
3273 statusCode: error.status,
3274 loaderHeaders: {},
3275 actionHeaders: {}
3276 };
3277 return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;
3278 } else if (!matches) {
3279 let error = getInternalRouterError(404, { pathname: location.pathname });
3280 let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes);
3281 let staticContext = {
3282 basename,
3283 location,
3284 matches: notFoundMatches,
3285 loaderData: {},
3286 actionData: null,
3287 errors: {
3288 [route.id]: error
3289 },
3290 statusCode: error.status,
3291 loaderHeaders: {},
3292 actionHeaders: {}
3293 };
3294 return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;
3295 }
3296 if (generateMiddlewareResponse) {
3297 invariant(
3298 requestContext instanceof RouterContextProvider,
3299 "When using middleware in `staticHandler.query()`, any provided `requestContext` must be an instance of `RouterContextProvider`"
3300 );
3301 try {
3302 await loadLazyMiddlewareForMatches(
3303 matches,
3304 manifest,
3305 mapRouteProperties2
3306 );
3307 let renderedStaticContext;
3308 let response = await runServerMiddlewarePipeline(
3309 {
3310 request,
3311 unstable_pattern: getRoutePattern(matches),
3312 matches,
3313 params: matches[0].params,
3314 // If we're calling middleware then it must be enabled so we can cast
3315 // this to the proper type knowing it's not an `AppLoadContext`
3316 context: requestContext
3317 },
3318 async () => {
3319 let res = await generateMiddlewareResponse(
3320 async (revalidationRequest, opts2 = {}) => {
3321 let result2 = await queryImpl(
3322 revalidationRequest,
3323 location,
3324 matches,
3325 requestContext,
3326 dataStrategy || null,
3327 skipLoaderErrorBubbling === true,
3328 null,
3329 "filterMatchesToLoad" in opts2 ? _nullishCoalesce(opts2.filterMatchesToLoad, () => ( null)) : _nullishCoalesce(filterMatchesToLoad, () => ( null)),
3330 skipRevalidation === true
3331 );
3332 if (isResponse(result2)) {
3333 return result2;
3334 }
3335 renderedStaticContext = { location, basename, ...result2 };
3336 return renderedStaticContext;
3337 }
3338 );
3339 return res;
3340 },
3341 async (error, routeId) => {
3342 if (isRedirectResponse(error)) {
3343 return error;
3344 }
3345 if (isResponse(error)) {
3346 try {
3347 error = new ErrorResponseImpl(
3348 error.status,
3349 error.statusText,
3350 await parseResponseBody(error)
3351 );
3352 } catch (e) {
3353 error = e;
3354 }
3355 }
3356 if (isDataWithResponseInit(error)) {
3357 error = dataWithResponseInitToErrorResponse(error);
3358 }
3359 if (renderedStaticContext) {
3360 if (routeId in renderedStaticContext.loaderData) {
3361 renderedStaticContext.loaderData[routeId] = void 0;
3362 }
3363 let staticContext = getStaticContextFromError(
3364 dataRoutes,
3365 renderedStaticContext,
3366 error,
3367 skipLoaderErrorBubbling ? routeId : findNearestBoundary(matches, routeId).route.id
3368 );
3369 return generateMiddlewareResponse(
3370 () => Promise.resolve(staticContext)
3371 );
3372 } else {
3373 let boundaryRouteId = skipLoaderErrorBubbling ? routeId : findNearestBoundary(
3374 matches,
3375 _optionalChain([matches, 'access', _31 => _31.find, 'call', _32 => _32(
3376 (m) => m.route.id === routeId || m.route.loader
3377 ), 'optionalAccess', _33 => _33.route, 'access', _34 => _34.id]) || routeId
3378 ).route.id;
3379 let staticContext = {
3380 matches,
3381 location,
3382 basename,
3383 loaderData: {},
3384 actionData: null,
3385 errors: {
3386 [boundaryRouteId]: error
3387 },
3388 statusCode: isRouteErrorResponse(error) ? error.status : 500,
3389 actionHeaders: {},
3390 loaderHeaders: {}
3391 };
3392 return generateMiddlewareResponse(
3393 () => Promise.resolve(staticContext)
3394 );
3395 }
3396 }
3397 );
3398 invariant(isResponse(response), "Expected a response in query()");
3399 return response;
3400 } catch (e) {
3401 if (isResponse(e)) {
3402 return e;
3403 }
3404 throw e;
3405 }
3406 }
3407 let result = await queryImpl(
3408 request,
3409 location,
3410 matches,
3411 requestContext,
3412 dataStrategy || null,
3413 skipLoaderErrorBubbling === true,
3414 null,
3415 filterMatchesToLoad || null,
3416 skipRevalidation === true
3417 );
3418 if (isResponse(result)) {
3419 return result;
3420 }
3421 return { location, basename, ...result };
3422 }
3423 async function queryRoute(request, {
3424 routeId,
3425 requestContext,
3426 dataStrategy,
3427 generateMiddlewareResponse
3428 } = {}) {
3429 let url = new URL(request.url);
3430 let method = request.method;
3431 let location = createLocation("", createPath(url), null, "default");
3432 let matches = matchRoutes(dataRoutes, location, basename);
3433 requestContext = requestContext != null ? requestContext : new RouterContextProvider();
3434 if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") {
3435 throw getInternalRouterError(405, { method });
3436 } else if (!matches) {
3437 throw getInternalRouterError(404, { pathname: location.pathname });
3438 }
3439 let match = routeId ? matches.find((m) => m.route.id === routeId) : getTargetMatch(matches, location);
3440 if (routeId && !match) {
3441 throw getInternalRouterError(403, {
3442 pathname: location.pathname,
3443 routeId
3444 });
3445 } else if (!match) {
3446 throw getInternalRouterError(404, { pathname: location.pathname });
3447 }
3448 if (generateMiddlewareResponse) {
3449 invariant(
3450 requestContext instanceof RouterContextProvider,
3451 "When using middleware in `staticHandler.queryRoute()`, any provided `requestContext` must be an instance of `RouterContextProvider`"
3452 );
3453 await loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2);
3454 let response = await runServerMiddlewarePipeline(
3455 {
3456 request,
3457 unstable_pattern: getRoutePattern(matches),
3458 matches,
3459 params: matches[0].params,
3460 // If we're calling middleware then it must be enabled so we can cast
3461 // this to the proper type knowing it's not an `AppLoadContext`
3462 context: requestContext
3463 },
3464 async () => {
3465 let res = await generateMiddlewareResponse(
3466 async (innerRequest) => {
3467 let result2 = await queryImpl(
3468 innerRequest,
3469 location,
3470 matches,
3471 requestContext,
3472 dataStrategy || null,
3473 false,
3474 match,
3475 null,
3476 false
3477 );
3478 let processed = handleQueryResult(result2);
3479 return isResponse(processed) ? processed : typeof processed === "string" ? new Response(processed) : Response.json(processed);
3480 }
3481 );
3482 return res;
3483 },
3484 (error) => {
3485 if (isDataWithResponseInit(error)) {
3486 return Promise.resolve(dataWithResponseInitToResponse(error));
3487 }
3488 if (isResponse(error)) {
3489 return Promise.resolve(error);
3490 }
3491 throw error;
3492 }
3493 );
3494 return response;
3495 }
3496 let result = await queryImpl(
3497 request,
3498 location,
3499 matches,
3500 requestContext,
3501 dataStrategy || null,
3502 false,
3503 match,
3504 null,
3505 false
3506 );
3507 return handleQueryResult(result);
3508 function handleQueryResult(result2) {
3509 if (isResponse(result2)) {
3510 return result2;
3511 }
3512 let error = result2.errors ? Object.values(result2.errors)[0] : void 0;
3513 if (error !== void 0) {
3514 throw error;
3515 }
3516 if (result2.actionData) {
3517 return Object.values(result2.actionData)[0];
3518 }
3519 if (result2.loaderData) {
3520 return Object.values(result2.loaderData)[0];
3521 }
3522 return void 0;
3523 }
3524 }
3525 async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, skipRevalidation) {
3526 invariant(
3527 request.signal,
3528 "query()/queryRoute() requests must contain an AbortController signal"
3529 );
3530 try {
3531 if (isMutationMethod(request.method)) {
3532 let result2 = await submit(
3533 request,
3534 matches,
3535 routeMatch || getTargetMatch(matches, location),
3536 requestContext,
3537 dataStrategy,
3538 skipLoaderErrorBubbling,
3539 routeMatch != null,
3540 filterMatchesToLoad,
3541 skipRevalidation
3542 );
3543 return result2;
3544 }
3545 let result = await loadRouteData(
3546 request,
3547 matches,
3548 requestContext,
3549 dataStrategy,
3550 skipLoaderErrorBubbling,
3551 routeMatch,
3552 filterMatchesToLoad
3553 );
3554 return isResponse(result) ? result : {
3555 ...result,
3556 actionData: null,
3557 actionHeaders: {}
3558 };
3559 } catch (e) {
3560 if (isDataStrategyResult(e) && isResponse(e.result)) {
3561 if (e.type === "error" /* error */) {
3562 throw e.result;
3563 }
3564 return e.result;
3565 }
3566 if (isRedirectResponse(e)) {
3567 return e;
3568 }
3569 throw e;
3570 }
3571 }
3572 async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest, filterMatchesToLoad, skipRevalidation) {
3573 let result;
3574 if (!actionMatch.route.action && !actionMatch.route.lazy) {
3575 let error = getInternalRouterError(405, {
3576 method: request.method,
3577 pathname: new URL(request.url).pathname,
3578 routeId: actionMatch.route.id
3579 });
3580 if (isRouteRequest) {
3581 throw error;
3582 }
3583 result = {
3584 type: "error" /* error */,
3585 error
3586 };
3587 } else {
3588 let dsMatches = getTargetedDataStrategyMatches(
3589 mapRouteProperties2,
3590 manifest,
3591 request,
3592 matches,
3593 actionMatch,
3594 [],
3595 requestContext
3596 );
3597 let results = await callDataStrategy(
3598 request,
3599 dsMatches,
3600 isRouteRequest,
3601 requestContext,
3602 dataStrategy
3603 );
3604 result = results[actionMatch.route.id];
3605 if (request.signal.aborted) {
3606 throwStaticHandlerAbortedError(request, isRouteRequest);
3607 }
3608 }
3609 if (isRedirectResult(result)) {
3610 throw new Response(null, {
3611 status: result.response.status,
3612 headers: {
3613 Location: result.response.headers.get("Location")
3614 }
3615 });
3616 }
3617 if (isRouteRequest) {
3618 if (isErrorResult(result)) {
3619 throw result.error;
3620 }
3621 return {
3622 matches: [actionMatch],
3623 loaderData: {},
3624 actionData: { [actionMatch.route.id]: result.data },
3625 errors: null,
3626 // Note: statusCode + headers are unused here since queryRoute will
3627 // return the raw Response or value
3628 statusCode: 200,
3629 loaderHeaders: {},
3630 actionHeaders: {}
3631 };
3632 }
3633 if (skipRevalidation) {
3634 if (isErrorResult(result)) {
3635 let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
3636 return {
3637 statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
3638 actionData: null,
3639 actionHeaders: {
3640 ...result.headers ? { [actionMatch.route.id]: result.headers } : {}
3641 },
3642 matches,
3643 loaderData: {},
3644 errors: {
3645 [boundaryMatch.route.id]: result.error
3646 },
3647 loaderHeaders: {}
3648 };
3649 } else {
3650 return {
3651 actionData: {
3652 [actionMatch.route.id]: result.data
3653 },
3654 actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {},
3655 matches,
3656 loaderData: {},
3657 errors: null,
3658 statusCode: result.statusCode || 200,
3659 loaderHeaders: {}
3660 };
3661 }
3662 }
3663 let loaderRequest = new Request(request.url, {
3664 headers: request.headers,
3665 redirect: request.redirect,
3666 signal: request.signal
3667 });
3668 if (isErrorResult(result)) {
3669 let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
3670 let handlerContext2 = await loadRouteData(
3671 loaderRequest,
3672 matches,
3673 requestContext,
3674 dataStrategy,
3675 skipLoaderErrorBubbling,
3676 null,
3677 filterMatchesToLoad,
3678 [boundaryMatch.route.id, result]
3679 );
3680 return {
3681 ...handlerContext2,
3682 statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
3683 actionData: null,
3684 actionHeaders: {
3685 ...result.headers ? { [actionMatch.route.id]: result.headers } : {}
3686 }
3687 };
3688 }
3689 let handlerContext = await loadRouteData(
3690 loaderRequest,
3691 matches,
3692 requestContext,
3693 dataStrategy,
3694 skipLoaderErrorBubbling,
3695 null,
3696 filterMatchesToLoad
3697 );
3698 return {
3699 ...handlerContext,
3700 actionData: {
3701 [actionMatch.route.id]: result.data
3702 },
3703 // action status codes take precedence over loader status codes
3704 ...result.statusCode ? { statusCode: result.statusCode } : {},
3705 actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {}
3706 };
3707 }
3708 async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, pendingActionResult) {
3709 let isRouteRequest = routeMatch != null;
3710 if (isRouteRequest && !_optionalChain([routeMatch, 'optionalAccess', _35 => _35.route, 'access', _36 => _36.loader]) && !_optionalChain([routeMatch, 'optionalAccess', _37 => _37.route, 'access', _38 => _38.lazy])) {
3711 throw getInternalRouterError(400, {
3712 method: request.method,
3713 pathname: new URL(request.url).pathname,
3714 routeId: _optionalChain([routeMatch, 'optionalAccess', _39 => _39.route, 'access', _40 => _40.id])
3715 });
3716 }
3717 let dsMatches;
3718 if (routeMatch) {
3719 dsMatches = getTargetedDataStrategyMatches(
3720 mapRouteProperties2,
3721 manifest,
3722 request,
3723 matches,
3724 routeMatch,
3725 [],
3726 requestContext
3727 );
3728 } else {
3729 let maxIdx = pendingActionResult && isErrorResult(pendingActionResult[1]) ? (
3730 // Up to but not including the boundary
3731 matches.findIndex((m) => m.route.id === pendingActionResult[0]) - 1
3732 ) : void 0;
3733 let pattern = getRoutePattern(matches);
3734 dsMatches = matches.map((match, index) => {
3735 if (maxIdx != null && index > maxIdx) {
3736 return getDataStrategyMatch(
3737 mapRouteProperties2,
3738 manifest,
3739 request,
3740 pattern,
3741 match,
3742 [],
3743 requestContext,
3744 false
3745 );
3746 }
3747 return getDataStrategyMatch(
3748 mapRouteProperties2,
3749 manifest,
3750 request,
3751 pattern,
3752 match,
3753 [],
3754 requestContext,
3755 (match.route.loader || match.route.lazy) != null && (!filterMatchesToLoad || filterMatchesToLoad(match))
3756 );
3757 });
3758 }
3759 if (!dataStrategy && !dsMatches.some((m) => m.shouldLoad)) {
3760 return {
3761 matches,
3762 loaderData: {},
3763 errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? {
3764 [pendingActionResult[0]]: pendingActionResult[1].error
3765 } : null,
3766 statusCode: 200,
3767 loaderHeaders: {}
3768 };
3769 }
3770 let results = await callDataStrategy(
3771 request,
3772 dsMatches,
3773 isRouteRequest,
3774 requestContext,
3775 dataStrategy
3776 );
3777 if (request.signal.aborted) {
3778 throwStaticHandlerAbortedError(request, isRouteRequest);
3779 }
3780 let handlerContext = processRouteLoaderData(
3781 matches,
3782 results,
3783 pendingActionResult,
3784 true,
3785 skipLoaderErrorBubbling
3786 );
3787 return {
3788 ...handlerContext,
3789 matches
3790 };
3791 }
3792 async function callDataStrategy(request, matches, isRouteRequest, requestContext, dataStrategy) {
3793 let results = await callDataStrategyImpl(
3794 dataStrategy || defaultDataStrategy,
3795 request,
3796 matches,
3797 null,
3798 requestContext,
3799 true
3800 );
3801 let dataResults = {};
3802 await Promise.all(
3803 matches.map(async (match) => {
3804 if (!(match.route.id in results)) {
3805 return;
3806 }
3807 let result = results[match.route.id];
3808 if (isRedirectDataStrategyResult(result)) {
3809 let response = result.result;
3810 throw normalizeRelativeRoutingRedirectResponse(
3811 response,
3812 request,
3813 match.route.id,
3814 matches,
3815 basename
3816 );
3817 }
3818 if (isRouteRequest) {
3819 if (isResponse(result.result)) {
3820 throw result;
3821 } else if (isDataWithResponseInit(result.result)) {
3822 throw dataWithResponseInitToResponse(result.result);
3823 }
3824 }
3825 dataResults[match.route.id] = await convertDataStrategyResultToDataResult(result);
3826 })
3827 );
3828 return dataResults;
3829 }
3830 return {
3831 dataRoutes,
3832 query,
3833 queryRoute
3834 };
3835}
3836function getStaticContextFromError(routes, handlerContext, error, boundaryId) {
3837 let errorBoundaryId = boundaryId || handlerContext._deepestRenderedBoundaryId || routes[0].id;
3838 return {
3839 ...handlerContext,
3840 statusCode: isRouteErrorResponse(error) ? error.status : 500,
3841 errors: {
3842 [errorBoundaryId]: error
3843 }
3844 };
3845}
3846function throwStaticHandlerAbortedError(request, isRouteRequest) {
3847 if (request.signal.reason !== void 0) {
3848 throw request.signal.reason;
3849 }
3850 let method = isRouteRequest ? "queryRoute" : "query";
3851 throw new Error(
3852 `${method}() call aborted without an \`AbortSignal.reason\`: ${request.method} ${request.url}`
3853 );
3854}
3855function isSubmissionNavigation(opts) {
3856 return opts != null && ("formData" in opts && opts.formData != null || "body" in opts && opts.body !== void 0);
3857}
3858function normalizeTo(location, matches, basename, to, fromRouteId, relative) {
3859 let contextualMatches;
3860 let activeRouteMatch;
3861 if (fromRouteId) {
3862 contextualMatches = [];
3863 for (let match of matches) {
3864 contextualMatches.push(match);
3865 if (match.route.id === fromRouteId) {
3866 activeRouteMatch = match;
3867 break;
3868 }
3869 }
3870 } else {
3871 contextualMatches = matches;
3872 activeRouteMatch = matches[matches.length - 1];
3873 }
3874 let path = resolveTo(
3875 to ? to : ".",
3876 getResolveToMatches(contextualMatches),
3877 stripBasename(location.pathname, basename) || location.pathname,
3878 relative === "path"
3879 );
3880 if (to == null) {
3881 path.search = location.search;
3882 path.hash = location.hash;
3883 }
3884 if ((to == null || to === "" || to === ".") && activeRouteMatch) {
3885 let nakedIndex = hasNakedIndexQuery(path.search);
3886 if (activeRouteMatch.route.index && !nakedIndex) {
3887 path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
3888 } else if (!activeRouteMatch.route.index && nakedIndex) {
3889 let params = new URLSearchParams(path.search);
3890 let indexValues = params.getAll("index");
3891 params.delete("index");
3892 indexValues.filter((v) => v).forEach((v) => params.append("index", v));
3893 let qs = params.toString();
3894 path.search = qs ? `?${qs}` : "";
3895 }
3896 }
3897 if (basename !== "/") {
3898 path.pathname = prependBasename({ basename, pathname: path.pathname });
3899 }
3900 return createPath(path);
3901}
3902function normalizeNavigateOptions(isFetcher, path, opts) {
3903 if (!opts || !isSubmissionNavigation(opts)) {
3904 return { path };
3905 }
3906 if (opts.formMethod && !isValidMethod(opts.formMethod)) {
3907 return {
3908 path,
3909 error: getInternalRouterError(405, { method: opts.formMethod })
3910 };
3911 }
3912 let getInvalidBodyError = () => ({
3913 path,
3914 error: getInternalRouterError(400, { type: "invalid-body" })
3915 });
3916 let rawFormMethod = opts.formMethod || "get";
3917 let formMethod = rawFormMethod.toUpperCase();
3918 let formAction = stripHashFromPath(path);
3919 if (opts.body !== void 0) {
3920 if (opts.formEncType === "text/plain") {
3921 if (!isMutationMethod(formMethod)) {
3922 return getInvalidBodyError();
3923 }
3924 let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? (
3925 // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data
3926 Array.from(opts.body.entries()).reduce(
3927 (acc, [name, value]) => `${acc}${name}=${value}
3928`,
3929 ""
3930 )
3931 ) : String(opts.body);
3932 return {
3933 path,
3934 submission: {
3935 formMethod,
3936 formAction,
3937 formEncType: opts.formEncType,
3938 formData: void 0,
3939 json: void 0,
3940 text
3941 }
3942 };
3943 } else if (opts.formEncType === "application/json") {
3944 if (!isMutationMethod(formMethod)) {
3945 return getInvalidBodyError();
3946 }
3947 try {
3948 let json = typeof opts.body === "string" ? JSON.parse(opts.body) : opts.body;
3949 return {
3950 path,
3951 submission: {
3952 formMethod,
3953 formAction,
3954 formEncType: opts.formEncType,
3955 formData: void 0,
3956 json,
3957 text: void 0
3958 }
3959 };
3960 } catch (e) {
3961 return getInvalidBodyError();
3962 }
3963 }
3964 }
3965 invariant(
3966 typeof FormData === "function",
3967 "FormData is not available in this environment"
3968 );
3969 let searchParams;
3970 let formData;
3971 if (opts.formData) {
3972 searchParams = convertFormDataToSearchParams(opts.formData);
3973 formData = opts.formData;
3974 } else if (opts.body instanceof FormData) {
3975 searchParams = convertFormDataToSearchParams(opts.body);
3976 formData = opts.body;
3977 } else if (opts.body instanceof URLSearchParams) {
3978 searchParams = opts.body;
3979 formData = convertSearchParamsToFormData(searchParams);
3980 } else if (opts.body == null) {
3981 searchParams = new URLSearchParams();
3982 formData = new FormData();
3983 } else {
3984 try {
3985 searchParams = new URLSearchParams(opts.body);
3986 formData = convertSearchParamsToFormData(searchParams);
3987 } catch (e) {
3988 return getInvalidBodyError();
3989 }
3990 }
3991 let submission = {
3992 formMethod,
3993 formAction,
3994 formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded",
3995 formData,
3996 json: void 0,
3997 text: void 0
3998 };
3999 if (isMutationMethod(submission.formMethod)) {
4000 return { path, submission };
4001 }
4002 let parsedPath = parsePath(path);
4003 if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {
4004 searchParams.append("index", "");
4005 }
4006 parsedPath.search = `?${searchParams}`;
4007 return { path: createPath(parsedPath), submission };
4008}
4009function getMatchesToLoad(request, scopedContext, mapRouteProperties2, manifest, history, state, matches, submission, location, lazyRoutePropertiesToSkip, initialHydration, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, hasPatchRoutesOnNavigation, pendingActionResult, callSiteDefaultShouldRevalidate) {
4010 let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : void 0;
4011 let currentUrl = history.createURL(state.location);
4012 let nextUrl = history.createURL(location);
4013 let maxIdx;
4014 if (initialHydration && state.errors) {
4015 let boundaryId = Object.keys(state.errors)[0];
4016 maxIdx = matches.findIndex((m) => m.route.id === boundaryId);
4017 } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) {
4018 let boundaryId = pendingActionResult[0];
4019 maxIdx = matches.findIndex((m) => m.route.id === boundaryId) - 1;
4020 }
4021 let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : void 0;
4022 let shouldSkipRevalidation = actionStatus && actionStatus >= 400;
4023 let baseShouldRevalidateArgs = {
4024 currentUrl,
4025 currentParams: _optionalChain([state, 'access', _41 => _41.matches, 'access', _42 => _42[0], 'optionalAccess', _43 => _43.params]) || {},
4026 nextUrl,
4027 nextParams: matches[0].params,
4028 ...submission,
4029 actionResult,
4030 actionStatus
4031 };
4032 let pattern = getRoutePattern(matches);
4033 let dsMatches = matches.map((match, index) => {
4034 let { route } = match;
4035 let forceShouldLoad = null;
4036 if (maxIdx != null && index > maxIdx) {
4037 forceShouldLoad = false;
4038 } else if (route.lazy) {
4039 forceShouldLoad = true;
4040 } else if (!routeHasLoaderOrMiddleware(route)) {
4041 forceShouldLoad = false;
4042 } else if (initialHydration) {
4043 let { shouldLoad: shouldLoad2 } = getRouteHydrationStatus(
4044 route,
4045 state.loaderData,
4046 state.errors
4047 );
4048 forceShouldLoad = shouldLoad2;
4049 } else if (isNewLoader(state.loaderData, state.matches[index], match)) {
4050 forceShouldLoad = true;
4051 }
4052 if (forceShouldLoad !== null) {
4053 return getDataStrategyMatch(
4054 mapRouteProperties2,
4055 manifest,
4056 request,
4057 pattern,
4058 match,
4059 lazyRoutePropertiesToSkip,
4060 scopedContext,
4061 forceShouldLoad
4062 );
4063 }
4064 let defaultShouldRevalidate = false;
4065 if (typeof callSiteDefaultShouldRevalidate === "boolean") {
4066 defaultShouldRevalidate = callSiteDefaultShouldRevalidate;
4067 } else if (shouldSkipRevalidation) {
4068 defaultShouldRevalidate = false;
4069 } else if (isRevalidationRequired) {
4070 defaultShouldRevalidate = true;
4071 } else if (currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search) {
4072 defaultShouldRevalidate = true;
4073 } else if (currentUrl.search !== nextUrl.search) {
4074 defaultShouldRevalidate = true;
4075 } else if (isNewRouteInstance(state.matches[index], match)) {
4076 defaultShouldRevalidate = true;
4077 }
4078 let shouldRevalidateArgs = {
4079 ...baseShouldRevalidateArgs,
4080 defaultShouldRevalidate
4081 };
4082 let shouldLoad = shouldRevalidateLoader(match, shouldRevalidateArgs);
4083 return getDataStrategyMatch(
4084 mapRouteProperties2,
4085 manifest,
4086 request,
4087 pattern,
4088 match,
4089 lazyRoutePropertiesToSkip,
4090 scopedContext,
4091 shouldLoad,
4092 shouldRevalidateArgs,
4093 callSiteDefaultShouldRevalidate
4094 );
4095 });
4096 let revalidatingFetchers = [];
4097 fetchLoadMatches.forEach((f, key) => {
4098 if (initialHydration || !matches.some((m) => m.route.id === f.routeId) || fetchersQueuedForDeletion.has(key)) {
4099 return;
4100 }
4101 let fetcher = state.fetchers.get(key);
4102 let isMidInitialLoad = fetcher && fetcher.state !== "idle" && fetcher.data === void 0;
4103 let fetcherMatches = matchRoutes(routesToUse, f.path, basename);
4104 if (!fetcherMatches) {
4105 if (hasPatchRoutesOnNavigation && isMidInitialLoad) {
4106 return;
4107 }
4108 revalidatingFetchers.push({
4109 key,
4110 routeId: f.routeId,
4111 path: f.path,
4112 matches: null,
4113 match: null,
4114 request: null,
4115 controller: null
4116 });
4117 return;
4118 }
4119 if (fetchRedirectIds.has(key)) {
4120 return;
4121 }
4122 let fetcherMatch = getTargetMatch(fetcherMatches, f.path);
4123 let fetchController = new AbortController();
4124 let fetchRequest = createClientSideRequest(
4125 history,
4126 f.path,
4127 fetchController.signal
4128 );
4129 let fetcherDsMatches = null;
4130 if (cancelledFetcherLoads.has(key)) {
4131 cancelledFetcherLoads.delete(key);
4132 fetcherDsMatches = getTargetedDataStrategyMatches(
4133 mapRouteProperties2,
4134 manifest,
4135 fetchRequest,
4136 fetcherMatches,
4137 fetcherMatch,
4138 lazyRoutePropertiesToSkip,
4139 scopedContext
4140 );
4141 } else if (isMidInitialLoad) {
4142 if (isRevalidationRequired) {
4143 fetcherDsMatches = getTargetedDataStrategyMatches(
4144 mapRouteProperties2,
4145 manifest,
4146 fetchRequest,
4147 fetcherMatches,
4148 fetcherMatch,
4149 lazyRoutePropertiesToSkip,
4150 scopedContext
4151 );
4152 }
4153 } else {
4154 let defaultShouldRevalidate;
4155 if (typeof callSiteDefaultShouldRevalidate === "boolean") {
4156 defaultShouldRevalidate = callSiteDefaultShouldRevalidate;
4157 } else if (shouldSkipRevalidation) {
4158 defaultShouldRevalidate = false;
4159 } else {
4160 defaultShouldRevalidate = isRevalidationRequired;
4161 }
4162 let shouldRevalidateArgs = {
4163 ...baseShouldRevalidateArgs,
4164 defaultShouldRevalidate
4165 };
4166 if (shouldRevalidateLoader(fetcherMatch, shouldRevalidateArgs)) {
4167 fetcherDsMatches = getTargetedDataStrategyMatches(
4168 mapRouteProperties2,
4169 manifest,
4170 fetchRequest,
4171 fetcherMatches,
4172 fetcherMatch,
4173 lazyRoutePropertiesToSkip,
4174 scopedContext,
4175 shouldRevalidateArgs
4176 );
4177 }
4178 }
4179 if (fetcherDsMatches) {
4180 revalidatingFetchers.push({
4181 key,
4182 routeId: f.routeId,
4183 path: f.path,
4184 matches: fetcherDsMatches,
4185 match: fetcherMatch,
4186 request: fetchRequest,
4187 controller: fetchController
4188 });
4189 }
4190 });
4191 return { dsMatches, revalidatingFetchers };
4192}
4193function routeHasLoaderOrMiddleware(route) {
4194 return route.loader != null || route.middleware != null && route.middleware.length > 0;
4195}
4196function getRouteHydrationStatus(route, loaderData, errors) {
4197 if (route.lazy) {
4198 return { shouldLoad: true, renderFallback: true };
4199 }
4200 if (!routeHasLoaderOrMiddleware(route)) {
4201 return { shouldLoad: false, renderFallback: false };
4202 }
4203 let hasData = loaderData != null && route.id in loaderData;
4204 let hasError = errors != null && errors[route.id] !== void 0;
4205 if (!hasData && hasError) {
4206 return { shouldLoad: false, renderFallback: false };
4207 }
4208 if (typeof route.loader === "function" && route.loader.hydrate === true) {
4209 return { shouldLoad: true, renderFallback: !hasData };
4210 }
4211 let shouldLoad = !hasData && !hasError;
4212 return { shouldLoad, renderFallback: shouldLoad };
4213}
4214function isNewLoader(currentLoaderData, currentMatch, match) {
4215 let isNew = (
4216 // [a] -> [a, b]
4217 !currentMatch || // [a, b] -> [a, c]
4218 match.route.id !== currentMatch.route.id
4219 );
4220 let isMissingData = !currentLoaderData.hasOwnProperty(match.route.id);
4221 return isNew || isMissingData;
4222}
4223function isNewRouteInstance(currentMatch, match) {
4224 let currentPath = currentMatch.route.path;
4225 return (
4226 // param change for this match, /users/123 -> /users/456
4227 currentMatch.pathname !== match.pathname || // splat param changed, which is not present in match.path
4228 // e.g. /files/images/avatar.jpg -> files/finances.xls
4229 currentPath != null && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"]
4230 );
4231}
4232function shouldRevalidateLoader(loaderMatch, arg) {
4233 if (loaderMatch.route.shouldRevalidate) {
4234 let routeChoice = loaderMatch.route.shouldRevalidate(arg);
4235 if (typeof routeChoice === "boolean") {
4236 return routeChoice;
4237 }
4238 }
4239 return arg.defaultShouldRevalidate;
4240}
4241function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties2, allowElementMutations) {
4242 let childrenToPatch;
4243 if (routeId) {
4244 let route = manifest[routeId];
4245 invariant(
4246 route,
4247 `No route found to patch children into: routeId = ${routeId}`
4248 );
4249 if (!route.children) {
4250 route.children = [];
4251 }
4252 childrenToPatch = route.children;
4253 } else {
4254 childrenToPatch = routesToUse;
4255 }
4256 let uniqueChildren = [];
4257 let existingChildren = [];
4258 children.forEach((newRoute) => {
4259 let existingRoute = childrenToPatch.find(
4260 (existingRoute2) => isSameRoute(newRoute, existingRoute2)
4261 );
4262 if (existingRoute) {
4263 existingChildren.push({ existingRoute, newRoute });
4264 } else {
4265 uniqueChildren.push(newRoute);
4266 }
4267 });
4268 if (uniqueChildren.length > 0) {
4269 let newRoutes = convertRoutesToDataRoutes(
4270 uniqueChildren,
4271 mapRouteProperties2,
4272 [routeId || "_", "patch", String(_optionalChain([childrenToPatch, 'optionalAccess', _44 => _44.length]) || "0")],
4273 manifest
4274 );
4275 childrenToPatch.push(...newRoutes);
4276 }
4277 if (allowElementMutations && existingChildren.length > 0) {
4278 for (let i = 0; i < existingChildren.length; i++) {
4279 let { existingRoute, newRoute } = existingChildren[i];
4280 let existingRouteTyped = existingRoute;
4281 let [newRouteTyped] = convertRoutesToDataRoutes(
4282 [newRoute],
4283 mapRouteProperties2,
4284 [],
4285 // Doesn't matter for mutated routes since they already have an id
4286 {},
4287 // Don't touch the manifest here since we're updating in place
4288 true
4289 );
4290 Object.assign(existingRouteTyped, {
4291 element: newRouteTyped.element ? newRouteTyped.element : existingRouteTyped.element,
4292 errorElement: newRouteTyped.errorElement ? newRouteTyped.errorElement : existingRouteTyped.errorElement,
4293 hydrateFallbackElement: newRouteTyped.hydrateFallbackElement ? newRouteTyped.hydrateFallbackElement : existingRouteTyped.hydrateFallbackElement
4294 });
4295 }
4296 }
4297}
4298function isSameRoute(newRoute, existingRoute) {
4299 if ("id" in newRoute && "id" in existingRoute && newRoute.id === existingRoute.id) {
4300 return true;
4301 }
4302 if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) {
4303 return false;
4304 }
4305 if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) {
4306 return true;
4307 }
4308 return _nullishCoalesce(_optionalChain([newRoute, 'access', _45 => _45.children, 'optionalAccess', _46 => _46.every, 'call', _47 => _47(
4309 (aChild, i) => _optionalChain([existingRoute, 'access', _48 => _48.children, 'optionalAccess', _49 => _49.some, 'call', _50 => _50((bChild) => isSameRoute(aChild, bChild))])
4310 )]), () => ( false));
4311}
4312var lazyRoutePropertyCache = /* @__PURE__ */ new WeakMap();
4313var loadLazyRouteProperty = ({
4314 key,
4315 route,
4316 manifest,
4317 mapRouteProperties: mapRouteProperties2
4318}) => {
4319 let routeToUpdate = manifest[route.id];
4320 invariant(routeToUpdate, "No route found in manifest");
4321 if (!routeToUpdate.lazy || typeof routeToUpdate.lazy !== "object") {
4322 return;
4323 }
4324 let lazyFn = routeToUpdate.lazy[key];
4325 if (!lazyFn) {
4326 return;
4327 }
4328 let cache = lazyRoutePropertyCache.get(routeToUpdate);
4329 if (!cache) {
4330 cache = {};
4331 lazyRoutePropertyCache.set(routeToUpdate, cache);
4332 }
4333 let cachedPromise = cache[key];
4334 if (cachedPromise) {
4335 return cachedPromise;
4336 }
4337 let propertyPromise = (async () => {
4338 let isUnsupported = isUnsupportedLazyRouteObjectKey(key);
4339 let staticRouteValue = routeToUpdate[key];
4340 let isStaticallyDefined = staticRouteValue !== void 0 && key !== "hasErrorBoundary";
4341 if (isUnsupported) {
4342 warning(
4343 !isUnsupported,
4344 "Route property " + key + " is not a supported lazy route property. This property will be ignored."
4345 );
4346 cache[key] = Promise.resolve();
4347 } else if (isStaticallyDefined) {
4348 warning(
4349 false,
4350 `Route "${routeToUpdate.id}" has a static property "${key}" defined. The lazy property will be ignored.`
4351 );
4352 } else {
4353 let value = await lazyFn();
4354 if (value != null) {
4355 Object.assign(routeToUpdate, { [key]: value });
4356 Object.assign(routeToUpdate, mapRouteProperties2(routeToUpdate));
4357 }
4358 }
4359 if (typeof routeToUpdate.lazy === "object") {
4360 routeToUpdate.lazy[key] = void 0;
4361 if (Object.values(routeToUpdate.lazy).every((value) => value === void 0)) {
4362 routeToUpdate.lazy = void 0;
4363 }
4364 }
4365 })();
4366 cache[key] = propertyPromise;
4367 return propertyPromise;
4368};
4369var lazyRouteFunctionCache = /* @__PURE__ */ new WeakMap();
4370function loadLazyRoute(route, type, manifest, mapRouteProperties2, lazyRoutePropertiesToSkip) {
4371 let routeToUpdate = manifest[route.id];
4372 invariant(routeToUpdate, "No route found in manifest");
4373 if (!route.lazy) {
4374 return {
4375 lazyRoutePromise: void 0,
4376 lazyHandlerPromise: void 0
4377 };
4378 }
4379 if (typeof route.lazy === "function") {
4380 let cachedPromise = lazyRouteFunctionCache.get(routeToUpdate);
4381 if (cachedPromise) {
4382 return {
4383 lazyRoutePromise: cachedPromise,
4384 lazyHandlerPromise: cachedPromise
4385 };
4386 }
4387 let lazyRoutePromise2 = (async () => {
4388 invariant(
4389 typeof route.lazy === "function",
4390 "No lazy route function found"
4391 );
4392 let lazyRoute = await route.lazy();
4393 let routeUpdates = {};
4394 for (let lazyRouteProperty in lazyRoute) {
4395 let lazyValue = lazyRoute[lazyRouteProperty];
4396 if (lazyValue === void 0) {
4397 continue;
4398 }
4399 let isUnsupported = isUnsupportedLazyRouteFunctionKey(lazyRouteProperty);
4400 let staticRouteValue = routeToUpdate[lazyRouteProperty];
4401 let isStaticallyDefined = staticRouteValue !== void 0 && // This property isn't static since it should always be updated based
4402 // on the route updates
4403 lazyRouteProperty !== "hasErrorBoundary";
4404 if (isUnsupported) {
4405 warning(
4406 !isUnsupported,
4407 "Route property " + lazyRouteProperty + " is not a supported property to be returned from a lazy route function. This property will be ignored."
4408 );
4409 } else if (isStaticallyDefined) {
4410 warning(
4411 !isStaticallyDefined,
4412 `Route "${routeToUpdate.id}" has a static property "${lazyRouteProperty}" defined but its lazy function is also returning a value for this property. The lazy route property "${lazyRouteProperty}" will be ignored.`
4413 );
4414 } else {
4415 routeUpdates[lazyRouteProperty] = lazyValue;
4416 }
4417 }
4418 Object.assign(routeToUpdate, routeUpdates);
4419 Object.assign(routeToUpdate, {
4420 // To keep things framework agnostic, we use the provided `mapRouteProperties`
4421 // function to set the framework-aware properties (`element`/`hasErrorBoundary`)
4422 // since the logic will differ between frameworks.
4423 ...mapRouteProperties2(routeToUpdate),
4424 lazy: void 0
4425 });
4426 })();
4427 lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise2);
4428 lazyRoutePromise2.catch(() => {
4429 });
4430 return {
4431 lazyRoutePromise: lazyRoutePromise2,
4432 lazyHandlerPromise: lazyRoutePromise2
4433 };
4434 }
4435 let lazyKeys = Object.keys(route.lazy);
4436 let lazyPropertyPromises = [];
4437 let lazyHandlerPromise = void 0;
4438 for (let key of lazyKeys) {
4439 if (lazyRoutePropertiesToSkip && lazyRoutePropertiesToSkip.includes(key)) {
4440 continue;
4441 }
4442 let promise = loadLazyRouteProperty({
4443 key,
4444 route,
4445 manifest,
4446 mapRouteProperties: mapRouteProperties2
4447 });
4448 if (promise) {
4449 lazyPropertyPromises.push(promise);
4450 if (key === type) {
4451 lazyHandlerPromise = promise;
4452 }
4453 }
4454 }
4455 let lazyRoutePromise = lazyPropertyPromises.length > 0 ? Promise.all(lazyPropertyPromises).then(() => {
4456 }) : void 0;
4457 _optionalChain([lazyRoutePromise, 'optionalAccess', _51 => _51.catch, 'call', _52 => _52(() => {
4458 })]);
4459 _optionalChain([lazyHandlerPromise, 'optionalAccess', _53 => _53.catch, 'call', _54 => _54(() => {
4460 })]);
4461 return {
4462 lazyRoutePromise,
4463 lazyHandlerPromise
4464 };
4465}
4466function isNonNullable(value) {
4467 return value !== void 0;
4468}
4469function loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2) {
4470 let promises = matches.map(({ route }) => {
4471 if (typeof route.lazy !== "object" || !route.lazy.middleware) {
4472 return void 0;
4473 }
4474 return loadLazyRouteProperty({
4475 key: "middleware",
4476 route,
4477 manifest,
4478 mapRouteProperties: mapRouteProperties2
4479 });
4480 }).filter(isNonNullable);
4481 return promises.length > 0 ? Promise.all(promises) : void 0;
4482}
4483async function defaultDataStrategy(args) {
4484 let matchesToLoad = args.matches.filter((m) => m.shouldLoad);
4485 let keyedResults = {};
4486 let results = await Promise.all(matchesToLoad.map((m) => m.resolve()));
4487 results.forEach((result, i) => {
4488 keyedResults[matchesToLoad[i].route.id] = result;
4489 });
4490 return keyedResults;
4491}
4492async function defaultDataStrategyWithMiddleware(args) {
4493 if (!args.matches.some((m) => m.route.middleware)) {
4494 return defaultDataStrategy(args);
4495 }
4496 return runClientMiddlewarePipeline(args, () => defaultDataStrategy(args));
4497}
4498function runServerMiddlewarePipeline(args, handler, errorHandler) {
4499 return runMiddlewarePipeline(
4500 args,
4501 handler,
4502 processResult,
4503 isResponse,
4504 errorHandler
4505 );
4506 function processResult(result) {
4507 return isDataWithResponseInit(result) ? dataWithResponseInitToResponse(result) : result;
4508 }
4509}
4510function runClientMiddlewarePipeline(args, handler) {
4511 return runMiddlewarePipeline(
4512 args,
4513 handler,
4514 (r) => {
4515 if (isRedirectResponse(r)) {
4516 throw r;
4517 }
4518 return r;
4519 },
4520 isDataStrategyResults,
4521 errorHandler
4522 );
4523 function errorHandler(error, routeId, nextResult) {
4524 if (nextResult) {
4525 return Promise.resolve(
4526 Object.assign(nextResult.value, {
4527 [routeId]: { type: "error", result: error }
4528 })
4529 );
4530 } else {
4531 let { matches } = args;
4532 let maxBoundaryIdx = Math.min(
4533 // Throwing route
4534 Math.max(
4535 matches.findIndex((m) => m.route.id === routeId),
4536 0
4537 ),
4538 // or the shallowest route that needs to load data
4539 Math.max(
4540 matches.findIndex((m) => m.shouldCallHandler()),
4541 0
4542 )
4543 );
4544 let boundaryRouteId = findNearestBoundary(
4545 matches,
4546 matches[maxBoundaryIdx].route.id
4547 ).route.id;
4548 return Promise.resolve({
4549 [boundaryRouteId]: { type: "error", result: error }
4550 });
4551 }
4552 }
4553}
4554async function runMiddlewarePipeline(args, handler, processResult, isResult, errorHandler) {
4555 let { matches, request, params, context, unstable_pattern } = args;
4556 let tuples = matches.flatMap(
4557 (m) => m.route.middleware ? m.route.middleware.map((fn) => [m.route.id, fn]) : []
4558 );
4559 let result = await callRouteMiddleware(
4560 {
4561 request,
4562 params,
4563 context,
4564 unstable_pattern
4565 },
4566 tuples,
4567 handler,
4568 processResult,
4569 isResult,
4570 errorHandler
4571 );
4572 return result;
4573}
4574async function callRouteMiddleware(args, middlewares, handler, processResult, isResult, errorHandler, idx = 0) {
4575 let { request } = args;
4576 if (request.signal.aborted) {
4577 throw _nullishCoalesce(request.signal.reason, () => ( new Error(`Request aborted: ${request.method} ${request.url}`)));
4578 }
4579 let tuple = middlewares[idx];
4580 if (!tuple) {
4581 let result = await handler();
4582 return result;
4583 }
4584 let [routeId, middleware] = tuple;
4585 let nextResult;
4586 let next = async () => {
4587 if (nextResult) {
4588 throw new Error("You may only call `next()` once per middleware");
4589 }
4590 try {
4591 let result = await callRouteMiddleware(
4592 args,
4593 middlewares,
4594 handler,
4595 processResult,
4596 isResult,
4597 errorHandler,
4598 idx + 1
4599 );
4600 nextResult = { value: result };
4601 return nextResult.value;
4602 } catch (error) {
4603 nextResult = { value: await errorHandler(error, routeId, nextResult) };
4604 return nextResult.value;
4605 }
4606 };
4607 try {
4608 let value = await middleware(args, next);
4609 let result = value != null ? processResult(value) : void 0;
4610 if (isResult(result)) {
4611 return result;
4612 } else if (nextResult) {
4613 return _nullishCoalesce(result, () => ( nextResult.value));
4614 } else {
4615 nextResult = { value: await next() };
4616 return nextResult.value;
4617 }
4618 } catch (error) {
4619 let response = await errorHandler(error, routeId, nextResult);
4620 return response;
4621 }
4622}
4623function getDataStrategyMatchLazyPromises(mapRouteProperties2, manifest, request, match, lazyRoutePropertiesToSkip) {
4624 let lazyMiddlewarePromise = loadLazyRouteProperty({
4625 key: "middleware",
4626 route: match.route,
4627 manifest,
4628 mapRouteProperties: mapRouteProperties2
4629 });
4630 let lazyRoutePromises = loadLazyRoute(
4631 match.route,
4632 isMutationMethod(request.method) ? "action" : "loader",
4633 manifest,
4634 mapRouteProperties2,
4635 lazyRoutePropertiesToSkip
4636 );
4637 return {
4638 middleware: lazyMiddlewarePromise,
4639 route: lazyRoutePromises.lazyRoutePromise,
4640 handler: lazyRoutePromises.lazyHandlerPromise
4641 };
4642}
4643function getDataStrategyMatch(mapRouteProperties2, manifest, request, unstable_pattern, match, lazyRoutePropertiesToSkip, scopedContext, shouldLoad, shouldRevalidateArgs = null, callSiteDefaultShouldRevalidate) {
4644 let isUsingNewApi = false;
4645 let _lazyPromises = getDataStrategyMatchLazyPromises(
4646 mapRouteProperties2,
4647 manifest,
4648 request,
4649 match,
4650 lazyRoutePropertiesToSkip
4651 );
4652 return {
4653 ...match,
4654 _lazyPromises,
4655 shouldLoad,
4656 shouldRevalidateArgs,
4657 shouldCallHandler(defaultShouldRevalidate) {
4658 isUsingNewApi = true;
4659 if (!shouldRevalidateArgs) {
4660 return shouldLoad;
4661 }
4662 if (typeof callSiteDefaultShouldRevalidate === "boolean") {
4663 return shouldRevalidateLoader(match, {
4664 ...shouldRevalidateArgs,
4665 defaultShouldRevalidate: callSiteDefaultShouldRevalidate
4666 });
4667 }
4668 if (typeof defaultShouldRevalidate === "boolean") {
4669 return shouldRevalidateLoader(match, {
4670 ...shouldRevalidateArgs,
4671 defaultShouldRevalidate
4672 });
4673 }
4674 return shouldRevalidateLoader(match, shouldRevalidateArgs);
4675 },
4676 resolve(handlerOverride) {
4677 let { lazy, loader, middleware } = match.route;
4678 let callHandler = isUsingNewApi || shouldLoad || handlerOverride && !isMutationMethod(request.method) && (lazy || loader);
4679 let isMiddlewareOnlyRoute = middleware && middleware.length > 0 && !loader && !lazy;
4680 if (callHandler && (isMutationMethod(request.method) || !isMiddlewareOnlyRoute)) {
4681 return callLoaderOrAction({
4682 request,
4683 unstable_pattern,
4684 match,
4685 lazyHandlerPromise: _optionalChain([_lazyPromises, 'optionalAccess', _55 => _55.handler]),
4686 lazyRoutePromise: _optionalChain([_lazyPromises, 'optionalAccess', _56 => _56.route]),
4687 handlerOverride,
4688 scopedContext
4689 });
4690 }
4691 return Promise.resolve({ type: "data" /* data */, result: void 0 });
4692 }
4693 };
4694}
4695function getTargetedDataStrategyMatches(mapRouteProperties2, manifest, request, matches, targetMatch, lazyRoutePropertiesToSkip, scopedContext, shouldRevalidateArgs = null) {
4696 return matches.map((match) => {
4697 if (match.route.id !== targetMatch.route.id) {
4698 return {
4699 ...match,
4700 shouldLoad: false,
4701 shouldRevalidateArgs,
4702 shouldCallHandler: () => false,
4703 _lazyPromises: getDataStrategyMatchLazyPromises(
4704 mapRouteProperties2,
4705 manifest,
4706 request,
4707 match,
4708 lazyRoutePropertiesToSkip
4709 ),
4710 resolve: () => Promise.resolve({ type: "data", result: void 0 })
4711 };
4712 }
4713 return getDataStrategyMatch(
4714 mapRouteProperties2,
4715 manifest,
4716 request,
4717 getRoutePattern(matches),
4718 match,
4719 lazyRoutePropertiesToSkip,
4720 scopedContext,
4721 true,
4722 shouldRevalidateArgs
4723 );
4724 });
4725}
4726async function callDataStrategyImpl(dataStrategyImpl, request, matches, fetcherKey, scopedContext, isStaticHandler) {
4727 if (matches.some((m) => _optionalChain([m, 'access', _57 => _57._lazyPromises, 'optionalAccess', _58 => _58.middleware]))) {
4728 await Promise.all(matches.map((m) => _optionalChain([m, 'access', _59 => _59._lazyPromises, 'optionalAccess', _60 => _60.middleware])));
4729 }
4730 let dataStrategyArgs = {
4731 request,
4732 unstable_pattern: getRoutePattern(matches),
4733 params: matches[0].params,
4734 context: scopedContext,
4735 matches
4736 };
4737 let runClientMiddleware = isStaticHandler ? () => {
4738 throw new Error(
4739 "You cannot call `runClientMiddleware()` from a static handler `dataStrategy`. Middleware is run outside of `dataStrategy` during SSR in order to bubble up the Response. You can enable middleware via the `respond` API in `query`/`queryRoute`"
4740 );
4741 } : (cb) => {
4742 let typedDataStrategyArgs = dataStrategyArgs;
4743 return runClientMiddlewarePipeline(typedDataStrategyArgs, () => {
4744 return cb({
4745 ...typedDataStrategyArgs,
4746 fetcherKey,
4747 runClientMiddleware: () => {
4748 throw new Error(
4749 "Cannot call `runClientMiddleware()` from within an `runClientMiddleware` handler"
4750 );
4751 }
4752 });
4753 });
4754 };
4755 let results = await dataStrategyImpl({
4756 ...dataStrategyArgs,
4757 fetcherKey,
4758 runClientMiddleware
4759 });
4760 try {
4761 await Promise.all(
4762 matches.flatMap((m) => [
4763 _optionalChain([m, 'access', _61 => _61._lazyPromises, 'optionalAccess', _62 => _62.handler]),
4764 _optionalChain([m, 'access', _63 => _63._lazyPromises, 'optionalAccess', _64 => _64.route])
4765 ])
4766 );
4767 } catch (e) {
4768 }
4769 return results;
4770}
4771async function callLoaderOrAction({
4772 request,
4773 unstable_pattern,
4774 match,
4775 lazyHandlerPromise,
4776 lazyRoutePromise,
4777 handlerOverride,
4778 scopedContext
4779}) {
4780 let result;
4781 let onReject;
4782 let isAction = isMutationMethod(request.method);
4783 let type = isAction ? "action" : "loader";
4784 let runHandler = (handler) => {
4785 let reject;
4786 let abortPromise = new Promise((_, r) => reject = r);
4787 onReject = () => reject();
4788 request.signal.addEventListener("abort", onReject);
4789 let actualHandler = (ctx) => {
4790 if (typeof handler !== "function") {
4791 return Promise.reject(
4792 new Error(
4793 `You cannot call the handler for a route which defines a boolean "${type}" [routeId: ${match.route.id}]`
4794 )
4795 );
4796 }
4797 return handler(
4798 {
4799 request,
4800 unstable_pattern,
4801 params: match.params,
4802 context: scopedContext
4803 },
4804 ...ctx !== void 0 ? [ctx] : []
4805 );
4806 };
4807 let handlerPromise = (async () => {
4808 try {
4809 let val = await (handlerOverride ? handlerOverride((ctx) => actualHandler(ctx)) : actualHandler());
4810 return { type: "data", result: val };
4811 } catch (e) {
4812 return { type: "error", result: e };
4813 }
4814 })();
4815 return Promise.race([handlerPromise, abortPromise]);
4816 };
4817 try {
4818 let handler = isAction ? match.route.action : match.route.loader;
4819 if (lazyHandlerPromise || lazyRoutePromise) {
4820 if (handler) {
4821 let handlerError;
4822 let [value] = await Promise.all([
4823 // If the handler throws, don't let it immediately bubble out,
4824 // since we need to let the lazy() execution finish so we know if this
4825 // route has a boundary that can handle the error
4826 runHandler(handler).catch((e) => {
4827 handlerError = e;
4828 }),
4829 // Ensure all lazy route promises are resolved before continuing
4830 lazyHandlerPromise,
4831 lazyRoutePromise
4832 ]);
4833 if (handlerError !== void 0) {
4834 throw handlerError;
4835 }
4836 result = value;
4837 } else {
4838 await lazyHandlerPromise;
4839 let handler2 = isAction ? match.route.action : match.route.loader;
4840 if (handler2) {
4841 [result] = await Promise.all([runHandler(handler2), lazyRoutePromise]);
4842 } else if (type === "action") {
4843 let url = new URL(request.url);
4844 let pathname = url.pathname + url.search;
4845 throw getInternalRouterError(405, {
4846 method: request.method,
4847 pathname,
4848 routeId: match.route.id
4849 });
4850 } else {
4851 return { type: "data" /* data */, result: void 0 };
4852 }
4853 }
4854 } else if (!handler) {
4855 let url = new URL(request.url);
4856 let pathname = url.pathname + url.search;
4857 throw getInternalRouterError(404, {
4858 pathname
4859 });
4860 } else {
4861 result = await runHandler(handler);
4862 }
4863 } catch (e) {
4864 return { type: "error" /* error */, result: e };
4865 } finally {
4866 if (onReject) {
4867 request.signal.removeEventListener("abort", onReject);
4868 }
4869 }
4870 return result;
4871}
4872async function parseResponseBody(response) {
4873 let contentType = response.headers.get("Content-Type");
4874 if (contentType && /\bapplication\/json\b/.test(contentType)) {
4875 return response.body == null ? null : response.json();
4876 }
4877 return response.text();
4878}
4879async function convertDataStrategyResultToDataResult(dataStrategyResult) {
4880 let { result, type } = dataStrategyResult;
4881 if (isResponse(result)) {
4882 let data2;
4883 try {
4884 data2 = await parseResponseBody(result);
4885 } catch (e) {
4886 return { type: "error" /* error */, error: e };
4887 }
4888 if (type === "error" /* error */) {
4889 return {
4890 type: "error" /* error */,
4891 error: new ErrorResponseImpl(result.status, result.statusText, data2),
4892 statusCode: result.status,
4893 headers: result.headers
4894 };
4895 }
4896 return {
4897 type: "data" /* data */,
4898 data: data2,
4899 statusCode: result.status,
4900 headers: result.headers
4901 };
4902 }
4903 if (type === "error" /* error */) {
4904 if (isDataWithResponseInit(result)) {
4905 if (result.data instanceof Error) {
4906 return {
4907 type: "error" /* error */,
4908 error: result.data,
4909 statusCode: _optionalChain([result, 'access', _65 => _65.init, 'optionalAccess', _66 => _66.status]),
4910 headers: _optionalChain([result, 'access', _67 => _67.init, 'optionalAccess', _68 => _68.headers]) ? new Headers(result.init.headers) : void 0
4911 };
4912 }
4913 return {
4914 type: "error" /* error */,
4915 error: dataWithResponseInitToErrorResponse(result),
4916 statusCode: isRouteErrorResponse(result) ? result.status : void 0,
4917 headers: _optionalChain([result, 'access', _69 => _69.init, 'optionalAccess', _70 => _70.headers]) ? new Headers(result.init.headers) : void 0
4918 };
4919 }
4920 return {
4921 type: "error" /* error */,
4922 error: result,
4923 statusCode: isRouteErrorResponse(result) ? result.status : void 0
4924 };
4925 }
4926 if (isDataWithResponseInit(result)) {
4927 return {
4928 type: "data" /* data */,
4929 data: result.data,
4930 statusCode: _optionalChain([result, 'access', _71 => _71.init, 'optionalAccess', _72 => _72.status]),
4931 headers: _optionalChain([result, 'access', _73 => _73.init, 'optionalAccess', _74 => _74.headers]) ? new Headers(result.init.headers) : void 0
4932 };
4933 }
4934 return { type: "data" /* data */, data: result };
4935}
4936function normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename) {
4937 let location = response.headers.get("Location");
4938 invariant(
4939 location,
4940 "Redirects returned/thrown from loaders/actions must have a Location header"
4941 );
4942 if (!isAbsoluteUrl(location)) {
4943 let trimmedMatches = matches.slice(
4944 0,
4945 matches.findIndex((m) => m.route.id === routeId) + 1
4946 );
4947 location = normalizeTo(
4948 new URL(request.url),
4949 trimmedMatches,
4950 basename,
4951 location
4952 );
4953 response.headers.set("Location", location);
4954 }
4955 return response;
4956}
4957function normalizeRedirectLocation(location, currentUrl, basename, historyInstance) {
4958 let invalidProtocols = [
4959 "about:",
4960 "blob:",
4961 "chrome:",
4962 "chrome-untrusted:",
4963 "content:",
4964 "data:",
4965 "devtools:",
4966 "file:",
4967 "filesystem:",
4968 // eslint-disable-next-line no-script-url
4969 "javascript:"
4970 ];
4971 if (isAbsoluteUrl(location)) {
4972 let normalizedLocation = location;
4973 let url = normalizedLocation.startsWith("//") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation);
4974 if (invalidProtocols.includes(url.protocol)) {
4975 throw new Error("Invalid redirect location");
4976 }
4977 let isSameBasename = stripBasename(url.pathname, basename) != null;
4978 if (url.origin === currentUrl.origin && isSameBasename) {
4979 return url.pathname + url.search + url.hash;
4980 }
4981 }
4982 try {
4983 let url = historyInstance.createURL(location);
4984 if (invalidProtocols.includes(url.protocol)) {
4985 throw new Error("Invalid redirect location");
4986 }
4987 } catch (e) {
4988 }
4989 return location;
4990}
4991function createClientSideRequest(history, location, signal, submission) {
4992 let url = history.createURL(stripHashFromPath(location)).toString();
4993 let init = { signal };
4994 if (submission && isMutationMethod(submission.formMethod)) {
4995 let { formMethod, formEncType } = submission;
4996 init.method = formMethod.toUpperCase();
4997 if (formEncType === "application/json") {
4998 init.headers = new Headers({ "Content-Type": formEncType });
4999 init.body = JSON.stringify(submission.json);
5000 } else if (formEncType === "text/plain") {
5001 init.body = submission.text;
5002 } else if (formEncType === "application/x-www-form-urlencoded" && submission.formData) {
5003 init.body = convertFormDataToSearchParams(submission.formData);
5004 } else {
5005 init.body = submission.formData;
5006 }
5007 }
5008 return new Request(url, init);
5009}
5010function convertFormDataToSearchParams(formData) {
5011 let searchParams = new URLSearchParams();
5012 for (let [key, value] of formData.entries()) {
5013 searchParams.append(key, typeof value === "string" ? value : value.name);
5014 }
5015 return searchParams;
5016}
5017function convertSearchParamsToFormData(searchParams) {
5018 let formData = new FormData();
5019 for (let [key, value] of searchParams.entries()) {
5020 formData.append(key, value);
5021 }
5022 return formData;
5023}
5024function processRouteLoaderData(matches, results, pendingActionResult, isStaticHandler = false, skipLoaderErrorBubbling = false) {
5025 let loaderData = {};
5026 let errors = null;
5027 let statusCode;
5028 let foundError = false;
5029 let loaderHeaders = {};
5030 let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : void 0;
5031 matches.forEach((match) => {
5032 if (!(match.route.id in results)) {
5033 return;
5034 }
5035 let id = match.route.id;
5036 let result = results[id];
5037 invariant(
5038 !isRedirectResult(result),
5039 "Cannot handle redirect results in processLoaderData"
5040 );
5041 if (isErrorResult(result)) {
5042 let error = result.error;
5043 if (pendingError !== void 0) {
5044 error = pendingError;
5045 pendingError = void 0;
5046 }
5047 errors = errors || {};
5048 if (skipLoaderErrorBubbling) {
5049 errors[id] = error;
5050 } else {
5051 let boundaryMatch = findNearestBoundary(matches, id);
5052 if (errors[boundaryMatch.route.id] == null) {
5053 errors[boundaryMatch.route.id] = error;
5054 }
5055 }
5056 if (!isStaticHandler) {
5057 loaderData[id] = ResetLoaderDataSymbol;
5058 }
5059 if (!foundError) {
5060 foundError = true;
5061 statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500;
5062 }
5063 if (result.headers) {
5064 loaderHeaders[id] = result.headers;
5065 }
5066 } else {
5067 loaderData[id] = result.data;
5068 if (result.statusCode && result.statusCode !== 200 && !foundError) {
5069 statusCode = result.statusCode;
5070 }
5071 if (result.headers) {
5072 loaderHeaders[id] = result.headers;
5073 }
5074 }
5075 });
5076 if (pendingError !== void 0 && pendingActionResult) {
5077 errors = { [pendingActionResult[0]]: pendingError };
5078 if (pendingActionResult[2]) {
5079 loaderData[pendingActionResult[2]] = void 0;
5080 }
5081 }
5082 return {
5083 loaderData,
5084 errors,
5085 statusCode: statusCode || 200,
5086 loaderHeaders
5087 };
5088}
5089function processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults) {
5090 let { loaderData, errors } = processRouteLoaderData(
5091 matches,
5092 results,
5093 pendingActionResult
5094 );
5095 revalidatingFetchers.filter((f) => !f.matches || f.matches.some((m) => m.shouldLoad)).forEach((rf) => {
5096 let { key, match, controller } = rf;
5097 if (controller && controller.signal.aborted) {
5098 return;
5099 }
5100 let result = fetcherResults[key];
5101 invariant(result, "Did not find corresponding fetcher result");
5102 if (isErrorResult(result)) {
5103 let boundaryMatch = findNearestBoundary(state.matches, _optionalChain([match, 'optionalAccess', _75 => _75.route, 'access', _76 => _76.id]));
5104 if (!(errors && errors[boundaryMatch.route.id])) {
5105 errors = {
5106 ...errors,
5107 [boundaryMatch.route.id]: result.error
5108 };
5109 }
5110 state.fetchers.delete(key);
5111 } else if (isRedirectResult(result)) {
5112 invariant(false, "Unhandled fetcher revalidation redirect");
5113 } else {
5114 let doneFetcher = getDoneFetcher(result.data);
5115 state.fetchers.set(key, doneFetcher);
5116 }
5117 });
5118 return { loaderData, errors };
5119}
5120function mergeLoaderData(loaderData, newLoaderData, matches, errors) {
5121 let mergedLoaderData = Object.entries(newLoaderData).filter(([, v]) => v !== ResetLoaderDataSymbol).reduce((merged, [k, v]) => {
5122 merged[k] = v;
5123 return merged;
5124 }, {});
5125 for (let match of matches) {
5126 let id = match.route.id;
5127 if (!newLoaderData.hasOwnProperty(id) && loaderData.hasOwnProperty(id) && match.route.loader) {
5128 mergedLoaderData[id] = loaderData[id];
5129 }
5130 if (errors && errors.hasOwnProperty(id)) {
5131 break;
5132 }
5133 }
5134 return mergedLoaderData;
5135}
5136function getActionDataForCommit(pendingActionResult) {
5137 if (!pendingActionResult) {
5138 return {};
5139 }
5140 return isErrorResult(pendingActionResult[1]) ? {
5141 // Clear out prior actionData on errors
5142 actionData: {}
5143 } : {
5144 actionData: {
5145 [pendingActionResult[0]]: pendingActionResult[1].data
5146 }
5147 };
5148}
5149function findNearestBoundary(matches, routeId) {
5150 let eligibleMatches = routeId ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1) : [...matches];
5151 return eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) || matches[0];
5152}
5153function getShortCircuitMatches(routes) {
5154 let route = routes.length === 1 ? routes[0] : routes.find((r) => r.index || !r.path || r.path === "/") || {
5155 id: `__shim-error-route__`
5156 };
5157 return {
5158 matches: [
5159 {
5160 params: {},
5161 pathname: "",
5162 pathnameBase: "",
5163 route
5164 }
5165 ],
5166 route
5167 };
5168}
5169function getInternalRouterError(status, {
5170 pathname,
5171 routeId,
5172 method,
5173 type,
5174 message
5175} = {}) {
5176 let statusText = "Unknown Server Error";
5177 let errorMessage = "Unknown @remix-run/router error";
5178 if (status === 400) {
5179 statusText = "Bad Request";
5180 if (method && pathname && routeId) {
5181 errorMessage = `You made a ${method} request to "${pathname}" but did not provide a \`loader\` for route "${routeId}", so there is no way to handle the request.`;
5182 } else if (type === "invalid-body") {
5183 errorMessage = "Unable to encode submission body";
5184 }
5185 } else if (status === 403) {
5186 statusText = "Forbidden";
5187 errorMessage = `Route "${routeId}" does not match URL "${pathname}"`;
5188 } else if (status === 404) {
5189 statusText = "Not Found";
5190 errorMessage = `No route matches URL "${pathname}"`;
5191 } else if (status === 405) {
5192 statusText = "Method Not Allowed";
5193 if (method && pathname && routeId) {
5194 errorMessage = `You made a ${method.toUpperCase()} request to "${pathname}" but did not provide an \`action\` for route "${routeId}", so there is no way to handle the request.`;
5195 } else if (method) {
5196 errorMessage = `Invalid request method "${method.toUpperCase()}"`;
5197 }
5198 }
5199 return new ErrorResponseImpl(
5200 status || 500,
5201 statusText,
5202 new Error(errorMessage),
5203 true
5204 );
5205}
5206function findRedirect(results) {
5207 let entries = Object.entries(results);
5208 for (let i = entries.length - 1; i >= 0; i--) {
5209 let [key, result] = entries[i];
5210 if (isRedirectResult(result)) {
5211 return { key, result };
5212 }
5213 }
5214}
5215function stripHashFromPath(path) {
5216 let parsedPath = typeof path === "string" ? parsePath(path) : path;
5217 return createPath({ ...parsedPath, hash: "" });
5218}
5219function isHashChangeOnly(a, b) {
5220 if (a.pathname !== b.pathname || a.search !== b.search) {
5221 return false;
5222 }
5223 if (a.hash === "") {
5224 return b.hash !== "";
5225 } else if (a.hash === b.hash) {
5226 return true;
5227 } else if (b.hash !== "") {
5228 return true;
5229 }
5230 return false;
5231}
5232function dataWithResponseInitToResponse(data2) {
5233 return Response.json(data2.data, _nullishCoalesce(data2.init, () => ( void 0)));
5234}
5235function dataWithResponseInitToErrorResponse(data2) {
5236 return new ErrorResponseImpl(
5237 _nullishCoalesce(_optionalChain([data2, 'access', _77 => _77.init, 'optionalAccess', _78 => _78.status]), () => ( 500)),
5238 _nullishCoalesce(_optionalChain([data2, 'access', _79 => _79.init, 'optionalAccess', _80 => _80.statusText]), () => ( "Internal Server Error")),
5239 data2.data
5240 );
5241}
5242function isDataStrategyResults(result) {
5243 return result != null && typeof result === "object" && Object.entries(result).every(
5244 ([key, value]) => typeof key === "string" && isDataStrategyResult(value)
5245 );
5246}
5247function isDataStrategyResult(result) {
5248 return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === "data" /* data */ || result.type === "error" /* error */);
5249}
5250function isRedirectDataStrategyResult(result) {
5251 return isResponse(result.result) && redirectStatusCodes.has(result.result.status);
5252}
5253function isErrorResult(result) {
5254 return result.type === "error" /* error */;
5255}
5256function isRedirectResult(result) {
5257 return (result && result.type) === "redirect" /* redirect */;
5258}
5259function isDataWithResponseInit(value) {
5260 return typeof value === "object" && value != null && "type" in value && "data" in value && "init" in value && value.type === "DataWithResponseInit";
5261}
5262function isResponse(value) {
5263 return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
5264}
5265function isRedirectStatusCode(statusCode) {
5266 return redirectStatusCodes.has(statusCode);
5267}
5268function isRedirectResponse(result) {
5269 return isResponse(result) && isRedirectStatusCode(result.status) && result.headers.has("Location");
5270}
5271function isValidMethod(method) {
5272 return validRequestMethods.has(method.toUpperCase());
5273}
5274function isMutationMethod(method) {
5275 return validMutationMethods.has(method.toUpperCase());
5276}
5277function hasNakedIndexQuery(search) {
5278 return new URLSearchParams(search).getAll("index").some((v) => v === "");
5279}
5280function getTargetMatch(matches, location) {
5281 let search = typeof location === "string" ? parsePath(location).search : location.search;
5282 if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) {
5283 return matches[matches.length - 1];
5284 }
5285 let pathMatches = getPathContributingMatches(matches);
5286 return pathMatches[pathMatches.length - 1];
5287}
5288function getSubmissionFromNavigation(navigation) {
5289 let { formMethod, formAction, formEncType, text, formData, json } = navigation;
5290 if (!formMethod || !formAction || !formEncType) {
5291 return;
5292 }
5293 if (text != null) {
5294 return {
5295 formMethod,
5296 formAction,
5297 formEncType,
5298 formData: void 0,
5299 json: void 0,
5300 text
5301 };
5302 } else if (formData != null) {
5303 return {
5304 formMethod,
5305 formAction,
5306 formEncType,
5307 formData,
5308 json: void 0,
5309 text: void 0
5310 };
5311 } else if (json !== void 0) {
5312 return {
5313 formMethod,
5314 formAction,
5315 formEncType,
5316 formData: void 0,
5317 json,
5318 text: void 0
5319 };
5320 }
5321}
5322function getLoadingNavigation(location, submission) {
5323 if (submission) {
5324 let navigation = {
5325 state: "loading",
5326 location,
5327 formMethod: submission.formMethod,
5328 formAction: submission.formAction,
5329 formEncType: submission.formEncType,
5330 formData: submission.formData,
5331 json: submission.json,
5332 text: submission.text
5333 };
5334 return navigation;
5335 } else {
5336 let navigation = {
5337 state: "loading",
5338 location,
5339 formMethod: void 0,
5340 formAction: void 0,
5341 formEncType: void 0,
5342 formData: void 0,
5343 json: void 0,
5344 text: void 0
5345 };
5346 return navigation;
5347 }
5348}
5349function getSubmittingNavigation(location, submission) {
5350 let navigation = {
5351 state: "submitting",
5352 location,
5353 formMethod: submission.formMethod,
5354 formAction: submission.formAction,
5355 formEncType: submission.formEncType,
5356 formData: submission.formData,
5357 json: submission.json,
5358 text: submission.text
5359 };
5360 return navigation;
5361}
5362function getLoadingFetcher(submission, data2) {
5363 if (submission) {
5364 let fetcher = {
5365 state: "loading",
5366 formMethod: submission.formMethod,
5367 formAction: submission.formAction,
5368 formEncType: submission.formEncType,
5369 formData: submission.formData,
5370 json: submission.json,
5371 text: submission.text,
5372 data: data2
5373 };
5374 return fetcher;
5375 } else {
5376 let fetcher = {
5377 state: "loading",
5378 formMethod: void 0,
5379 formAction: void 0,
5380 formEncType: void 0,
5381 formData: void 0,
5382 json: void 0,
5383 text: void 0,
5384 data: data2
5385 };
5386 return fetcher;
5387 }
5388}
5389function getSubmittingFetcher(submission, existingFetcher) {
5390 let fetcher = {
5391 state: "submitting",
5392 formMethod: submission.formMethod,
5393 formAction: submission.formAction,
5394 formEncType: submission.formEncType,
5395 formData: submission.formData,
5396 json: submission.json,
5397 text: submission.text,
5398 data: existingFetcher ? existingFetcher.data : void 0
5399 };
5400 return fetcher;
5401}
5402function getDoneFetcher(data2) {
5403 let fetcher = {
5404 state: "idle",
5405 formMethod: void 0,
5406 formAction: void 0,
5407 formEncType: void 0,
5408 formData: void 0,
5409 json: void 0,
5410 text: void 0,
5411 data: data2
5412 };
5413 return fetcher;
5414}
5415function restoreAppliedTransitions(_window, transitions) {
5416 try {
5417 let sessionPositions = _window.sessionStorage.getItem(
5418 TRANSITIONS_STORAGE_KEY
5419 );
5420 if (sessionPositions) {
5421 let json = JSON.parse(sessionPositions);
5422 for (let [k, v] of Object.entries(json || {})) {
5423 if (v && Array.isArray(v)) {
5424 transitions.set(k, new Set(v || []));
5425 }
5426 }
5427 }
5428 } catch (e) {
5429 }
5430}
5431function persistAppliedTransitions(_window, transitions) {
5432 if (transitions.size > 0) {
5433 let json = {};
5434 for (let [k, v] of transitions) {
5435 json[k] = [...v];
5436 }
5437 try {
5438 _window.sessionStorage.setItem(
5439 TRANSITIONS_STORAGE_KEY,
5440 JSON.stringify(json)
5441 );
5442 } catch (error) {
5443 warning(
5444 false,
5445 `Failed to save applied view transitions in sessionStorage (${error}).`
5446 );
5447 }
5448 }
5449}
5450function createDeferred() {
5451 let resolve;
5452 let reject;
5453 let promise = new Promise((res, rej) => {
5454 resolve = async (val) => {
5455 res(val);
5456 try {
5457 await promise;
5458 } catch (e) {
5459 }
5460 };
5461 reject = async (error) => {
5462 rej(error);
5463 try {
5464 await promise;
5465 } catch (e) {
5466 }
5467 };
5468 });
5469 return {
5470 promise,
5471 //@ts-ignore
5472 resolve,
5473 //@ts-ignore
5474 reject
5475 };
5476}
5477
5478// lib/dom/ssr/single-fetch.tsx
5479var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react); var React3 = _interopRequireWildcard(_react); var React8 = _interopRequireWildcard(_react); var React7 = _interopRequireWildcard(_react); var React6 = _interopRequireWildcard(_react); var React5 = _interopRequireWildcard(_react); var React4 = _interopRequireWildcard(_react); var React9 = _interopRequireWildcard(_react);
5480
5481// vendor/turbo-stream-v2/utils.ts
5482var HOLE = -1;
5483var NAN = -2;
5484var NEGATIVE_INFINITY = -3;
5485var NEGATIVE_ZERO = -4;
5486var NULL = -5;
5487var POSITIVE_INFINITY = -6;
5488var UNDEFINED = -7;
5489var TYPE_BIGINT = "B";
5490var TYPE_DATE = "D";
5491var TYPE_ERROR = "E";
5492var TYPE_MAP = "M";
5493var TYPE_NULL_OBJECT = "N";
5494var TYPE_PROMISE = "P";
5495var TYPE_REGEXP = "R";
5496var TYPE_SET = "S";
5497var TYPE_SYMBOL = "Y";
5498var TYPE_URL = "U";
5499var TYPE_PREVIOUS_RESOLVED = "Z";
5500var Deferred = class {
5501 constructor() {
5502 this.promise = new Promise((resolve, reject) => {
5503 this.resolve = resolve;
5504 this.reject = reject;
5505 });
5506 }
5507};
5508function createLineSplittingTransform() {
5509 const decoder = new TextDecoder();
5510 let leftover = "";
5511 return new TransformStream({
5512 transform(chunk, controller) {
5513 const str = decoder.decode(chunk, { stream: true });
5514 const parts = (leftover + str).split("\n");
5515 leftover = parts.pop() || "";
5516 for (const part of parts) {
5517 controller.enqueue(part);
5518 }
5519 },
5520 flush(controller) {
5521 if (leftover) {
5522 controller.enqueue(leftover);
5523 }
5524 }
5525 });
5526}
5527
5528// vendor/turbo-stream-v2/flatten.ts
5529function flatten(input) {
5530 const { indices } = this;
5531 const existing = indices.get(input);
5532 if (existing) return [existing];
5533 if (input === void 0) return UNDEFINED;
5534 if (input === null) return NULL;
5535 if (Number.isNaN(input)) return NAN;
5536 if (input === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY;
5537 if (input === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY;
5538 if (input === 0 && 1 / input < 0) return NEGATIVE_ZERO;
5539 const index = this.index++;
5540 indices.set(input, index);
5541 stringify.call(this, input, index);
5542 return index;
5543}
5544function stringify(input, index) {
5545 const { deferred, plugins, postPlugins } = this;
5546 const str = this.stringified;
5547 const stack = [[input, index]];
5548 while (stack.length > 0) {
5549 const [input2, index2] = stack.pop();
5550 const partsForObj = (obj) => Object.keys(obj).map((k) => `"_${flatten.call(this, k)}":${flatten.call(this, obj[k])}`).join(",");
5551 let error = null;
5552 switch (typeof input2) {
5553 case "boolean":
5554 case "number":
5555 case "string":
5556 str[index2] = JSON.stringify(input2);
5557 break;
5558 case "bigint":
5559 str[index2] = `["${TYPE_BIGINT}","${input2}"]`;
5560 break;
5561 case "symbol": {
5562 const keyFor = Symbol.keyFor(input2);
5563 if (!keyFor) {
5564 error = new Error(
5565 "Cannot encode symbol unless created with Symbol.for()"
5566 );
5567 } else {
5568 str[index2] = `["${TYPE_SYMBOL}",${JSON.stringify(keyFor)}]`;
5569 }
5570 break;
5571 }
5572 case "object": {
5573 if (!input2) {
5574 str[index2] = `${NULL}`;
5575 break;
5576 }
5577 const isArray = Array.isArray(input2);
5578 let pluginHandled = false;
5579 if (!isArray && plugins) {
5580 for (const plugin of plugins) {
5581 const pluginResult = plugin(input2);
5582 if (Array.isArray(pluginResult)) {
5583 pluginHandled = true;
5584 const [pluginIdentifier, ...rest] = pluginResult;
5585 str[index2] = `[${JSON.stringify(pluginIdentifier)}`;
5586 if (rest.length > 0) {
5587 str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(",")}`;
5588 }
5589 str[index2] += "]";
5590 break;
5591 }
5592 }
5593 }
5594 if (!pluginHandled) {
5595 let result = isArray ? "[" : "{";
5596 if (isArray) {
5597 for (let i = 0; i < input2.length; i++)
5598 result += (i ? "," : "") + (i in input2 ? flatten.call(this, input2[i]) : HOLE);
5599 str[index2] = `${result}]`;
5600 } else if (input2 instanceof Date) {
5601 const dateTime = input2.getTime();
5602 str[index2] = `["${TYPE_DATE}",${Number.isNaN(dateTime) ? JSON.stringify("invalid") : dateTime}]`;
5603 } else if (input2 instanceof URL) {
5604 str[index2] = `["${TYPE_URL}",${JSON.stringify(input2.href)}]`;
5605 } else if (input2 instanceof RegExp) {
5606 str[index2] = `["${TYPE_REGEXP}",${JSON.stringify(
5607 input2.source
5608 )},${JSON.stringify(input2.flags)}]`;
5609 } else if (input2 instanceof Set) {
5610 if (input2.size > 0) {
5611 str[index2] = `["${TYPE_SET}",${[...input2].map((val) => flatten.call(this, val)).join(",")}]`;
5612 } else {
5613 str[index2] = `["${TYPE_SET}"]`;
5614 }
5615 } else if (input2 instanceof Map) {
5616 if (input2.size > 0) {
5617 str[index2] = `["${TYPE_MAP}",${[...input2].flatMap(([k, v]) => [
5618 flatten.call(this, k),
5619 flatten.call(this, v)
5620 ]).join(",")}]`;
5621 } else {
5622 str[index2] = `["${TYPE_MAP}"]`;
5623 }
5624 } else if (input2 instanceof Promise) {
5625 str[index2] = `["${TYPE_PROMISE}",${index2}]`;
5626 deferred[index2] = input2;
5627 } else if (input2 instanceof Error) {
5628 str[index2] = `["${TYPE_ERROR}",${JSON.stringify(input2.message)}`;
5629 if (input2.name !== "Error") {
5630 str[index2] += `,${JSON.stringify(input2.name)}`;
5631 }
5632 str[index2] += "]";
5633 } else if (Object.getPrototypeOf(input2) === null) {
5634 str[index2] = `["${TYPE_NULL_OBJECT}",{${partsForObj(input2)}}]`;
5635 } else if (isPlainObject2(input2)) {
5636 str[index2] = `{${partsForObj(input2)}}`;
5637 } else {
5638 error = new Error("Cannot encode object with prototype");
5639 }
5640 }
5641 break;
5642 }
5643 default: {
5644 const isArray = Array.isArray(input2);
5645 let pluginHandled = false;
5646 if (!isArray && plugins) {
5647 for (const plugin of plugins) {
5648 const pluginResult = plugin(input2);
5649 if (Array.isArray(pluginResult)) {
5650 pluginHandled = true;
5651 const [pluginIdentifier, ...rest] = pluginResult;
5652 str[index2] = `[${JSON.stringify(pluginIdentifier)}`;
5653 if (rest.length > 0) {
5654 str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(",")}`;
5655 }
5656 str[index2] += "]";
5657 break;
5658 }
5659 }
5660 }
5661 if (!pluginHandled) {
5662 error = new Error("Cannot encode function or unexpected type");
5663 }
5664 }
5665 }
5666 if (error) {
5667 let pluginHandled = false;
5668 if (postPlugins) {
5669 for (const plugin of postPlugins) {
5670 const pluginResult = plugin(input2);
5671 if (Array.isArray(pluginResult)) {
5672 pluginHandled = true;
5673 const [pluginIdentifier, ...rest] = pluginResult;
5674 str[index2] = `[${JSON.stringify(pluginIdentifier)}`;
5675 if (rest.length > 0) {
5676 str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(",")}`;
5677 }
5678 str[index2] += "]";
5679 break;
5680 }
5681 }
5682 }
5683 if (!pluginHandled) {
5684 throw error;
5685 }
5686 }
5687 }
5688}
5689var objectProtoNames2 = Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
5690function isPlainObject2(thing) {
5691 const proto = Object.getPrototypeOf(thing);
5692 return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames2;
5693}
5694
5695// vendor/turbo-stream-v2/unflatten.ts
5696var globalObj = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : void 0;
5697function unflatten(parsed) {
5698 const { hydrated, values } = this;
5699 if (typeof parsed === "number") return hydrate.call(this, parsed);
5700 if (!Array.isArray(parsed) || !parsed.length) throw new SyntaxError();
5701 const startIndex = values.length;
5702 for (const value of parsed) {
5703 values.push(value);
5704 }
5705 hydrated.length = values.length;
5706 return hydrate.call(this, startIndex);
5707}
5708function hydrate(index) {
5709 const { hydrated, values, deferred, plugins } = this;
5710 let result;
5711 const stack = [
5712 [
5713 index,
5714 (v) => {
5715 result = v;
5716 }
5717 ]
5718 ];
5719 let postRun = [];
5720 while (stack.length > 0) {
5721 const [index2, set] = stack.pop();
5722 switch (index2) {
5723 case UNDEFINED:
5724 set(void 0);
5725 continue;
5726 case NULL:
5727 set(null);
5728 continue;
5729 case NAN:
5730 set(NaN);
5731 continue;
5732 case POSITIVE_INFINITY:
5733 set(Infinity);
5734 continue;
5735 case NEGATIVE_INFINITY:
5736 set(-Infinity);
5737 continue;
5738 case NEGATIVE_ZERO:
5739 set(-0);
5740 continue;
5741 }
5742 if (hydrated[index2]) {
5743 set(hydrated[index2]);
5744 continue;
5745 }
5746 const value = values[index2];
5747 if (!value || typeof value !== "object") {
5748 hydrated[index2] = value;
5749 set(value);
5750 continue;
5751 }
5752 if (Array.isArray(value)) {
5753 if (typeof value[0] === "string") {
5754 const [type, b, c] = value;
5755 switch (type) {
5756 case TYPE_DATE:
5757 set(hydrated[index2] = new Date(b));
5758 continue;
5759 case TYPE_URL:
5760 set(hydrated[index2] = new URL(b));
5761 continue;
5762 case TYPE_BIGINT:
5763 set(hydrated[index2] = BigInt(b));
5764 continue;
5765 case TYPE_REGEXP:
5766 set(hydrated[index2] = new RegExp(b, c));
5767 continue;
5768 case TYPE_SYMBOL:
5769 set(hydrated[index2] = Symbol.for(b));
5770 continue;
5771 case TYPE_SET:
5772 const newSet = /* @__PURE__ */ new Set();
5773 hydrated[index2] = newSet;
5774 for (let i = value.length - 1; i > 0; i--)
5775 stack.push([
5776 value[i],
5777 (v) => {
5778 newSet.add(v);
5779 }
5780 ]);
5781 set(newSet);
5782 continue;
5783 case TYPE_MAP:
5784 const map = /* @__PURE__ */ new Map();
5785 hydrated[index2] = map;
5786 for (let i = value.length - 2; i > 0; i -= 2) {
5787 const r = [];
5788 stack.push([
5789 value[i + 1],
5790 (v) => {
5791 r[1] = v;
5792 }
5793 ]);
5794 stack.push([
5795 value[i],
5796 (k) => {
5797 r[0] = k;
5798 }
5799 ]);
5800 postRun.push(() => {
5801 map.set(r[0], r[1]);
5802 });
5803 }
5804 set(map);
5805 continue;
5806 case TYPE_NULL_OBJECT:
5807 const obj = /* @__PURE__ */ Object.create(null);
5808 hydrated[index2] = obj;
5809 for (const key of Object.keys(b).reverse()) {
5810 const r = [];
5811 stack.push([
5812 b[key],
5813 (v) => {
5814 r[1] = v;
5815 }
5816 ]);
5817 stack.push([
5818 Number(key.slice(1)),
5819 (k) => {
5820 r[0] = k;
5821 }
5822 ]);
5823 postRun.push(() => {
5824 obj[r[0]] = r[1];
5825 });
5826 }
5827 set(obj);
5828 continue;
5829 case TYPE_PROMISE:
5830 if (hydrated[b]) {
5831 set(hydrated[index2] = hydrated[b]);
5832 } else {
5833 const d = new Deferred();
5834 deferred[b] = d;
5835 set(hydrated[index2] = d.promise);
5836 }
5837 continue;
5838 case TYPE_ERROR:
5839 const [, message, errorType] = value;
5840 let error = errorType && globalObj && globalObj[errorType] ? new globalObj[errorType](message) : new Error(message);
5841 hydrated[index2] = error;
5842 set(error);
5843 continue;
5844 case TYPE_PREVIOUS_RESOLVED:
5845 set(hydrated[index2] = hydrated[b]);
5846 continue;
5847 default:
5848 if (Array.isArray(plugins)) {
5849 const r = [];
5850 const vals = value.slice(1);
5851 for (let i = 0; i < vals.length; i++) {
5852 const v = vals[i];
5853 stack.push([
5854 v,
5855 (v2) => {
5856 r[i] = v2;
5857 }
5858 ]);
5859 }
5860 postRun.push(() => {
5861 for (const plugin of plugins) {
5862 const result2 = plugin(value[0], ...r);
5863 if (result2) {
5864 set(hydrated[index2] = result2.value);
5865 return;
5866 }
5867 }
5868 throw new SyntaxError();
5869 });
5870 continue;
5871 }
5872 throw new SyntaxError();
5873 }
5874 } else {
5875 const array = [];
5876 hydrated[index2] = array;
5877 for (let i = 0; i < value.length; i++) {
5878 const n = value[i];
5879 if (n !== HOLE) {
5880 stack.push([
5881 n,
5882 (v) => {
5883 array[i] = v;
5884 }
5885 ]);
5886 }
5887 }
5888 set(array);
5889 continue;
5890 }
5891 } else {
5892 const object = {};
5893 hydrated[index2] = object;
5894 for (const key of Object.keys(value).reverse()) {
5895 const r = [];
5896 stack.push([
5897 value[key],
5898 (v) => {
5899 r[1] = v;
5900 }
5901 ]);
5902 stack.push([
5903 Number(key.slice(1)),
5904 (k) => {
5905 r[0] = k;
5906 }
5907 ]);
5908 postRun.push(() => {
5909 object[r[0]] = r[1];
5910 });
5911 }
5912 set(object);
5913 continue;
5914 }
5915 }
5916 while (postRun.length > 0) {
5917 postRun.pop()();
5918 }
5919 return result;
5920}
5921
5922// vendor/turbo-stream-v2/turbo-stream.ts
5923async function decode(readable, options) {
5924 const { plugins } = _nullishCoalesce(options, () => ( {}));
5925 const done = new Deferred();
5926 const reader = readable.pipeThrough(createLineSplittingTransform()).getReader();
5927 const decoder = {
5928 values: [],
5929 hydrated: [],
5930 deferred: {},
5931 plugins
5932 };
5933 const decoded = await decodeInitial.call(decoder, reader);
5934 let donePromise = done.promise;
5935 if (decoded.done) {
5936 done.resolve();
5937 } else {
5938 donePromise = decodeDeferred.call(decoder, reader).then(done.resolve).catch((reason) => {
5939 for (const deferred of Object.values(decoder.deferred)) {
5940 deferred.reject(reason);
5941 }
5942 done.reject(reason);
5943 });
5944 }
5945 return {
5946 done: donePromise.then(() => reader.closed),
5947 value: decoded.value
5948 };
5949}
5950async function decodeInitial(reader) {
5951 const read = await reader.read();
5952 if (!read.value) {
5953 throw new SyntaxError();
5954 }
5955 let line;
5956 try {
5957 line = JSON.parse(read.value);
5958 } catch (reason) {
5959 throw new SyntaxError();
5960 }
5961 return {
5962 done: read.done,
5963 value: unflatten.call(this, line)
5964 };
5965}
5966async function decodeDeferred(reader) {
5967 let read = await reader.read();
5968 while (!read.done) {
5969 if (!read.value) continue;
5970 const line = read.value;
5971 switch (line[0]) {
5972 case TYPE_PROMISE: {
5973 const colonIndex = line.indexOf(":");
5974 const deferredId = Number(line.slice(1, colonIndex));
5975 const deferred = this.deferred[deferredId];
5976 if (!deferred) {
5977 throw new Error(`Deferred ID ${deferredId} not found in stream`);
5978 }
5979 const lineData = line.slice(colonIndex + 1);
5980 let jsonLine;
5981 try {
5982 jsonLine = JSON.parse(lineData);
5983 } catch (reason) {
5984 throw new SyntaxError();
5985 }
5986 const value = unflatten.call(this, jsonLine);
5987 deferred.resolve(value);
5988 break;
5989 }
5990 case TYPE_ERROR: {
5991 const colonIndex = line.indexOf(":");
5992 const deferredId = Number(line.slice(1, colonIndex));
5993 const deferred = this.deferred[deferredId];
5994 if (!deferred) {
5995 throw new Error(`Deferred ID ${deferredId} not found in stream`);
5996 }
5997 const lineData = line.slice(colonIndex + 1);
5998 let jsonLine;
5999 try {
6000 jsonLine = JSON.parse(lineData);
6001 } catch (reason) {
6002 throw new SyntaxError();
6003 }
6004 const value = unflatten.call(this, jsonLine);
6005 deferred.reject(value);
6006 break;
6007 }
6008 default:
6009 throw new SyntaxError();
6010 }
6011 read = await reader.read();
6012 }
6013}
6014function encode(input, options) {
6015 const { plugins, postPlugins, signal, onComplete } = _nullishCoalesce(options, () => ( {}));
6016 const encoder = {
6017 deferred: {},
6018 index: 0,
6019 indices: /* @__PURE__ */ new Map(),
6020 stringified: [],
6021 plugins,
6022 postPlugins,
6023 signal
6024 };
6025 const textEncoder = new TextEncoder();
6026 let lastSentIndex = 0;
6027 const readable = new ReadableStream({
6028 async start(controller) {
6029 const id = flatten.call(encoder, input);
6030 if (Array.isArray(id)) {
6031 throw new Error("This should never happen");
6032 }
6033 if (id < 0) {
6034 controller.enqueue(textEncoder.encode(`${id}
6035`));
6036 } else {
6037 controller.enqueue(
6038 textEncoder.encode(`[${encoder.stringified.join(",")}]
6039`)
6040 );
6041 lastSentIndex = encoder.stringified.length - 1;
6042 }
6043 const seenPromises = /* @__PURE__ */ new WeakSet();
6044 if (Object.keys(encoder.deferred).length) {
6045 let raceDone;
6046 const racePromise = new Promise((resolve, reject) => {
6047 raceDone = resolve;
6048 if (signal) {
6049 const rejectPromise = () => reject(signal.reason || new Error("Signal was aborted."));
6050 if (signal.aborted) {
6051 rejectPromise();
6052 } else {
6053 signal.addEventListener("abort", (event) => {
6054 rejectPromise();
6055 });
6056 }
6057 }
6058 });
6059 while (Object.keys(encoder.deferred).length > 0) {
6060 for (const [deferredId, deferred] of Object.entries(
6061 encoder.deferred
6062 )) {
6063 if (seenPromises.has(deferred)) continue;
6064 seenPromises.add(
6065 // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
6066 encoder.deferred[Number(deferredId)] = Promise.race([
6067 racePromise,
6068 deferred
6069 ]).then(
6070 (resolved) => {
6071 const id2 = flatten.call(encoder, resolved);
6072 if (Array.isArray(id2)) {
6073 controller.enqueue(
6074 textEncoder.encode(
6075 `${TYPE_PROMISE}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]]
6076`
6077 )
6078 );
6079 encoder.index++;
6080 lastSentIndex++;
6081 } else if (id2 < 0) {
6082 controller.enqueue(
6083 textEncoder.encode(
6084 `${TYPE_PROMISE}${deferredId}:${id2}
6085`
6086 )
6087 );
6088 } else {
6089 const values = encoder.stringified.slice(lastSentIndex + 1).join(",");
6090 controller.enqueue(
6091 textEncoder.encode(
6092 `${TYPE_PROMISE}${deferredId}:[${values}]
6093`
6094 )
6095 );
6096 lastSentIndex = encoder.stringified.length - 1;
6097 }
6098 },
6099 (reason) => {
6100 if (!reason || typeof reason !== "object" || !(reason instanceof Error)) {
6101 reason = new Error("An unknown error occurred");
6102 }
6103 const id2 = flatten.call(encoder, reason);
6104 if (Array.isArray(id2)) {
6105 controller.enqueue(
6106 textEncoder.encode(
6107 `${TYPE_ERROR}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]]
6108`
6109 )
6110 );
6111 encoder.index++;
6112 lastSentIndex++;
6113 } else if (id2 < 0) {
6114 controller.enqueue(
6115 textEncoder.encode(
6116 `${TYPE_ERROR}${deferredId}:${id2}
6117`
6118 )
6119 );
6120 } else {
6121 const values = encoder.stringified.slice(lastSentIndex + 1).join(",");
6122 controller.enqueue(
6123 textEncoder.encode(
6124 `${TYPE_ERROR}${deferredId}:[${values}]
6125`
6126 )
6127 );
6128 lastSentIndex = encoder.stringified.length - 1;
6129 }
6130 }
6131 ).finally(() => {
6132 delete encoder.deferred[Number(deferredId)];
6133 })
6134 );
6135 }
6136 await Promise.race(Object.values(encoder.deferred));
6137 }
6138 raceDone();
6139 }
6140 await Promise.all(Object.values(encoder.deferred));
6141 _optionalChain([onComplete, 'optionalCall', _81 => _81()]);
6142 controller.close();
6143 }
6144 });
6145 return readable;
6146}
6147
6148// lib/dom/ssr/data.ts
6149async function createRequestInit(request) {
6150 let init = { signal: request.signal };
6151 if (request.method !== "GET") {
6152 init.method = request.method;
6153 let contentType = request.headers.get("Content-Type");
6154 if (contentType && /\bapplication\/json\b/.test(contentType)) {
6155 init.headers = { "Content-Type": contentType };
6156 init.body = JSON.stringify(await request.json());
6157 } else if (contentType && /\btext\/plain\b/.test(contentType)) {
6158 init.headers = { "Content-Type": contentType };
6159 init.body = await request.text();
6160 } else if (contentType && /\bapplication\/x-www-form-urlencoded\b/.test(contentType)) {
6161 init.body = new URLSearchParams(await request.text());
6162 } else {
6163 init.body = await request.formData();
6164 }
6165 }
6166 return init;
6167}
6168
6169// lib/dom/ssr/markup.ts
6170var ESCAPE_LOOKUP = {
6171 "&": "\\u0026",
6172 ">": "\\u003e",
6173 "<": "\\u003c",
6174 "\u2028": "\\u2028",
6175 "\u2029": "\\u2029"
6176};
6177var ESCAPE_REGEX = /[&><\u2028\u2029]/g;
6178function escapeHtml(html) {
6179 return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
6180}
6181
6182// lib/dom/ssr/invariant.ts
6183function invariant2(value, message) {
6184 if (value === false || value === null || typeof value === "undefined") {
6185 throw new Error(message);
6186 }
6187}
6188
6189// lib/dom/ssr/single-fetch.tsx
6190var SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect");
6191var SingleFetchNoResultError = class extends Error {
6192};
6193var SINGLE_FETCH_REDIRECT_STATUS = 202;
6194var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205]);
6195function StreamTransfer({
6196 context,
6197 identifier,
6198 reader,
6199 textDecoder,
6200 nonce
6201}) {
6202 if (!context.renderMeta || !context.renderMeta.didRenderScripts) {
6203 return null;
6204 }
6205 if (!context.renderMeta.streamCache) {
6206 context.renderMeta.streamCache = {};
6207 }
6208 let { streamCache } = context.renderMeta;
6209 let promise = streamCache[identifier];
6210 if (!promise) {
6211 promise = streamCache[identifier] = reader.read().then((result) => {
6212 streamCache[identifier].result = {
6213 done: result.done,
6214 value: textDecoder.decode(result.value, { stream: true })
6215 };
6216 }).catch((e) => {
6217 streamCache[identifier].error = e;
6218 });
6219 }
6220 if (promise.error) {
6221 throw promise.error;
6222 }
6223 if (promise.result === void 0) {
6224 throw promise;
6225 }
6226 let { done, value } = promise.result;
6227 let scriptTag = value ? /* @__PURE__ */ React.createElement(
6228 "script",
6229 {
6230 nonce,
6231 dangerouslySetInnerHTML: {
6232 __html: `window.__reactRouterContext.streamController.enqueue(${escapeHtml(
6233 JSON.stringify(value)
6234 )});`
6235 }
6236 }
6237 ) : null;
6238 if (done) {
6239 return /* @__PURE__ */ React.createElement(React.Fragment, null, scriptTag, /* @__PURE__ */ React.createElement(
6240 "script",
6241 {
6242 nonce,
6243 dangerouslySetInnerHTML: {
6244 __html: `window.__reactRouterContext.streamController.close();`
6245 }
6246 }
6247 ));
6248 } else {
6249 return /* @__PURE__ */ React.createElement(React.Fragment, null, scriptTag, /* @__PURE__ */ React.createElement(React.Suspense, null, /* @__PURE__ */ React.createElement(
6250 StreamTransfer,
6251 {
6252 context,
6253 identifier: identifier + 1,
6254 reader,
6255 textDecoder,
6256 nonce
6257 }
6258 )));
6259 }
6260}
6261function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr, basename, trailingSlashAware) {
6262 let dataStrategy = getSingleFetchDataStrategyImpl(
6263 getRouter,
6264 (match) => {
6265 let manifestRoute = manifest.routes[match.route.id];
6266 invariant2(manifestRoute, "Route not found in manifest");
6267 let routeModule = routeModules[match.route.id];
6268 return {
6269 hasLoader: manifestRoute.hasLoader,
6270 hasClientLoader: manifestRoute.hasClientLoader,
6271 hasShouldRevalidate: Boolean(_optionalChain([routeModule, 'optionalAccess', _82 => _82.shouldRevalidate]))
6272 };
6273 },
6274 fetchAndDecodeViaTurboStream,
6275 ssr,
6276 basename,
6277 trailingSlashAware
6278 );
6279 return async (args) => args.runClientMiddleware(dataStrategy);
6280}
6281function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, basename, trailingSlashAware, shouldAllowOptOut = () => true) {
6282 return async (args) => {
6283 let { request, matches, fetcherKey } = args;
6284 let router = getRouter();
6285 if (request.method !== "GET") {
6286 return singleFetchActionStrategy(
6287 args,
6288 fetchAndDecode,
6289 basename,
6290 trailingSlashAware
6291 );
6292 }
6293 let foundRevalidatingServerLoader = matches.some((m) => {
6294 let { hasLoader, hasClientLoader } = getRouteInfo(m);
6295 return m.shouldCallHandler() && hasLoader && !hasClientLoader;
6296 });
6297 if (!ssr && !foundRevalidatingServerLoader) {
6298 return nonSsrStrategy(
6299 args,
6300 getRouteInfo,
6301 fetchAndDecode,
6302 basename,
6303 trailingSlashAware
6304 );
6305 }
6306 if (fetcherKey) {
6307 return singleFetchLoaderFetcherStrategy(
6308 args,
6309 fetchAndDecode,
6310 basename,
6311 trailingSlashAware
6312 );
6313 }
6314 return singleFetchLoaderNavigationStrategy(
6315 args,
6316 router,
6317 getRouteInfo,
6318 fetchAndDecode,
6319 ssr,
6320 basename,
6321 trailingSlashAware,
6322 shouldAllowOptOut
6323 );
6324 };
6325}
6326async function singleFetchActionStrategy(args, fetchAndDecode, basename, trailingSlashAware) {
6327 let actionMatch = args.matches.find((m) => m.shouldCallHandler());
6328 invariant2(actionMatch, "No action match found");
6329 let actionStatus = void 0;
6330 let result = await actionMatch.resolve(async (handler) => {
6331 let result2 = await handler(async () => {
6332 let { data: data2, status } = await fetchAndDecode(
6333 args,
6334 basename,
6335 trailingSlashAware,
6336 [actionMatch.route.id]
6337 );
6338 actionStatus = status;
6339 return unwrapSingleFetchResult(data2, actionMatch.route.id);
6340 });
6341 return result2;
6342 });
6343 if (isResponse(result.result) || isRouteErrorResponse(result.result) || isDataWithResponseInit(result.result)) {
6344 return { [actionMatch.route.id]: result };
6345 }
6346 return {
6347 [actionMatch.route.id]: {
6348 type: result.type,
6349 result: data(result.result, actionStatus)
6350 }
6351 };
6352}
6353async function nonSsrStrategy(args, getRouteInfo, fetchAndDecode, basename, trailingSlashAware) {
6354 let matchesToLoad = args.matches.filter((m) => m.shouldCallHandler());
6355 let results = {};
6356 await Promise.all(
6357 matchesToLoad.map(
6358 (m) => m.resolve(async (handler) => {
6359 try {
6360 let { hasClientLoader } = getRouteInfo(m);
6361 let routeId = m.route.id;
6362 let result = hasClientLoader ? await handler(async () => {
6363 let { data: data2 } = await fetchAndDecode(
6364 args,
6365 basename,
6366 trailingSlashAware,
6367 [routeId]
6368 );
6369 return unwrapSingleFetchResult(data2, routeId);
6370 }) : await handler();
6371 results[m.route.id] = { type: "data", result };
6372 } catch (e) {
6373 results[m.route.id] = { type: "error", result: e };
6374 }
6375 })
6376 )
6377 );
6378 return results;
6379}
6380async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, basename, trailingSlashAware, shouldAllowOptOut = () => true) {
6381 let routesParams = /* @__PURE__ */ new Set();
6382 let foundOptOutRoute = false;
6383 let routeDfds = args.matches.map(() => createDeferred2());
6384 let singleFetchDfd = createDeferred2();
6385 let results = {};
6386 let resolvePromise = Promise.all(
6387 args.matches.map(
6388 async (m, i) => m.resolve(async (handler) => {
6389 routeDfds[i].resolve();
6390 let routeId = m.route.id;
6391 let { hasLoader, hasClientLoader, hasShouldRevalidate } = getRouteInfo(m);
6392 let defaultShouldRevalidate = !m.shouldRevalidateArgs || m.shouldRevalidateArgs.actionStatus == null || m.shouldRevalidateArgs.actionStatus < 400;
6393 let shouldCall = m.shouldCallHandler(defaultShouldRevalidate);
6394 if (!shouldCall) {
6395 foundOptOutRoute || (foundOptOutRoute = m.shouldRevalidateArgs != null && // This is a revalidation,
6396 hasLoader && // for a route with a server loader,
6397 hasShouldRevalidate === true);
6398 return;
6399 }
6400 if (shouldAllowOptOut(m) && hasClientLoader) {
6401 if (hasLoader) {
6402 foundOptOutRoute = true;
6403 }
6404 try {
6405 let result = await handler(async () => {
6406 let { data: data2 } = await fetchAndDecode(
6407 args,
6408 basename,
6409 trailingSlashAware,
6410 [routeId]
6411 );
6412 return unwrapSingleFetchResult(data2, routeId);
6413 });
6414 results[routeId] = { type: "data", result };
6415 } catch (e) {
6416 results[routeId] = { type: "error", result: e };
6417 }
6418 return;
6419 }
6420 if (hasLoader) {
6421 routesParams.add(routeId);
6422 }
6423 try {
6424 let result = await handler(async () => {
6425 let data2 = await singleFetchDfd.promise;
6426 return unwrapSingleFetchResult(data2, routeId);
6427 });
6428 results[routeId] = { type: "data", result };
6429 } catch (e) {
6430 results[routeId] = { type: "error", result: e };
6431 }
6432 })
6433 )
6434 );
6435 await Promise.all(routeDfds.map((d) => d.promise));
6436 let isInitialLoad = !router.state.initialized && router.state.navigation.state === "idle";
6437 if ((isInitialLoad || routesParams.size === 0) && !window.__reactRouterHdrActive) {
6438 singleFetchDfd.resolve({ routes: {} });
6439 } else {
6440 let targetRoutes = ssr && foundOptOutRoute && routesParams.size > 0 ? [...routesParams.keys()] : void 0;
6441 try {
6442 let data2 = await fetchAndDecode(
6443 args,
6444 basename,
6445 trailingSlashAware,
6446 targetRoutes
6447 );
6448 singleFetchDfd.resolve(data2.data);
6449 } catch (e) {
6450 singleFetchDfd.reject(e);
6451 }
6452 }
6453 await resolvePromise;
6454 await bubbleMiddlewareErrors(
6455 singleFetchDfd.promise,
6456 args.matches,
6457 routesParams,
6458 results
6459 );
6460 return results;
6461}
6462async function bubbleMiddlewareErrors(singleFetchPromise, matches, routesParams, results) {
6463 try {
6464 let middlewareError;
6465 let fetchedData = await singleFetchPromise;
6466 if ("routes" in fetchedData) {
6467 for (let match of matches) {
6468 if (match.route.id in fetchedData.routes) {
6469 let routeResult = fetchedData.routes[match.route.id];
6470 if ("error" in routeResult) {
6471 middlewareError = routeResult.error;
6472 if (_optionalChain([results, 'access', _83 => _83[match.route.id], 'optionalAccess', _84 => _84.result]) == null) {
6473 results[match.route.id] = {
6474 type: "error",
6475 result: middlewareError
6476 };
6477 }
6478 break;
6479 }
6480 }
6481 }
6482 }
6483 if (middlewareError !== void 0) {
6484 Array.from(routesParams.values()).forEach((routeId) => {
6485 if (results[routeId].result instanceof SingleFetchNoResultError) {
6486 results[routeId].result = middlewareError;
6487 }
6488 });
6489 }
6490 } catch (e) {
6491 }
6492}
6493async function singleFetchLoaderFetcherStrategy(args, fetchAndDecode, basename, trailingSlashAware) {
6494 let fetcherMatch = args.matches.find((m) => m.shouldCallHandler());
6495 invariant2(fetcherMatch, "No fetcher match found");
6496 let routeId = fetcherMatch.route.id;
6497 let result = await fetcherMatch.resolve(
6498 async (handler) => handler(async () => {
6499 let { data: data2 } = await fetchAndDecode(args, basename, trailingSlashAware, [
6500 routeId
6501 ]);
6502 return unwrapSingleFetchResult(data2, routeId);
6503 })
6504 );
6505 return { [fetcherMatch.route.id]: result };
6506}
6507function stripIndexParam(url) {
6508 let indexValues = url.searchParams.getAll("index");
6509 url.searchParams.delete("index");
6510 let indexValuesToKeep = [];
6511 for (let indexValue of indexValues) {
6512 if (indexValue) {
6513 indexValuesToKeep.push(indexValue);
6514 }
6515 }
6516 for (let toKeep of indexValuesToKeep) {
6517 url.searchParams.append("index", toKeep);
6518 }
6519 return url;
6520}
6521function singleFetchUrl(reqUrl, basename, trailingSlashAware, extension) {
6522 let url = typeof reqUrl === "string" ? new URL(
6523 reqUrl,
6524 // This can be called during the SSR flow via PrefetchPageLinksImpl so
6525 // don't assume window is available
6526 typeof window === "undefined" ? "server://singlefetch/" : window.location.origin
6527 ) : reqUrl;
6528 if (trailingSlashAware) {
6529 if (url.pathname.endsWith("/")) {
6530 url.pathname = `${url.pathname}_.${extension}`;
6531 } else {
6532 url.pathname = `${url.pathname}.${extension}`;
6533 }
6534 } else {
6535 if (url.pathname === "/") {
6536 url.pathname = `_root.${extension}`;
6537 } else if (basename && stripBasename(url.pathname, basename) === "/") {
6538 url.pathname = `${basename.replace(/\/$/, "")}/_root.${extension}`;
6539 } else {
6540 url.pathname = `${url.pathname.replace(/\/$/, "")}.${extension}`;
6541 }
6542 }
6543 return url;
6544}
6545async function fetchAndDecodeViaTurboStream(args, basename, trailingSlashAware, targetRoutes) {
6546 let { request } = args;
6547 let url = singleFetchUrl(request.url, basename, trailingSlashAware, "data");
6548 if (request.method === "GET") {
6549 url = stripIndexParam(url);
6550 if (targetRoutes) {
6551 url.searchParams.set("_routes", targetRoutes.join(","));
6552 }
6553 }
6554 let res = await fetch(url, await createRequestInit(request));
6555 if (res.status >= 400 && !res.headers.has("X-Remix-Response")) {
6556 throw new ErrorResponseImpl(res.status, res.statusText, await res.text());
6557 }
6558 if (res.status === 204 && res.headers.has("X-Remix-Redirect")) {
6559 return {
6560 status: SINGLE_FETCH_REDIRECT_STATUS,
6561 data: {
6562 redirect: {
6563 redirect: res.headers.get("X-Remix-Redirect"),
6564 status: Number(res.headers.get("X-Remix-Status") || "302"),
6565 revalidate: res.headers.get("X-Remix-Revalidate") === "true",
6566 reload: res.headers.get("X-Remix-Reload-Document") === "true",
6567 replace: res.headers.get("X-Remix-Replace") === "true"
6568 }
6569 }
6570 };
6571 }
6572 if (NO_BODY_STATUS_CODES.has(res.status)) {
6573 let routes = {};
6574 if (targetRoutes && request.method !== "GET") {
6575 routes[targetRoutes[0]] = { data: void 0 };
6576 }
6577 return {
6578 status: res.status,
6579 data: { routes }
6580 };
6581 }
6582 invariant2(res.body, "No response body to decode");
6583 try {
6584 let decoded = await decodeViaTurboStream(res.body, window);
6585 let data2;
6586 if (request.method === "GET") {
6587 let typed = decoded.value;
6588 if (SingleFetchRedirectSymbol in typed) {
6589 data2 = { redirect: typed[SingleFetchRedirectSymbol] };
6590 } else {
6591 data2 = { routes: typed };
6592 }
6593 } else {
6594 let typed = decoded.value;
6595 let routeId = _optionalChain([targetRoutes, 'optionalAccess', _85 => _85[0]]);
6596 invariant2(routeId, "No routeId found for single fetch call decoding");
6597 if ("redirect" in typed) {
6598 data2 = { redirect: typed };
6599 } else {
6600 data2 = { routes: { [routeId]: typed } };
6601 }
6602 }
6603 return { status: res.status, data: data2 };
6604 } catch (e) {
6605 throw new Error("Unable to decode turbo-stream response");
6606 }
6607}
6608function decodeViaTurboStream(body, global) {
6609 return decode(body, {
6610 plugins: [
6611 (type, ...rest) => {
6612 if (type === "SanitizedError") {
6613 let [name, message, stack] = rest;
6614 let Constructor = Error;
6615 if (name && name in global && typeof global[name] === "function") {
6616 Constructor = global[name];
6617 }
6618 let error = new Constructor(message);
6619 error.stack = stack;
6620 return { value: error };
6621 }
6622 if (type === "ErrorResponse") {
6623 let [data2, status, statusText] = rest;
6624 return {
6625 value: new ErrorResponseImpl(status, statusText, data2)
6626 };
6627 }
6628 if (type === "SingleFetchRedirect") {
6629 return { value: { [SingleFetchRedirectSymbol]: rest[0] } };
6630 }
6631 if (type === "SingleFetchClassInstance") {
6632 return { value: rest[0] };
6633 }
6634 if (type === "SingleFetchFallback") {
6635 return { value: void 0 };
6636 }
6637 }
6638 ]
6639 });
6640}
6641function unwrapSingleFetchResult(result, routeId) {
6642 if ("redirect" in result) {
6643 let {
6644 redirect: location,
6645 revalidate,
6646 reload,
6647 replace: replace2,
6648 status
6649 } = result.redirect;
6650 throw redirect(location, {
6651 status,
6652 headers: {
6653 // Three R's of redirecting (lol Veep)
6654 ...revalidate ? { "X-Remix-Revalidate": "yes" } : null,
6655 ...reload ? { "X-Remix-Reload-Document": "yes" } : null,
6656 ...replace2 ? { "X-Remix-Replace": "yes" } : null
6657 }
6658 });
6659 }
6660 let routeResult = result.routes[routeId];
6661 if (routeResult == null) {
6662 throw new SingleFetchNoResultError(
6663 `No result found for routeId "${routeId}"`
6664 );
6665 } else if ("error" in routeResult) {
6666 throw routeResult.error;
6667 } else if ("data" in routeResult) {
6668 return routeResult.data;
6669 } else {
6670 throw new Error(`Invalid response found for routeId "${routeId}"`);
6671 }
6672}
6673function createDeferred2() {
6674 let resolve;
6675 let reject;
6676 let promise = new Promise((res, rej) => {
6677 resolve = async (val) => {
6678 res(val);
6679 try {
6680 await promise;
6681 } catch (e) {
6682 }
6683 };
6684 reject = async (error) => {
6685 rej(error);
6686 try {
6687 await promise;
6688 } catch (e) {
6689 }
6690 };
6691 });
6692 return {
6693 promise,
6694 //@ts-ignore
6695 resolve,
6696 //@ts-ignore
6697 reject
6698 };
6699}
6700
6701// lib/context.ts
6702
6703var DataRouterContext = React2.createContext(null);
6704DataRouterContext.displayName = "DataRouter";
6705var DataRouterStateContext = React2.createContext(null);
6706DataRouterStateContext.displayName = "DataRouterState";
6707var RSCRouterContext = React2.createContext(false);
6708function useIsRSCRouterContext() {
6709 return React2.useContext(RSCRouterContext);
6710}
6711var ViewTransitionContext = React2.createContext({
6712 isTransitioning: false
6713});
6714ViewTransitionContext.displayName = "ViewTransition";
6715var FetchersContext = React2.createContext(
6716 /* @__PURE__ */ new Map()
6717);
6718FetchersContext.displayName = "Fetchers";
6719var AwaitContext = React2.createContext(null);
6720AwaitContext.displayName = "Await";
6721var AwaitContextProvider = (props) => React2.createElement(AwaitContext.Provider, props);
6722var NavigationContext = React2.createContext(
6723 null
6724);
6725NavigationContext.displayName = "Navigation";
6726var LocationContext = React2.createContext(
6727 null
6728);
6729LocationContext.displayName = "Location";
6730var RouteContext = React2.createContext({
6731 outlet: null,
6732 matches: [],
6733 isDataRoute: false
6734});
6735RouteContext.displayName = "Route";
6736var RouteErrorContext = React2.createContext(null);
6737RouteErrorContext.displayName = "RouteError";
6738var ENABLE_DEV_WARNINGS = false;
6739
6740// lib/hooks.tsx
6741
6742
6743// lib/errors.ts
6744var ERROR_DIGEST_BASE = "REACT_ROUTER_ERROR";
6745var ERROR_DIGEST_REDIRECT = "REDIRECT";
6746var ERROR_DIGEST_ROUTE_ERROR_RESPONSE = "ROUTE_ERROR_RESPONSE";
6747function decodeRedirectErrorDigest(digest) {
6748 if (digest.startsWith(`${ERROR_DIGEST_BASE}:${ERROR_DIGEST_REDIRECT}:{`)) {
6749 try {
6750 let parsed = JSON.parse(digest.slice(28));
6751 if (typeof parsed === "object" && parsed && typeof parsed.status === "number" && typeof parsed.statusText === "string" && typeof parsed.location === "string" && typeof parsed.reloadDocument === "boolean" && typeof parsed.replace === "boolean") {
6752 return parsed;
6753 }
6754 } catch (e2) {
6755 }
6756 }
6757}
6758function decodeRouteErrorResponseDigest(digest) {
6759 if (digest.startsWith(
6760 `${ERROR_DIGEST_BASE}:${ERROR_DIGEST_ROUTE_ERROR_RESPONSE}:{`
6761 )) {
6762 try {
6763 let parsed = JSON.parse(digest.slice(40));
6764 if (typeof parsed === "object" && parsed && typeof parsed.status === "number" && typeof parsed.statusText === "string") {
6765 return new ErrorResponseImpl(
6766 parsed.status,
6767 parsed.statusText,
6768 parsed.data
6769 );
6770 }
6771 } catch (e3) {
6772 }
6773 }
6774}
6775
6776// lib/hooks.tsx
6777function useHref(to, { relative } = {}) {
6778 invariant(
6779 useInRouterContext(),
6780 // TODO: This error is probably because they somehow have 2 versions of the
6781 // router loaded. We can help them understand how to avoid that.
6782 `useHref() may be used only in the context of a <Router> component.`
6783 );
6784 let { basename, navigator } = React3.useContext(NavigationContext);
6785 let { hash, pathname, search } = useResolvedPath(to, { relative });
6786 let joinedPathname = pathname;
6787 if (basename !== "/") {
6788 joinedPathname = pathname === "/" ? basename : joinPaths([basename, pathname]);
6789 }
6790 return navigator.createHref({ pathname: joinedPathname, search, hash });
6791}
6792function useInRouterContext() {
6793 return React3.useContext(LocationContext) != null;
6794}
6795function useLocation() {
6796 invariant(
6797 useInRouterContext(),
6798 // TODO: This error is probably because they somehow have 2 versions of the
6799 // router loaded. We can help them understand how to avoid that.
6800 `useLocation() may be used only in the context of a <Router> component.`
6801 );
6802 return React3.useContext(LocationContext).location;
6803}
6804function useNavigationType() {
6805 return React3.useContext(LocationContext).navigationType;
6806}
6807function useMatch(pattern) {
6808 invariant(
6809 useInRouterContext(),
6810 // TODO: This error is probably because they somehow have 2 versions of the
6811 // router loaded. We can help them understand how to avoid that.
6812 `useMatch() may be used only in the context of a <Router> component.`
6813 );
6814 let { pathname } = useLocation();
6815 return React3.useMemo(
6816 () => matchPath(pattern, decodePath(pathname)),
6817 [pathname, pattern]
6818 );
6819}
6820var navigateEffectWarning = `You should call navigate() in a React.useEffect(), not when your component is first rendered.`;
6821function useIsomorphicLayoutEffect(cb) {
6822 let isStatic = React3.useContext(NavigationContext).static;
6823 if (!isStatic) {
6824 React3.useLayoutEffect(cb);
6825 }
6826}
6827function useNavigate() {
6828 let { isDataRoute } = React3.useContext(RouteContext);
6829 return isDataRoute ? useNavigateStable() : useNavigateUnstable();
6830}
6831function useNavigateUnstable() {
6832 invariant(
6833 useInRouterContext(),
6834 // TODO: This error is probably because they somehow have 2 versions of the
6835 // router loaded. We can help them understand how to avoid that.
6836 `useNavigate() may be used only in the context of a <Router> component.`
6837 );
6838 let dataRouterContext = React3.useContext(DataRouterContext);
6839 let { basename, navigator } = React3.useContext(NavigationContext);
6840 let { matches } = React3.useContext(RouteContext);
6841 let { pathname: locationPathname } = useLocation();
6842 let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));
6843 let activeRef = React3.useRef(false);
6844 useIsomorphicLayoutEffect(() => {
6845 activeRef.current = true;
6846 });
6847 let navigate = React3.useCallback(
6848 (to, options = {}) => {
6849 warning(activeRef.current, navigateEffectWarning);
6850 if (!activeRef.current) return;
6851 if (typeof to === "number") {
6852 navigator.go(to);
6853 return;
6854 }
6855 let path = resolveTo(
6856 to,
6857 JSON.parse(routePathnamesJson),
6858 locationPathname,
6859 options.relative === "path"
6860 );
6861 if (dataRouterContext == null && basename !== "/") {
6862 path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
6863 }
6864 (!!options.replace ? navigator.replace : navigator.push)(
6865 path,
6866 options.state,
6867 options
6868 );
6869 },
6870 [
6871 basename,
6872 navigator,
6873 routePathnamesJson,
6874 locationPathname,
6875 dataRouterContext
6876 ]
6877 );
6878 return navigate;
6879}
6880var OutletContext = React3.createContext(null);
6881function useOutletContext() {
6882 return React3.useContext(OutletContext);
6883}
6884function useOutlet(context) {
6885 let outlet = React3.useContext(RouteContext).outlet;
6886 return React3.useMemo(
6887 () => outlet && /* @__PURE__ */ React3.createElement(OutletContext.Provider, { value: context }, outlet),
6888 [outlet, context]
6889 );
6890}
6891function useParams() {
6892 let { matches } = React3.useContext(RouteContext);
6893 let routeMatch = matches[matches.length - 1];
6894 return routeMatch ? routeMatch.params : {};
6895}
6896function useResolvedPath(to, { relative } = {}) {
6897 let { matches } = React3.useContext(RouteContext);
6898 let { pathname: locationPathname } = useLocation();
6899 let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));
6900 return React3.useMemo(
6901 () => resolveTo(
6902 to,
6903 JSON.parse(routePathnamesJson),
6904 locationPathname,
6905 relative === "path"
6906 ),
6907 [to, routePathnamesJson, locationPathname, relative]
6908 );
6909}
6910function useRoutes(routes, locationArg) {
6911 return useRoutesImpl(routes, locationArg);
6912}
6913function useRoutesImpl(routes, locationArg, dataRouterOpts) {
6914 invariant(
6915 useInRouterContext(),
6916 // TODO: This error is probably because they somehow have 2 versions of the
6917 // router loaded. We can help them understand how to avoid that.
6918 `useRoutes() may be used only in the context of a <Router> component.`
6919 );
6920 let { navigator } = React3.useContext(NavigationContext);
6921 let { matches: parentMatches } = React3.useContext(RouteContext);
6922 let routeMatch = parentMatches[parentMatches.length - 1];
6923 let parentParams = routeMatch ? routeMatch.params : {};
6924 let parentPathname = routeMatch ? routeMatch.pathname : "/";
6925 let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
6926 let parentRoute = routeMatch && routeMatch.route;
6927 if (ENABLE_DEV_WARNINGS) {
6928 let parentPath = parentRoute && parentRoute.path || "";
6929 warningOnce(
6930 parentPathname,
6931 !parentRoute || parentPath.endsWith("*") || parentPath.endsWith("*?"),
6932 `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.
6933
6934Please change the parent <Route path="${parentPath}"> to <Route path="${parentPath === "/" ? "*" : `${parentPath}/*`}">.`
6935 );
6936 }
6937 let locationFromContext = useLocation();
6938 let location;
6939 if (locationArg) {
6940 let parsedLocationArg = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
6941 invariant(
6942 parentPathnameBase === "/" || _optionalChain([parsedLocationArg, 'access', _86 => _86.pathname, 'optionalAccess', _87 => _87.startsWith, 'call', _88 => _88(parentPathnameBase)]),
6943 `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.`
6944 );
6945 location = parsedLocationArg;
6946 } else {
6947 location = locationFromContext;
6948 }
6949 let pathname = location.pathname || "/";
6950 let remainingPathname = pathname;
6951 if (parentPathnameBase !== "/") {
6952 let parentSegments = parentPathnameBase.replace(/^\//, "").split("/");
6953 let segments = pathname.replace(/^\//, "").split("/");
6954 remainingPathname = "/" + segments.slice(parentSegments.length).join("/");
6955 }
6956 let matches = matchRoutes(routes, { pathname: remainingPathname });
6957 if (ENABLE_DEV_WARNINGS) {
6958 warning(
6959 parentRoute || matches != null,
6960 `No routes matched location "${location.pathname}${location.search}${location.hash}" `
6961 );
6962 warning(
6963 matches == null || matches[matches.length - 1].route.element !== void 0 || matches[matches.length - 1].route.Component !== void 0 || matches[matches.length - 1].route.lazy !== void 0,
6964 `Matched leaf route at location "${location.pathname}${location.search}${location.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`
6965 );
6966 }
6967 let renderedMatches = _renderMatches(
6968 matches && matches.map(
6969 (match) => Object.assign({}, match, {
6970 params: Object.assign({}, parentParams, match.params),
6971 pathname: joinPaths([
6972 parentPathnameBase,
6973 // Re-encode pathnames that were decoded inside matchRoutes.
6974 // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses
6975 // `new URL()` internally and we need to prevent it from treating
6976 // them as separators
6977 navigator.encodeLocation ? navigator.encodeLocation(
6978 match.pathname.replace(/\?/g, "%3F").replace(/#/g, "%23")
6979 ).pathname : match.pathname
6980 ]),
6981 pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([
6982 parentPathnameBase,
6983 // Re-encode pathnames that were decoded inside matchRoutes
6984 // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses
6985 // `new URL()` internally and we need to prevent it from treating
6986 // them as separators
6987 navigator.encodeLocation ? navigator.encodeLocation(
6988 match.pathnameBase.replace(/\?/g, "%3F").replace(/#/g, "%23")
6989 ).pathname : match.pathnameBase
6990 ])
6991 })
6992 ),
6993 parentMatches,
6994 dataRouterOpts
6995 );
6996 if (locationArg && renderedMatches) {
6997 return /* @__PURE__ */ React3.createElement(
6998 LocationContext.Provider,
6999 {
7000 value: {
7001 location: {
7002 pathname: "/",
7003 search: "",
7004 hash: "",
7005 state: null,
7006 key: "default",
7007 unstable_mask: void 0,
7008 ...location
7009 },
7010 navigationType: "POP" /* Pop */
7011 }
7012 },
7013 renderedMatches
7014 );
7015 }
7016 return renderedMatches;
7017}
7018function DefaultErrorComponent() {
7019 let error = useRouteError();
7020 let message = isRouteErrorResponse(error) ? `${error.status} ${error.statusText}` : error instanceof Error ? error.message : JSON.stringify(error);
7021 let stack = error instanceof Error ? error.stack : null;
7022 let lightgrey = "rgba(200,200,200, 0.5)";
7023 let preStyles = { padding: "0.5rem", backgroundColor: lightgrey };
7024 let codeStyles = { padding: "2px 4px", backgroundColor: lightgrey };
7025 let devInfo = null;
7026 if (ENABLE_DEV_WARNINGS) {
7027 console.error(
7028 "Error handled by React Router default ErrorBoundary:",
7029 error
7030 );
7031 devInfo = /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("p", null, "\u{1F4BF} Hey developer \u{1F44B}"), /* @__PURE__ */ React3.createElement("p", null, "You can provide a way better UX than this when your app throws errors by providing your own ", /* @__PURE__ */ React3.createElement("code", { style: codeStyles }, "ErrorBoundary"), " or", " ", /* @__PURE__ */ React3.createElement("code", { style: codeStyles }, "errorElement"), " prop on your route."));
7032 }
7033 return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("h2", null, "Unexpected Application Error!"), /* @__PURE__ */ React3.createElement("h3", { style: { fontStyle: "italic" } }, message), stack ? /* @__PURE__ */ React3.createElement("pre", { style: preStyles }, stack) : null, devInfo);
7034}
7035var defaultErrorElement = /* @__PURE__ */ React3.createElement(DefaultErrorComponent, null);
7036var RenderErrorBoundary = class extends React3.Component {
7037 constructor(props) {
7038 super(props);
7039 this.state = {
7040 location: props.location,
7041 revalidation: props.revalidation,
7042 error: props.error
7043 };
7044 }
7045 static getDerivedStateFromError(error) {
7046 return { error };
7047 }
7048 static getDerivedStateFromProps(props, state) {
7049 if (state.location !== props.location || state.revalidation !== "idle" && props.revalidation === "idle") {
7050 return {
7051 error: props.error,
7052 location: props.location,
7053 revalidation: props.revalidation
7054 };
7055 }
7056 return {
7057 error: props.error !== void 0 ? props.error : state.error,
7058 location: state.location,
7059 revalidation: props.revalidation || state.revalidation
7060 };
7061 }
7062 componentDidCatch(error, errorInfo) {
7063 if (this.props.onError) {
7064 this.props.onError(error, errorInfo);
7065 } else {
7066 console.error(
7067 "React Router caught the following error during render",
7068 error
7069 );
7070 }
7071 }
7072 render() {
7073 let error = this.state.error;
7074 if (this.context && typeof error === "object" && error && "digest" in error && typeof error.digest === "string") {
7075 const decoded = decodeRouteErrorResponseDigest(error.digest);
7076 if (decoded) error = decoded;
7077 }
7078 let result = error !== void 0 ? /* @__PURE__ */ React3.createElement(RouteContext.Provider, { value: this.props.routeContext }, /* @__PURE__ */ React3.createElement(
7079 RouteErrorContext.Provider,
7080 {
7081 value: error,
7082 children: this.props.component
7083 }
7084 )) : this.props.children;
7085 if (this.context) {
7086 return /* @__PURE__ */ React3.createElement(RSCErrorHandler, { error }, result);
7087 }
7088 return result;
7089 }
7090};
7091RenderErrorBoundary.contextType = RSCRouterContext;
7092var errorRedirectHandledMap = /* @__PURE__ */ new WeakMap();
7093function RSCErrorHandler({
7094 children,
7095 error
7096}) {
7097 let { basename } = React3.useContext(NavigationContext);
7098 if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") {
7099 let redirect2 = decodeRedirectErrorDigest(error.digest);
7100 if (redirect2) {
7101 let existingRedirect = errorRedirectHandledMap.get(error);
7102 if (existingRedirect) throw existingRedirect;
7103 let parsed = parseToInfo(redirect2.location, basename);
7104 if (isBrowser && !errorRedirectHandledMap.get(error)) {
7105 if (parsed.isExternal || redirect2.reloadDocument) {
7106 window.location.href = parsed.absoluteURL || parsed.to;
7107 } else {
7108 const redirectPromise = Promise.resolve().then(
7109 () => window.__reactRouterDataRouter.navigate(parsed.to, {
7110 replace: redirect2.replace
7111 })
7112 );
7113 errorRedirectHandledMap.set(error, redirectPromise);
7114 throw redirectPromise;
7115 }
7116 }
7117 return /* @__PURE__ */ React3.createElement(
7118 "meta",
7119 {
7120 httpEquiv: "refresh",
7121 content: `0;url=${parsed.absoluteURL || parsed.to}`
7122 }
7123 );
7124 }
7125 }
7126 return children;
7127}
7128function RenderedRoute({ routeContext, match, children }) {
7129 let dataRouterContext = React3.useContext(DataRouterContext);
7130 if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {
7131 dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;
7132 }
7133 return /* @__PURE__ */ React3.createElement(RouteContext.Provider, { value: routeContext }, children);
7134}
7135function _renderMatches(matches, parentMatches = [], dataRouterOpts) {
7136 let dataRouterState = _optionalChain([dataRouterOpts, 'optionalAccess', _89 => _89.state]);
7137 if (matches == null) {
7138 if (!dataRouterState) {
7139 return null;
7140 }
7141 if (dataRouterState.errors) {
7142 matches = dataRouterState.matches;
7143 } else if (parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) {
7144 matches = dataRouterState.matches;
7145 } else {
7146 return null;
7147 }
7148 }
7149 let renderedMatches = matches;
7150 let errors = _optionalChain([dataRouterState, 'optionalAccess', _90 => _90.errors]);
7151 if (errors != null) {
7152 let errorIndex = renderedMatches.findIndex(
7153 (m) => m.route.id && _optionalChain([errors, 'optionalAccess', _91 => _91[m.route.id]]) !== void 0
7154 );
7155 invariant(
7156 errorIndex >= 0,
7157 `Could not find a matching route for errors on route IDs: ${Object.keys(
7158 errors
7159 ).join(",")}`
7160 );
7161 renderedMatches = renderedMatches.slice(
7162 0,
7163 Math.min(renderedMatches.length, errorIndex + 1)
7164 );
7165 }
7166 let renderFallback = false;
7167 let fallbackIndex = -1;
7168 if (dataRouterOpts && dataRouterState) {
7169 renderFallback = dataRouterState.renderFallback;
7170 for (let i = 0; i < renderedMatches.length; i++) {
7171 let match = renderedMatches[i];
7172 if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {
7173 fallbackIndex = i;
7174 }
7175 if (match.route.id) {
7176 let { loaderData, errors: errors2 } = dataRouterState;
7177 let needsToRunLoader = match.route.loader && !loaderData.hasOwnProperty(match.route.id) && (!errors2 || errors2[match.route.id] === void 0);
7178 if (match.route.lazy || needsToRunLoader) {
7179 if (dataRouterOpts.isStatic) {
7180 renderFallback = true;
7181 }
7182 if (fallbackIndex >= 0) {
7183 renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);
7184 } else {
7185 renderedMatches = [renderedMatches[0]];
7186 }
7187 break;
7188 }
7189 }
7190 }
7191 }
7192 let onErrorHandler = _optionalChain([dataRouterOpts, 'optionalAccess', _92 => _92.onError]);
7193 let onError = dataRouterState && onErrorHandler ? (error, errorInfo) => {
7194 onErrorHandler(error, {
7195 location: dataRouterState.location,
7196 params: _nullishCoalesce(_optionalChain([dataRouterState, 'access', _93 => _93.matches, 'optionalAccess', _94 => _94[0], 'optionalAccess', _95 => _95.params]), () => ( {})),
7197 unstable_pattern: getRoutePattern(dataRouterState.matches),
7198 errorInfo
7199 });
7200 } : void 0;
7201 return renderedMatches.reduceRight(
7202 (outlet, match, index) => {
7203 let error;
7204 let shouldRenderHydrateFallback = false;
7205 let errorElement = null;
7206 let hydrateFallbackElement = null;
7207 if (dataRouterState) {
7208 error = errors && match.route.id ? errors[match.route.id] : void 0;
7209 errorElement = match.route.errorElement || defaultErrorElement;
7210 if (renderFallback) {
7211 if (fallbackIndex < 0 && index === 0) {
7212 warningOnce(
7213 "route-fallback",
7214 false,
7215 "No `HydrateFallback` element provided to render during initial hydration"
7216 );
7217 shouldRenderHydrateFallback = true;
7218 hydrateFallbackElement = null;
7219 } else if (fallbackIndex === index) {
7220 shouldRenderHydrateFallback = true;
7221 hydrateFallbackElement = match.route.hydrateFallbackElement || null;
7222 }
7223 }
7224 }
7225 let matches2 = parentMatches.concat(renderedMatches.slice(0, index + 1));
7226 let getChildren = () => {
7227 let children;
7228 if (error) {
7229 children = errorElement;
7230 } else if (shouldRenderHydrateFallback) {
7231 children = hydrateFallbackElement;
7232 } else if (match.route.Component) {
7233 children = /* @__PURE__ */ React3.createElement(match.route.Component, null);
7234 } else if (match.route.element) {
7235 children = match.route.element;
7236 } else {
7237 children = outlet;
7238 }
7239 return /* @__PURE__ */ React3.createElement(
7240 RenderedRoute,
7241 {
7242 match,
7243 routeContext: {
7244 outlet,
7245 matches: matches2,
7246 isDataRoute: dataRouterState != null
7247 },
7248 children
7249 }
7250 );
7251 };
7252 return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /* @__PURE__ */ React3.createElement(
7253 RenderErrorBoundary,
7254 {
7255 location: dataRouterState.location,
7256 revalidation: dataRouterState.revalidation,
7257 component: errorElement,
7258 error,
7259 children: getChildren(),
7260 routeContext: { outlet: null, matches: matches2, isDataRoute: true },
7261 onError
7262 }
7263 ) : getChildren();
7264 },
7265 null
7266 );
7267}
7268function getDataRouterConsoleError(hookName) {
7269 return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`;
7270}
7271function useDataRouterContext(hookName) {
7272 let ctx = React3.useContext(DataRouterContext);
7273 invariant(ctx, getDataRouterConsoleError(hookName));
7274 return ctx;
7275}
7276function useDataRouterState(hookName) {
7277 let state = React3.useContext(DataRouterStateContext);
7278 invariant(state, getDataRouterConsoleError(hookName));
7279 return state;
7280}
7281function useRouteContext(hookName) {
7282 let route = React3.useContext(RouteContext);
7283 invariant(route, getDataRouterConsoleError(hookName));
7284 return route;
7285}
7286function useCurrentRouteId(hookName) {
7287 let route = useRouteContext(hookName);
7288 let thisRoute = route.matches[route.matches.length - 1];
7289 invariant(
7290 thisRoute.route.id,
7291 `${hookName} can only be used on routes that contain a unique "id"`
7292 );
7293 return thisRoute.route.id;
7294}
7295function useRouteId() {
7296 return useCurrentRouteId("useRouteId" /* UseRouteId */);
7297}
7298function useNavigation() {
7299 let state = useDataRouterState("useNavigation" /* UseNavigation */);
7300 return state.navigation;
7301}
7302function useRevalidator() {
7303 let dataRouterContext = useDataRouterContext("useRevalidator" /* UseRevalidator */);
7304 let state = useDataRouterState("useRevalidator" /* UseRevalidator */);
7305 let revalidate = React3.useCallback(async () => {
7306 await dataRouterContext.router.revalidate();
7307 }, [dataRouterContext.router]);
7308 return React3.useMemo(
7309 () => ({ revalidate, state: state.revalidation }),
7310 [revalidate, state.revalidation]
7311 );
7312}
7313function useMatches() {
7314 let { matches, loaderData } = useDataRouterState(
7315 "useMatches" /* UseMatches */
7316 );
7317 return React3.useMemo(
7318 () => matches.map((m) => convertRouteMatchToUiMatch(m, loaderData)),
7319 [matches, loaderData]
7320 );
7321}
7322function useLoaderData() {
7323 let state = useDataRouterState("useLoaderData" /* UseLoaderData */);
7324 let routeId = useCurrentRouteId("useLoaderData" /* UseLoaderData */);
7325 return state.loaderData[routeId];
7326}
7327function useRouteLoaderData(routeId) {
7328 let state = useDataRouterState("useRouteLoaderData" /* UseRouteLoaderData */);
7329 return state.loaderData[routeId];
7330}
7331function useActionData() {
7332 let state = useDataRouterState("useActionData" /* UseActionData */);
7333 let routeId = useCurrentRouteId("useLoaderData" /* UseLoaderData */);
7334 return state.actionData ? state.actionData[routeId] : void 0;
7335}
7336function useRouteError() {
7337 let error = React3.useContext(RouteErrorContext);
7338 let state = useDataRouterState("useRouteError" /* UseRouteError */);
7339 let routeId = useCurrentRouteId("useRouteError" /* UseRouteError */);
7340 if (error !== void 0) {
7341 return error;
7342 }
7343 return _optionalChain([state, 'access', _96 => _96.errors, 'optionalAccess', _97 => _97[routeId]]);
7344}
7345function useAsyncValue() {
7346 let value = React3.useContext(AwaitContext);
7347 return _optionalChain([value, 'optionalAccess', _98 => _98._data]);
7348}
7349function useAsyncError() {
7350 let value = React3.useContext(AwaitContext);
7351 return _optionalChain([value, 'optionalAccess', _99 => _99._error]);
7352}
7353var blockerId = 0;
7354function useBlocker(shouldBlock) {
7355 let { router, basename } = useDataRouterContext("useBlocker" /* UseBlocker */);
7356 let state = useDataRouterState("useBlocker" /* UseBlocker */);
7357 let [blockerKey, setBlockerKey] = React3.useState("");
7358 let blockerFunction = React3.useCallback(
7359 (arg) => {
7360 if (typeof shouldBlock !== "function") {
7361 return !!shouldBlock;
7362 }
7363 if (basename === "/") {
7364 return shouldBlock(arg);
7365 }
7366 let { currentLocation, nextLocation, historyAction } = arg;
7367 return shouldBlock({
7368 currentLocation: {
7369 ...currentLocation,
7370 pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname
7371 },
7372 nextLocation: {
7373 ...nextLocation,
7374 pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname
7375 },
7376 historyAction
7377 });
7378 },
7379 [basename, shouldBlock]
7380 );
7381 React3.useEffect(() => {
7382 let key = String(++blockerId);
7383 setBlockerKey(key);
7384 return () => router.deleteBlocker(key);
7385 }, [router]);
7386 React3.useEffect(() => {
7387 if (blockerKey !== "") {
7388 router.getBlocker(blockerKey, blockerFunction);
7389 }
7390 }, [router, blockerKey, blockerFunction]);
7391 return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;
7392}
7393function useNavigateStable() {
7394 let { router } = useDataRouterContext("useNavigate" /* UseNavigateStable */);
7395 let id = useCurrentRouteId("useNavigate" /* UseNavigateStable */);
7396 let activeRef = React3.useRef(false);
7397 useIsomorphicLayoutEffect(() => {
7398 activeRef.current = true;
7399 });
7400 let navigate = React3.useCallback(
7401 async (to, options = {}) => {
7402 warning(activeRef.current, navigateEffectWarning);
7403 if (!activeRef.current) return;
7404 if (typeof to === "number") {
7405 await router.navigate(to);
7406 } else {
7407 await router.navigate(to, { fromRouteId: id, ...options });
7408 }
7409 },
7410 [router, id]
7411 );
7412 return navigate;
7413}
7414var alreadyWarned = {};
7415function warningOnce(key, cond, message) {
7416 if (!cond && !alreadyWarned[key]) {
7417 alreadyWarned[key] = true;
7418 warning(false, message);
7419 }
7420}
7421function useRoute(...args) {
7422 const currentRouteId = useCurrentRouteId(
7423 "useRoute" /* UseRoute */
7424 );
7425 const id = _nullishCoalesce(args[0], () => ( currentRouteId));
7426 const state = useDataRouterState("useRoute" /* UseRoute */);
7427 const route = state.matches.find(({ route: route2 }) => route2.id === id);
7428 if (route === void 0) return void 0;
7429 return {
7430 handle: route.route.handle,
7431 loaderData: state.loaderData[id],
7432 actionData: _optionalChain([state, 'access', _100 => _100.actionData, 'optionalAccess', _101 => _101[id]])
7433 };
7434}
7435
7436// lib/dom/ssr/errorBoundaries.tsx
7437
7438
7439// lib/dom/ssr/components.tsx
7440
7441
7442// lib/dom/ssr/routeModules.ts
7443async function loadRouteModule(route, routeModulesCache) {
7444 if (route.id in routeModulesCache) {
7445 return routeModulesCache[route.id];
7446 }
7447 try {
7448 let routeModule = await Promise.resolve().then(() => _interopRequireWildcard(require(
7449 /* @vite-ignore */
7450 /* webpackIgnore: true */
7451 route.module
7452 )));
7453 routeModulesCache[route.id] = routeModule;
7454 return routeModule;
7455 } catch (error) {
7456 console.error(
7457 `Error loading route module \`${route.module}\`, reloading page...`
7458 );
7459 console.error(error);
7460 if (window.__reactRouterContext && window.__reactRouterContext.isSpaMode && // @ts-expect-error
7461 void 0) {
7462 throw error;
7463 }
7464 window.location.reload();
7465 return new Promise(() => {
7466 });
7467 }
7468}
7469
7470// lib/dom/ssr/links.ts
7471function getKeyedLinksForMatches(matches, routeModules, manifest) {
7472 let descriptors = matches.map((match) => {
7473 let module = routeModules[match.route.id];
7474 let route = manifest.routes[match.route.id];
7475 return [
7476 route && route.css ? route.css.map((href) => ({ rel: "stylesheet", href })) : [],
7477 _optionalChain([module, 'optionalAccess', _102 => _102.links, 'optionalCall', _103 => _103()]) || []
7478 ];
7479 }).flat(2);
7480 let preloads = getModuleLinkHrefs(matches, manifest);
7481 return dedupeLinkDescriptors(descriptors, preloads);
7482}
7483function getRouteCssDescriptors(route) {
7484 if (!route.css) return [];
7485 return route.css.map((href) => ({ rel: "stylesheet", href }));
7486}
7487async function prefetchRouteCss(route) {
7488 if (!route.css) return;
7489 let descriptors = getRouteCssDescriptors(route);
7490 await Promise.all(descriptors.map(prefetchStyleLink));
7491}
7492async function prefetchStyleLinks(route, routeModule) {
7493 if (!route.css && !routeModule.links || !isPreloadSupported()) return;
7494 let descriptors = [];
7495 if (route.css) {
7496 descriptors.push(...getRouteCssDescriptors(route));
7497 }
7498 if (routeModule.links) {
7499 descriptors.push(...routeModule.links());
7500 }
7501 if (descriptors.length === 0) return;
7502 let styleLinks = [];
7503 for (let descriptor of descriptors) {
7504 if (!isPageLinkDescriptor(descriptor) && descriptor.rel === "stylesheet") {
7505 styleLinks.push({
7506 ...descriptor,
7507 rel: "preload",
7508 as: "style"
7509 });
7510 }
7511 }
7512 await Promise.all(styleLinks.map(prefetchStyleLink));
7513}
7514async function prefetchStyleLink(descriptor) {
7515 return new Promise((resolve) => {
7516 if (descriptor.media && !window.matchMedia(descriptor.media).matches || document.querySelector(
7517 `link[rel="stylesheet"][href="${descriptor.href}"]`
7518 )) {
7519 return resolve();
7520 }
7521 let link = document.createElement("link");
7522 Object.assign(link, descriptor);
7523 function removeLink() {
7524 if (document.head.contains(link)) {
7525 document.head.removeChild(link);
7526 }
7527 }
7528 link.onload = () => {
7529 removeLink();
7530 resolve();
7531 };
7532 link.onerror = () => {
7533 removeLink();
7534 resolve();
7535 };
7536 document.head.appendChild(link);
7537 });
7538}
7539function isPageLinkDescriptor(object) {
7540 return object != null && typeof object.page === "string";
7541}
7542function isHtmlLinkDescriptor(object) {
7543 if (object == null) {
7544 return false;
7545 }
7546 if (object.href == null) {
7547 return object.rel === "preload" && typeof object.imageSrcSet === "string" && typeof object.imageSizes === "string";
7548 }
7549 return typeof object.rel === "string" && typeof object.href === "string";
7550}
7551async function getKeyedPrefetchLinks(matches, manifest, routeModules) {
7552 let links = await Promise.all(
7553 matches.map(async (match) => {
7554 let route = manifest.routes[match.route.id];
7555 if (route) {
7556 let mod = await loadRouteModule(route, routeModules);
7557 return mod.links ? mod.links() : [];
7558 }
7559 return [];
7560 })
7561 );
7562 return dedupeLinkDescriptors(
7563 links.flat(1).filter(isHtmlLinkDescriptor).filter((link) => link.rel === "stylesheet" || link.rel === "preload").map(
7564 (link) => link.rel === "stylesheet" ? { ...link, rel: "prefetch", as: "style" } : { ...link, rel: "prefetch" }
7565 )
7566 );
7567}
7568function getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, location, mode) {
7569 let isNew = (match, index) => {
7570 if (!currentMatches[index]) return true;
7571 return match.route.id !== currentMatches[index].route.id;
7572 };
7573 let matchPathChanged = (match, index) => {
7574 return (
7575 // param change, /users/123 -> /users/456
7576 currentMatches[index].pathname !== match.pathname || // splat param changed, which is not present in match.path
7577 // e.g. /files/images/avatar.jpg -> files/finances.xls
7578 _optionalChain([currentMatches, 'access', _104 => _104[index], 'access', _105 => _105.route, 'access', _106 => _106.path, 'optionalAccess', _107 => _107.endsWith, 'call', _108 => _108("*")]) && currentMatches[index].params["*"] !== match.params["*"]
7579 );
7580 };
7581 if (mode === "assets") {
7582 return nextMatches.filter(
7583 (match, index) => isNew(match, index) || matchPathChanged(match, index)
7584 );
7585 }
7586 if (mode === "data") {
7587 return nextMatches.filter((match, index) => {
7588 let manifestRoute = manifest.routes[match.route.id];
7589 if (!manifestRoute || !manifestRoute.hasLoader) {
7590 return false;
7591 }
7592 if (isNew(match, index) || matchPathChanged(match, index)) {
7593 return true;
7594 }
7595 if (match.route.shouldRevalidate) {
7596 let routeChoice = match.route.shouldRevalidate({
7597 currentUrl: new URL(
7598 location.pathname + location.search + location.hash,
7599 window.origin
7600 ),
7601 currentParams: _optionalChain([currentMatches, 'access', _109 => _109[0], 'optionalAccess', _110 => _110.params]) || {},
7602 nextUrl: new URL(page, window.origin),
7603 nextParams: match.params,
7604 defaultShouldRevalidate: true
7605 });
7606 if (typeof routeChoice === "boolean") {
7607 return routeChoice;
7608 }
7609 }
7610 return true;
7611 });
7612 }
7613 return [];
7614}
7615function getModuleLinkHrefs(matches, manifest, { includeHydrateFallback } = {}) {
7616 return dedupeHrefs(
7617 matches.map((match) => {
7618 let route = manifest.routes[match.route.id];
7619 if (!route) return [];
7620 let hrefs = [route.module];
7621 if (route.clientActionModule) {
7622 hrefs = hrefs.concat(route.clientActionModule);
7623 }
7624 if (route.clientLoaderModule) {
7625 hrefs = hrefs.concat(route.clientLoaderModule);
7626 }
7627 if (includeHydrateFallback && route.hydrateFallbackModule) {
7628 hrefs = hrefs.concat(route.hydrateFallbackModule);
7629 }
7630 if (route.imports) {
7631 hrefs = hrefs.concat(route.imports);
7632 }
7633 return hrefs;
7634 }).flat(1)
7635 );
7636}
7637function dedupeHrefs(hrefs) {
7638 return [...new Set(hrefs)];
7639}
7640function sortKeys(obj) {
7641 let sorted = {};
7642 let keys = Object.keys(obj).sort();
7643 for (let key of keys) {
7644 sorted[key] = obj[key];
7645 }
7646 return sorted;
7647}
7648function dedupeLinkDescriptors(descriptors, preloads) {
7649 let set = /* @__PURE__ */ new Set();
7650 let preloadsSet = new Set(preloads);
7651 return descriptors.reduce((deduped, descriptor) => {
7652 let alreadyModulePreload = preloads && !isPageLinkDescriptor(descriptor) && descriptor.as === "script" && descriptor.href && preloadsSet.has(descriptor.href);
7653 if (alreadyModulePreload) {
7654 return deduped;
7655 }
7656 let key = JSON.stringify(sortKeys(descriptor));
7657 if (!set.has(key)) {
7658 set.add(key);
7659 deduped.push({ key, link: descriptor });
7660 }
7661 return deduped;
7662 }, []);
7663}
7664var _isPreloadSupported;
7665function isPreloadSupported() {
7666 if (_isPreloadSupported !== void 0) {
7667 return _isPreloadSupported;
7668 }
7669 let el = document.createElement("link");
7670 _isPreloadSupported = el.relList.supports("preload");
7671 el = null;
7672 return _isPreloadSupported;
7673}
7674
7675// lib/server-runtime/warnings.ts
7676var alreadyWarned2 = {};
7677function warnOnce(condition, message) {
7678 if (!condition && !alreadyWarned2[message]) {
7679 alreadyWarned2[message] = true;
7680 console.warn(message);
7681 }
7682}
7683
7684// lib/dom/ssr/fog-of-war.ts
7685
7686
7687// lib/dom/ssr/routes.tsx
7688
7689
7690// lib/dom/ssr/fallback.tsx
7691
7692function RemixRootDefaultHydrateFallback() {
7693 return /* @__PURE__ */ React4.createElement(BoundaryShell, { title: "Loading...", renderScripts: true }, ENABLE_DEV_WARNINGS ? /* @__PURE__ */ React4.createElement(
7694 "script",
7695 {
7696 dangerouslySetInnerHTML: {
7697 __html: `
7698 console.log(
7699 "\u{1F4BF} Hey developer \u{1F44B}. You can provide a way better UX than this " +
7700 "when your app is loading JS modules and/or running \`clientLoader\` " +
7701 "functions. Check out https://reactrouter.com/start/framework/route-module#hydratefallback " +
7702 "for more information."
7703 );
7704 `
7705 }
7706 }
7707 ) : null);
7708}
7709
7710// lib/dom/ssr/routes.tsx
7711function groupRoutesByParentId(manifest) {
7712 let routes = {};
7713 Object.values(manifest).forEach((route) => {
7714 if (route) {
7715 let parentId = route.parentId || "";
7716 if (!routes[parentId]) {
7717 routes[parentId] = [];
7718 }
7719 routes[parentId].push(route);
7720 }
7721 });
7722 return routes;
7723}
7724function getRouteComponents(route, routeModule, isSpaMode) {
7725 let Component4 = getRouteModuleComponent(routeModule);
7726 let HydrateFallback = routeModule.HydrateFallback && (!isSpaMode || route.id === "root") ? routeModule.HydrateFallback : route.id === "root" ? RemixRootDefaultHydrateFallback : void 0;
7727 let ErrorBoundary = routeModule.ErrorBoundary ? routeModule.ErrorBoundary : route.id === "root" ? () => /* @__PURE__ */ React5.createElement(RemixRootDefaultErrorBoundary, { error: useRouteError() }) : void 0;
7728 if (route.id === "root" && routeModule.Layout) {
7729 return {
7730 ...Component4 ? {
7731 element: /* @__PURE__ */ React5.createElement(routeModule.Layout, null, /* @__PURE__ */ React5.createElement(Component4, null))
7732 } : { Component: Component4 },
7733 ...ErrorBoundary ? {
7734 errorElement: /* @__PURE__ */ React5.createElement(routeModule.Layout, null, /* @__PURE__ */ React5.createElement(ErrorBoundary, null))
7735 } : { ErrorBoundary },
7736 ...HydrateFallback ? {
7737 hydrateFallbackElement: /* @__PURE__ */ React5.createElement(routeModule.Layout, null, /* @__PURE__ */ React5.createElement(HydrateFallback, null))
7738 } : { HydrateFallback }
7739 };
7740 }
7741 return { Component: Component4, ErrorBoundary, HydrateFallback };
7742}
7743function createServerRoutes(manifest, routeModules, future, isSpaMode, parentId = "", routesByParentId = groupRoutesByParentId(manifest), spaModeLazyPromise = Promise.resolve({ Component: () => null })) {
7744 return (routesByParentId[parentId] || []).map((route) => {
7745 let routeModule = routeModules[route.id];
7746 invariant2(
7747 routeModule,
7748 "No `routeModule` available to create server routes"
7749 );
7750 let dataRoute = {
7751 ...getRouteComponents(route, routeModule, isSpaMode),
7752 caseSensitive: route.caseSensitive,
7753 id: route.id,
7754 index: route.index,
7755 path: route.path,
7756 handle: routeModule.handle,
7757 // For SPA Mode, all routes are lazy except root. However we tell the
7758 // router root is also lazy here too since we don't need a full
7759 // implementation - we just need a `lazy` prop to tell the RR rendering
7760 // where to stop which is always at the root route in SPA mode
7761 lazy: isSpaMode ? () => spaModeLazyPromise : void 0,
7762 // For partial hydration rendering, we need to indicate when the route
7763 // has a loader/clientLoader, but it won't ever be called during the static
7764 // render, so just give it a no-op function so we can render down to the
7765 // proper fallback
7766 loader: route.hasLoader || route.hasClientLoader ? () => null : void 0
7767 // We don't need middleware/action/shouldRevalidate on these routes since
7768 // they're for a static render
7769 };
7770 let children = createServerRoutes(
7771 manifest,
7772 routeModules,
7773 future,
7774 isSpaMode,
7775 route.id,
7776 routesByParentId,
7777 spaModeLazyPromise
7778 );
7779 if (children.length > 0) dataRoute.children = children;
7780 return dataRoute;
7781 });
7782}
7783function createClientRoutesWithHMRRevalidationOptOut(needsRevalidation, manifest, routeModulesCache, initialState, ssr, isSpaMode) {
7784 return createClientRoutes(
7785 manifest,
7786 routeModulesCache,
7787 initialState,
7788 ssr,
7789 isSpaMode,
7790 "",
7791 groupRoutesByParentId(manifest),
7792 needsRevalidation
7793 );
7794}
7795function preventInvalidServerHandlerCall(type, route) {
7796 if (type === "loader" && !route.hasLoader || type === "action" && !route.hasAction) {
7797 let fn = type === "action" ? "serverAction()" : "serverLoader()";
7798 let msg = `You are trying to call ${fn} on a route that does not have a server ${type} (routeId: "${route.id}")`;
7799 console.error(msg);
7800 throw new ErrorResponseImpl(400, "Bad Request", new Error(msg), true);
7801 }
7802}
7803function noActionDefinedError(type, routeId) {
7804 let article = type === "clientAction" ? "a" : "an";
7805 let msg = `Route "${routeId}" does not have ${article} ${type}, but you are trying to submit to it. To fix this, please add ${article} \`${type}\` function to the route`;
7806 console.error(msg);
7807 throw new ErrorResponseImpl(405, "Method Not Allowed", new Error(msg), true);
7808}
7809function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSpaMode, parentId = "", routesByParentId = groupRoutesByParentId(manifest), needsRevalidation) {
7810 return (routesByParentId[parentId] || []).map((route) => {
7811 let routeModule = routeModulesCache[route.id];
7812 function fetchServerHandler(singleFetch) {
7813 invariant2(
7814 typeof singleFetch === "function",
7815 "No single fetch function available for route handler"
7816 );
7817 return singleFetch();
7818 }
7819 function fetchServerLoader(singleFetch) {
7820 if (!route.hasLoader) return Promise.resolve(null);
7821 return fetchServerHandler(singleFetch);
7822 }
7823 function fetchServerAction(singleFetch) {
7824 if (!route.hasAction) {
7825 throw noActionDefinedError("action", route.id);
7826 }
7827 return fetchServerHandler(singleFetch);
7828 }
7829 function prefetchModule(modulePath) {
7830 Promise.resolve().then(() => _interopRequireWildcard(require(
7831 /* @vite-ignore */
7832 /* webpackIgnore: true */
7833 modulePath
7834 )));
7835 }
7836 function prefetchRouteModuleChunks(route2) {
7837 if (route2.clientActionModule) {
7838 prefetchModule(route2.clientActionModule);
7839 }
7840 if (route2.clientLoaderModule) {
7841 prefetchModule(route2.clientLoaderModule);
7842 }
7843 }
7844 async function prefetchStylesAndCallHandler(handler) {
7845 let cachedModule = routeModulesCache[route.id];
7846 let linkPrefetchPromise = cachedModule ? prefetchStyleLinks(route, cachedModule) : Promise.resolve();
7847 try {
7848 return handler();
7849 } finally {
7850 await linkPrefetchPromise;
7851 }
7852 }
7853 let dataRoute = {
7854 id: route.id,
7855 index: route.index,
7856 path: route.path
7857 };
7858 if (routeModule) {
7859 Object.assign(dataRoute, {
7860 ...dataRoute,
7861 ...getRouteComponents(route, routeModule, isSpaMode),
7862 middleware: routeModule.clientMiddleware,
7863 handle: routeModule.handle,
7864 shouldRevalidate: getShouldRevalidateFunction(
7865 dataRoute.path,
7866 routeModule,
7867 route,
7868 ssr,
7869 needsRevalidation
7870 )
7871 });
7872 let hasInitialData = initialState && initialState.loaderData && route.id in initialState.loaderData;
7873 let initialData = hasInitialData ? _optionalChain([initialState, 'optionalAccess', _111 => _111.loaderData, 'optionalAccess', _112 => _112[route.id]]) : void 0;
7874 let hasInitialError = initialState && initialState.errors && route.id in initialState.errors;
7875 let initialError = hasInitialError ? _optionalChain([initialState, 'optionalAccess', _113 => _113.errors, 'optionalAccess', _114 => _114[route.id]]) : void 0;
7876 let isHydrationRequest = needsRevalidation == null && (_optionalChain([routeModule, 'access', _115 => _115.clientLoader, 'optionalAccess', _116 => _116.hydrate]) === true || !route.hasLoader);
7877 dataRoute.loader = async ({ request, params, context, unstable_pattern }, singleFetch) => {
7878 try {
7879 let result = await prefetchStylesAndCallHandler(async () => {
7880 invariant2(
7881 routeModule,
7882 "No `routeModule` available for critical-route loader"
7883 );
7884 if (!routeModule.clientLoader) {
7885 return fetchServerLoader(singleFetch);
7886 }
7887 return routeModule.clientLoader({
7888 request,
7889 params,
7890 context,
7891 unstable_pattern,
7892 async serverLoader() {
7893 preventInvalidServerHandlerCall("loader", route);
7894 if (isHydrationRequest) {
7895 if (hasInitialData) {
7896 return initialData;
7897 }
7898 if (hasInitialError) {
7899 throw initialError;
7900 }
7901 }
7902 return fetchServerLoader(singleFetch);
7903 }
7904 });
7905 });
7906 return result;
7907 } finally {
7908 isHydrationRequest = false;
7909 }
7910 };
7911 dataRoute.loader.hydrate = shouldHydrateRouteLoader(
7912 route.id,
7913 routeModule.clientLoader,
7914 route.hasLoader,
7915 isSpaMode
7916 );
7917 dataRoute.action = ({ request, params, context, unstable_pattern }, singleFetch) => {
7918 return prefetchStylesAndCallHandler(async () => {
7919 invariant2(
7920 routeModule,
7921 "No `routeModule` available for critical-route action"
7922 );
7923 if (!routeModule.clientAction) {
7924 if (isSpaMode) {
7925 throw noActionDefinedError("clientAction", route.id);
7926 }
7927 return fetchServerAction(singleFetch);
7928 }
7929 return routeModule.clientAction({
7930 request,
7931 params,
7932 context,
7933 unstable_pattern,
7934 async serverAction() {
7935 preventInvalidServerHandlerCall("action", route);
7936 return fetchServerAction(singleFetch);
7937 }
7938 });
7939 });
7940 };
7941 } else {
7942 if (!route.hasClientLoader) {
7943 dataRoute.loader = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
7944 return fetchServerLoader(singleFetch);
7945 });
7946 }
7947 if (!route.hasClientAction) {
7948 dataRoute.action = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
7949 if (isSpaMode) {
7950 throw noActionDefinedError("clientAction", route.id);
7951 }
7952 return fetchServerAction(singleFetch);
7953 });
7954 }
7955 let lazyRoutePromise;
7956 async function getLazyRoute() {
7957 if (lazyRoutePromise) {
7958 return await lazyRoutePromise;
7959 }
7960 lazyRoutePromise = (async () => {
7961 if (route.clientLoaderModule || route.clientActionModule) {
7962 await new Promise((resolve) => setTimeout(resolve, 0));
7963 }
7964 let routeModulePromise = loadRouteModuleWithBlockingLinks(
7965 route,
7966 routeModulesCache
7967 );
7968 prefetchRouteModuleChunks(route);
7969 return await routeModulePromise;
7970 })();
7971 return await lazyRoutePromise;
7972 }
7973 dataRoute.lazy = {
7974 loader: route.hasClientLoader ? async () => {
7975 let { clientLoader } = route.clientLoaderModule ? await Promise.resolve().then(() => _interopRequireWildcard(require(
7976 /* @vite-ignore */
7977 /* webpackIgnore: true */
7978 route.clientLoaderModule
7979 ))) : await getLazyRoute();
7980 invariant2(clientLoader, "No `clientLoader` export found");
7981 return (args, singleFetch) => clientLoader({
7982 ...args,
7983 async serverLoader() {
7984 preventInvalidServerHandlerCall("loader", route);
7985 return fetchServerLoader(singleFetch);
7986 }
7987 });
7988 } : void 0,
7989 action: route.hasClientAction ? async () => {
7990 let clientActionPromise = route.clientActionModule ? Promise.resolve().then(() => _interopRequireWildcard(require(
7991 /* @vite-ignore */
7992 /* webpackIgnore: true */
7993 route.clientActionModule
7994 ))) : getLazyRoute();
7995 prefetchRouteModuleChunks(route);
7996 let { clientAction } = await clientActionPromise;
7997 invariant2(clientAction, "No `clientAction` export found");
7998 return (args, singleFetch) => clientAction({
7999 ...args,
8000 async serverAction() {
8001 preventInvalidServerHandlerCall("action", route);
8002 return fetchServerAction(singleFetch);
8003 }
8004 });
8005 } : void 0,
8006 middleware: route.hasClientMiddleware ? async () => {
8007 let { clientMiddleware } = route.clientMiddlewareModule ? await Promise.resolve().then(() => _interopRequireWildcard(require(
8008 /* @vite-ignore */
8009 /* webpackIgnore: true */
8010 route.clientMiddlewareModule
8011 ))) : await getLazyRoute();
8012 invariant2(clientMiddleware, "No `clientMiddleware` export found");
8013 return clientMiddleware;
8014 } : void 0,
8015 shouldRevalidate: async () => {
8016 let lazyRoute = await getLazyRoute();
8017 return getShouldRevalidateFunction(
8018 dataRoute.path,
8019 lazyRoute,
8020 route,
8021 ssr,
8022 needsRevalidation
8023 );
8024 },
8025 handle: async () => (await getLazyRoute()).handle,
8026 // No need to wrap these in layout since the root route is never
8027 // loaded via route.lazy()
8028 Component: async () => (await getLazyRoute()).Component,
8029 ErrorBoundary: route.hasErrorBoundary ? async () => (await getLazyRoute()).ErrorBoundary : void 0
8030 };
8031 }
8032 let children = createClientRoutes(
8033 manifest,
8034 routeModulesCache,
8035 initialState,
8036 ssr,
8037 isSpaMode,
8038 route.id,
8039 routesByParentId,
8040 needsRevalidation
8041 );
8042 if (children.length > 0) dataRoute.children = children;
8043 return dataRoute;
8044 });
8045}
8046function getShouldRevalidateFunction(path, route, manifestRoute, ssr, needsRevalidation) {
8047 if (needsRevalidation) {
8048 return wrapShouldRevalidateForHdr(
8049 manifestRoute.id,
8050 route.shouldRevalidate,
8051 needsRevalidation
8052 );
8053 }
8054 if (!ssr && manifestRoute.hasLoader && !manifestRoute.hasClientLoader) {
8055 let myParams = path ? compilePath(path)[1].map((p) => p.paramName) : [];
8056 const didParamsChange = (opts) => myParams.some((p) => opts.currentParams[p] !== opts.nextParams[p]);
8057 if (route.shouldRevalidate) {
8058 let fn = route.shouldRevalidate;
8059 return (opts) => fn({
8060 ...opts,
8061 defaultShouldRevalidate: didParamsChange(opts)
8062 });
8063 } else {
8064 return (opts) => didParamsChange(opts);
8065 }
8066 }
8067 return route.shouldRevalidate;
8068}
8069function wrapShouldRevalidateForHdr(routeId, routeShouldRevalidate, needsRevalidation) {
8070 let handledRevalidation = false;
8071 return (arg) => {
8072 if (!handledRevalidation) {
8073 handledRevalidation = true;
8074 return needsRevalidation.has(routeId);
8075 }
8076 return routeShouldRevalidate ? routeShouldRevalidate(arg) : arg.defaultShouldRevalidate;
8077 };
8078}
8079async function loadRouteModuleWithBlockingLinks(route, routeModules) {
8080 let routeModulePromise = loadRouteModule(route, routeModules);
8081 let prefetchRouteCssPromise = prefetchRouteCss(route);
8082 let routeModule = await routeModulePromise;
8083 await Promise.all([
8084 prefetchRouteCssPromise,
8085 prefetchStyleLinks(route, routeModule)
8086 ]);
8087 return {
8088 Component: getRouteModuleComponent(routeModule),
8089 ErrorBoundary: routeModule.ErrorBoundary,
8090 clientMiddleware: routeModule.clientMiddleware,
8091 clientAction: routeModule.clientAction,
8092 clientLoader: routeModule.clientLoader,
8093 handle: routeModule.handle,
8094 links: routeModule.links,
8095 meta: routeModule.meta,
8096 shouldRevalidate: routeModule.shouldRevalidate
8097 };
8098}
8099function getRouteModuleComponent(routeModule) {
8100 if (routeModule.default == null) return void 0;
8101 let isEmptyObject = typeof routeModule.default === "object" && Object.keys(routeModule.default).length === 0;
8102 if (!isEmptyObject) {
8103 return routeModule.default;
8104 }
8105}
8106function shouldHydrateRouteLoader(routeId, clientLoader, hasLoader, isSpaMode) {
8107 return isSpaMode && routeId !== "root" || clientLoader != null && (clientLoader.hydrate === true || hasLoader !== true);
8108}
8109
8110// lib/dom/ssr/fog-of-war.ts
8111var nextPaths = /* @__PURE__ */ new Set();
8112var discoveredPathsMaxSize = 1e3;
8113var discoveredPaths = /* @__PURE__ */ new Set();
8114var URL_LIMIT = 7680;
8115function isFogOfWarEnabled(routeDiscovery, ssr) {
8116 return routeDiscovery.mode === "lazy" && ssr === true;
8117}
8118function getPartialManifest({ sri, ...manifest }, router) {
8119 let routeIds = new Set(router.state.matches.map((m) => m.route.id));
8120 let segments = router.state.location.pathname.split("/").filter(Boolean);
8121 let paths = ["/"];
8122 segments.pop();
8123 while (segments.length > 0) {
8124 paths.push(`/${segments.join("/")}`);
8125 segments.pop();
8126 }
8127 paths.forEach((path) => {
8128 let matches = matchRoutes(router.routes, path, router.basename);
8129 if (matches) {
8130 matches.forEach((m) => routeIds.add(m.route.id));
8131 }
8132 });
8133 let initialRoutes = [...routeIds].reduce(
8134 (acc, id) => Object.assign(acc, { [id]: manifest.routes[id] }),
8135 {}
8136 );
8137 return {
8138 ...manifest,
8139 routes: initialRoutes,
8140 sri: sri ? true : void 0
8141 };
8142}
8143function getPatchRoutesOnNavigationFunction(getRouter, manifest, routeModules, ssr, routeDiscovery, isSpaMode, basename) {
8144 if (!isFogOfWarEnabled(routeDiscovery, ssr)) {
8145 return void 0;
8146 }
8147 return async ({ path, patch, signal, fetcherKey }) => {
8148 if (discoveredPaths.has(path)) {
8149 return;
8150 }
8151 let { state } = getRouter();
8152 await fetchAndApplyManifestPatches(
8153 [path],
8154 // If we're patching for a fetcher call, reload the current location
8155 // Otherwise prefer any ongoing navigation location
8156 fetcherKey ? window.location.href : createPath(state.navigation.location || state.location),
8157 manifest,
8158 routeModules,
8159 ssr,
8160 isSpaMode,
8161 basename,
8162 routeDiscovery.manifestPath,
8163 patch,
8164 signal
8165 );
8166 };
8167}
8168function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscovery, isSpaMode) {
8169 React6.useEffect(() => {
8170 if (!isFogOfWarEnabled(routeDiscovery, ssr) || // @ts-expect-error - TS doesn't know about this yet
8171 _optionalChain([window, 'access', _117 => _117.navigator, 'optionalAccess', _118 => _118.connection, 'optionalAccess', _119 => _119.saveData]) === true) {
8172 return;
8173 }
8174 function registerElement(el) {
8175 let path = el.tagName === "FORM" ? el.getAttribute("action") : el.getAttribute("href");
8176 if (!path) {
8177 return;
8178 }
8179 let pathname = el.tagName === "A" ? el.pathname : new URL(path, window.location.origin).pathname;
8180 if (!discoveredPaths.has(pathname)) {
8181 nextPaths.add(pathname);
8182 }
8183 }
8184 async function fetchPatches() {
8185 document.querySelectorAll("a[data-discover], form[data-discover]").forEach(registerElement);
8186 let lazyPaths = Array.from(nextPaths.keys()).filter((path) => {
8187 if (discoveredPaths.has(path)) {
8188 nextPaths.delete(path);
8189 return false;
8190 }
8191 return true;
8192 });
8193 if (lazyPaths.length === 0) {
8194 return;
8195 }
8196 try {
8197 await fetchAndApplyManifestPatches(
8198 lazyPaths,
8199 null,
8200 manifest,
8201 routeModules,
8202 ssr,
8203 isSpaMode,
8204 router.basename,
8205 routeDiscovery.manifestPath,
8206 router.patchRoutes
8207 );
8208 } catch (e) {
8209 console.error("Failed to fetch manifest patches", e);
8210 }
8211 }
8212 let debouncedFetchPatches = debounce(fetchPatches, 100);
8213 fetchPatches();
8214 let observer = new MutationObserver(() => debouncedFetchPatches());
8215 observer.observe(document.documentElement, {
8216 subtree: true,
8217 childList: true,
8218 attributes: true,
8219 attributeFilter: ["data-discover", "href", "action"]
8220 });
8221 return () => observer.disconnect();
8222 }, [ssr, isSpaMode, manifest, routeModules, router, routeDiscovery]);
8223}
8224function getManifestPath(_manifestPath, basename) {
8225 let manifestPath = _manifestPath || "/__manifest";
8226 if (basename == null) {
8227 return manifestPath;
8228 }
8229 return `${basename}${manifestPath}`.replace(/\/+/g, "/");
8230}
8231var MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
8232async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) {
8233 const searchParams = new URLSearchParams();
8234 searchParams.set("paths", paths.sort().join(","));
8235 searchParams.set("version", manifest.version);
8236 let url = new URL(
8237 getManifestPath(manifestPath, basename),
8238 window.location.origin
8239 );
8240 url.search = searchParams.toString();
8241 if (url.toString().length > URL_LIMIT) {
8242 nextPaths.clear();
8243 return;
8244 }
8245 let serverPatches;
8246 try {
8247 let res = await fetch(url, { signal });
8248 if (!res.ok) {
8249 throw new Error(`${res.status} ${res.statusText}`);
8250 } else if (res.status === 204 && res.headers.has("X-Remix-Reload-Document")) {
8251 if (!errorReloadPath) {
8252 console.warn(
8253 "Detected a manifest version mismatch during eager route discovery. The next navigation/fetch to an undiscovered route will result in a new document navigation to sync up with the latest manifest."
8254 );
8255 return;
8256 }
8257 try {
8258 if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) {
8259 console.error(
8260 "Unable to discover routes due to manifest version mismatch."
8261 );
8262 return;
8263 }
8264 sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);
8265 } catch (e4) {
8266 }
8267 window.location.href = errorReloadPath;
8268 console.warn("Detected manifest version mismatch, reloading...");
8269 await new Promise(() => {
8270 });
8271 } else if (res.status >= 400) {
8272 throw new Error(await res.text());
8273 }
8274 try {
8275 sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
8276 } catch (e5) {
8277 }
8278 serverPatches = await res.json();
8279 } catch (e) {
8280 if (_optionalChain([signal, 'optionalAccess', _120 => _120.aborted])) return;
8281 throw e;
8282 }
8283 let knownRoutes = new Set(Object.keys(manifest.routes));
8284 let patches = Object.values(serverPatches).reduce((acc, route) => {
8285 if (route && !knownRoutes.has(route.id)) {
8286 acc[route.id] = route;
8287 }
8288 return acc;
8289 }, {});
8290 Object.assign(manifest.routes, patches);
8291 paths.forEach((p) => addToFifoQueue(p, discoveredPaths));
8292 let parentIds = /* @__PURE__ */ new Set();
8293 Object.values(patches).forEach((patch) => {
8294 if (patch && (!patch.parentId || !patches[patch.parentId])) {
8295 parentIds.add(patch.parentId);
8296 }
8297 });
8298 parentIds.forEach(
8299 (parentId) => patchRoutes(
8300 parentId || null,
8301 createClientRoutes(patches, routeModules, null, ssr, isSpaMode, parentId)
8302 )
8303 );
8304}
8305function addToFifoQueue(path, queue) {
8306 if (queue.size >= discoveredPathsMaxSize) {
8307 let first = queue.values().next().value;
8308 queue.delete(first);
8309 }
8310 queue.add(path);
8311}
8312function debounce(callback, wait) {
8313 let timeoutId;
8314 return (...args) => {
8315 window.clearTimeout(timeoutId);
8316 timeoutId = window.setTimeout(() => callback(...args), wait);
8317 };
8318}
8319
8320// lib/dom/ssr/components.tsx
8321function useDataRouterContext2() {
8322 let context = React7.useContext(DataRouterContext);
8323 invariant2(
8324 context,
8325 "You must render this element inside a <DataRouterContext.Provider> element"
8326 );
8327 return context;
8328}
8329function useDataRouterStateContext() {
8330 let context = React7.useContext(DataRouterStateContext);
8331 invariant2(
8332 context,
8333 "You must render this element inside a <DataRouterStateContext.Provider> element"
8334 );
8335 return context;
8336}
8337var FrameworkContext = React7.createContext(void 0);
8338FrameworkContext.displayName = "FrameworkContext";
8339function useFrameworkContext() {
8340 let context = React7.useContext(FrameworkContext);
8341 invariant2(
8342 context,
8343 "You must render this element inside a <HydratedRouter> element"
8344 );
8345 return context;
8346}
8347function usePrefetchBehavior(prefetch, theirElementProps) {
8348 let frameworkContext = React7.useContext(FrameworkContext);
8349 let [maybePrefetch, setMaybePrefetch] = React7.useState(false);
8350 let [shouldPrefetch, setShouldPrefetch] = React7.useState(false);
8351 let { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps;
8352 let ref = React7.useRef(null);
8353 React7.useEffect(() => {
8354 if (prefetch === "render") {
8355 setShouldPrefetch(true);
8356 }
8357 if (prefetch === "viewport") {
8358 let callback = (entries) => {
8359 entries.forEach((entry) => {
8360 setShouldPrefetch(entry.isIntersecting);
8361 });
8362 };
8363 let observer = new IntersectionObserver(callback, { threshold: 0.5 });
8364 if (ref.current) observer.observe(ref.current);
8365 return () => {
8366 observer.disconnect();
8367 };
8368 }
8369 }, [prefetch]);
8370 React7.useEffect(() => {
8371 if (maybePrefetch) {
8372 let id = setTimeout(() => {
8373 setShouldPrefetch(true);
8374 }, 100);
8375 return () => {
8376 clearTimeout(id);
8377 };
8378 }
8379 }, [maybePrefetch]);
8380 let setIntent = () => {
8381 setMaybePrefetch(true);
8382 };
8383 let cancelIntent = () => {
8384 setMaybePrefetch(false);
8385 setShouldPrefetch(false);
8386 };
8387 if (!frameworkContext) {
8388 return [false, ref, {}];
8389 }
8390 if (prefetch !== "intent") {
8391 return [shouldPrefetch, ref, {}];
8392 }
8393 return [
8394 shouldPrefetch,
8395 ref,
8396 {
8397 onFocus: composeEventHandlers(onFocus, setIntent),
8398 onBlur: composeEventHandlers(onBlur, cancelIntent),
8399 onMouseEnter: composeEventHandlers(onMouseEnter, setIntent),
8400 onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent),
8401 onTouchStart: composeEventHandlers(onTouchStart, setIntent)
8402 }
8403 ];
8404}
8405function composeEventHandlers(theirHandler, ourHandler) {
8406 return (event) => {
8407 theirHandler && theirHandler(event);
8408 if (!event.defaultPrevented) {
8409 ourHandler(event);
8410 }
8411 };
8412}
8413function getActiveMatches(matches, errors, isSpaMode) {
8414 if (isSpaMode && !isHydrated) {
8415 return [matches[0]];
8416 }
8417 if (errors) {
8418 let errorIdx = matches.findIndex((m) => errors[m.route.id] !== void 0);
8419 return matches.slice(0, errorIdx + 1);
8420 }
8421 return matches;
8422}
8423var CRITICAL_CSS_DATA_ATTRIBUTE = "data-react-router-critical-css";
8424function Links({ nonce, crossOrigin }) {
8425 let { isSpaMode, manifest, routeModules, criticalCss } = useFrameworkContext();
8426 let { errors, matches: routerMatches } = useDataRouterStateContext();
8427 let matches = getActiveMatches(routerMatches, errors, isSpaMode);
8428 let keyedLinks = React7.useMemo(
8429 () => getKeyedLinksForMatches(matches, routeModules, manifest),
8430 [matches, routeModules, manifest]
8431 );
8432 return /* @__PURE__ */ React7.createElement(React7.Fragment, null, typeof criticalCss === "string" ? /* @__PURE__ */ React7.createElement(
8433 "style",
8434 {
8435 ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: "" },
8436 nonce,
8437 dangerouslySetInnerHTML: { __html: criticalCss }
8438 }
8439 ) : null, typeof criticalCss === "object" ? /* @__PURE__ */ React7.createElement(
8440 "link",
8441 {
8442 ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: "" },
8443 rel: "stylesheet",
8444 href: criticalCss.href,
8445 nonce,
8446 crossOrigin
8447 }
8448 ) : null, keyedLinks.map(
8449 ({ key, link }) => isPageLinkDescriptor(link) ? /* @__PURE__ */ React7.createElement(
8450 PrefetchPageLinks,
8451 {
8452 key,
8453 nonce,
8454 ...link,
8455 crossOrigin: _nullishCoalesce(link.crossOrigin, () => ( crossOrigin))
8456 }
8457 ) : /* @__PURE__ */ React7.createElement(
8458 "link",
8459 {
8460 key,
8461 nonce,
8462 ...link,
8463 crossOrigin: _nullishCoalesce(link.crossOrigin, () => ( crossOrigin))
8464 }
8465 )
8466 ));
8467}
8468function PrefetchPageLinks({ page, ...linkProps }) {
8469 let { router } = useDataRouterContext2();
8470 let matches = React7.useMemo(
8471 () => matchRoutes(router.routes, page, router.basename),
8472 [router.routes, page, router.basename]
8473 );
8474 if (!matches) {
8475 return null;
8476 }
8477 return /* @__PURE__ */ React7.createElement(PrefetchPageLinksImpl, { page, matches, ...linkProps });
8478}
8479function useKeyedPrefetchLinks(matches) {
8480 let { manifest, routeModules } = useFrameworkContext();
8481 let [keyedPrefetchLinks, setKeyedPrefetchLinks] = React7.useState([]);
8482 React7.useEffect(() => {
8483 let interrupted = false;
8484 void getKeyedPrefetchLinks(matches, manifest, routeModules).then(
8485 (links) => {
8486 if (!interrupted) {
8487 setKeyedPrefetchLinks(links);
8488 }
8489 }
8490 );
8491 return () => {
8492 interrupted = true;
8493 };
8494 }, [matches, manifest, routeModules]);
8495 return keyedPrefetchLinks;
8496}
8497function PrefetchPageLinksImpl({
8498 page,
8499 matches: nextMatches,
8500 ...linkProps
8501}) {
8502 let location = useLocation();
8503 let { future, manifest, routeModules } = useFrameworkContext();
8504 let { basename } = useDataRouterContext2();
8505 let { loaderData, matches } = useDataRouterStateContext();
8506 let newMatchesForData = React7.useMemo(
8507 () => getNewMatchesForLinks(
8508 page,
8509 nextMatches,
8510 matches,
8511 manifest,
8512 location,
8513 "data"
8514 ),
8515 [page, nextMatches, matches, manifest, location]
8516 );
8517 let newMatchesForAssets = React7.useMemo(
8518 () => getNewMatchesForLinks(
8519 page,
8520 nextMatches,
8521 matches,
8522 manifest,
8523 location,
8524 "assets"
8525 ),
8526 [page, nextMatches, matches, manifest, location]
8527 );
8528 let dataHrefs = React7.useMemo(() => {
8529 if (page === location.pathname + location.search + location.hash) {
8530 return [];
8531 }
8532 let routesParams = /* @__PURE__ */ new Set();
8533 let foundOptOutRoute = false;
8534 nextMatches.forEach((m) => {
8535 let manifestRoute = manifest.routes[m.route.id];
8536 if (!manifestRoute || !manifestRoute.hasLoader) {
8537 return;
8538 }
8539 if (!newMatchesForData.some((m2) => m2.route.id === m.route.id) && m.route.id in loaderData && _optionalChain([routeModules, 'access', _121 => _121[m.route.id], 'optionalAccess', _122 => _122.shouldRevalidate])) {
8540 foundOptOutRoute = true;
8541 } else if (manifestRoute.hasClientLoader) {
8542 foundOptOutRoute = true;
8543 } else {
8544 routesParams.add(m.route.id);
8545 }
8546 });
8547 if (routesParams.size === 0) {
8548 return [];
8549 }
8550 let url = singleFetchUrl(
8551 page,
8552 basename,
8553 future.unstable_trailingSlashAwareDataRequests,
8554 "data"
8555 );
8556 if (foundOptOutRoute && routesParams.size > 0) {
8557 url.searchParams.set(
8558 "_routes",
8559 nextMatches.filter((m) => routesParams.has(m.route.id)).map((m) => m.route.id).join(",")
8560 );
8561 }
8562 return [url.pathname + url.search];
8563 }, [
8564 basename,
8565 future.unstable_trailingSlashAwareDataRequests,
8566 loaderData,
8567 location,
8568 manifest,
8569 newMatchesForData,
8570 nextMatches,
8571 page,
8572 routeModules
8573 ]);
8574 let moduleHrefs = React7.useMemo(
8575 () => getModuleLinkHrefs(newMatchesForAssets, manifest),
8576 [newMatchesForAssets, manifest]
8577 );
8578 let keyedPrefetchLinks = useKeyedPrefetchLinks(newMatchesForAssets);
8579 return /* @__PURE__ */ React7.createElement(React7.Fragment, null, dataHrefs.map((href) => /* @__PURE__ */ React7.createElement("link", { key: href, rel: "prefetch", as: "fetch", href, ...linkProps })), moduleHrefs.map((href) => /* @__PURE__ */ React7.createElement("link", { key: href, rel: "modulepreload", href, ...linkProps })), keyedPrefetchLinks.map(({ key, link }) => (
8580 // these don't spread `linkProps` because they are full link descriptors
8581 // already with their own props
8582 /* @__PURE__ */ React7.createElement(
8583 "link",
8584 {
8585 key,
8586 nonce: linkProps.nonce,
8587 ...link,
8588 crossOrigin: _nullishCoalesce(link.crossOrigin, () => ( linkProps.crossOrigin))
8589 }
8590 )
8591 )));
8592}
8593function Meta() {
8594 let { isSpaMode, routeModules } = useFrameworkContext();
8595 let {
8596 errors,
8597 matches: routerMatches,
8598 loaderData
8599 } = useDataRouterStateContext();
8600 let location = useLocation();
8601 let _matches = getActiveMatches(routerMatches, errors, isSpaMode);
8602 let error = null;
8603 if (errors) {
8604 error = errors[_matches[_matches.length - 1].route.id];
8605 }
8606 let meta = [];
8607 let leafMeta = null;
8608 let matches = [];
8609 for (let i = 0; i < _matches.length; i++) {
8610 let _match = _matches[i];
8611 let routeId = _match.route.id;
8612 let data2 = loaderData[routeId];
8613 let params = _match.params;
8614 let routeModule = routeModules[routeId];
8615 let routeMeta = [];
8616 let match = {
8617 id: routeId,
8618 data: data2,
8619 loaderData: data2,
8620 meta: [],
8621 params: _match.params,
8622 pathname: _match.pathname,
8623 handle: _match.route.handle,
8624 error
8625 };
8626 matches[i] = match;
8627 if (_optionalChain([routeModule, 'optionalAccess', _123 => _123.meta])) {
8628 routeMeta = typeof routeModule.meta === "function" ? routeModule.meta({
8629 data: data2,
8630 loaderData: data2,
8631 params,
8632 location,
8633 matches,
8634 error
8635 }) : Array.isArray(routeModule.meta) ? [...routeModule.meta] : routeModule.meta;
8636 } else if (leafMeta) {
8637 routeMeta = [...leafMeta];
8638 }
8639 routeMeta = routeMeta || [];
8640 if (!Array.isArray(routeMeta)) {
8641 throw new Error(
8642 "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://reactrouter.com/start/framework/route-module#meta"
8643 );
8644 }
8645 match.meta = routeMeta;
8646 matches[i] = match;
8647 meta = [...routeMeta];
8648 leafMeta = meta;
8649 }
8650 return /* @__PURE__ */ React7.createElement(React7.Fragment, null, meta.flat().map((metaProps) => {
8651 if (!metaProps) {
8652 return null;
8653 }
8654 if ("tagName" in metaProps) {
8655 let { tagName, ...rest } = metaProps;
8656 if (!isValidMetaTag(tagName)) {
8657 console.warn(
8658 `A meta object uses an invalid tagName: ${tagName}. Expected either 'link' or 'meta'`
8659 );
8660 return null;
8661 }
8662 let Comp = tagName;
8663 return /* @__PURE__ */ React7.createElement(Comp, { key: JSON.stringify(rest), ...rest });
8664 }
8665 if ("title" in metaProps) {
8666 return /* @__PURE__ */ React7.createElement("title", { key: "title" }, String(metaProps.title));
8667 }
8668 if ("charset" in metaProps) {
8669 _nullishCoalesce(metaProps.charSet, () => ( (metaProps.charSet = metaProps.charset)));
8670 delete metaProps.charset;
8671 }
8672 if ("charSet" in metaProps && metaProps.charSet != null) {
8673 return typeof metaProps.charSet === "string" ? /* @__PURE__ */ React7.createElement("meta", { key: "charSet", charSet: metaProps.charSet }) : null;
8674 }
8675 if ("script:ld+json" in metaProps) {
8676 try {
8677 let json = JSON.stringify(metaProps["script:ld+json"]);
8678 return /* @__PURE__ */ React7.createElement(
8679 "script",
8680 {
8681 key: `script:ld+json:${json}`,
8682 type: "application/ld+json",
8683 dangerouslySetInnerHTML: { __html: escapeHtml(json) }
8684 }
8685 );
8686 } catch (err) {
8687 return null;
8688 }
8689 }
8690 return /* @__PURE__ */ React7.createElement("meta", { key: JSON.stringify(metaProps), ...metaProps });
8691 }));
8692}
8693function isValidMetaTag(tagName) {
8694 return typeof tagName === "string" && /^(meta|link)$/.test(tagName);
8695}
8696var isHydrated = false;
8697function setIsHydrated() {
8698 isHydrated = true;
8699}
8700function Scripts(scriptProps) {
8701 let {
8702 manifest,
8703 serverHandoffString,
8704 isSpaMode,
8705 renderMeta,
8706 routeDiscovery,
8707 ssr
8708 } = useFrameworkContext();
8709 let { router, static: isStatic, staticContext } = useDataRouterContext2();
8710 let { matches: routerMatches } = useDataRouterStateContext();
8711 let isRSCRouterContext = useIsRSCRouterContext();
8712 let enableFogOfWar = isFogOfWarEnabled(routeDiscovery, ssr);
8713 if (renderMeta) {
8714 renderMeta.didRenderScripts = true;
8715 }
8716 let matches = getActiveMatches(routerMatches, null, isSpaMode);
8717 React7.useEffect(() => {
8718 setIsHydrated();
8719 }, []);
8720 let initialScripts = React7.useMemo(() => {
8721 if (isRSCRouterContext) {
8722 return null;
8723 }
8724 let streamScript = "window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());";
8725 let contextScript = staticContext ? `window.__reactRouterContext = ${serverHandoffString};${streamScript}` : " ";
8726 let routeModulesScript = !isStatic ? " " : `${_optionalChain([manifest, 'access', _124 => _124.hmr, 'optionalAccess', _125 => _125.runtime]) ? `import ${JSON.stringify(manifest.hmr.runtime)};` : ""}${!enableFogOfWar ? `import ${JSON.stringify(manifest.url)}` : ""};
8727${matches.map((match, routeIndex) => {
8728 let routeVarName = `route${routeIndex}`;
8729 let manifestEntry = manifest.routes[match.route.id];
8730 invariant2(manifestEntry, `Route ${match.route.id} not found in manifest`);
8731 let {
8732 clientActionModule,
8733 clientLoaderModule,
8734 clientMiddlewareModule,
8735 hydrateFallbackModule,
8736 module
8737 } = manifestEntry;
8738 let chunks = [
8739 ...clientActionModule ? [
8740 {
8741 module: clientActionModule,
8742 varName: `${routeVarName}_clientAction`
8743 }
8744 ] : [],
8745 ...clientLoaderModule ? [
8746 {
8747 module: clientLoaderModule,
8748 varName: `${routeVarName}_clientLoader`
8749 }
8750 ] : [],
8751 ...clientMiddlewareModule ? [
8752 {
8753 module: clientMiddlewareModule,
8754 varName: `${routeVarName}_clientMiddleware`
8755 }
8756 ] : [],
8757 ...hydrateFallbackModule ? [
8758 {
8759 module: hydrateFallbackModule,
8760 varName: `${routeVarName}_HydrateFallback`
8761 }
8762 ] : [],
8763 { module, varName: `${routeVarName}_main` }
8764 ];
8765 if (chunks.length === 1) {
8766 return `import * as ${routeVarName} from ${JSON.stringify(module)};`;
8767 }
8768 let chunkImportsSnippet = chunks.map((chunk) => `import * as ${chunk.varName} from "${chunk.module}";`).join("\n");
8769 let mergedChunksSnippet = `const ${routeVarName} = {${chunks.map((chunk) => `...${chunk.varName}`).join(",")}};`;
8770 return [chunkImportsSnippet, mergedChunksSnippet].join("\n");
8771 }).join("\n")}
8772 ${enableFogOfWar ? (
8773 // Inline a minimal manifest with the SSR matches
8774 `window.__reactRouterManifest = ${JSON.stringify(
8775 getPartialManifest(manifest, router),
8776 null,
8777 2
8778 )};`
8779 ) : ""}
8780 window.__reactRouterRouteModules = {${matches.map((match, index) => `${JSON.stringify(match.route.id)}:route${index}`).join(",")}};
8781
8782import(${JSON.stringify(manifest.entry.module)});`;
8783 return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(
8784 "script",
8785 {
8786 ...scriptProps,
8787 suppressHydrationWarning: true,
8788 dangerouslySetInnerHTML: { __html: contextScript },
8789 type: void 0
8790 }
8791 ), /* @__PURE__ */ React7.createElement(
8792 "script",
8793 {
8794 ...scriptProps,
8795 suppressHydrationWarning: true,
8796 dangerouslySetInnerHTML: { __html: routeModulesScript },
8797 type: "module",
8798 async: true
8799 }
8800 ));
8801 }, []);
8802 let preloads = isHydrated || isRSCRouterContext ? [] : dedupe(
8803 manifest.entry.imports.concat(
8804 getModuleLinkHrefs(matches, manifest, {
8805 includeHydrateFallback: true
8806 })
8807 )
8808 );
8809 let sri = typeof manifest.sri === "object" ? manifest.sri : {};
8810 warnOnce(
8811 !isRSCRouterContext,
8812 "The <Scripts /> element is a no-op when using RSC and can be safely removed."
8813 );
8814 return isHydrated || isRSCRouterContext ? null : /* @__PURE__ */ React7.createElement(React7.Fragment, null, typeof manifest.sri === "object" ? /* @__PURE__ */ React7.createElement(
8815 "script",
8816 {
8817 ...scriptProps,
8818 "rr-importmap": "",
8819 type: "importmap",
8820 suppressHydrationWarning: true,
8821 dangerouslySetInnerHTML: {
8822 __html: JSON.stringify({
8823 integrity: sri
8824 })
8825 }
8826 }
8827 ) : null, !enableFogOfWar ? /* @__PURE__ */ React7.createElement(
8828 "link",
8829 {
8830 rel: "modulepreload",
8831 href: manifest.url,
8832 crossOrigin: scriptProps.crossOrigin,
8833 integrity: sri[manifest.url],
8834 suppressHydrationWarning: true
8835 }
8836 ) : null, /* @__PURE__ */ React7.createElement(
8837 "link",
8838 {
8839 rel: "modulepreload",
8840 href: manifest.entry.module,
8841 crossOrigin: scriptProps.crossOrigin,
8842 integrity: sri[manifest.entry.module],
8843 suppressHydrationWarning: true
8844 }
8845 ), preloads.map((path) => /* @__PURE__ */ React7.createElement(
8846 "link",
8847 {
8848 key: path,
8849 rel: "modulepreload",
8850 href: path,
8851 crossOrigin: scriptProps.crossOrigin,
8852 integrity: sri[path],
8853 suppressHydrationWarning: true
8854 }
8855 )), initialScripts);
8856}
8857function dedupe(array) {
8858 return [...new Set(array)];
8859}
8860function mergeRefs(...refs) {
8861 return (value) => {
8862 refs.forEach((ref) => {
8863 if (typeof ref === "function") {
8864 ref(value);
8865 } else if (ref != null) {
8866 ref.current = value;
8867 }
8868 });
8869 };
8870}
8871
8872// lib/dom/ssr/errorBoundaries.tsx
8873var RemixErrorBoundary = class extends React8.Component {
8874 constructor(props) {
8875 super(props);
8876 this.state = { error: props.error || null, location: props.location };
8877 }
8878 static getDerivedStateFromError(error) {
8879 return { error };
8880 }
8881 static getDerivedStateFromProps(props, state) {
8882 if (state.location !== props.location) {
8883 return { error: props.error || null, location: props.location };
8884 }
8885 return { error: props.error || state.error, location: state.location };
8886 }
8887 render() {
8888 if (this.state.error) {
8889 return /* @__PURE__ */ React8.createElement(
8890 RemixRootDefaultErrorBoundary,
8891 {
8892 error: this.state.error,
8893 isOutsideRemixApp: true
8894 }
8895 );
8896 } else {
8897 return this.props.children;
8898 }
8899 }
8900};
8901function RemixRootDefaultErrorBoundary({
8902 error,
8903 isOutsideRemixApp
8904}) {
8905 console.error(error);
8906 let heyDeveloper = /* @__PURE__ */ React8.createElement(
8907 "script",
8908 {
8909 dangerouslySetInnerHTML: {
8910 __html: `
8911 console.log(
8912 "\u{1F4BF} Hey developer \u{1F44B}. You can provide a way better UX than this when your app throws errors. Check out https://reactrouter.com/how-to/error-boundary for more information."
8913 );
8914 `
8915 }
8916 }
8917 );
8918 if (isRouteErrorResponse(error)) {
8919 return /* @__PURE__ */ React8.createElement(BoundaryShell, { title: "Unhandled Thrown Response!" }, /* @__PURE__ */ React8.createElement("h1", { style: { fontSize: "24px" } }, error.status, " ", error.statusText), ENABLE_DEV_WARNINGS ? heyDeveloper : null);
8920 }
8921 let errorInstance;
8922 if (error instanceof Error) {
8923 errorInstance = error;
8924 } else {
8925 let errorString = error == null ? "Unknown Error" : typeof error === "object" && "toString" in error ? error.toString() : JSON.stringify(error);
8926 errorInstance = new Error(errorString);
8927 }
8928 return /* @__PURE__ */ React8.createElement(
8929 BoundaryShell,
8930 {
8931 title: "Application Error!",
8932 isOutsideRemixApp
8933 },
8934 /* @__PURE__ */ React8.createElement("h1", { style: { fontSize: "24px" } }, "Application Error"),
8935 /* @__PURE__ */ React8.createElement(
8936 "pre",
8937 {
8938 style: {
8939 padding: "2rem",
8940 background: "hsla(10, 50%, 50%, 0.1)",
8941 color: "red",
8942 overflow: "auto"
8943 }
8944 },
8945 errorInstance.stack
8946 ),
8947 heyDeveloper
8948 );
8949}
8950function BoundaryShell({
8951 title,
8952 renderScripts,
8953 isOutsideRemixApp,
8954 children
8955}) {
8956 let { routeModules } = useFrameworkContext();
8957 if (_optionalChain([routeModules, 'access', _126 => _126.root, 'optionalAccess', _127 => _127.Layout]) && !isOutsideRemixApp) {
8958 return children;
8959 }
8960 return /* @__PURE__ */ React8.createElement("html", { lang: "en" }, /* @__PURE__ */ React8.createElement("head", null, /* @__PURE__ */ React8.createElement("meta", { charSet: "utf-8" }), /* @__PURE__ */ React8.createElement(
8961 "meta",
8962 {
8963 name: "viewport",
8964 content: "width=device-width,initial-scale=1,viewport-fit=cover"
8965 }
8966 ), /* @__PURE__ */ React8.createElement("title", null, title)), /* @__PURE__ */ React8.createElement("body", null, /* @__PURE__ */ React8.createElement("main", { style: { fontFamily: "system-ui, sans-serif", padding: "2rem" } }, children, renderScripts ? /* @__PURE__ */ React8.createElement(Scripts, null) : null)));
8967}
8968
8969// lib/components.tsx
8970
8971var USE_OPTIMISTIC = "useOptimistic";
8972var useOptimisticImpl = React9[USE_OPTIMISTIC];
8973var stableUseOptimisticSetter = () => void 0;
8974function useOptimisticSafe(val) {
8975 if (useOptimisticImpl) {
8976 return useOptimisticImpl(val);
8977 } else {
8978 return [val, stableUseOptimisticSetter];
8979 }
8980}
8981function mapRouteProperties(route) {
8982 let updates = {
8983 // Note: this check also occurs in createRoutesFromChildren so update
8984 // there if you change this -- please and thank you!
8985 hasErrorBoundary: route.hasErrorBoundary || route.ErrorBoundary != null || route.errorElement != null
8986 };
8987 if (route.Component) {
8988 if (ENABLE_DEV_WARNINGS) {
8989 if (route.element) {
8990 warning(
8991 false,
8992 "You should not include both `Component` and `element` on your route - `Component` will be used."
8993 );
8994 }
8995 }
8996 Object.assign(updates, {
8997 element: React9.createElement(route.Component),
8998 Component: void 0
8999 });
9000 }
9001 if (route.HydrateFallback) {
9002 if (ENABLE_DEV_WARNINGS) {
9003 if (route.hydrateFallbackElement) {
9004 warning(
9005 false,
9006 "You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used."
9007 );
9008 }
9009 }
9010 Object.assign(updates, {
9011 hydrateFallbackElement: React9.createElement(route.HydrateFallback),
9012 HydrateFallback: void 0
9013 });
9014 }
9015 if (route.ErrorBoundary) {
9016 if (ENABLE_DEV_WARNINGS) {
9017 if (route.errorElement) {
9018 warning(
9019 false,
9020 "You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used."
9021 );
9022 }
9023 }
9024 Object.assign(updates, {
9025 errorElement: React9.createElement(route.ErrorBoundary),
9026 ErrorBoundary: void 0
9027 });
9028 }
9029 return updates;
9030}
9031var hydrationRouteProperties = [
9032 "HydrateFallback",
9033 "hydrateFallbackElement"
9034];
9035function createMemoryRouter(routes, opts) {
9036 return createRouter({
9037 basename: _optionalChain([opts, 'optionalAccess', _128 => _128.basename]),
9038 getContext: _optionalChain([opts, 'optionalAccess', _129 => _129.getContext]),
9039 future: _optionalChain([opts, 'optionalAccess', _130 => _130.future]),
9040 history: createMemoryHistory({
9041 initialEntries: _optionalChain([opts, 'optionalAccess', _131 => _131.initialEntries]),
9042 initialIndex: _optionalChain([opts, 'optionalAccess', _132 => _132.initialIndex])
9043 }),
9044 hydrationData: _optionalChain([opts, 'optionalAccess', _133 => _133.hydrationData]),
9045 routes,
9046 hydrationRouteProperties,
9047 mapRouteProperties,
9048 dataStrategy: _optionalChain([opts, 'optionalAccess', _134 => _134.dataStrategy]),
9049 patchRoutesOnNavigation: _optionalChain([opts, 'optionalAccess', _135 => _135.patchRoutesOnNavigation]),
9050 unstable_instrumentations: _optionalChain([opts, 'optionalAccess', _136 => _136.unstable_instrumentations])
9051 }).initialize();
9052}
9053var Deferred2 = class {
9054 constructor() {
9055 this.status = "pending";
9056 this.promise = new Promise((resolve, reject) => {
9057 this.resolve = (value) => {
9058 if (this.status === "pending") {
9059 this.status = "resolved";
9060 resolve(value);
9061 }
9062 };
9063 this.reject = (reason) => {
9064 if (this.status === "pending") {
9065 this.status = "rejected";
9066 reject(reason);
9067 }
9068 };
9069 });
9070 }
9071};
9072function RouterProvider({
9073 router,
9074 flushSync: reactDomFlushSyncImpl,
9075 onError,
9076 unstable_useTransitions
9077}) {
9078 let unstable_rsc = useIsRSCRouterContext();
9079 unstable_useTransitions = unstable_rsc || unstable_useTransitions;
9080 let [_state, setStateImpl] = React9.useState(router.state);
9081 let [state, setOptimisticState] = useOptimisticSafe(_state);
9082 let [pendingState, setPendingState] = React9.useState();
9083 let [vtContext, setVtContext] = React9.useState({
9084 isTransitioning: false
9085 });
9086 let [renderDfd, setRenderDfd] = React9.useState();
9087 let [transition, setTransition] = React9.useState();
9088 let [interruption, setInterruption] = React9.useState();
9089 let fetcherData = React9.useRef(/* @__PURE__ */ new Map());
9090 let setState = React9.useCallback(
9091 (newState, { deletedFetchers, newErrors, flushSync, viewTransitionOpts }) => {
9092 if (newErrors && onError) {
9093 Object.values(newErrors).forEach(
9094 (error) => onError(error, {
9095 location: newState.location,
9096 params: _nullishCoalesce(_optionalChain([newState, 'access', _137 => _137.matches, 'access', _138 => _138[0], 'optionalAccess', _139 => _139.params]), () => ( {})),
9097 unstable_pattern: getRoutePattern(newState.matches)
9098 })
9099 );
9100 }
9101 newState.fetchers.forEach((fetcher, key) => {
9102 if (fetcher.data !== void 0) {
9103 fetcherData.current.set(key, fetcher.data);
9104 }
9105 });
9106 deletedFetchers.forEach((key) => fetcherData.current.delete(key));
9107 warnOnce(
9108 flushSync === false || reactDomFlushSyncImpl != null,
9109 'You provided the `flushSync` option to a router update, but you are not using the `<RouterProvider>` from `react-router/dom` so `ReactDOM.flushSync()` is unavailable. Please update your app to `import { RouterProvider } from "react-router/dom"` and ensure you have `react-dom` installed as a dependency to use the `flushSync` option.'
9110 );
9111 let isViewTransitionAvailable = router.window != null && router.window.document != null && typeof router.window.document.startViewTransition === "function";
9112 warnOnce(
9113 viewTransitionOpts == null || isViewTransitionAvailable,
9114 "You provided the `viewTransition` option to a router update, but you do not appear to be running in a DOM environment as `window.startViewTransition` is not available."
9115 );
9116 if (!viewTransitionOpts || !isViewTransitionAvailable) {
9117 if (reactDomFlushSyncImpl && flushSync) {
9118 reactDomFlushSyncImpl(() => setStateImpl(newState));
9119 } else if (unstable_useTransitions === false) {
9120 setStateImpl(newState);
9121 } else {
9122 React9.startTransition(() => {
9123 if (unstable_useTransitions === true) {
9124 setOptimisticState((s) => getOptimisticRouterState(s, newState));
9125 }
9126 setStateImpl(newState);
9127 });
9128 }
9129 return;
9130 }
9131 if (reactDomFlushSyncImpl && flushSync) {
9132 reactDomFlushSyncImpl(() => {
9133 if (transition) {
9134 _optionalChain([renderDfd, 'optionalAccess', _140 => _140.resolve, 'call', _141 => _141()]);
9135 transition.skipTransition();
9136 }
9137 setVtContext({
9138 isTransitioning: true,
9139 flushSync: true,
9140 currentLocation: viewTransitionOpts.currentLocation,
9141 nextLocation: viewTransitionOpts.nextLocation
9142 });
9143 });
9144 let t = router.window.document.startViewTransition(() => {
9145 reactDomFlushSyncImpl(() => setStateImpl(newState));
9146 });
9147 t.finished.finally(() => {
9148 reactDomFlushSyncImpl(() => {
9149 setRenderDfd(void 0);
9150 setTransition(void 0);
9151 setPendingState(void 0);
9152 setVtContext({ isTransitioning: false });
9153 });
9154 });
9155 reactDomFlushSyncImpl(() => setTransition(t));
9156 return;
9157 }
9158 if (transition) {
9159 _optionalChain([renderDfd, 'optionalAccess', _142 => _142.resolve, 'call', _143 => _143()]);
9160 transition.skipTransition();
9161 setInterruption({
9162 state: newState,
9163 currentLocation: viewTransitionOpts.currentLocation,
9164 nextLocation: viewTransitionOpts.nextLocation
9165 });
9166 } else {
9167 setPendingState(newState);
9168 setVtContext({
9169 isTransitioning: true,
9170 flushSync: false,
9171 currentLocation: viewTransitionOpts.currentLocation,
9172 nextLocation: viewTransitionOpts.nextLocation
9173 });
9174 }
9175 },
9176 [
9177 router.window,
9178 reactDomFlushSyncImpl,
9179 transition,
9180 renderDfd,
9181 unstable_useTransitions,
9182 setOptimisticState,
9183 onError
9184 ]
9185 );
9186 React9.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
9187 React9.useEffect(() => {
9188 if (vtContext.isTransitioning && !vtContext.flushSync) {
9189 setRenderDfd(new Deferred2());
9190 }
9191 }, [vtContext]);
9192 React9.useEffect(() => {
9193 if (renderDfd && pendingState && router.window) {
9194 let newState = pendingState;
9195 let renderPromise = renderDfd.promise;
9196 let transition2 = router.window.document.startViewTransition(async () => {
9197 if (unstable_useTransitions === false) {
9198 setStateImpl(newState);
9199 } else {
9200 React9.startTransition(() => {
9201 if (unstable_useTransitions === true) {
9202 setOptimisticState((s) => getOptimisticRouterState(s, newState));
9203 }
9204 setStateImpl(newState);
9205 });
9206 }
9207 await renderPromise;
9208 });
9209 transition2.finished.finally(() => {
9210 setRenderDfd(void 0);
9211 setTransition(void 0);
9212 setPendingState(void 0);
9213 setVtContext({ isTransitioning: false });
9214 });
9215 setTransition(transition2);
9216 }
9217 }, [
9218 pendingState,
9219 renderDfd,
9220 router.window,
9221 unstable_useTransitions,
9222 setOptimisticState
9223 ]);
9224 React9.useEffect(() => {
9225 if (renderDfd && pendingState && state.location.key === pendingState.location.key) {
9226 renderDfd.resolve();
9227 }
9228 }, [renderDfd, transition, state.location, pendingState]);
9229 React9.useEffect(() => {
9230 if (!vtContext.isTransitioning && interruption) {
9231 setPendingState(interruption.state);
9232 setVtContext({
9233 isTransitioning: true,
9234 flushSync: false,
9235 currentLocation: interruption.currentLocation,
9236 nextLocation: interruption.nextLocation
9237 });
9238 setInterruption(void 0);
9239 }
9240 }, [vtContext.isTransitioning, interruption]);
9241 let navigator = React9.useMemo(() => {
9242 return {
9243 createHref: router.createHref,
9244 encodeLocation: router.encodeLocation,
9245 go: (n) => router.navigate(n),
9246 push: (to, state2, opts) => router.navigate(to, {
9247 state: state2,
9248 preventScrollReset: _optionalChain([opts, 'optionalAccess', _144 => _144.preventScrollReset])
9249 }),
9250 replace: (to, state2, opts) => router.navigate(to, {
9251 replace: true,
9252 state: state2,
9253 preventScrollReset: _optionalChain([opts, 'optionalAccess', _145 => _145.preventScrollReset])
9254 })
9255 };
9256 }, [router]);
9257 let basename = router.basename || "/";
9258 let dataRouterContext = React9.useMemo(
9259 () => ({
9260 router,
9261 navigator,
9262 static: false,
9263 basename,
9264 onError
9265 }),
9266 [router, navigator, basename, onError]
9267 );
9268 return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(DataRouterContext.Provider, { value: dataRouterContext }, /* @__PURE__ */ React9.createElement(DataRouterStateContext.Provider, { value: state }, /* @__PURE__ */ React9.createElement(FetchersContext.Provider, { value: fetcherData.current }, /* @__PURE__ */ React9.createElement(ViewTransitionContext.Provider, { value: vtContext }, /* @__PURE__ */ React9.createElement(
9269 Router,
9270 {
9271 basename,
9272 location: state.location,
9273 navigationType: state.historyAction,
9274 navigator,
9275 unstable_useTransitions
9276 },
9277 /* @__PURE__ */ React9.createElement(
9278 MemoizedDataRoutes,
9279 {
9280 routes: router.routes,
9281 future: router.future,
9282 state,
9283 isStatic: false,
9284 onError
9285 }
9286 )
9287 ))))), null);
9288}
9289function getOptimisticRouterState(currentState, newState) {
9290 return {
9291 // Don't surface "current location specific" stuff mid-navigation
9292 // (historyAction, location, matches, loaderData, errors, initialized,
9293 // restoreScroll, preventScrollReset, blockers, etc.)
9294 ...currentState,
9295 // Only surface "pending/in-flight stuff"
9296 // (navigation, revalidation, actionData, fetchers, )
9297 navigation: newState.navigation.state !== "idle" ? newState.navigation : currentState.navigation,
9298 revalidation: newState.revalidation !== "idle" ? newState.revalidation : currentState.revalidation,
9299 actionData: newState.navigation.state !== "submitting" ? newState.actionData : currentState.actionData,
9300 fetchers: newState.fetchers
9301 };
9302}
9303var MemoizedDataRoutes = React9.memo(DataRoutes);
9304function DataRoutes({
9305 routes,
9306 future,
9307 state,
9308 isStatic,
9309 onError
9310}) {
9311 return useRoutesImpl(routes, void 0, { state, isStatic, onError, future });
9312}
9313function MemoryRouter({
9314 basename,
9315 children,
9316 initialEntries,
9317 initialIndex,
9318 unstable_useTransitions
9319}) {
9320 let historyRef = React9.useRef();
9321 if (historyRef.current == null) {
9322 historyRef.current = createMemoryHistory({
9323 initialEntries,
9324 initialIndex,
9325 v5Compat: true
9326 });
9327 }
9328 let history = historyRef.current;
9329 let [state, setStateImpl] = React9.useState({
9330 action: history.action,
9331 location: history.location
9332 });
9333 let setState = React9.useCallback(
9334 (newState) => {
9335 if (unstable_useTransitions === false) {
9336 setStateImpl(newState);
9337 } else {
9338 React9.startTransition(() => setStateImpl(newState));
9339 }
9340 },
9341 [unstable_useTransitions]
9342 );
9343 React9.useLayoutEffect(() => history.listen(setState), [history, setState]);
9344 return /* @__PURE__ */ React9.createElement(
9345 Router,
9346 {
9347 basename,
9348 children,
9349 location: state.location,
9350 navigationType: state.action,
9351 navigator: history,
9352 unstable_useTransitions
9353 }
9354 );
9355}
9356function Navigate({
9357 to,
9358 replace: replace2,
9359 state,
9360 relative
9361}) {
9362 invariant(
9363 useInRouterContext(),
9364 // TODO: This error is probably because they somehow have 2 versions of
9365 // the router loaded. We can help them understand how to avoid that.
9366 `<Navigate> may be used only in the context of a <Router> component.`
9367 );
9368 let { static: isStatic } = React9.useContext(NavigationContext);
9369 warning(
9370 !isStatic,
9371 `<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.`
9372 );
9373 let { matches } = React9.useContext(RouteContext);
9374 let { pathname: locationPathname } = useLocation();
9375 let navigate = useNavigate();
9376 let path = resolveTo(
9377 to,
9378 getResolveToMatches(matches),
9379 locationPathname,
9380 relative === "path"
9381 );
9382 let jsonPath = JSON.stringify(path);
9383 React9.useEffect(() => {
9384 navigate(JSON.parse(jsonPath), { replace: replace2, state, relative });
9385 }, [navigate, jsonPath, relative, replace2, state]);
9386 return null;
9387}
9388function Outlet(props) {
9389 return useOutlet(props.context);
9390}
9391function Route(props) {
9392 invariant(
9393 false,
9394 `A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.`
9395 );
9396}
9397function Router({
9398 basename: basenameProp = "/",
9399 children = null,
9400 location: locationProp,
9401 navigationType = "POP" /* Pop */,
9402 navigator,
9403 static: staticProp = false,
9404 unstable_useTransitions
9405}) {
9406 invariant(
9407 !useInRouterContext(),
9408 `You cannot render a <Router> inside another <Router>. You should never have more than one in your app.`
9409 );
9410 let basename = basenameProp.replace(/^\/*/, "/");
9411 let navigationContext = React9.useMemo(
9412 () => ({
9413 basename,
9414 navigator,
9415 static: staticProp,
9416 unstable_useTransitions,
9417 future: {}
9418 }),
9419 [basename, navigator, staticProp, unstable_useTransitions]
9420 );
9421 if (typeof locationProp === "string") {
9422 locationProp = parsePath(locationProp);
9423 }
9424 let {
9425 pathname = "/",
9426 search = "",
9427 hash = "",
9428 state = null,
9429 key = "default",
9430 unstable_mask
9431 } = locationProp;
9432 let locationContext = React9.useMemo(() => {
9433 let trailingPathname = stripBasename(pathname, basename);
9434 if (trailingPathname == null) {
9435 return null;
9436 }
9437 return {
9438 location: {
9439 pathname: trailingPathname,
9440 search,
9441 hash,
9442 state,
9443 key,
9444 unstable_mask
9445 },
9446 navigationType
9447 };
9448 }, [
9449 basename,
9450 pathname,
9451 search,
9452 hash,
9453 state,
9454 key,
9455 navigationType,
9456 unstable_mask
9457 ]);
9458 warning(
9459 locationContext != null,
9460 `<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.`
9461 );
9462 if (locationContext == null) {
9463 return null;
9464 }
9465 return /* @__PURE__ */ React9.createElement(NavigationContext.Provider, { value: navigationContext }, /* @__PURE__ */ React9.createElement(LocationContext.Provider, { children, value: locationContext }));
9466}
9467function Routes({
9468 children,
9469 location
9470}) {
9471 return useRoutes(createRoutesFromChildren(children), location);
9472}
9473function Await({
9474 children,
9475 errorElement,
9476 resolve
9477}) {
9478 let dataRouterContext = React9.useContext(DataRouterContext);
9479 let dataRouterStateContext = React9.useContext(DataRouterStateContext);
9480 let onError = React9.useCallback(
9481 (error, errorInfo) => {
9482 if (dataRouterContext && dataRouterContext.onError && dataRouterStateContext) {
9483 dataRouterContext.onError(error, {
9484 location: dataRouterStateContext.location,
9485 params: _optionalChain([dataRouterStateContext, 'access', _146 => _146.matches, 'access', _147 => _147[0], 'optionalAccess', _148 => _148.params]) || {},
9486 unstable_pattern: getRoutePattern(dataRouterStateContext.matches),
9487 errorInfo
9488 });
9489 }
9490 },
9491 [dataRouterContext, dataRouterStateContext]
9492 );
9493 return /* @__PURE__ */ React9.createElement(
9494 AwaitErrorBoundary,
9495 {
9496 resolve,
9497 errorElement,
9498 onError
9499 },
9500 /* @__PURE__ */ React9.createElement(ResolveAwait, null, children)
9501 );
9502}
9503var AwaitErrorBoundary = class extends React9.Component {
9504 constructor(props) {
9505 super(props);
9506 this.state = { error: null };
9507 }
9508 static getDerivedStateFromError(error) {
9509 return { error };
9510 }
9511 componentDidCatch(error, errorInfo) {
9512 if (this.props.onError) {
9513 this.props.onError(error, errorInfo);
9514 } else {
9515 console.error(
9516 "<Await> caught the following error during render",
9517 error,
9518 errorInfo
9519 );
9520 }
9521 }
9522 render() {
9523 let { children, errorElement, resolve } = this.props;
9524 let promise = null;
9525 let status = 0 /* pending */;
9526 if (!(resolve instanceof Promise)) {
9527 status = 1 /* success */;
9528 promise = Promise.resolve();
9529 Object.defineProperty(promise, "_tracked", { get: () => true });
9530 Object.defineProperty(promise, "_data", { get: () => resolve });
9531 } else if (this.state.error) {
9532 status = 2 /* error */;
9533 let renderError = this.state.error;
9534 promise = Promise.reject().catch(() => {
9535 });
9536 Object.defineProperty(promise, "_tracked", { get: () => true });
9537 Object.defineProperty(promise, "_error", { get: () => renderError });
9538 } else if (resolve._tracked) {
9539 promise = resolve;
9540 status = "_error" in promise ? 2 /* error */ : "_data" in promise ? 1 /* success */ : 0 /* pending */;
9541 } else {
9542 status = 0 /* pending */;
9543 Object.defineProperty(resolve, "_tracked", { get: () => true });
9544 promise = resolve.then(
9545 (data2) => Object.defineProperty(resolve, "_data", { get: () => data2 }),
9546 (error) => {
9547 _optionalChain([this, 'access', _149 => _149.props, 'access', _150 => _150.onError, 'optionalCall', _151 => _151(error)]);
9548 Object.defineProperty(resolve, "_error", { get: () => error });
9549 }
9550 );
9551 }
9552 if (status === 2 /* error */ && !errorElement) {
9553 throw promise._error;
9554 }
9555 if (status === 2 /* error */) {
9556 return /* @__PURE__ */ React9.createElement(AwaitContext.Provider, { value: promise, children: errorElement });
9557 }
9558 if (status === 1 /* success */) {
9559 return /* @__PURE__ */ React9.createElement(AwaitContext.Provider, { value: promise, children });
9560 }
9561 throw promise;
9562 }
9563};
9564function ResolveAwait({
9565 children
9566}) {
9567 let data2 = useAsyncValue();
9568 let toRender = typeof children === "function" ? children(data2) : children;
9569 return /* @__PURE__ */ React9.createElement(React9.Fragment, null, toRender);
9570}
9571function createRoutesFromChildren(children, parentPath = []) {
9572 let routes = [];
9573 React9.Children.forEach(children, (element, index) => {
9574 if (!React9.isValidElement(element)) {
9575 return;
9576 }
9577 let treePath = [...parentPath, index];
9578 if (element.type === React9.Fragment) {
9579 routes.push.apply(
9580 routes,
9581 createRoutesFromChildren(element.props.children, treePath)
9582 );
9583 return;
9584 }
9585 invariant(
9586 element.type === Route,
9587 `[${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>`
9588 );
9589 invariant(
9590 !element.props.index || !element.props.children,
9591 "An index route cannot have child routes."
9592 );
9593 let route = {
9594 id: element.props.id || treePath.join("-"),
9595 caseSensitive: element.props.caseSensitive,
9596 element: element.props.element,
9597 Component: element.props.Component,
9598 index: element.props.index,
9599 path: element.props.path,
9600 middleware: element.props.middleware,
9601 loader: element.props.loader,
9602 action: element.props.action,
9603 hydrateFallbackElement: element.props.hydrateFallbackElement,
9604 HydrateFallback: element.props.HydrateFallback,
9605 errorElement: element.props.errorElement,
9606 ErrorBoundary: element.props.ErrorBoundary,
9607 hasErrorBoundary: element.props.hasErrorBoundary === true || element.props.ErrorBoundary != null || element.props.errorElement != null,
9608 shouldRevalidate: element.props.shouldRevalidate,
9609 handle: element.props.handle,
9610 lazy: element.props.lazy
9611 };
9612 if (element.props.children) {
9613 route.children = createRoutesFromChildren(
9614 element.props.children,
9615 treePath
9616 );
9617 }
9618 routes.push(route);
9619 });
9620 return routes;
9621}
9622var createRoutesFromElements = createRoutesFromChildren;
9623function renderMatches(matches) {
9624 return _renderMatches(matches);
9625}
9626function useRouteComponentProps() {
9627 return {
9628 params: useParams(),
9629 loaderData: useLoaderData(),
9630 actionData: useActionData(),
9631 matches: useMatches()
9632 };
9633}
9634function WithComponentProps({
9635 children
9636}) {
9637 const props = useRouteComponentProps();
9638 return React9.cloneElement(children, props);
9639}
9640function withComponentProps(Component4) {
9641 return function WithComponentProps2() {
9642 const props = useRouteComponentProps();
9643 return React9.createElement(Component4, props);
9644 };
9645}
9646function useHydrateFallbackProps() {
9647 return {
9648 params: useParams(),
9649 loaderData: useLoaderData(),
9650 actionData: useActionData()
9651 };
9652}
9653function WithHydrateFallbackProps({
9654 children
9655}) {
9656 const props = useHydrateFallbackProps();
9657 return React9.cloneElement(children, props);
9658}
9659function withHydrateFallbackProps(HydrateFallback) {
9660 return function WithHydrateFallbackProps2() {
9661 const props = useHydrateFallbackProps();
9662 return React9.createElement(HydrateFallback, props);
9663 };
9664}
9665function useErrorBoundaryProps() {
9666 return {
9667 params: useParams(),
9668 loaderData: useLoaderData(),
9669 actionData: useActionData(),
9670 error: useRouteError()
9671 };
9672}
9673function WithErrorBoundaryProps({
9674 children
9675}) {
9676 const props = useErrorBoundaryProps();
9677 return React9.cloneElement(children, props);
9678}
9679function withErrorBoundaryProps(ErrorBoundary) {
9680 return function WithErrorBoundaryProps2() {
9681 const props = useErrorBoundaryProps();
9682 return React9.createElement(ErrorBoundary, props);
9683 };
9684}
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811exports.Action = Action; exports.createMemoryHistory = createMemoryHistory; exports.createBrowserHistory = createBrowserHistory; exports.createHashHistory = createHashHistory; exports.invariant = invariant; exports.warning = warning; exports.createPath = createPath; exports.parsePath = parsePath; exports.createContext = createContext; exports.RouterContextProvider = RouterContextProvider; exports.convertRoutesToDataRoutes = convertRoutesToDataRoutes; exports.matchRoutes = matchRoutes; exports.generatePath = generatePath; exports.matchPath = matchPath; exports.stripBasename = stripBasename; exports.resolvePath = resolvePath; exports.resolveTo = resolveTo; exports.joinPaths = joinPaths; exports.data = data; exports.redirect = redirect; exports.redirectDocument = redirectDocument; exports.replace = replace; exports.ErrorResponseImpl = ErrorResponseImpl; exports.isRouteErrorResponse = isRouteErrorResponse; exports.parseToInfo = parseToInfo; exports.escapeHtml = escapeHtml; exports.encode = encode; exports.instrumentHandler = instrumentHandler; exports.IDLE_NAVIGATION = IDLE_NAVIGATION; exports.IDLE_FETCHER = IDLE_FETCHER; exports.IDLE_BLOCKER = IDLE_BLOCKER; exports.createRouter = createRouter; exports.createStaticHandler = createStaticHandler; exports.getStaticContextFromError = getStaticContextFromError; exports.isDataWithResponseInit = isDataWithResponseInit; exports.isResponse = isResponse; exports.isRedirectStatusCode = isRedirectStatusCode; exports.isRedirectResponse = isRedirectResponse; exports.isMutationMethod = isMutationMethod; exports.createRequestInit = createRequestInit; exports.SingleFetchRedirectSymbol = SingleFetchRedirectSymbol; exports.SINGLE_FETCH_REDIRECT_STATUS = SINGLE_FETCH_REDIRECT_STATUS; exports.NO_BODY_STATUS_CODES = NO_BODY_STATUS_CODES; exports.StreamTransfer = StreamTransfer; exports.getTurboStreamSingleFetchDataStrategy = getTurboStreamSingleFetchDataStrategy; exports.getSingleFetchDataStrategyImpl = getSingleFetchDataStrategyImpl; exports.stripIndexParam = stripIndexParam; exports.singleFetchUrl = singleFetchUrl; exports.decodeViaTurboStream = decodeViaTurboStream; exports.DataRouterContext = DataRouterContext; exports.DataRouterStateContext = DataRouterStateContext; exports.RSCRouterContext = RSCRouterContext; exports.ViewTransitionContext = ViewTransitionContext; exports.FetchersContext = FetchersContext; exports.AwaitContextProvider = AwaitContextProvider; exports.NavigationContext = NavigationContext; exports.LocationContext = LocationContext; exports.RouteContext = RouteContext; exports.ENABLE_DEV_WARNINGS = ENABLE_DEV_WARNINGS; exports.warnOnce = warnOnce; exports.decodeRedirectErrorDigest = decodeRedirectErrorDigest; exports.decodeRouteErrorResponseDigest = decodeRouteErrorResponseDigest; exports.useHref = useHref; exports.useInRouterContext = useInRouterContext; exports.useLocation = useLocation; exports.useNavigationType = useNavigationType; exports.useMatch = useMatch; exports.useNavigate = useNavigate; exports.useOutletContext = useOutletContext; exports.useOutlet = useOutlet; exports.useParams = useParams; exports.useResolvedPath = useResolvedPath; exports.useRoutes = useRoutes; exports.useRouteId = useRouteId; exports.useNavigation = useNavigation; exports.useRevalidator = useRevalidator; exports.useMatches = useMatches; exports.useLoaderData = useLoaderData; exports.useRouteLoaderData = useRouteLoaderData; exports.useActionData = useActionData; exports.useRouteError = useRouteError; exports.useAsyncValue = useAsyncValue; exports.useAsyncError = useAsyncError; exports.useBlocker = useBlocker; exports.useRoute = useRoute; exports.RemixErrorBoundary = RemixErrorBoundary; exports.createServerRoutes = createServerRoutes; exports.createClientRoutesWithHMRRevalidationOptOut = createClientRoutesWithHMRRevalidationOptOut; exports.noActionDefinedError = noActionDefinedError; exports.createClientRoutes = createClientRoutes; exports.shouldHydrateRouteLoader = shouldHydrateRouteLoader; exports.getPatchRoutesOnNavigationFunction = getPatchRoutesOnNavigationFunction; exports.useFogOFWarDiscovery = useFogOFWarDiscovery; exports.getManifestPath = getManifestPath; exports.FrameworkContext = FrameworkContext; exports.usePrefetchBehavior = usePrefetchBehavior; exports.CRITICAL_CSS_DATA_ATTRIBUTE = CRITICAL_CSS_DATA_ATTRIBUTE; exports.Links = Links; exports.PrefetchPageLinks = PrefetchPageLinks; exports.Meta = Meta; exports.setIsHydrated = setIsHydrated; exports.Scripts = Scripts; exports.mergeRefs = mergeRefs; exports.mapRouteProperties = mapRouteProperties; exports.hydrationRouteProperties = hydrationRouteProperties; exports.createMemoryRouter = createMemoryRouter; exports.RouterProvider = RouterProvider; exports.DataRoutes = DataRoutes; exports.MemoryRouter = MemoryRouter; exports.Navigate = Navigate; exports.Outlet = Outlet; exports.Route = Route; exports.Router = Router; exports.Routes = Routes; exports.Await = Await; exports.createRoutesFromChildren = createRoutesFromChildren; exports.createRoutesFromElements = createRoutesFromElements; exports.renderMatches = renderMatches; exports.WithComponentProps = WithComponentProps; exports.withComponentProps = withComponentProps; exports.WithHydrateFallbackProps = WithHydrateFallbackProps; exports.withHydrateFallbackProps = withHydrateFallbackProps; exports.WithErrorBoundaryProps = WithErrorBoundaryProps; exports.withErrorBoundaryProps = withErrorBoundaryProps;