UNPKG

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