1import { injectQuery as __vite__injectQuery } from "/@vite/client";import { createHotContext as __vite__createHotContext } from "/@vite/client";import.meta.hot = __vite__createHotContext("/node_modules/.vite/deps/react-router-dom.js?v=f660f992");import { 2 require_react_dom 3} from "/node_modules/.vite/deps/chunk-5ZUYLXJE.js?v=f660f992"; 4import { 5 require_react 6} from "/node_modules/.vite/deps/chunk-LNT7LFTT.js?v=f660f992"; 7import { 8 __commonJS, 9 __toESM 10} from "/node_modules/.vite/deps/chunk-G3PMV62Z.js?v=f660f992"; 11
vendor: 8,484 bytes, lines 12-260
12// node_modules/cookie/dist/index.js 13var require_dist = __commonJS({ 14 "node_modules/cookie/dist/index.js"(exports) { 15 "use strict"; 16 Object.defineProperty(exports, "__esModule", { value: true }); 17 exports.parseCookie = parseCookie; 18 exports.parse = parseCookie; 19 exports.stringifyCookie = stringifyCookie; 20 exports.stringifySetCookie = stringifySetCookie; 21 exports.serialize = stringifySetCookie; 22 exports.parseSetCookie = parseSetCookie; 23 exports.stringifySetCookie = stringifySetCookie; 24 exports.serialize = stringifySetCookie; 25 var cookieNameRegExp = /^[\u0021-\u003A\u003C\u003E-\u007E]+$/; 26 var cookieValueRegExp = /^[\u0021-\u003A\u003C-\u007E]*$/; 27 var domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i; 28 var pathValueRegExp = /^[\u0020-\u003A\u003D-\u007E]*$/; 29 var maxAgeRegExp = /^-?\d+$/; 30 var __toString = Object.prototype.toString; 31 var NullObject = (() => { 32 const C = function() { 33 }; 34 C.prototype = /* @__PURE__ */ Object.create(null); 35 return C; 36 })(); 37 function parseCookie(str, options) { 38 const obj = new NullObject(); 39 const len = str.length; 40 if (len < 2) 41 return obj; 42 const dec = options?.decode || decode2; 43 let index = 0; 44 do { 45 const eqIdx = eqIndex(str, index, len); 46 if (eqIdx === -1) 47 break; 48 const endIdx = endIndex(str, index, len); 49 if (eqIdx > endIdx) { 50 index = str.lastIndexOf(";", eqIdx - 1) + 1; 51 continue; 52 } 53 const key = valueSlice(str, index, eqIdx); 54 if (obj[key] === void 0) { 55 obj[key] = dec(valueSlice(str, eqIdx + 1, endIdx)); 56 } 57 index = endIdx + 1; 58 } while (index < len); 59 return obj; 60 } 61 function stringifyCookie(cookie, options) { 62 const enc = options?.encode || encodeURIComponent; 63 const cookieStrings = []; 64 for (const name of Object.keys(cookie)) { 65 const val = cookie[name]; 66 if (val === void 0) 67 continue; 68 if (!cookieNameRegExp.test(name)) { 69 throw new TypeError(`cookie name is invalid: ${name}`); 70 } 71 const value = enc(val); 72 if (!cookieValueRegExp.test(value)) { 73 throw new TypeError(`cookie val is invalid: ${val}`); 74 } 75 cookieStrings.push(`${name}=${value}`); 76 } 77 return cookieStrings.join("; "); 78 } 79 function stringifySetCookie(_name, _val, _opts) { 80 const cookie = typeof _name === "object" ? _name : { ..._opts, name: _name, value: String(_val) }; 81 const options = typeof _val === "object" ? _val : _opts; 82 const enc = options?.encode || encodeURIComponent; 83 if (!cookieNameRegExp.test(cookie.name)) { 84 throw new TypeError(`argument name is invalid: ${cookie.name}`); 85 } 86 const value = cookie.value ? enc(cookie.value) : ""; 87 if (!cookieValueRegExp.test(value)) { 88 throw new TypeError(`argument val is invalid: ${cookie.value}`); 89 } 90 let str = cookie.name + "=" + value; 91 if (cookie.maxAge !== void 0) { 92 if (!Number.isInteger(cookie.maxAge)) { 93 throw new TypeError(`option maxAge is invalid: ${cookie.maxAge}`); 94 } 95 str += "; Max-Age=" + cookie.maxAge; 96 } 97 if (cookie.domain) { 98 if (!domainValueRegExp.test(cookie.domain)) { 99 throw new TypeError(`option domain is invalid: ${cookie.domain}`); 100 } 101 str += "; Domain=" + cookie.domain; 102 } 103 if (cookie.path) { 104 if (!pathValueRegExp.test(cookie.path)) { 105 throw new TypeError(`option path is invalid: ${cookie.path}`); 106 } 107 str += "; Path=" + cookie.path; 108 } 109 if (cookie.expires) { 110 if (!isDate(cookie.expires) || !Number.isFinite(cookie.expires.valueOf())) { 111 throw new TypeError(`option expires is invalid: ${cookie.expires}`); 112 } 113 str += "; Expires=" + cookie.expires.toUTCString(); 114 } 115 if (cookie.httpOnly) { 116 str += "; HttpOnly"; 117 } 118 if (cookie.secure) { 119 str += "; Secure"; 120 } 121 if (cookie.partitioned) { 122 str += "; Partitioned"; 123 } 124 if (cookie.priority) { 125 const priority = typeof cookie.priority === "string" ? cookie.priority.toLowerCase() : void 0; 126 switch (priority) { 127 case "low": 128 str += "; Priority=Low"; 129 break; 130 case "medium": 131 str += "; Priority=Medium"; 132 break; 133 case "high": 134 str += "; Priority=High"; 135 break; 136 default: 137 throw new TypeError(`option priority is invalid: ${cookie.priority}`); 138 } 139 } 140 if (cookie.sameSite) { 141 const sameSite = typeof cookie.sameSite === "string" ? cookie.sameSite.toLowerCase() : cookie.sameSite; 142 switch (sameSite) { 143 case true: 144 case "strict": 145 str += "; SameSite=Strict"; 146 break; 147 case "lax": 148 str += "; SameSite=Lax"; 149 break; 150 case "none": 151 str += "; SameSite=None"; 152 break; 153 default: 154 throw new TypeError(`option sameSite is invalid: ${cookie.sameSite}`); 155 } 156 } 157 return str; 158 } 159 function parseSetCookie(str, options) { 160 const dec = options?.decode || decode2; 161 const len = str.length; 162 const endIdx = endIndex(str, 0, len); 163 const eqIdx = eqIndex(str, 0, endIdx); 164 const setCookie = eqIdx === -1 ? { name: "", value: dec(valueSlice(str, 0, endIdx)) } : { 165 name: valueSlice(str, 0, eqIdx), 166 value: dec(valueSlice(str, eqIdx + 1, endIdx)) 167 }; 168 let index = endIdx + 1; 169 while (index < len) { 170 const endIdx2 = endIndex(str, index, len); 171 const eqIdx2 = eqIndex(str, index, endIdx2); 172 const attr = eqIdx2 === -1 ? valueSlice(str, index, endIdx2) : valueSlice(str, index, eqIdx2); 173 const val = eqIdx2 === -1 ? void 0 : valueSlice(str, eqIdx2 + 1, endIdx2); 174 switch (attr.toLowerCase()) { 175 case "httponly": 176 setCookie.httpOnly = true; 177 break; 178 case "secure": 179 setCookie.secure = true; 180 break; 181 case "partitioned": 182 setCookie.partitioned = true; 183 break; 184 case "domain": 185 setCookie.domain = val; 186 break; 187 case "path": 188 setCookie.path = val; 189 break; 190 case "max-age": 191 if (val && maxAgeRegExp.test(val)) 192 setCookie.maxAge = Number(val); 193 break; 194 case "expires": 195 if (!val) 196 break; 197 const date = new Date(val); 198 if (Number.isFinite(date.valueOf())) 199 setCookie.expires = date; 200 break; 201 case "priority": 202 if (!val) 203 break; 204 const priority = val.toLowerCase(); 205 if (priority === "low" || priority === "medium" || priority === "high") { 206 setCookie.priority = priority; 207 } 208 break; 209 case "samesite": 210 if (!val) 211 break; 212 const sameSite = val.toLowerCase(); 213 if (sameSite === "lax" || sameSite === "strict" || sameSite === "none") { 214 setCookie.sameSite = sameSite; 215 } 216 break; 217 } 218 index = endIdx2 + 1; 219 } 220 return setCookie; 221 } 222 function endIndex(str, min, len) { 223 const index = str.indexOf(";", min); 224 return index === -1 ? len : index; 225 } 226 function eqIndex(str, min, max) { 227 const index = str.indexOf("=", min); 228 return index < max ? index : -1; 229 } 230 function valueSlice(str, min, max) { 231 let start = min; 232 let end = max; 233 do { 234 const code = str.charCodeAt(start); 235 if (code !== 32 && code !== 9) 236 break; 237 } while (++start < end); 238 while (end > start) { 239 const code = str.charCodeAt(end - 1); 240 if (code !== 32 && code !== 9) 241 break; 242 end--; 243 } 244 return str.slice(start, end); 245 } 246 function decode2(str) { 247 if (str.indexOf("%") === -1) 248 return str; 249 try { 250 return decodeURIComponent(str); 251 } catch (e) { 252 return str; 253 } 254 } 255 function isDate(val) { 256 return __toString.call(val) === "[object Date]"; 257 } 258 } 259}); 260
vendor: 6,148 bytes, lines 261-443
261// node_modules/set-cookie-parser/lib/set-cookie.js 262var require_set_cookie = __commonJS({ 263 "node_modules/set-cookie-parser/lib/set-cookie.js"(exports, module) { 264 "use strict"; 265 var defaultParseOptions = { 266 decodeValues: true, 267 map: false, 268 silent: false 269 }; 270 function isForbiddenKey(key) { 271 return typeof key !== "string" || key in {}; 272 } 273 function createNullObj() { 274 return /* @__PURE__ */ Object.create(null); 275 } 276 function isNonEmptyString(str) { 277 return typeof str === "string" && !!str.trim(); 278 } 279 function parseString(setCookieValue, options) { 280 var parts = setCookieValue.split(";").filter(isNonEmptyString); 281 var nameValuePairStr = parts.shift(); 282 var parsed = parseNameValuePair(nameValuePairStr); 283 var name = parsed.name; 284 var value = parsed.value; 285 options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions; 286 if (isForbiddenKey(name)) { 287 return null; 288 } 289 try { 290 value = options.decodeValues ? decodeURIComponent(value) : value; 291 } catch (e) { 292 console.error( 293 "set-cookie-parser: failed to decode cookie value. Set options.decodeValues=false to disable decoding.", 294 e 295 ); 296 } 297 var cookie = createNullObj(); 298 cookie.name = name; 299 cookie.value = value; 300 parts.forEach(function(part) { 301 var sides = part.split("="); 302 var key = sides.shift().trimLeft().toLowerCase(); 303 if (isForbiddenKey(key)) { 304 return; 305 } 306 var value2 = sides.join("="); 307 if (key === "expires") { 308 cookie.expires = new Date(value2); 309 } else if (key === "max-age") { 310 var n = parseInt(value2, 10); 311 if (!Number.isNaN(n)) cookie.maxAge = n; 312 } else if (key === "secure") { 313 cookie.secure = true; 314 } else if (key === "httponly") { 315 cookie.httpOnly = true; 316 } else if (key === "samesite") { 317 cookie.sameSite = value2; 318 } else if (key === "partitioned") { 319 cookie.partitioned = true; 320 } else if (key) { 321 cookie[key] = value2; 322 } 323 }); 324 return cookie; 325 } 326 function parseNameValuePair(nameValuePairStr) { 327 var name = ""; 328 var value = ""; 329 var nameValueArr = nameValuePairStr.split("="); 330 if (nameValueArr.length > 1) { 331 name = nameValueArr.shift(); 332 value = nameValueArr.join("="); 333 } else { 334 value = nameValuePairStr; 335 } 336 return { name, value }; 337 } 338 function parse2(input, options) { 339 options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions; 340 if (!input) { 341 if (!options.map) { 342 return []; 343 } else { 344 return createNullObj(); 345 } 346 } 347 if (input.headers) { 348 if (typeof input.headers.getSetCookie === "function") { 349 input = input.headers.getSetCookie(); 350 } else if (input.headers["set-cookie"]) { 351 input = input.headers["set-cookie"]; 352 } else { 353 var sch = input.headers[Object.keys(input.headers).find(function(key) { 354 return key.toLowerCase() === "set-cookie"; 355 })]; 356 if (!sch && input.headers.cookie && !options.silent) { 357 console.warn( 358 "Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning." 359 ); 360 } 361 input = sch; 362 } 363 } 364 if (!Array.isArray(input)) { 365 input = [input]; 366 } 367 if (!options.map) { 368 return input.filter(isNonEmptyString).map(function(str) { 369 return parseString(str, options); 370 }).filter(Boolean); 371 } else { 372 var cookies = createNullObj(); 373 return input.filter(isNonEmptyString).reduce(function(cookies2, str) { 374 var cookie = parseString(str, options); 375 if (cookie && !isForbiddenKey(cookie.name)) { 376 cookies2[cookie.name] = cookie; 377 } 378 return cookies2; 379 }, cookies); 380 } 381 } 382 function splitCookiesString2(cookiesString) { 383 if (Array.isArray(cookiesString)) { 384 return cookiesString; 385 } 386 if (typeof cookiesString !== "string") { 387 return []; 388 } 389 var cookiesStrings = []; 390 var pos = 0; 391 var start; 392 var ch; 393 var lastComma; 394 var nextStart; 395 var cookiesSeparatorFound; 396 function skipWhitespace() { 397 while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) { 398 pos += 1; 399 } 400 return pos < cookiesString.length; 401 } 402 function notSpecialChar() { 403 ch = cookiesString.charAt(pos); 404 return ch !== "=" && ch !== ";" && ch !== ","; 405 } 406 while (pos < cookiesString.length) { 407 start = pos; 408 cookiesSeparatorFound = false; 409 while (skipWhitespace()) { 410 ch = cookiesString.charAt(pos); 411 if (ch === ",") { 412 lastComma = pos; 413 pos += 1; 414 skipWhitespace(); 415 nextStart = pos; 416 while (pos < cookiesString.length && notSpecialChar()) { 417 pos += 1; 418 } 419 if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") { 420 cookiesSeparatorFound = true; 421 pos = nextStart; 422 cookiesStrings.push(cookiesString.substring(start, lastComma)); 423 start = pos; 424 } else { 425 pos = lastComma + 1; 426 } 427 } else { 428 pos += 1; 429 } 430 } 431 if (!cookiesSeparatorFound || pos >= cookiesString.length) { 432 cookiesStrings.push(cookiesString.substring(start, cookiesString.length)); 433 } 434 } 435 return cookiesStrings; 436 } 437 module.exports = parse2; 438 module.exports.parse = parse2; 439 module.exports.parseString = parseString; 440 module.exports.splitCookiesString = splitCookiesString2; 441 } 442}); 443
vendor: 353,311 bytes, lines 444-11391
444// node_modules/react-router/dist/development/chunk-LFPYN7LY.mjs 445var React = __toESM(require_react(), 1); 446var React2 = __toESM(require_react(), 1); 447var React3 = __toESM(require_react(), 1); 448var React4 = __toESM(require_react(), 1); 449var React9 = __toESM(require_react(), 1); 450var React8 = __toESM(require_react(), 1); 451var React7 = __toESM(require_react(), 1); 452var React6 = __toESM(require_react(), 1); 453var React5 = __toESM(require_react(), 1); 454var React10 = __toESM(require_react(), 1); 455var React11 = __toESM(require_react(), 1); 456var __typeError = (msg) => { 457 throw TypeError(msg); 458}; 459var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); 460var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); 461var __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); 462var Action = ((Action2) => { 463 Action2["Pop"] = "POP"; 464 Action2["Push"] = "PUSH"; 465 Action2["Replace"] = "REPLACE"; 466 return Action2; 467})(Action || {}); 468var PopStateEventType = "popstate"; 469function isLocation(obj) { 470 return typeof obj === "object" && obj != null && "pathname" in obj && "search" in obj && "hash" in obj && "state" in obj && "key" in obj; 471} 472function createMemoryHistory(options = {}) { 473 let { initialEntries = ["/"], initialIndex, v5Compat = false } = options; 474 let entries; 475 entries = initialEntries.map( 476 (entry, index2) => createMemoryLocation( 477 entry, 478 typeof entry === "string" ? null : entry.state, 479 index2 === 0 ? "default" : void 0, 480 typeof entry === "string" ? void 0 : entry.unstable_mask 481 ) 482 ); 483 let index = clampIndex( 484 initialIndex == null ? entries.length - 1 : initialIndex 485 ); 486 let action = "POP"; 487 let listener = null; 488 function clampIndex(n) { 489 return Math.min(Math.max(n, 0), entries.length - 1); 490 } 491 function getCurrentLocation() { 492 return entries[index]; 493 } 494 function createMemoryLocation(to, state = null, key, unstable_mask) { 495 let location2 = createLocation( 496 entries ? getCurrentLocation().pathname : "/", 497 to, 498 state, 499 key, 500 unstable_mask 501 ); 502 warning( 503 location2.pathname.charAt(0) === "/", 504 `relative pathnames are not supported in memory history: ${JSON.stringify( 505 to 506 )}` 507 ); 508 return location2; 509 } 510 function createHref2(to) { 511 return typeof to === "string" ? to : createPath(to); 512 } 513 let history = { 514 get index() { 515 return index; 516 }, 517 get action() { 518 return action; 519 }, 520 get location() { 521 return getCurrentLocation(); 522 }, 523 createHref: createHref2, 524 createURL(to) { 525 return new URL(createHref2(to), "http://localhost"); 526 }, 527 encodeLocation(to) { 528 let path = typeof to === "string" ? parsePath(to) : to; 529 return { 530 pathname: path.pathname || "", 531 search: path.search || "", 532 hash: path.hash || "" 533 }; 534 }, 535 push(to, state) { 536 action = "PUSH"; 537 let nextLocation = isLocation(to) ? to : createMemoryLocation(to, state); 538 index += 1; 539 entries.splice(index, entries.length, nextLocation); 540 if (v5Compat && listener) { 541 listener({ action, location: nextLocation, delta: 1 }); 542 } 543 }, 544 replace(to, state) { 545 action = "REPLACE"; 546 let nextLocation = isLocation(to) ? to : createMemoryLocation(to, state); 547 entries[index] = nextLocation; 548 if (v5Compat && listener) { 549 listener({ action, location: nextLocation, delta: 0 }); 550 } 551 }, 552 go(delta) { 553 action = "POP"; 554 let nextIndex = clampIndex(index + delta); 555 let nextLocation = entries[nextIndex]; 556 index = nextIndex; 557 if (listener) { 558 listener({ action, location: nextLocation, delta }); 559 } 560 }, 561 listen(fn) { 562 listener = fn; 563 return () => { 564 listener = null; 565 }; 566 } 567 }; 568 return history; 569} 570function createBrowserHistory(options = {}) { 571 function createBrowserLocation(window2, globalHistory) { 572 let maskedLocation = globalHistory.state?.masked; 573 let { pathname, search, hash } = maskedLocation || window2.location; 574 return createLocation( 575 "", 576 { pathname, search, hash }, 577 // state defaults to `null` because `window.history.state` does 578 globalHistory.state && globalHistory.state.usr || null, 579 globalHistory.state && globalHistory.state.key || "default", 580 maskedLocation ? { 581 pathname: window2.location.pathname, 582 search: window2.location.search, 583 hash: window2.location.hash 584 } : void 0 585 ); 586 } 587 function createBrowserHref(window2, to) { 588 return typeof to === "string" ? to : createPath(to); 589 } 590 return getUrlBasedHistory( 591 createBrowserLocation, 592 createBrowserHref, 593 null, 594 options 595 ); 596} 597function createHashHistory(options = {}) { 598 function createHashLocation(window2, globalHistory) { 599 let { 600 pathname = "/", 601 search = "", 602 hash = "" 603 } = parsePath(window2.location.hash.substring(1)); 604 if (!pathname.startsWith("/") && !pathname.startsWith(".")) { 605 pathname = "/" + pathname; 606 } 607 return createLocation( 608 "", 609 { pathname, search, hash }, 610 // state defaults to `null` because `window.history.state` does 611 globalHistory.state && globalHistory.state.usr || null, 612 globalHistory.state && globalHistory.state.key || "default" 613 ); 614 } 615 function createHashHref(window2, to) { 616 let base = window2.document.querySelector("base"); 617 let href2 = ""; 618 if (base && base.getAttribute("href")) { 619 let url = window2.location.href; 620 let hashIndex = url.indexOf("#"); 621 href2 = hashIndex === -1 ? url : url.slice(0, hashIndex); 622 } 623 return href2 + "#" + (typeof to === "string" ? to : createPath(to)); 624 } 625 function validateHashLocation(location2, to) { 626 warning( 627 location2.pathname.charAt(0) === "/", 628 `relative pathnames are not supported in hash history.push(${JSON.stringify( 629 to 630 )})` 631 ); 632 } 633 return getUrlBasedHistory( 634 createHashLocation, 635 createHashHref, 636 validateHashLocation, 637 options 638 ); 639} 640function invariant(value, message) { 641 if (value === false || value === null || typeof value === "undefined") { 642 throw new Error(message); 643 } 644} 645function warning(cond, message) { 646 if (!cond) { 647 if (typeof console !== "undefined") console.warn(message); 648 try { 649 throw new Error(message); 650 } catch (e) { 651 } 652 } 653} 654function createKey() { 655 return Math.random().toString(36).substring(2, 10); 656} 657function getHistoryState(location2, index) { 658 return { 659 usr: location2.state, 660 key: location2.key, 661 idx: index, 662 masked: location2.unstable_mask ? { 663 pathname: location2.pathname, 664 search: location2.search, 665 hash: location2.hash 666 } : void 0 667 }; 668} 669function createLocation(current, to, state = null, key, unstable_mask) { 670 let location2 = { 671 pathname: typeof current === "string" ? current : current.pathname, 672 search: "", 673 hash: "", 674 ...typeof to === "string" ? parsePath(to) : to, 675 state, 676 // TODO: This could be cleaned up. push/replace should probably just take 677 // full Locations now and avoid the need to run through this flow at all 678 // But that's a pretty big refactor to the current test suite so going to 679 // keep as is for the time being and just let any incoming keys take precedence 680 key: to && to.key || key || createKey(), 681 unstable_mask 682 }; 683 return location2; 684} 685function createPath({ 686 pathname = "/", 687 search = "", 688 hash = "" 689}) { 690 if (search && search !== "?") 691 pathname += search.charAt(0) === "?" ? search : "?" + search; 692 if (hash && hash !== "#") 693 pathname += hash.charAt(0) === "#" ? hash : "#" + hash; 694 return pathname; 695} 696function parsePath(path) { 697 let parsedPath = {}; 698 if (path) { 699 let hashIndex = path.indexOf("#"); 700 if (hashIndex >= 0) { 701 parsedPath.hash = path.substring(hashIndex); 702 path = path.substring(0, hashIndex); 703 } 704 let searchIndex = path.indexOf("?"); 705 if (searchIndex >= 0) { 706 parsedPath.search = path.substring(searchIndex); 707 path = path.substring(0, searchIndex); 708 } 709 if (path) { 710 parsedPath.pathname = path; 711 } 712 } 713 return parsedPath; 714} 715function getUrlBasedHistory(getLocation, createHref2, validateLocation, options = {}) { 716 let { window: window2 = document.defaultView, v5Compat = false } = options; 717 let globalHistory = window2.history; 718 let action = "POP"; 719 let listener = null; 720 let index = getIndex(); 721 if (index == null) { 722 index = 0; 723 globalHistory.replaceState({ ...globalHistory.state, idx: index }, ""); 724 } 725 function getIndex() { 726 let state = globalHistory.state || { idx: null }; 727 return state.idx; 728 } 729 function handlePop() { 730 action = "POP"; 731 let nextIndex = getIndex(); 732 let delta = nextIndex == null ? null : nextIndex - index; 733 index = nextIndex; 734 if (listener) { 735 listener({ action, location: history.location, delta }); 736 } 737 } 738 function push(to, state) { 739 action = "PUSH"; 740 let location2 = isLocation(to) ? to : createLocation(history.location, to, state); 741 if (validateLocation) validateLocation(location2, to); 742 index = getIndex() + 1; 743 let historyState = getHistoryState(location2, index); 744 let url = history.createHref(location2.unstable_mask || location2); 745 try { 746 globalHistory.pushState(historyState, "", url); 747 } catch (error) { 748 if (error instanceof DOMException && error.name === "DataCloneError") { 749 throw error; 750 } 751 window2.location.assign(url); 752 } 753 if (v5Compat && listener) { 754 listener({ action, location: history.location, delta: 1 }); 755 } 756 } 757 function replace2(to, state) { 758 action = "REPLACE"; 759 let location2 = isLocation(to) ? to : createLocation(history.location, to, state); 760 if (validateLocation) validateLocation(location2, to); 761 index = getIndex(); 762 let historyState = getHistoryState(location2, index); 763 let url = history.createHref(location2.unstable_mask || location2); 764 globalHistory.replaceState(historyState, "", url); 765 if (v5Compat && listener) { 766 listener({ action, location: history.location, delta: 0 }); 767 } 768 } 769 function createURL(to) { 770 return createBrowserURLImpl(to); 771 } 772 let history = { 773 get action() { 774 return action; 775 }, 776 get location() { 777 return getLocation(window2, globalHistory); 778 }, 779 listen(fn) { 780 if (listener) { 781 throw new Error("A history only accepts one active listener"); 782 } 783 window2.addEventListener(PopStateEventType, handlePop); 784 listener = fn; 785 return () => { 786 window2.removeEventListener(PopStateEventType, handlePop); 787 listener = null; 788 }; 789 }, 790 createHref(to) { 791 return createHref2(window2, to); 792 }, 793 createURL, 794 encodeLocation(to) { 795 let url = createURL(to); 796 return { 797 pathname: url.pathname, 798 search: url.search, 799 hash: url.hash 800 }; 801 }, 802 push, 803 replace: replace2, 804 go(n) { 805 return globalHistory.go(n); 806 } 807 }; 808 return history; 809} 810function createBrowserURLImpl(to, isAbsolute = false) { 811 let base = "http://localhost"; 812 if (typeof window !== "undefined") { 813 base = window.location.origin !== "null" ? window.location.origin : window.location.href; 814 } 815 invariant(base, "No window.location.(origin|href) available to create URL"); 816 let href2 = typeof to === "string" ? to : createPath(to); 817 href2 = href2.replace(/ $/, "%20"); 818 if (!isAbsolute && href2.startsWith("//")) { 819 href2 = base + href2; 820 } 821 return new URL(href2, base); 822} 823function createContext4(defaultValue) { 824 return { defaultValue }; 825} 826var _map; 827var RouterContextProvider = class { 828 /** 829 * Create a new `RouterContextProvider` instance 830 * @param init An optional initial context map to populate the provider with 831 */ 832 constructor(init) { 833 __privateAdd(this, _map, /* @__PURE__ */ new Map()); 834 if (init) { 835 for (let [context, value] of init) { 836 this.set(context, value); 837 } 838 } 839 } 840 /** 841 * Access a value from the context. If no value has been set for the context, 842 * it will return the context's `defaultValue` if provided, or throw an error 843 * if no `defaultValue` was set. 844 * @param context The context to get the value for 845 * @returns The value for the context, or the context's `defaultValue` if no 846 * value was set 847 */ 848 get(context) { 849 if (__privateGet(this, _map).has(context)) { 850 return __privateGet(this, _map).get(context); 851 } 852 if (context.defaultValue !== void 0) { 853 return context.defaultValue; 854 } 855 throw new Error("No value found for context"); 856 } 857 /** 858 * Set a value for the context. If the context already has a value set, this 859 * will overwrite it. 860 * 861 * @param context The context to set the value for 862 * @param value The value to set for the context 863 * @returns {void} 864 */ 865 set(context, value) { 866 __privateGet(this, _map).set(context, value); 867 } 868}; 869_map = /* @__PURE__ */ new WeakMap(); 870var unsupportedLazyRouteObjectKeys = /* @__PURE__ */ new Set([ 871 "lazy", 872 "caseSensitive", 873 "path", 874 "id", 875 "index", 876 "children" 877]); 878function isUnsupportedLazyRouteObjectKey(key) { 879 return unsupportedLazyRouteObjectKeys.has( 880 key 881 ); 882} 883var unsupportedLazyRouteFunctionKeys = /* @__PURE__ */ new Set([ 884 "lazy", 885 "caseSensitive", 886 "path", 887 "id", 888 "index", 889 "middleware", 890 "children" 891]); 892function isUnsupportedLazyRouteFunctionKey(key) { 893 return unsupportedLazyRouteFunctionKeys.has( 894 key 895 ); 896} 897function isIndexRoute(route) { 898 return route.index === true; 899} 900function convertRoutesToDataRoutes(routes, mapRouteProperties2, parentPath = [], manifest = {}, allowInPlaceMutations = false) { 901 return routes.map((route, index) => { 902 let treePath = [...parentPath, String(index)]; 903 let id = typeof route.id === "string" ? route.id : treePath.join("-"); 904 invariant( 905 route.index !== true || !route.children, 906 `Cannot specify children on an index route` 907 ); 908 invariant( 909 allowInPlaceMutations || !manifest[id], 910 `Found a route id collision on id "${id}". Route id's must be globally unique within Data Router usages` 911 ); 912 if (isIndexRoute(route)) { 913 let indexRoute = { 914 ...route, 915 id 916 }; 917 manifest[id] = mergeRouteUpdates( 918 indexRoute, 919 mapRouteProperties2(indexRoute) 920 ); 921 return indexRoute; 922 } else { 923 let pathOrLayoutRoute = { 924 ...route, 925 id, 926 children: void 0 927 }; 928 manifest[id] = mergeRouteUpdates( 929 pathOrLayoutRoute, 930 mapRouteProperties2(pathOrLayoutRoute) 931 ); 932 if (route.children) { 933 pathOrLayoutRoute.children = convertRoutesToDataRoutes( 934 route.children, 935 mapRouteProperties2, 936 treePath, 937 manifest, 938 allowInPlaceMutations 939 ); 940 } 941 return pathOrLayoutRoute; 942 } 943 }); 944} 945function mergeRouteUpdates(route, updates) { 946 return Object.assign(route, { 947 ...updates, 948 ...typeof updates.lazy === "object" && updates.lazy != null ? { 949 lazy: { 950 ...route.lazy, 951 ...updates.lazy 952 } 953 } : {} 954 }); 955} 956function matchRoutes(routes, locationArg, basename = "/") { 957 return matchRoutesImpl(routes, locationArg, basename, false); 958} 959function matchRoutesImpl(routes, locationArg, basename, allowPartial) { 960 let location2 = typeof locationArg === "string" ? parsePath(locationArg) : locationArg; 961 let pathname = stripBasename(location2.pathname || "/", basename); 962 if (pathname == null) { 963 return null; 964 } 965 let branches = flattenRoutes(routes); 966 rankRouteBranches(branches); 967 let matches = null; 968 for (let i = 0; matches == null && i < branches.length; ++i) { 969 let decoded = decodePath(pathname); 970 matches = matchRouteBranch( 971 branches[i], 972 decoded, 973 allowPartial 974 ); 975 } 976 return matches; 977} 978function convertRouteMatchToUiMatch(match, loaderData) { 979 let { route, pathname, params } = match; 980 return { 981 id: route.id, 982 pathname, 983 params, 984 data: loaderData[route.id], 985 loaderData: loaderData[route.id], 986 handle: route.handle 987 }; 988} 989function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "", _hasParentOptionalSegments = false) { 990 let flattenRoute = (route, index, hasParentOptionalSegments = _hasParentOptionalSegments, relativePath) => { 991 let meta = { 992 relativePath: relativePath === void 0 ? route.path || "" : relativePath, 993 caseSensitive: route.caseSensitive === true, 994 childrenIndex: index, 995 route 996 }; 997 if (meta.relativePath.startsWith("/")) { 998 if (!meta.relativePath.startsWith(parentPath) && hasParentOptionalSegments) { 999 return; 1000 } 1001 invariant( 1002 meta.relativePath.startsWith(parentPath), 1003 `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.` 1004 ); 1005 meta.relativePath = meta.relativePath.slice(parentPath.length); 1006 } 1007 let path = joinPaths([parentPath, meta.relativePath]); 1008 let routesMeta = parentsMeta.concat(meta); 1009 if (route.children && route.children.length > 0) { 1010 invariant( 1011 // Our types know better, but runtime JS may not! 1012 // @ts-expect-error 1013 route.index !== true, 1014 `Index routes must not have child routes. Please remove all child routes from route path "${path}".` 1015 ); 1016 flattenRoutes( 1017 route.children, 1018 branches, 1019 routesMeta, 1020 path, 1021 hasParentOptionalSegments 1022 ); 1023 } 1024 if (route.path == null && !route.index) { 1025 return; 1026 } 1027 branches.push({ 1028 path, 1029 score: computeScore(path, route.index), 1030 routesMeta 1031 }); 1032 }; 1033 routes.forEach((route, index) => { 1034 if (route.path === "" || !route.path?.includes("?")) { 1035 flattenRoute(route, index); 1036 } else { 1037 for (let exploded of explodeOptionalSegments(route.path)) { 1038 flattenRoute(route, index, true, exploded); 1039 } 1040 } 1041 }); 1042 return branches; 1043} 1044function explodeOptionalSegments(path) { 1045 let segments = path.split("/"); 1046 if (segments.length === 0) return []; 1047 let [first, ...rest] = segments; 1048 let isOptional = first.endsWith("?"); 1049 let required = first.replace(/\?$/, ""); 1050 if (rest.length === 0) { 1051 return isOptional ? [required, ""] : [required]; 1052 } 1053 let restExploded = explodeOptionalSegments(rest.join("/")); 1054 let result = []; 1055 result.push( 1056 ...restExploded.map( 1057 (subpath) => subpath === "" ? required : [required, subpath].join("/") 1058 ) 1059 ); 1060 if (isOptional) { 1061 result.push(...restExploded); 1062 } 1063 return result.map( 1064 (exploded) => path.startsWith("/") && exploded === "" ? "/" : exploded 1065 ); 1066} 1067function rankRouteBranches(branches) { 1068 branches.sort( 1069 (a, b) => a.score !== b.score ? b.score - a.score : compareIndexes( 1070 a.routesMeta.map((meta) => meta.childrenIndex), 1071 b.routesMeta.map((meta) => meta.childrenIndex) 1072 ) 1073 ); 1074} 1075var paramRe = /^:[\w-]+$/; 1076var dynamicSegmentValue = 3; 1077var indexRouteValue = 2; 1078var emptySegmentValue = 1; 1079var staticSegmentValue = 10; 1080var splatPenalty = -2; 1081var isSplat = (s) => s === "*"; 1082function computeScore(path, index) { 1083 let segments = path.split("/"); 1084 let initialScore = segments.length; 1085 if (segments.some(isSplat)) { 1086 initialScore += splatPenalty; 1087 } 1088 if (index) { 1089 initialScore += indexRouteValue; 1090 } 1091 return segments.filter((s) => !isSplat(s)).reduce( 1092 (score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), 1093 initialScore 1094 ); 1095} 1096function compareIndexes(a, b) { 1097 let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]); 1098 return siblings ? ( 1099 // If two routes are siblings, we should try to match the earlier sibling 1100 // first. This allows people to have fine-grained control over the matching 1101 // behavior by simply putting routes with identical paths in the order they 1102 // want them tried. 1103 a[a.length - 1] - b[b.length - 1] 1104 ) : ( 1105 // Otherwise, it doesn't really make sense to rank non-siblings by index, 1106 // so they sort equally. 1107 0 1108 ); 1109} 1110function matchRouteBranch(branch, pathname, allowPartial = false) { 1111 let { routesMeta } = branch; 1112 let matchedParams = {}; 1113 let matchedPathname = "/"; 1114 let matches = []; 1115 for (let i = 0; i < routesMeta.length; ++i) { 1116 let meta = routesMeta[i]; 1117 let end = i === routesMeta.length - 1; 1118 let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/"; 1119 let match = matchPath( 1120 { path: meta.relativePath, caseSensitive: meta.caseSensitive, end }, 1121 remainingPathname 1122 ); 1123 let route = meta.route; 1124 if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) { 1125 match = matchPath( 1126 { 1127 path: meta.relativePath, 1128 caseSensitive: meta.caseSensitive, 1129 end: false 1130 }, 1131 remainingPathname 1132 ); 1133 } 1134 if (!match) { 1135 return null; 1136 } 1137 Object.assign(matchedParams, match.params); 1138 matches.push({ 1139 // TODO: Can this as be avoided? 1140 params: matchedParams, 1141 pathname: joinPaths([matchedPathname, match.pathname]), 1142 pathnameBase: normalizePathname( 1143 joinPaths([matchedPathname, match.pathnameBase]) 1144 ), 1145 route 1146 }); 1147 if (match.pathnameBase !== "/") { 1148 matchedPathname = joinPaths([matchedPathname, match.pathnameBase]); 1149 } 1150 } 1151 return matches; 1152} 1153function generatePath(originalPath, params = {}) { 1154 let path = originalPath; 1155 if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) { 1156 warning( 1157 false, 1158 `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(/\*$/, "/*")}".` 1159 ); 1160 path = path.replace(/\*$/, "/*"); 1161 } 1162 const prefix = path.startsWith("/") ? "/" : ""; 1163 const stringify2 = (p) => p == null ? "" : typeof p === "string" ? p : String(p); 1164 const segments = path.split(/\/+/).map((segment, index, array) => { 1165 const isLastSegment = index === array.length - 1; 1166 if (isLastSegment && segment === "*") { 1167 const star = "*"; 1168 return stringify2(params[star]); 1169 } 1170 const keyMatch = segment.match(/^:([\w-]+)(\??)(.*)/); 1171 if (keyMatch) { 1172 const [, key, optional, suffix] = keyMatch; 1173 let param = params[key]; 1174 invariant(optional === "?" || param != null, `Missing ":${key}" param`); 1175 return encodeURIComponent(stringify2(param)) + suffix; 1176 } 1177 return segment.replace(/\?$/g, ""); 1178 }).filter((segment) => !!segment); 1179 return prefix + segments.join("/"); 1180} 1181function matchPath(pattern, pathname) { 1182 if (typeof pattern === "string") { 1183 pattern = { path: pattern, caseSensitive: false, end: true }; 1184 } 1185 let [matcher, compiledParams] = compilePath( 1186 pattern.path, 1187 pattern.caseSensitive, 1188 pattern.end 1189 ); 1190 let match = pathname.match(matcher); 1191 if (!match) return null; 1192 let matchedPathname = match[0]; 1193 let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1"); 1194 let captureGroups = match.slice(1); 1195 let params = compiledParams.reduce( 1196 (memo2, { paramName, isOptional }, index) => { 1197 if (paramName === "*") { 1198 let splatValue = captureGroups[index] || ""; 1199 pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1"); 1200 } 1201 const value = captureGroups[index]; 1202 if (isOptional && !value) { 1203 memo2[paramName] = void 0; 1204 } else { 1205 memo2[paramName] = (value || "").replace(/%2F/g, "/"); 1206 } 1207 return memo2; 1208 }, 1209 {} 1210 ); 1211 return { 1212 params, 1213 pathname: matchedPathname, 1214 pathnameBase, 1215 pattern 1216 }; 1217} 1218function compilePath(path, caseSensitive = false, end = true) { 1219 warning( 1220 path === "*" || !path.endsWith("*") || path.endsWith("/*"), 1221 `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(/\*$/, "/*")}".` 1222 ); 1223 let params = []; 1224 let regexpSource = "^" + path.replace(/\/*\*?$/, "").replace(/^\/*/, "/").replace(/[\\.*+^${}|()[\]]/g, "\\$&").replace( 1225 /\/:([\w-]+)(\?)?/g, 1226 (match, paramName, isOptional, index, str) => { 1227 params.push({ paramName, isOptional: isOptional != null }); 1228 if (isOptional) { 1229 let nextChar = str.charAt(index + match.length); 1230 if (nextChar && nextChar !== "/") { 1231 return "/([^\\/]*)"; 1232 } 1233 return "(?:/([^\\/]*))?"; 1234 } 1235 return "/([^\\/]+)"; 1236 } 1237 ).replace(/\/([\w-]+)\?(\/|$)/g, "(/$1)?$2"); 1238 if (path.endsWith("*")) { 1239 params.push({ paramName: "*" }); 1240 regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$"; 1241 } else if (end) { 1242 regexpSource += "\\/*$"; 1243 } else if (path !== "" && path !== "/") { 1244 regexpSource += "(?:(?=\\/|$))"; 1245 } else { 1246 } 1247 let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i"); 1248 return [matcher, params]; 1249} 1250function decodePath(value) { 1251 try { 1252 return value.split("/").map((v) => decodeURIComponent(v).replace(/\//g, "%2F")).join("/"); 1253 } catch (error) { 1254 warning( 1255 false, 1256 `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}).` 1257 ); 1258 return value; 1259 } 1260} 1261function stripBasename(pathname, basename) { 1262 if (basename === "/") return pathname; 1263 if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) { 1264 return null; 1265 } 1266 let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length; 1267 let nextChar = pathname.charAt(startIndex); 1268 if (nextChar && nextChar !== "/") { 1269 return null; 1270 } 1271 return pathname.slice(startIndex) || "/"; 1272} 1273function prependBasename({ 1274 basename, 1275 pathname 1276}) { 1277 return pathname === "/" ? basename : joinPaths([basename, pathname]); 1278} 1279var ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; 1280var isAbsoluteUrl = (url) => ABSOLUTE_URL_REGEX.test(url); 1281function resolvePath(to, fromPathname = "/") { 1282 let { 1283 pathname: toPathname, 1284 search = "", 1285 hash = "" 1286 } = typeof to === "string" ? parsePath(to) : to; 1287 let pathname; 1288 if (toPathname) { 1289 toPathname = toPathname.replace(/\/\/+/g, "/"); 1290 if (toPathname.startsWith("/")) { 1291 pathname = resolvePathname(toPathname.substring(1), "/"); 1292 } else { 1293 pathname = resolvePathname(toPathname, fromPathname); 1294 } 1295 } else { 1296 pathname = fromPathname; 1297 } 1298 return { 1299 pathname, 1300 search: normalizeSearch(search), 1301 hash: normalizeHash(hash) 1302 }; 1303} 1304function resolvePathname(relativePath, fromPathname) { 1305 let segments = fromPathname.replace(/\/+$/, "").split("/"); 1306 let relativeSegments = relativePath.split("/"); 1307 relativeSegments.forEach((segment) => { 1308 if (segment === "..") { 1309 if (segments.length > 1) segments.pop(); 1310 } else if (segment !== ".") { 1311 segments.push(segment); 1312 } 1313 }); 1314 return segments.length > 1 ? segments.join("/") : "/"; 1315} 1316function getInvalidPathError(char, field, dest, path) { 1317 return `Cannot include a '${char}' character in a manually specified \`to.${field}\` field [${JSON.stringify( 1318 path 1319 )}]. 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.`; 1320} 1321function getPathContributingMatches(matches) { 1322 return matches.filter( 1323 (match, index) => index === 0 || match.route.path && match.route.path.length > 0 1324 ); 1325} 1326function getResolveToMatches(matches) { 1327 let pathMatches = getPathContributingMatches(matches); 1328 return pathMatches.map( 1329 (match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase 1330 ); 1331} 1332function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) { 1333 let to; 1334 if (typeof toArg === "string") { 1335 to = parsePath(toArg); 1336 } else { 1337 to = { ...toArg }; 1338 invariant( 1339 !to.pathname || !to.pathname.includes("?"), 1340 getInvalidPathError("?", "pathname", "search", to) 1341 ); 1342 invariant( 1343 !to.pathname || !to.pathname.includes("#"), 1344 getInvalidPathError("#", "pathname", "hash", to) 1345 ); 1346 invariant( 1347 !to.search || !to.search.includes("#"), 1348 getInvalidPathError("#", "search", "hash", to) 1349 ); 1350 } 1351 let isEmptyPath = toArg === "" || to.pathname === ""; 1352 let toPathname = isEmptyPath ? "/" : to.pathname; 1353 let from; 1354 if (toPathname == null) { 1355 from = locationPathname; 1356 } else { 1357 let routePathnameIndex = routePathnames.length - 1; 1358 if (!isPathRelative && toPathname.startsWith("..")) { 1359 let toSegments = toPathname.split("/"); 1360 while (toSegments[0] === "..") { 1361 toSegments.shift(); 1362 routePathnameIndex -= 1; 1363 } 1364 to.pathname = toSegments.join("/"); 1365 } 1366 from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/"; 1367 } 1368 let path = resolvePath(to, from); 1369 let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/"); 1370 let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/"); 1371 if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) { 1372 path.pathname += "/"; 1373 } 1374 return path; 1375} 1376var joinPaths = (paths) => paths.join("/").replace(/\/\/+/g, "/"); 1377var normalizePathname = (pathname) => pathname.replace(/\/+$/, "").replace(/^\/*/, "/"); 1378var normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search; 1379var normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash; 1380var DataWithResponseInit = class { 1381 constructor(data2, init) { 1382 this.type = "DataWithResponseInit"; 1383 this.data = data2; 1384 this.init = init || null; 1385 } 1386}; 1387function data(data2, init) { 1388 return new DataWithResponseInit( 1389 data2, 1390 typeof init === "number" ? { status: init } : init 1391 ); 1392} 1393var redirect = (url, init = 302) => { 1394 let responseInit = init; 1395 if (typeof responseInit === "number") { 1396 responseInit = { status: responseInit }; 1397 } else if (typeof responseInit.status === "undefined") { 1398 responseInit.status = 302; 1399 } 1400 let headers = new Headers(responseInit.headers); 1401 headers.set("Location", url); 1402 return new Response(null, { ...responseInit, headers }); 1403}; 1404var redirectDocument = (url, init) => { 1405 let response = redirect(url, init); 1406 response.headers.set("X-Remix-Reload-Document", "true"); 1407 return response; 1408}; 1409var replace = (url, init) => { 1410 let response = redirect(url, init); 1411 response.headers.set("X-Remix-Replace", "true"); 1412 return response; 1413}; 1414var ErrorResponseImpl = class { 1415 constructor(status, statusText, data2, internal = false) { 1416 this.status = status; 1417 this.statusText = statusText || ""; 1418 this.internal = internal; 1419 if (data2 instanceof Error) { 1420 this.data = data2.toString(); 1421 this.error = data2; 1422 } else { 1423 this.data = data2; 1424 } 1425 } 1426}; 1427function isRouteErrorResponse(error) { 1428 return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error; 1429} 1430function getRoutePattern(matches) { 1431 return matches.map((m) => m.route.path).filter(Boolean).join("/").replace(/\/\/*/g, "/") || "/"; 1432} 1433var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"; 1434function parseToInfo(_to, basename) { 1435 let to = _to; 1436 if (typeof to !== "string" || !ABSOLUTE_URL_REGEX.test(to)) { 1437 return { 1438 absoluteURL: void 0, 1439 isExternal: false, 1440 to 1441 }; 1442 } 1443 let absoluteURL = to; 1444 let isExternal = false; 1445 if (isBrowser) { 1446 try { 1447 let currentUrl = new URL(window.location.href); 1448 let targetUrl = to.startsWith("//") ? new URL(currentUrl.protocol + to) : new URL(to); 1449 let path = stripBasename(targetUrl.pathname, basename); 1450 if (targetUrl.origin === currentUrl.origin && path != null) { 1451 to = path + targetUrl.search + targetUrl.hash; 1452 } else { 1453 isExternal = true; 1454 } 1455 } catch (e) { 1456 warning( 1457 false, 1458 `<Link to="${to}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.` 1459 ); 1460 } 1461 } 1462 return { 1463 absoluteURL, 1464 isExternal, 1465 to 1466 }; 1467} 1468var UninstrumentedSymbol = /* @__PURE__ */ Symbol("Uninstrumented"); 1469function getRouteInstrumentationUpdates(fns, route) { 1470 let aggregated = { 1471 lazy: [], 1472 "lazy.loader": [], 1473 "lazy.action": [], 1474 "lazy.middleware": [], 1475 middleware: [], 1476 loader: [], 1477 action: [] 1478 }; 1479 fns.forEach( 1480 (fn) => fn({ 1481 id: route.id, 1482 index: route.index, 1483 path: route.path, 1484 instrument(i) { 1485 let keys = Object.keys(aggregated); 1486 for (let key of keys) { 1487 if (i[key]) { 1488 aggregated[key].push(i[key]); 1489 } 1490 } 1491 } 1492 }) 1493 ); 1494 let updates = {}; 1495 if (typeof route.lazy === "function" && aggregated.lazy.length > 0) { 1496 let instrumented = wrapImpl(aggregated.lazy, route.lazy, () => void 0); 1497 if (instrumented) { 1498 updates.lazy = instrumented; 1499 } 1500 } 1501 if (typeof route.lazy === "object") { 1502 let lazyObject = route.lazy; 1503 ["middleware", "loader", "action"].forEach((key) => { 1504 let lazyFn = lazyObject[key]; 1505 let instrumentations = aggregated[`lazy.${key}`]; 1506 if (typeof lazyFn === "function" && instrumentations.length > 0) { 1507 let instrumented = wrapImpl(instrumentations, lazyFn, () => void 0); 1508 if (instrumented) { 1509 updates.lazy = Object.assign(updates.lazy || {}, { 1510 [key]: instrumented 1511 }); 1512 } 1513 } 1514 }); 1515 } 1516 ["loader", "action"].forEach((key) => { 1517 let handler = route[key]; 1518 if (typeof handler === "function" && aggregated[key].length > 0) { 1519 let original = handler[UninstrumentedSymbol] ?? handler; 1520 let instrumented = wrapImpl( 1521 aggregated[key], 1522 original, 1523 (...args) => getHandlerInfo(args[0]) 1524 ); 1525 if (instrumented) { 1526 if (key === "loader" && original.hydrate === true) { 1527 instrumented.hydrate = true; 1528 } 1529 instrumented[UninstrumentedSymbol] = original; 1530 updates[key] = instrumented; 1531 } 1532 } 1533 }); 1534 if (route.middleware && route.middleware.length > 0 && aggregated.middleware.length > 0) { 1535 updates.middleware = route.middleware.map((middleware) => { 1536 let original = middleware[UninstrumentedSymbol] ?? middleware; 1537 let instrumented = wrapImpl( 1538 aggregated.middleware, 1539 original, 1540 (...args) => getHandlerInfo(args[0]) 1541 ); 1542 if (instrumented) { 1543 instrumented[UninstrumentedSymbol] = original; 1544 return instrumented; 1545 } 1546 return middleware; 1547 }); 1548 } 1549 return updates; 1550} 1551function instrumentClientSideRouter(router2, fns) { 1552 let aggregated = { 1553 navigate: [], 1554 fetch: [] 1555 }; 1556 fns.forEach( 1557 (fn) => fn({ 1558 instrument(i) { 1559 let keys = Object.keys(i); 1560 for (let key of keys) { 1561 if (i[key]) { 1562 aggregated[key].push(i[key]); 1563 } 1564 } 1565 } 1566 }) 1567 ); 1568 if (aggregated.navigate.length > 0) { 1569 let navigate = router2.navigate[UninstrumentedSymbol] ?? router2.navigate; 1570 let instrumentedNavigate = wrapImpl( 1571 aggregated.navigate, 1572 navigate, 1573 (...args) => { 1574 let [to, opts] = args; 1575 return { 1576 to: typeof to === "number" || typeof to === "string" ? to : to ? createPath(to) : ".", 1577 ...getRouterInfo(router2, opts ?? {}) 1578 }; 1579 } 1580 ); 1581 if (instrumentedNavigate) { 1582 instrumentedNavigate[UninstrumentedSymbol] = navigate; 1583 router2.navigate = instrumentedNavigate; 1584 } 1585 } 1586 if (aggregated.fetch.length > 0) { 1587 let fetch2 = router2.fetch[UninstrumentedSymbol] ?? router2.fetch; 1588 let instrumentedFetch = wrapImpl(aggregated.fetch, fetch2, (...args) => { 1589 let [key, , href2, opts] = args; 1590 return { 1591 href: href2 ?? ".", 1592 fetcherKey: key, 1593 ...getRouterInfo(router2, opts ?? {}) 1594 }; 1595 }); 1596 if (instrumentedFetch) { 1597 instrumentedFetch[UninstrumentedSymbol] = fetch2; 1598 router2.fetch = instrumentedFetch; 1599 } 1600 } 1601 return router2; 1602} 1603function instrumentHandler(handler, fns) { 1604 let aggregated = { 1605 request: [] 1606 }; 1607 fns.forEach( 1608 (fn) => fn({ 1609 instrument(i) { 1610 let keys = Object.keys(i); 1611 for (let key of keys) { 1612 if (i[key]) { 1613 aggregated[key].push(i[key]); 1614 } 1615 } 1616 } 1617 }) 1618 ); 1619 let instrumentedHandler = handler; 1620 if (aggregated.request.length > 0) { 1621 instrumentedHandler = wrapImpl(aggregated.request, handler, (...args) => { 1622 let [request, context] = args; 1623 return { 1624 request: getReadonlyRequest(request), 1625 context: context != null ? getReadonlyContext(context) : context 1626 }; 1627 }); 1628 } 1629 return instrumentedHandler; 1630} 1631function wrapImpl(impls, handler, getInfo) { 1632 if (impls.length === 0) { 1633 return null; 1634 } 1635 return async (...args) => { 1636 let result = await recurseRight( 1637 impls, 1638 getInfo(...args), 1639 () => handler(...args), 1640 impls.length - 1 1641 ); 1642 if (result.type === "error") { 1643 throw result.value; 1644 } 1645 return result.value; 1646 }; 1647} 1648async function recurseRight(impls, info, handler, index) { 1649 let impl = impls[index]; 1650 let result; 1651 if (!impl) { 1652 try { 1653 let value = await handler(); 1654 result = { type: "success", value }; 1655 } catch (e) { 1656 result = { type: "error", value: e }; 1657 } 1658 } else { 1659 let handlerPromise = void 0; 1660 let callHandler = async () => { 1661 if (handlerPromise) { 1662 console.error("You cannot call instrumented handlers more than once"); 1663 } else { 1664 handlerPromise = recurseRight(impls, info, handler, index - 1); 1665 } 1666 result = await handlerPromise; 1667 invariant(result, "Expected a result"); 1668 if (result.type === "error" && result.value instanceof Error) { 1669 return { status: "error", error: result.value }; 1670 } 1671 return { status: "success", error: void 0 }; 1672 }; 1673 try { 1674 await impl(callHandler, info); 1675 } catch (e) { 1676 console.error("An instrumentation function threw an error:", e); 1677 } 1678 if (!handlerPromise) { 1679 await callHandler(); 1680 } 1681 await handlerPromise; 1682 } 1683 if (result) { 1684 return result; 1685 } 1686 return { 1687 type: "error", 1688 value: new Error("No result assigned in instrumentation chain.") 1689 }; 1690} 1691function getHandlerInfo(args) { 1692 let { request, context, params, unstable_pattern } = args; 1693 return { 1694 request: getReadonlyRequest(request), 1695 params: { ...params }, 1696 unstable_pattern, 1697 context: getReadonlyContext(context) 1698 }; 1699} 1700function getRouterInfo(router2, opts) { 1701 return { 1702 currentUrl: createPath(router2.state.location), 1703 ..."formMethod" in opts ? { formMethod: opts.formMethod } : {}, 1704 ..."formEncType" in opts ? { formEncType: opts.formEncType } : {}, 1705 ..."formData" in opts ? { formData: opts.formData } : {}, 1706 ..."body" in opts ? { body: opts.body } : {} 1707 }; 1708} 1709function getReadonlyRequest(request) { 1710 return { 1711 method: request.method, 1712 url: request.url, 1713 headers: { 1714 get: (...args) => request.headers.get(...args) 1715 } 1716 }; 1717} 1718function getReadonlyContext(context) { 1719 if (isPlainObject(context)) { 1720 let frozen = { ...context }; 1721 Object.freeze(frozen); 1722 return frozen; 1723 } else { 1724 return { 1725 get: (ctx) => context.get(ctx) 1726 }; 1727 } 1728} 1729var objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join("\0"); 1730function isPlainObject(thing) { 1731 if (thing === null || typeof thing !== "object") { 1732 return false; 1733 } 1734 const proto = Object.getPrototypeOf(thing); 1735 return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames; 1736} 1737var validMutationMethodsArr = [ 1738 "POST", 1739 "PUT", 1740 "PATCH", 1741 "DELETE" 1742]; 1743var validMutationMethods = new Set( 1744 validMutationMethodsArr 1745); 1746var validRequestMethodsArr = [ 1747 "GET", 1748 ...validMutationMethodsArr 1749]; 1750var validRequestMethods = new Set(validRequestMethodsArr); 1751var redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]); 1752var redirectPreserveMethodStatusCodes = /* @__PURE__ */ new Set([307, 308]); 1753var IDLE_NAVIGATION = { 1754 state: "idle", 1755 location: void 0, 1756 formMethod: void 0, 1757 formAction: void 0, 1758 formEncType: void 0, 1759 formData: void 0, 1760 json: void 0, 1761 text: void 0 1762}; 1763var IDLE_FETCHER = { 1764 state: "idle", 1765 data: void 0, 1766 formMethod: void 0, 1767 formAction: void 0, 1768 formEncType: void 0, 1769 formData: void 0, 1770 json: void 0, 1771 text: void 0 1772}; 1773var IDLE_BLOCKER = { 1774 state: "unblocked", 1775 proceed: void 0, 1776 reset: void 0, 1777 location: void 0 1778}; 1779var defaultMapRouteProperties = (route) => ({ 1780 hasErrorBoundary: Boolean(route.hasErrorBoundary) 1781}); 1782var TRANSITIONS_STORAGE_KEY = "remix-router-transitions"; 1783var ResetLoaderDataSymbol = /* @__PURE__ */ Symbol("ResetLoaderData"); 1784function createRouter(init) { 1785 const routerWindow = init.window ? init.window : typeof window !== "undefined" ? window : void 0; 1786 const isBrowser3 = typeof routerWindow !== "undefined" && typeof routerWindow.document !== "undefined" && typeof routerWindow.document.createElement !== "undefined"; 1787 invariant( 1788 init.routes.length > 0, 1789 "You must provide a non-empty routes array to createRouter" 1790 ); 1791 let hydrationRouteProperties2 = init.hydrationRouteProperties || []; 1792 let _mapRouteProperties = init.mapRouteProperties || defaultMapRouteProperties; 1793 let mapRouteProperties2 = _mapRouteProperties; 1794 if (init.unstable_instrumentations) { 1795 let instrumentations = init.unstable_instrumentations; 1796 mapRouteProperties2 = (route) => { 1797 return { 1798 ..._mapRouteProperties(route), 1799 ...getRouteInstrumentationUpdates( 1800 instrumentations.map((i) => i.route).filter(Boolean), 1801 route 1802 ) 1803 }; 1804 }; 1805 } 1806 let manifest = {}; 1807 let dataRoutes = convertRoutesToDataRoutes( 1808 init.routes, 1809 mapRouteProperties2, 1810 void 0, 1811 manifest 1812 ); 1813 let inFlightDataRoutes; 1814 let basename = init.basename || "/"; 1815 if (!basename.startsWith("/")) { 1816 basename = `/${basename}`; 1817 } 1818 let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware; 1819 let future = { 1820 ...init.future 1821 }; 1822 let unlistenHistory = null; 1823 let subscribers = /* @__PURE__ */ new Set(); 1824 let savedScrollPositions2 = null; 1825 let getScrollRestorationKey2 = null; 1826 let getScrollPosition = null; 1827 let initialScrollRestored = init.hydrationData != null; 1828 let initialMatches = matchRoutes(dataRoutes, init.history.location, basename); 1829 let initialMatchesIsFOW = false; 1830 let initialErrors = null; 1831 let initialized; 1832 let renderFallback; 1833 if (initialMatches == null && !init.patchRoutesOnNavigation) { 1834 let error = getInternalRouterError(404, { 1835 pathname: init.history.location.pathname 1836 }); 1837 let { matches, route } = getShortCircuitMatches(dataRoutes); 1838 initialized = true; 1839 renderFallback = !initialized; 1840 initialMatches = matches; 1841 initialErrors = { [route.id]: error }; 1842 } else { 1843 if (initialMatches && !init.hydrationData) { 1844 let fogOfWar = checkFogOfWar( 1845 initialMatches, 1846 dataRoutes, 1847 init.history.location.pathname 1848 ); 1849 if (fogOfWar.active) { 1850 initialMatches = null; 1851 } 1852 } 1853 if (!initialMatches) { 1854 initialized = false; 1855 renderFallback = !initialized; 1856 initialMatches = []; 1857 let fogOfWar = checkFogOfWar( 1858 null, 1859 dataRoutes, 1860 init.history.location.pathname 1861 ); 1862 if (fogOfWar.active && fogOfWar.matches) { 1863 initialMatchesIsFOW = true; 1864 initialMatches = fogOfWar.matches; 1865 } 1866 } else if (initialMatches.some((m) => m.route.lazy)) { 1867 initialized = false; 1868 renderFallback = !initialized; 1869 } else if (!initialMatches.some((m) => routeHasLoaderOrMiddleware(m.route))) { 1870 initialized = true; 1871 renderFallback = !initialized; 1872 } else { 1873 let loaderData = init.hydrationData ? init.hydrationData.loaderData : null; 1874 let errors = init.hydrationData ? init.hydrationData.errors : null; 1875 let relevantMatches = initialMatches; 1876 if (errors) { 1877 let idx = initialMatches.findIndex( 1878 (m) => errors[m.route.id] !== void 0 1879 ); 1880 relevantMatches = relevantMatches.slice(0, idx + 1); 1881 } 1882 renderFallback = false; 1883 initialized = relevantMatches.every((m) => { 1884 let status = getRouteHydrationStatus(m.route, loaderData, errors); 1885 renderFallback = renderFallback || status.renderFallback; 1886 return !status.shouldLoad; 1887 }); 1888 } 1889 } 1890 let router2; 1891 let state = { 1892 historyAction: init.history.action, 1893 location: init.history.location, 1894 matches: initialMatches, 1895 initialized, 1896 renderFallback, 1897 navigation: IDLE_NAVIGATION, 1898 // Don't restore on initial updateState() if we were SSR'd 1899 restoreScrollPosition: init.hydrationData != null ? false : null, 1900 preventScrollReset: false, 1901 revalidation: "idle", 1902 loaderData: init.hydrationData && init.hydrationData.loaderData || {}, 1903 actionData: init.hydrationData && init.hydrationData.actionData || null, 1904 errors: init.hydrationData && init.hydrationData.errors || initialErrors, 1905 fetchers: /* @__PURE__ */ new Map(), 1906 blockers: /* @__PURE__ */ new Map() 1907 }; 1908 let pendingAction = "POP"; 1909 let pendingPopstateNavigationDfd = null; 1910 let pendingPreventScrollReset = false; 1911 let pendingNavigationController; 1912 let pendingViewTransitionEnabled = false; 1913 let appliedViewTransitions = /* @__PURE__ */ new Map(); 1914 let removePageHideEventListener = null; 1915 let isUninterruptedRevalidation = false; 1916 let isRevalidationRequired = false; 1917 let cancelledFetcherLoads = /* @__PURE__ */ new Set(); 1918 let fetchControllers = /* @__PURE__ */ new Map(); 1919 let incrementingLoadId = 0; 1920 let pendingNavigationLoadId = -1; 1921 let fetchReloadIds = /* @__PURE__ */ new Map(); 1922 let fetchRedirectIds = /* @__PURE__ */ new Set(); 1923 let fetchLoadMatches = /* @__PURE__ */ new Map(); 1924 let activeFetchers = /* @__PURE__ */ new Map(); 1925 let fetchersQueuedForDeletion = /* @__PURE__ */ new Set(); 1926 let blockerFunctions = /* @__PURE__ */ new Map(); 1927 let unblockBlockerHistoryUpdate = void 0; 1928 let pendingRevalidationDfd = null; 1929 function initialize() { 1930 unlistenHistory = init.history.listen( 1931 ({ action: historyAction, location: location2, delta }) => { 1932 if (unblockBlockerHistoryUpdate) { 1933 unblockBlockerHistoryUpdate(); 1934 unblockBlockerHistoryUpdate = void 0; 1935 return; 1936 } 1937 warning( 1938 blockerFunctions.size === 0 || delta != null, 1939 "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." 1940 ); 1941 let blockerKey = shouldBlockNavigation({ 1942 currentLocation: state.location, 1943 nextLocation: location2, 1944 historyAction 1945 }); 1946 if (blockerKey && delta != null) { 1947 let nextHistoryUpdatePromise = new Promise((resolve) => { 1948 unblockBlockerHistoryUpdate = resolve; 1949 }); 1950 init.history.go(delta * -1); 1951 updateBlocker(blockerKey, { 1952 state: "blocked", 1953 location: location2, 1954 proceed() { 1955 updateBlocker(blockerKey, { 1956 state: "proceeding", 1957 proceed: void 0, 1958 reset: void 0, 1959 location: location2 1960 }); 1961 nextHistoryUpdatePromise.then(() => init.history.go(delta)); 1962 }, 1963 reset() { 1964 let blockers = new Map(state.blockers); 1965 blockers.set(blockerKey, IDLE_BLOCKER); 1966 updateState({ blockers }); 1967 } 1968 }); 1969 pendingPopstateNavigationDfd?.resolve(); 1970 pendingPopstateNavigationDfd = null; 1971 return; 1972 } 1973 return startNavigation(historyAction, location2); 1974 } 1975 ); 1976 if (isBrowser3) { 1977 restoreAppliedTransitions(routerWindow, appliedViewTransitions); 1978 let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions); 1979 routerWindow.addEventListener("pagehide", _saveAppliedTransitions); 1980 removePageHideEventListener = () => routerWindow.removeEventListener("pagehide", _saveAppliedTransitions); 1981 } 1982 if (!state.initialized) { 1983 startNavigation("POP", state.location, { 1984 initialHydration: true 1985 }); 1986 } 1987 return router2; 1988 } 1989 function dispose() { 1990 if (unlistenHistory) { 1991 unlistenHistory(); 1992 } 1993 if (removePageHideEventListener) { 1994 removePageHideEventListener(); 1995 } 1996 subscribers.clear(); 1997 pendingNavigationController && pendingNavigationController.abort(); 1998 state.fetchers.forEach((_, key) => deleteFetcher(key)); 1999 state.blockers.forEach((_, key) => deleteBlocker(key)); 2000 } 2001 function subscribe(fn) { 2002 subscribers.add(fn); 2003 return () => subscribers.delete(fn); 2004 } 2005 function updateState(newState, opts = {}) { 2006 if (newState.matches) { 2007 newState.matches = newState.matches.map((m) => { 2008 let route = manifest[m.route.id]; 2009 let matchRoute = m.route; 2010 if (matchRoute.element !== route.element || matchRoute.errorElement !== route.errorElement || matchRoute.hydrateFallbackElement !== route.hydrateFallbackElement) { 2011 return { 2012 ...m, 2013 route 2014 }; 2015 } 2016 return m; 2017 }); 2018 } 2019 state = { 2020 ...state, 2021 ...newState 2022 }; 2023 let unmountedFetchers = []; 2024 let mountedFetchers = []; 2025 state.fetchers.forEach((fetcher, key) => { 2026 if (fetcher.state === "idle") { 2027 if (fetchersQueuedForDeletion.has(key)) { 2028 unmountedFetchers.push(key); 2029 } else { 2030 mountedFetchers.push(key); 2031 } 2032 } 2033 }); 2034 fetchersQueuedForDeletion.forEach((key) => { 2035 if (!state.fetchers.has(key) && !fetchControllers.has(key)) { 2036 unmountedFetchers.push(key); 2037 } 2038 }); 2039 [...subscribers].forEach( 2040 (subscriber) => subscriber(state, { 2041 deletedFetchers: unmountedFetchers, 2042 newErrors: newState.errors ?? null, 2043 viewTransitionOpts: opts.viewTransitionOpts, 2044 flushSync: opts.flushSync === true 2045 }) 2046 ); 2047 unmountedFetchers.forEach((key) => deleteFetcher(key)); 2048 mountedFetchers.forEach((key) => state.fetchers.delete(key)); 2049 } 2050 function completeNavigation(location2, newState, { flushSync: flushSync3 } = {}) { 2051 let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === "loading" && location2.state?._isRedirect !== true; 2052 let actionData; 2053 if (newState.actionData) { 2054 if (Object.keys(newState.actionData).length > 0) { 2055 actionData = newState.actionData; 2056 } else { 2057 actionData = null; 2058 } 2059 } else if (isActionReload) { 2060 actionData = state.actionData; 2061 } else { 2062 actionData = null; 2063 } 2064 let loaderData = newState.loaderData ? mergeLoaderData( 2065 state.loaderData, 2066 newState.loaderData, 2067 newState.matches || [], 2068 newState.errors 2069 ) : state.loaderData; 2070 let blockers = state.blockers; 2071 if (blockers.size > 0) { 2072 blockers = new Map(blockers); 2073 blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER)); 2074 } 2075 let restoreScrollPosition = isUninterruptedRevalidation ? false : getSavedScrollPosition(location2, newState.matches || state.matches); 2076 let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && location2.state?._isRedirect !== true; 2077 if (inFlightDataRoutes) { 2078 dataRoutes = inFlightDataRoutes; 2079 inFlightDataRoutes = void 0; 2080 } 2081 if (isUninterruptedRevalidation) { 2082 } else if (pendingAction === "POP") { 2083 } else if (pendingAction === "PUSH") { 2084 init.history.push(location2, location2.state); 2085 } else if (pendingAction === "REPLACE") { 2086 init.history.replace(location2, location2.state); 2087 } 2088 let viewTransitionOpts; 2089 if (pendingAction === "POP") { 2090 let priorPaths = appliedViewTransitions.get(state.location.pathname); 2091 if (priorPaths && priorPaths.has(location2.pathname)) { 2092 viewTransitionOpts = { 2093 currentLocation: state.location, 2094 nextLocation: location2 2095 }; 2096 } else if (appliedViewTransitions.has(location2.pathname)) { 2097 viewTransitionOpts = { 2098 currentLocation: location2, 2099 nextLocation: state.location 2100 }; 2101 } 2102 } else if (pendingViewTransitionEnabled) { 2103 let toPaths = appliedViewTransitions.get(state.location.pathname); 2104 if (toPaths) { 2105 toPaths.add(location2.pathname); 2106 } else { 2107 toPaths = /* @__PURE__ */ new Set([location2.pathname]); 2108 appliedViewTransitions.set(state.location.pathname, toPaths); 2109 } 2110 viewTransitionOpts = { 2111 currentLocation: state.location, 2112 nextLocation: location2 2113 }; 2114 } 2115 updateState( 2116 { 2117 ...newState, 2118 // matches, errors, fetchers go through as-is 2119 actionData, 2120 loaderData, 2121 historyAction: pendingAction, 2122 location: location2, 2123 initialized: true, 2124 renderFallback: false, 2125 navigation: IDLE_NAVIGATION, 2126 revalidation: "idle", 2127 restoreScrollPosition, 2128 preventScrollReset, 2129 blockers 2130 }, 2131 { 2132 viewTransitionOpts, 2133 flushSync: flushSync3 === true 2134 } 2135 ); 2136 pendingAction = "POP"; 2137 pendingPreventScrollReset = false; 2138 pendingViewTransitionEnabled = false; 2139 isUninterruptedRevalidation = false; 2140 isRevalidationRequired = false; 2141 pendingPopstateNavigationDfd?.resolve(); 2142 pendingPopstateNavigationDfd = null; 2143 pendingRevalidationDfd?.resolve(); 2144 pendingRevalidationDfd = null; 2145 } 2146 async function navigate(to, opts) { 2147 pendingPopstateNavigationDfd?.resolve(); 2148 pendingPopstateNavigationDfd = null; 2149 if (typeof to === "number") { 2150 if (!pendingPopstateNavigationDfd) { 2151 pendingPopstateNavigationDfd = createDeferred(); 2152 } 2153 let promise = pendingPopstateNavigationDfd.promise; 2154 init.history.go(to); 2155 return promise; 2156 } 2157 let normalizedPath = normalizeTo( 2158 state.location, 2159 state.matches, 2160 basename, 2161 to, 2162 opts?.fromRouteId, 2163 opts?.relative 2164 ); 2165 let { path, submission, error } = normalizeNavigateOptions( 2166 false, 2167 normalizedPath, 2168 opts 2169 ); 2170 let maskPath; 2171 if (opts?.unstable_mask) { 2172 let partialPath = typeof opts.unstable_mask === "string" ? parsePath(opts.unstable_mask) : { 2173 ...state.location.unstable_mask, 2174 ...opts.unstable_mask 2175 }; 2176 maskPath = { 2177 pathname: "", 2178 search: "", 2179 hash: "", 2180 ...partialPath 2181 }; 2182 } 2183 let currentLocation = state.location; 2184 let nextLocation = createLocation( 2185 currentLocation, 2186 path, 2187 opts && opts.state, 2188 void 0, 2189 maskPath 2190 ); 2191 nextLocation = { 2192 ...nextLocation, 2193 ...init.history.encodeLocation(nextLocation) 2194 }; 2195 let userReplace = opts && opts.replace != null ? opts.replace : void 0; 2196 let historyAction = "PUSH"; 2197 if (userReplace === true) { 2198 historyAction = "REPLACE"; 2199 } else if (userReplace === false) { 2200 } else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) { 2201 historyAction = "REPLACE"; 2202 } 2203 let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : void 0; 2204 let flushSync3 = (opts && opts.flushSync) === true; 2205 let blockerKey = shouldBlockNavigation({ 2206 currentLocation, 2207 nextLocation, 2208 historyAction 2209 }); 2210 if (blockerKey) { 2211 updateBlocker(blockerKey, { 2212 state: "blocked", 2213 location: nextLocation, 2214 proceed() { 2215 updateBlocker(blockerKey, { 2216 state: "proceeding", 2217 proceed: void 0, 2218 reset: void 0, 2219 location: nextLocation 2220 }); 2221 navigate(to, opts); 2222 }, 2223 reset() { 2224 let blockers = new Map(state.blockers); 2225 blockers.set(blockerKey, IDLE_BLOCKER); 2226 updateState({ blockers }); 2227 } 2228 }); 2229 return; 2230 } 2231 await startNavigation(historyAction, nextLocation, { 2232 submission, 2233 // Send through the formData serialization error if we have one so we can 2234 // render at the right error boundary after we match routes 2235 pendingError: error, 2236 preventScrollReset, 2237 replace: opts && opts.replace, 2238 enableViewTransition: opts && opts.viewTransition, 2239 flushSync: flushSync3, 2240 callSiteDefaultShouldRevalidate: opts && opts.unstable_defaultShouldRevalidate 2241 }); 2242 } 2243 function revalidate() { 2244 if (!pendingRevalidationDfd) { 2245 pendingRevalidationDfd = createDeferred(); 2246 } 2247 interruptActiveLoads(); 2248 updateState({ revalidation: "loading" }); 2249 let promise = pendingRevalidationDfd.promise; 2250 if (state.navigation.state === "submitting") { 2251 return promise; 2252 } 2253 if (state.navigation.state === "idle") { 2254 startNavigation(state.historyAction, state.location, { 2255 startUninterruptedRevalidation: true 2256 }); 2257 return promise; 2258 } 2259 startNavigation( 2260 pendingAction || state.historyAction, 2261 state.navigation.location, 2262 { 2263 overrideNavigation: state.navigation, 2264 // Proxy through any rending view transition 2265 enableViewTransition: pendingViewTransitionEnabled === true 2266 } 2267 ); 2268 return promise; 2269 } 2270 async function startNavigation(historyAction, location2, opts) { 2271 pendingNavigationController && pendingNavigationController.abort(); 2272 pendingNavigationController = null; 2273 pendingAction = historyAction; 2274 isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true; 2275 saveScrollPosition(state.location, state.matches); 2276 pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; 2277 pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true; 2278 let routesToUse = inFlightDataRoutes || dataRoutes; 2279 let loadingNavigation = opts && opts.overrideNavigation; 2280 let matches = opts?.initialHydration && state.matches && state.matches.length > 0 && !initialMatchesIsFOW ? ( 2281 // `matchRoutes()` has already been called if we're in here via `router.initialize()` 2282 state.matches 2283 ) : matchRoutes(routesToUse, location2, basename); 2284 let flushSync3 = (opts && opts.flushSync) === true; 2285 if (matches && state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location2) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) { 2286 completeNavigation(location2, { matches }, { flushSync: flushSync3 }); 2287 return; 2288 } 2289 let fogOfWar = checkFogOfWar(matches, routesToUse, location2.pathname); 2290 if (fogOfWar.active && fogOfWar.matches) { 2291 matches = fogOfWar.matches; 2292 } 2293 if (!matches) { 2294 let { error, notFoundMatches, route } = handleNavigational404( 2295 location2.pathname 2296 ); 2297 completeNavigation( 2298 location2, 2299 { 2300 matches: notFoundMatches, 2301 loaderData: {}, 2302 errors: { 2303 [route.id]: error 2304 } 2305 }, 2306 { flushSync: flushSync3 } 2307 ); 2308 return; 2309 } 2310 pendingNavigationController = new AbortController(); 2311 let request = createClientSideRequest( 2312 init.history, 2313 location2, 2314 pendingNavigationController.signal, 2315 opts && opts.submission 2316 ); 2317 let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider(); 2318 let pendingActionResult; 2319 if (opts && opts.pendingError) { 2320 pendingActionResult = [ 2321 findNearestBoundary(matches).route.id, 2322 { type: "error", error: opts.pendingError } 2323 ]; 2324 } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) { 2325 let actionResult = await handleAction( 2326 request, 2327 location2, 2328 opts.submission, 2329 matches, 2330 scopedContext, 2331 fogOfWar.active, 2332 opts && opts.initialHydration === true, 2333 { replace: opts.replace, flushSync: flushSync3 } 2334 ); 2335 if (actionResult.shortCircuited) { 2336 return; 2337 } 2338 if (actionResult.pendingActionResult) { 2339 let [routeId, result] = actionResult.pendingActionResult; 2340 if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) { 2341 pendingNavigationController = null; 2342 completeNavigation(location2, { 2343 matches: actionResult.matches, 2344 loaderData: {}, 2345 errors: { 2346 [routeId]: result.error 2347 } 2348 }); 2349 return; 2350 } 2351 } 2352 matches = actionResult.matches || matches; 2353 pendingActionResult = actionResult.pendingActionResult; 2354 loadingNavigation = getLoadingNavigation(location2, opts.submission); 2355 flushSync3 = false; 2356 fogOfWar.active = false; 2357 request = createClientSideRequest( 2358 init.history, 2359 request.url, 2360 request.signal 2361 ); 2362 } 2363 let { 2364 shortCircuited, 2365 matches: updatedMatches, 2366 loaderData, 2367 errors 2368 } = await handleLoaders( 2369 request, 2370 location2, 2371 matches, 2372 scopedContext, 2373 fogOfWar.active, 2374 loadingNavigation, 2375 opts && opts.submission, 2376 opts && opts.fetcherSubmission, 2377 opts && opts.replace, 2378 opts && opts.initialHydration === true, 2379 flushSync3, 2380 pendingActionResult, 2381 opts && opts.callSiteDefaultShouldRevalidate 2382 ); 2383 if (shortCircuited) { 2384 return; 2385 } 2386 pendingNavigationController = null; 2387 completeNavigation(location2, { 2388 matches: updatedMatches || matches, 2389 ...getActionDataForCommit(pendingActionResult), 2390 loaderData, 2391 errors 2392 }); 2393 } 2394 async function handleAction(request, location2, submission, matches, scopedContext, isFogOfWar, initialHydration, opts = {}) { 2395 interruptActiveLoads(); 2396 let navigation = getSubmittingNavigation(location2, submission); 2397 updateState({ navigation }, { flushSync: opts.flushSync === true }); 2398 if (isFogOfWar) { 2399 let discoverResult = await discoverRoutes( 2400 matches, 2401 location2.pathname, 2402 request.signal 2403 ); 2404 if (discoverResult.type === "aborted") { 2405 return { shortCircuited: true }; 2406 } else if (discoverResult.type === "error") { 2407 if (discoverResult.partialMatches.length === 0) { 2408 let { matches: matches2, route } = getShortCircuitMatches(dataRoutes); 2409 return { 2410 matches: matches2, 2411 pendingActionResult: [ 2412 route.id, 2413 { 2414 type: "error", 2415 error: discoverResult.error 2416 } 2417 ] 2418 }; 2419 } 2420 let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id; 2421 return { 2422 matches: discoverResult.partialMatches, 2423 pendingActionResult: [ 2424 boundaryId, 2425 { 2426 type: "error", 2427 error: discoverResult.error 2428 } 2429 ] 2430 }; 2431 } else if (!discoverResult.matches) { 2432 let { notFoundMatches, error, route } = handleNavigational404( 2433 location2.pathname 2434 ); 2435 return { 2436 matches: notFoundMatches, 2437 pendingActionResult: [ 2438 route.id, 2439 { 2440 type: "error", 2441 error 2442 } 2443 ] 2444 }; 2445 } else { 2446 matches = discoverResult.matches; 2447 } 2448 } 2449 let result; 2450 let actionMatch = getTargetMatch(matches, location2); 2451 if (!actionMatch.route.action && !actionMatch.route.lazy) { 2452 result = { 2453 type: "error", 2454 error: getInternalRouterError(405, { 2455 method: request.method, 2456 pathname: location2.pathname, 2457 routeId: actionMatch.route.id 2458 }) 2459 }; 2460 } else { 2461 let dsMatches = getTargetedDataStrategyMatches( 2462 mapRouteProperties2, 2463 manifest, 2464 request, 2465 matches, 2466 actionMatch, 2467 initialHydration ? [] : hydrationRouteProperties2, 2468 scopedContext 2469 ); 2470 let results = await callDataStrategy( 2471 request, 2472 dsMatches, 2473 scopedContext, 2474 null 2475 ); 2476 result = results[actionMatch.route.id]; 2477 if (!result) { 2478 for (let match of matches) { 2479 if (results[match.route.id]) { 2480 result = results[match.route.id]; 2481 break; 2482 } 2483 } 2484 } 2485 if (request.signal.aborted) { 2486 return { shortCircuited: true }; 2487 } 2488 } 2489 if (isRedirectResult(result)) { 2490 let replace2; 2491 if (opts && opts.replace != null) { 2492 replace2 = opts.replace; 2493 } else { 2494 let location22 = normalizeRedirectLocation( 2495 result.response.headers.get("Location"), 2496 new URL(request.url), 2497 basename, 2498 init.history 2499 ); 2500 replace2 = location22 === state.location.pathname + state.location.search; 2501 } 2502 await startRedirectNavigation(request, result, true, { 2503 submission, 2504 replace: replace2 2505 }); 2506 return { shortCircuited: true }; 2507 } 2508 if (isErrorResult(result)) { 2509 let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id); 2510 if ((opts && opts.replace) !== true) { 2511 pendingAction = "PUSH"; 2512 } 2513 return { 2514 matches, 2515 pendingActionResult: [ 2516 boundaryMatch.route.id, 2517 result, 2518 actionMatch.route.id 2519 ] 2520 }; 2521 } 2522 return { 2523 matches, 2524 pendingActionResult: [actionMatch.route.id, result] 2525 }; 2526 } 2527 async function handleLoaders(request, location2, matches, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync3, pendingActionResult, callSiteDefaultShouldRevalidate) { 2528 let loadingNavigation = overrideNavigation || getLoadingNavigation(location2, submission); 2529 let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation); 2530 let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration; 2531 if (isFogOfWar) { 2532 if (shouldUpdateNavigationState) { 2533 let actionData = getUpdatedActionData(pendingActionResult); 2534 updateState( 2535 { 2536 navigation: loadingNavigation, 2537 ...actionData !== void 0 ? { actionData } : {} 2538 }, 2539 { 2540 flushSync: flushSync3 2541 } 2542 ); 2543 } 2544 let discoverResult = await discoverRoutes( 2545 matches, 2546 location2.pathname, 2547 request.signal 2548 ); 2549 if (discoverResult.type === "aborted") { 2550 return { shortCircuited: true }; 2551 } else if (discoverResult.type === "error") { 2552 if (discoverResult.partialMatches.length === 0) { 2553 let { matches: matches2, route } = getShortCircuitMatches(dataRoutes); 2554 return { 2555 matches: matches2, 2556 loaderData: {}, 2557 errors: { 2558 [route.id]: discoverResult.error 2559 } 2560 }; 2561 } 2562 let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id; 2563 return { 2564 matches: discoverResult.partialMatches, 2565 loaderData: {}, 2566 errors: { 2567 [boundaryId]: discoverResult.error 2568 } 2569 }; 2570 } else if (!discoverResult.matches) { 2571 let { error, notFoundMatches, route } = handleNavigational404( 2572 location2.pathname 2573 ); 2574 return { 2575 matches: notFoundMatches, 2576 loaderData: {}, 2577 errors: { 2578 [route.id]: error 2579 } 2580 }; 2581 } else { 2582 matches = discoverResult.matches; 2583 } 2584 } 2585 let routesToUse = inFlightDataRoutes || dataRoutes; 2586 let { dsMatches, revalidatingFetchers } = getMatchesToLoad( 2587 request, 2588 scopedContext, 2589 mapRouteProperties2, 2590 manifest, 2591 init.history, 2592 state, 2593 matches, 2594 activeSubmission, 2595 location2, 2596 initialHydration ? [] : hydrationRouteProperties2, 2597 initialHydration === true, 2598 isRevalidationRequired, 2599 cancelledFetcherLoads, 2600 fetchersQueuedForDeletion, 2601 fetchLoadMatches, 2602 fetchRedirectIds, 2603 routesToUse, 2604 basename, 2605 init.patchRoutesOnNavigation != null, 2606 pendingActionResult, 2607 callSiteDefaultShouldRevalidate 2608 ); 2609 pendingNavigationLoadId = ++incrementingLoadId; 2610 if (!init.dataStrategy && !dsMatches.some((m) => m.shouldLoad) && !dsMatches.some( 2611 (m) => m.route.middleware && m.route.middleware.length > 0 2612 ) && revalidatingFetchers.length === 0) { 2613 let updatedFetchers2 = markFetchRedirectsDone(); 2614 completeNavigation( 2615 location2, 2616 { 2617 matches, 2618 loaderData: {}, 2619 // Commit pending error if we're short circuiting 2620 errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { [pendingActionResult[0]]: pendingActionResult[1].error } : null, 2621 ...getActionDataForCommit(pendingActionResult), 2622 ...updatedFetchers2 ? { fetchers: new Map(state.fetchers) } : {} 2623 }, 2624 { flushSync: flushSync3 } 2625 ); 2626 return { shortCircuited: true }; 2627 } 2628 if (shouldUpdateNavigationState) { 2629 let updates = {}; 2630 if (!isFogOfWar) { 2631 updates.navigation = loadingNavigation; 2632 let actionData = getUpdatedActionData(pendingActionResult); 2633 if (actionData !== void 0) { 2634 updates.actionData = actionData; 2635 } 2636 } 2637 if (revalidatingFetchers.length > 0) { 2638 updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers); 2639 } 2640 updateState(updates, { flushSync: flushSync3 }); 2641 } 2642 revalidatingFetchers.forEach((rf) => { 2643 abortFetcher(rf.key); 2644 if (rf.controller) { 2645 fetchControllers.set(rf.key, rf.controller); 2646 } 2647 }); 2648 let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((f) => abortFetcher(f.key)); 2649 if (pendingNavigationController) { 2650 pendingNavigationController.signal.addEventListener( 2651 "abort", 2652 abortPendingFetchRevalidations 2653 ); 2654 } 2655 let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData( 2656 dsMatches, 2657 revalidatingFetchers, 2658 request, 2659 scopedContext 2660 ); 2661 if (request.signal.aborted) { 2662 return { shortCircuited: true }; 2663 } 2664 if (pendingNavigationController) { 2665 pendingNavigationController.signal.removeEventListener( 2666 "abort", 2667 abortPendingFetchRevalidations 2668 ); 2669 } 2670 revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key)); 2671 let redirect2 = findRedirect(loaderResults); 2672 if (redirect2) { 2673 await startRedirectNavigation(request, redirect2.result, true, { 2674 replace: replace2 2675 }); 2676 return { shortCircuited: true }; 2677 } 2678 redirect2 = findRedirect(fetcherResults); 2679 if (redirect2) { 2680 fetchRedirectIds.add(redirect2.key); 2681 await startRedirectNavigation(request, redirect2.result, true, { 2682 replace: replace2 2683 }); 2684 return { shortCircuited: true }; 2685 } 2686 let { loaderData, errors } = processLoaderData( 2687 state, 2688 matches, 2689 loaderResults, 2690 pendingActionResult, 2691 revalidatingFetchers, 2692 fetcherResults 2693 ); 2694 if (initialHydration && state.errors) { 2695 errors = { ...state.errors, ...errors }; 2696 } 2697 let updatedFetchers = markFetchRedirectsDone(); 2698 let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); 2699 let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0; 2700 return { 2701 matches, 2702 loaderData, 2703 errors, 2704 ...shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {} 2705 }; 2706 } 2707 function getUpdatedActionData(pendingActionResult) { 2708 if (pendingActionResult && !isErrorResult(pendingActionResult[1])) { 2709 return { 2710 [pendingActionResult[0]]: pendingActionResult[1].data 2711 }; 2712 } else if (state.actionData) { 2713 if (Object.keys(state.actionData).length === 0) { 2714 return null; 2715 } else { 2716 return state.actionData; 2717 } 2718 } 2719 } 2720 function getUpdatedRevalidatingFetchers(revalidatingFetchers) { 2721 revalidatingFetchers.forEach((rf) => { 2722 let fetcher = state.fetchers.get(rf.key); 2723 let revalidatingFetcher = getLoadingFetcher( 2724 void 0, 2725 fetcher ? fetcher.data : void 0 2726 ); 2727 state.fetchers.set(rf.key, revalidatingFetcher); 2728 }); 2729 return new Map(state.fetchers); 2730 } 2731 async function fetch2(key, routeId, href2, opts) { 2732 abortFetcher(key); 2733 let flushSync3 = (opts && opts.flushSync) === true; 2734 let routesToUse = inFlightDataRoutes || dataRoutes; 2735 let normalizedPath = normalizeTo( 2736 state.location, 2737 state.matches, 2738 basename, 2739 href2, 2740 routeId, 2741 opts?.relative 2742 ); 2743 let matches = matchRoutes(routesToUse, normalizedPath, basename); 2744 let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath); 2745 if (fogOfWar.active && fogOfWar.matches) { 2746 matches = fogOfWar.matches; 2747 } 2748 if (!matches) { 2749 setFetcherError( 2750 key, 2751 routeId, 2752 getInternalRouterError(404, { pathname: normalizedPath }), 2753 { flushSync: flushSync3 } 2754 ); 2755 return; 2756 } 2757 let { path, submission, error } = normalizeNavigateOptions( 2758 true, 2759 normalizedPath, 2760 opts 2761 ); 2762 if (error) { 2763 setFetcherError(key, routeId, error, { flushSync: flushSync3 }); 2764 return; 2765 } 2766 let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider(); 2767 let preventScrollReset = (opts && opts.preventScrollReset) === true; 2768 if (submission && isMutationMethod(submission.formMethod)) { 2769 await handleFetcherAction( 2770 key, 2771 routeId, 2772 path, 2773 matches, 2774 scopedContext, 2775 fogOfWar.active, 2776 flushSync3, 2777 preventScrollReset, 2778 submission, 2779 opts && opts.unstable_defaultShouldRevalidate 2780 ); 2781 return; 2782 } 2783 fetchLoadMatches.set(key, { routeId, path }); 2784 await handleFetcherLoader( 2785 key, 2786 routeId, 2787 path, 2788 matches, 2789 scopedContext, 2790 fogOfWar.active, 2791 flushSync3, 2792 preventScrollReset, 2793 submission 2794 ); 2795 } 2796 async function handleFetcherAction(key, routeId, path, requestMatches, scopedContext, isFogOfWar, flushSync3, preventScrollReset, submission, callSiteDefaultShouldRevalidate) { 2797 interruptActiveLoads(); 2798 fetchLoadMatches.delete(key); 2799 let existingFetcher = state.fetchers.get(key); 2800 updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), { 2801 flushSync: flushSync3 2802 }); 2803 let abortController = new AbortController(); 2804 let fetchRequest = createClientSideRequest( 2805 init.history, 2806 path, 2807 abortController.signal, 2808 submission 2809 ); 2810 if (isFogOfWar) { 2811 let discoverResult = await discoverRoutes( 2812 requestMatches, 2813 new URL(fetchRequest.url).pathname, 2814 fetchRequest.signal, 2815 key 2816 ); 2817 if (discoverResult.type === "aborted") { 2818 return; 2819 } else if (discoverResult.type === "error") { 2820 setFetcherError(key, routeId, discoverResult.error, { flushSync: flushSync3 }); 2821 return; 2822 } else if (!discoverResult.matches) { 2823 setFetcherError( 2824 key, 2825 routeId, 2826 getInternalRouterError(404, { pathname: path }), 2827 { flushSync: flushSync3 } 2828 ); 2829 return; 2830 } else { 2831 requestMatches = discoverResult.matches; 2832 } 2833 } 2834 let match = getTargetMatch(requestMatches, path); 2835 if (!match.route.action && !match.route.lazy) { 2836 let error = getInternalRouterError(405, { 2837 method: submission.formMethod, 2838 pathname: path, 2839 routeId 2840 }); 2841 setFetcherError(key, routeId, error, { flushSync: flushSync3 }); 2842 return; 2843 } 2844 fetchControllers.set(key, abortController); 2845 let originatingLoadId = incrementingLoadId; 2846 let fetchMatches = getTargetedDataStrategyMatches( 2847 mapRouteProperties2, 2848 manifest, 2849 fetchRequest, 2850 requestMatches, 2851 match, 2852 hydrationRouteProperties2, 2853 scopedContext 2854 ); 2855 let actionResults = await callDataStrategy( 2856 fetchRequest, 2857 fetchMatches, 2858 scopedContext, 2859 key 2860 ); 2861 let actionResult = actionResults[match.route.id]; 2862 if (!actionResult) { 2863 for (let match2 of fetchMatches) { 2864 if (actionResults[match2.route.id]) { 2865 actionResult = actionResults[match2.route.id]; 2866 break; 2867 } 2868 } 2869 } 2870 if (fetchRequest.signal.aborted) { 2871 if (fetchControllers.get(key) === abortController) { 2872 fetchControllers.delete(key); 2873 } 2874 return; 2875 } 2876 if (fetchersQueuedForDeletion.has(key)) { 2877 if (isRedirectResult(actionResult) || isErrorResult(actionResult)) { 2878 updateFetcherState(key, getDoneFetcher(void 0)); 2879 return; 2880 } 2881 } else { 2882 if (isRedirectResult(actionResult)) { 2883 fetchControllers.delete(key); 2884 if (pendingNavigationLoadId > originatingLoadId) { 2885 updateFetcherState(key, getDoneFetcher(void 0)); 2886 return; 2887 } else { 2888 fetchRedirectIds.add(key); 2889 updateFetcherState(key, getLoadingFetcher(submission)); 2890 return startRedirectNavigation(fetchRequest, actionResult, false, { 2891 fetcherSubmission: submission, 2892 preventScrollReset 2893 }); 2894 } 2895 } 2896 if (isErrorResult(actionResult)) { 2897 setFetcherError(key, routeId, actionResult.error); 2898 return; 2899 } 2900 } 2901 let nextLocation = state.navigation.location || state.location; 2902 let revalidationRequest = createClientSideRequest( 2903 init.history, 2904 nextLocation, 2905 abortController.signal 2906 ); 2907 let routesToUse = inFlightDataRoutes || dataRoutes; 2908 let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches; 2909 invariant(matches, "Didn't find any matches after fetcher action"); 2910 let loadId = ++incrementingLoadId; 2911 fetchReloadIds.set(key, loadId); 2912 let loadFetcher = getLoadingFetcher(submission, actionResult.data); 2913 state.fetchers.set(key, loadFetcher); 2914 let { dsMatches, revalidatingFetchers } = getMatchesToLoad( 2915 revalidationRequest, 2916 scopedContext, 2917 mapRouteProperties2, 2918 manifest, 2919 init.history, 2920 state, 2921 matches, 2922 submission, 2923 nextLocation, 2924 hydrationRouteProperties2, 2925 false, 2926 isRevalidationRequired, 2927 cancelledFetcherLoads, 2928 fetchersQueuedForDeletion, 2929 fetchLoadMatches, 2930 fetchRedirectIds, 2931 routesToUse, 2932 basename, 2933 init.patchRoutesOnNavigation != null, 2934 [match.route.id, actionResult], 2935 callSiteDefaultShouldRevalidate 2936 ); 2937 revalidatingFetchers.filter((rf) => rf.key !== key).forEach((rf) => { 2938 let staleKey = rf.key; 2939 let existingFetcher2 = state.fetchers.get(staleKey); 2940 let revalidatingFetcher = getLoadingFetcher( 2941 void 0, 2942 existingFetcher2 ? existingFetcher2.data : void 0 2943 ); 2944 state.fetchers.set(staleKey, revalidatingFetcher); 2945 abortFetcher(staleKey); 2946 if (rf.controller) { 2947 fetchControllers.set(staleKey, rf.controller); 2948 } 2949 }); 2950 updateState({ fetchers: new Map(state.fetchers) }); 2951 let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => abortFetcher(rf.key)); 2952 abortController.signal.addEventListener( 2953 "abort", 2954 abortPendingFetchRevalidations 2955 ); 2956 let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData( 2957 dsMatches, 2958 revalidatingFetchers, 2959 revalidationRequest, 2960 scopedContext 2961 ); 2962 if (abortController.signal.aborted) { 2963 return; 2964 } 2965 abortController.signal.removeEventListener( 2966 "abort", 2967 abortPendingFetchRevalidations 2968 ); 2969 fetchReloadIds.delete(key); 2970 fetchControllers.delete(key); 2971 revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key)); 2972 if (state.fetchers.has(key)) { 2973 let doneFetcher = getDoneFetcher(actionResult.data); 2974 state.fetchers.set(key, doneFetcher); 2975 } 2976 let redirect2 = findRedirect(loaderResults); 2977 if (redirect2) { 2978 return startRedirectNavigation( 2979 revalidationRequest, 2980 redirect2.result, 2981 false, 2982 { preventScrollReset } 2983 ); 2984 } 2985 redirect2 = findRedirect(fetcherResults); 2986 if (redirect2) { 2987 fetchRedirectIds.add(redirect2.key); 2988 return startRedirectNavigation( 2989 revalidationRequest, 2990 redirect2.result, 2991 false, 2992 { preventScrollReset } 2993 ); 2994 } 2995 let { loaderData, errors } = processLoaderData( 2996 state, 2997 matches, 2998 loaderResults, 2999 void 0, 3000 revalidatingFetchers, 3001 fetcherResults 3002 ); 3003 abortStaleFetchLoads(loadId); 3004 if (state.navigation.state === "loading" && loadId > pendingNavigationLoadId) { 3005 invariant(pendingAction, "Expected pending action"); 3006 pendingNavigationController && pendingNavigationController.abort(); 3007 completeNavigation(state.navigation.location, { 3008 matches, 3009 loaderData, 3010 errors, 3011 fetchers: new Map(state.fetchers) 3012 }); 3013 } else { 3014 updateState({ 3015 errors, 3016 loaderData: mergeLoaderData( 3017 state.loaderData, 3018 loaderData, 3019 matches, 3020 errors 3021 ), 3022 fetchers: new Map(state.fetchers) 3023 }); 3024 isRevalidationRequired = false; 3025 } 3026 } 3027 async function handleFetcherLoader(key, routeId, path, matches, scopedContext, isFogOfWar, flushSync3, preventScrollReset, submission) { 3028 let existingFetcher = state.fetchers.get(key); 3029 updateFetcherState( 3030 key, 3031 getLoadingFetcher( 3032 submission, 3033 existingFetcher ? existingFetcher.data : void 0 3034 ), 3035 { flushSync: flushSync3 } 3036 ); 3037 let abortController = new AbortController(); 3038 let fetchRequest = createClientSideRequest( 3039 init.history, 3040 path, 3041 abortController.signal 3042 ); 3043 if (isFogOfWar) { 3044 let discoverResult = await discoverRoutes( 3045 matches, 3046 new URL(fetchRequest.url).pathname, 3047 fetchRequest.signal, 3048 key 3049 ); 3050 if (discoverResult.type === "aborted") { 3051 return; 3052 } else if (discoverResult.type === "error") { 3053 setFetcherError(key, routeId, discoverResult.error, { flushSync: flushSync3 }); 3054 return; 3055 } else if (!discoverResult.matches) { 3056 setFetcherError( 3057 key, 3058 routeId, 3059 getInternalRouterError(404, { pathname: path }), 3060 { flushSync: flushSync3 } 3061 ); 3062 return; 3063 } else { 3064 matches = discoverResult.matches; 3065 } 3066 } 3067 let match = getTargetMatch(matches, path); 3068 fetchControllers.set(key, abortController); 3069 let originatingLoadId = incrementingLoadId; 3070 let dsMatches = getTargetedDataStrategyMatches( 3071 mapRouteProperties2, 3072 manifest, 3073 fetchRequest, 3074 matches, 3075 match, 3076 hydrationRouteProperties2, 3077 scopedContext 3078 ); 3079 let results = await callDataStrategy( 3080 fetchRequest, 3081 dsMatches, 3082 scopedContext, 3083 key 3084 ); 3085 let result = results[match.route.id]; 3086 if (fetchControllers.get(key) === abortController) { 3087 fetchControllers.delete(key); 3088 } 3089 if (fetchRequest.signal.aborted) { 3090 return; 3091 } 3092 if (fetchersQueuedForDeletion.has(key)) { 3093 updateFetcherState(key, getDoneFetcher(void 0)); 3094 return; 3095 } 3096 if (isRedirectResult(result)) { 3097 if (pendingNavigationLoadId > originatingLoadId) { 3098 updateFetcherState(key, getDoneFetcher(void 0)); 3099 return; 3100 } else { 3101 fetchRedirectIds.add(key); 3102 await startRedirectNavigation(fetchRequest, result, false, { 3103 preventScrollReset 3104 }); 3105 return; 3106 } 3107 } 3108 if (isErrorResult(result)) { 3109 setFetcherError(key, routeId, result.error); 3110 return; 3111 } 3112 updateFetcherState(key, getDoneFetcher(result.data)); 3113 } 3114 async function startRedirectNavigation(request, redirect2, isNavigation, { 3115 submission, 3116 fetcherSubmission, 3117 preventScrollReset, 3118 replace: replace2 3119 } = {}) { 3120 if (!isNavigation) { 3121 pendingPopstateNavigationDfd?.resolve(); 3122 pendingPopstateNavigationDfd = null; 3123 } 3124 if (redirect2.response.headers.has("X-Remix-Revalidate")) { 3125 isRevalidationRequired = true; 3126 } 3127 let location2 = redirect2.response.headers.get("Location"); 3128 invariant(location2, "Expected a Location header on the redirect Response"); 3129 location2 = normalizeRedirectLocation( 3130 location2, 3131 new URL(request.url), 3132 basename, 3133 init.history 3134 ); 3135 let redirectLocation = createLocation(state.location, location2, { 3136 _isRedirect: true 3137 }); 3138 if (isBrowser3) { 3139 let isDocumentReload = false; 3140 if (redirect2.response.headers.has("X-Remix-Reload-Document")) { 3141 isDocumentReload = true; 3142 } else if (isAbsoluteUrl(location2)) { 3143 const url = createBrowserURLImpl(location2, true); 3144 isDocumentReload = // Hard reload if it's an absolute URL to a new origin 3145 url.origin !== routerWindow.location.origin || // Hard reload if it's an absolute URL that does not match our basename 3146 stripBasename(url.pathname, basename) == null; 3147 } 3148 if (isDocumentReload) { 3149 if (replace2) { 3150 routerWindow.location.replace(location2); 3151 } else { 3152 routerWindow.location.assign(location2); 3153 } 3154 return; 3155 } 3156 } 3157 pendingNavigationController = null; 3158 let redirectNavigationType = replace2 === true || redirect2.response.headers.has("X-Remix-Replace") ? "REPLACE" : "PUSH"; 3159 let { formMethod, formAction, formEncType } = state.navigation; 3160 if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) { 3161 submission = getSubmissionFromNavigation(state.navigation); 3162 } 3163 let activeSubmission = submission || fetcherSubmission; 3164 if (redirectPreserveMethodStatusCodes.has(redirect2.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) { 3165 await startNavigation(redirectNavigationType, redirectLocation, { 3166 submission: { 3167 ...activeSubmission, 3168 formAction: location2 3169 }, 3170 // Preserve these flags across redirects 3171 preventScrollReset: preventScrollReset || pendingPreventScrollReset, 3172 enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0 3173 }); 3174 } else { 3175 let overrideNavigation = getLoadingNavigation( 3176 redirectLocation, 3177 submission 3178 ); 3179 await startNavigation(redirectNavigationType, redirectLocation, { 3180 overrideNavigation, 3181 // Send fetcher submissions through for shouldRevalidate 3182 fetcherSubmission, 3183 // Preserve these flags across redirects 3184 preventScrollReset: preventScrollReset || pendingPreventScrollReset, 3185 enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0 3186 }); 3187 } 3188 } 3189 async function callDataStrategy(request, matches, scopedContext, fetcherKey) { 3190 let results; 3191 let dataResults = {}; 3192 try { 3193 results = await callDataStrategyImpl( 3194 dataStrategyImpl, 3195 request, 3196 matches, 3197 fetcherKey, 3198 scopedContext, 3199 false 3200 ); 3201 } catch (e) { 3202 matches.filter((m) => m.shouldLoad).forEach((m) => { 3203 dataResults[m.route.id] = { 3204 type: "error", 3205 error: e 3206 }; 3207 }); 3208 return dataResults; 3209 } 3210 if (request.signal.aborted) { 3211 return dataResults; 3212 } 3213 if (!isMutationMethod(request.method)) { 3214 for (let match of matches) { 3215 if (results[match.route.id]?.type === "error") { 3216 break; 3217 } 3218 if (!results.hasOwnProperty(match.route.id) && !state.loaderData.hasOwnProperty(match.route.id) && (!state.errors || !state.errors.hasOwnProperty(match.route.id)) && match.shouldCallHandler()) { 3219 results[match.route.id] = { 3220 type: "error", 3221 result: new Error( 3222 `No result returned from dataStrategy for route ${match.route.id}` 3223 ) 3224 }; 3225 } 3226 } 3227 } 3228 for (let [routeId, result] of Object.entries(results)) { 3229 if (isRedirectDataStrategyResult(result)) { 3230 let response = result.result; 3231 dataResults[routeId] = { 3232 type: "redirect", 3233 response: normalizeRelativeRoutingRedirectResponse( 3234 response, 3235 request, 3236 routeId, 3237 matches, 3238 basename 3239 ) 3240 }; 3241 } else { 3242 dataResults[routeId] = await convertDataStrategyResultToDataResult(result); 3243 } 3244 } 3245 return dataResults; 3246 } 3247 async function callLoadersAndMaybeResolveData(matches, fetchersToLoad, request, scopedContext) { 3248 let loaderResultsPromise = callDataStrategy( 3249 request, 3250 matches, 3251 scopedContext, 3252 null 3253 ); 3254 let fetcherResultsPromise = Promise.all( 3255 fetchersToLoad.map(async (f) => { 3256 if (f.matches && f.match && f.request && f.controller) { 3257 let results = await callDataStrategy( 3258 f.request, 3259 f.matches, 3260 scopedContext, 3261 f.key 3262 ); 3263 let result = results[f.match.route.id]; 3264 return { [f.key]: result }; 3265 } else { 3266 return Promise.resolve({ 3267 [f.key]: { 3268 type: "error", 3269 error: getInternalRouterError(404, { 3270 pathname: f.path 3271 }) 3272 } 3273 }); 3274 } 3275 }) 3276 ); 3277 let loaderResults = await loaderResultsPromise; 3278 let fetcherResults = (await fetcherResultsPromise).reduce( 3279 (acc, r) => Object.assign(acc, r), 3280 {} 3281 ); 3282 return { 3283 loaderResults, 3284 fetcherResults 3285 }; 3286 } 3287 function interruptActiveLoads() { 3288 isRevalidationRequired = true; 3289 fetchLoadMatches.forEach((_, key) => { 3290 if (fetchControllers.has(key)) { 3291 cancelledFetcherLoads.add(key); 3292 } 3293 abortFetcher(key); 3294 }); 3295 } 3296 function updateFetcherState(key, fetcher, opts = {}) { 3297 state.fetchers.set(key, fetcher); 3298 updateState( 3299 { fetchers: new Map(state.fetchers) }, 3300 { flushSync: (opts && opts.flushSync) === true } 3301 ); 3302 } 3303 function setFetcherError(key, routeId, error, opts = {}) { 3304 let boundaryMatch = findNearestBoundary(state.matches, routeId); 3305 deleteFetcher(key); 3306 updateState( 3307 { 3308 errors: { 3309 [boundaryMatch.route.id]: error 3310 }, 3311 fetchers: new Map(state.fetchers) 3312 }, 3313 { flushSync: (opts && opts.flushSync) === true } 3314 ); 3315 } 3316 function getFetcher(key) { 3317 activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1); 3318 if (fetchersQueuedForDeletion.has(key)) { 3319 fetchersQueuedForDeletion.delete(key); 3320 } 3321 return state.fetchers.get(key) || IDLE_FETCHER; 3322 } 3323 function resetFetcher(key, opts) { 3324 abortFetcher(key, opts?.reason); 3325 updateFetcherState(key, getDoneFetcher(null)); 3326 } 3327 function deleteFetcher(key) { 3328 let fetcher = state.fetchers.get(key); 3329 if (fetchControllers.has(key) && !(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key))) { 3330 abortFetcher(key); 3331 } 3332 fetchLoadMatches.delete(key); 3333 fetchReloadIds.delete(key); 3334 fetchRedirectIds.delete(key); 3335 fetchersQueuedForDeletion.delete(key); 3336 cancelledFetcherLoads.delete(key); 3337 state.fetchers.delete(key); 3338 } 3339 function queueFetcherForDeletion(key) { 3340 let count = (activeFetchers.get(key) || 0) - 1; 3341 if (count <= 0) { 3342 activeFetchers.delete(key); 3343 fetchersQueuedForDeletion.add(key); 3344 } else { 3345 activeFetchers.set(key, count); 3346 } 3347 updateState({ fetchers: new Map(state.fetchers) }); 3348 } 3349 function abortFetcher(key, reason) { 3350 let controller = fetchControllers.get(key); 3351 if (controller) { 3352 controller.abort(reason); 3353 fetchControllers.delete(key); 3354 } 3355 } 3356 function markFetchersDone(keys) { 3357 for (let key of keys) { 3358 let fetcher = getFetcher(key); 3359 let doneFetcher = getDoneFetcher(fetcher.data); 3360 state.fetchers.set(key, doneFetcher); 3361 } 3362 } 3363 function markFetchRedirectsDone() { 3364 let doneKeys = []; 3365 let updatedFetchers = false; 3366 for (let key of fetchRedirectIds) { 3367 let fetcher = state.fetchers.get(key); 3368 invariant(fetcher, `Expected fetcher: ${key}`); 3369 if (fetcher.state === "loading") { 3370 fetchRedirectIds.delete(key); 3371 doneKeys.push(key); 3372 updatedFetchers = true; 3373 } 3374 } 3375 markFetchersDone(doneKeys); 3376 return updatedFetchers; 3377 } 3378 function abortStaleFetchLoads(landedId) { 3379 let yeetedKeys = []; 3380 for (let [key, id] of fetchReloadIds) { 3381 if (id < landedId) { 3382 let fetcher = state.fetchers.get(key); 3383 invariant(fetcher, `Expected fetcher: ${key}`); 3384 if (fetcher.state === "loading") { 3385 abortFetcher(key); 3386 fetchReloadIds.delete(key); 3387 yeetedKeys.push(key); 3388 } 3389 } 3390 } 3391 markFetchersDone(yeetedKeys); 3392 return yeetedKeys.length > 0; 3393 } 3394 function getBlocker(key, fn) { 3395 let blocker = state.blockers.get(key) || IDLE_BLOCKER; 3396 if (blockerFunctions.get(key) !== fn) { 3397 blockerFunctions.set(key, fn); 3398 } 3399 return blocker; 3400 } 3401 function deleteBlocker(key) { 3402 state.blockers.delete(key); 3403 blockerFunctions.delete(key); 3404 } 3405 function updateBlocker(key, newBlocker) { 3406 let blocker = state.blockers.get(key) || IDLE_BLOCKER; 3407 invariant( 3408 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", 3409 `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}` 3410 ); 3411 let blockers = new Map(state.blockers); 3412 blockers.set(key, newBlocker); 3413 updateState({ blockers }); 3414 } 3415 function shouldBlockNavigation({ 3416 currentLocation, 3417 nextLocation, 3418 historyAction 3419 }) { 3420 if (blockerFunctions.size === 0) { 3421 return; 3422 } 3423 if (blockerFunctions.size > 1) { 3424 warning(false, "A router only supports one blocker at a time"); 3425 } 3426 let entries = Array.from(blockerFunctions.entries()); 3427 let [blockerKey, blockerFunction] = entries[entries.length - 1]; 3428 let blocker = state.blockers.get(blockerKey); 3429 if (blocker && blocker.state === "proceeding") { 3430 return; 3431 } 3432 if (blockerFunction({ currentLocation, nextLocation, historyAction })) { 3433 return blockerKey; 3434 } 3435 } 3436 function handleNavigational404(pathname) { 3437 let error = getInternalRouterError(404, { pathname }); 3438 let routesToUse = inFlightDataRoutes || dataRoutes; 3439 let { matches, route } = getShortCircuitMatches(routesToUse); 3440 return { notFoundMatches: matches, route, error }; 3441 } 3442 function enableScrollRestoration(positions, getPosition, getKey) { 3443 savedScrollPositions2 = positions; 3444 getScrollPosition = getPosition; 3445 getScrollRestorationKey2 = getKey || null; 3446 if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) { 3447 initialScrollRestored = true; 3448 let y = getSavedScrollPosition(state.location, state.matches); 3449 if (y != null) { 3450 updateState({ restoreScrollPosition: y }); 3451 } 3452 } 3453 return () => { 3454 savedScrollPositions2 = null; 3455 getScrollPosition = null; 3456 getScrollRestorationKey2 = null; 3457 }; 3458 } 3459 function getScrollKey(location2, matches) { 3460 if (getScrollRestorationKey2) { 3461 let key = getScrollRestorationKey2( 3462 location2, 3463 matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData)) 3464 ); 3465 return key || location2.key; 3466 } 3467 return location2.key; 3468 } 3469 function saveScrollPosition(location2, matches) { 3470 if (savedScrollPositions2 && getScrollPosition) { 3471 let key = getScrollKey(location2, matches); 3472 savedScrollPositions2[key] = getScrollPosition(); 3473 } 3474 } 3475 function getSavedScrollPosition(location2, matches) { 3476 if (savedScrollPositions2) { 3477 let key = getScrollKey(location2, matches); 3478 let y = savedScrollPositions2[key]; 3479 if (typeof y === "number") { 3480 return y; 3481 } 3482 } 3483 return null; 3484 } 3485 function checkFogOfWar(matches, routesToUse, pathname) { 3486 if (init.patchRoutesOnNavigation) { 3487 if (!matches) { 3488 let fogMatches = matchRoutesImpl( 3489 routesToUse, 3490 pathname, 3491 basename, 3492 true 3493 ); 3494 return { active: true, matches: fogMatches || [] }; 3495 } else { 3496 if (Object.keys(matches[0].params).length > 0) { 3497 let partialMatches = matchRoutesImpl( 3498 routesToUse, 3499 pathname, 3500 basename, 3501 true 3502 ); 3503 return { active: true, matches: partialMatches }; 3504 } 3505 } 3506 } 3507 return { active: false, matches: null }; 3508 } 3509 async function discoverRoutes(matches, pathname, signal, fetcherKey) { 3510 if (!init.patchRoutesOnNavigation) { 3511 return { type: "success", matches }; 3512 } 3513 let partialMatches = matches; 3514 while (true) { 3515 let isNonHMR = inFlightDataRoutes == null; 3516 let routesToUse = inFlightDataRoutes || dataRoutes; 3517 let localManifest = manifest; 3518 try { 3519 await init.patchRoutesOnNavigation({ 3520 signal, 3521 path: pathname, 3522 matches: partialMatches, 3523 fetcherKey, 3524 patch: (routeId, children) => { 3525 if (signal.aborted) return; 3526 patchRoutesImpl( 3527 routeId, 3528 children, 3529 routesToUse, 3530 localManifest, 3531 mapRouteProperties2, 3532 false 3533 ); 3534 } 3535 }); 3536 } catch (e) { 3537 return { type: "error", error: e, partialMatches }; 3538 } finally { 3539 if (isNonHMR && !signal.aborted) { 3540 dataRoutes = [...dataRoutes]; 3541 } 3542 } 3543 if (signal.aborted) { 3544 return { type: "aborted" }; 3545 } 3546 let newMatches = matchRoutes(routesToUse, pathname, basename); 3547 let newPartialMatches = null; 3548 if (newMatches) { 3549 if (Object.keys(newMatches[0].params).length === 0) { 3550 return { type: "success", matches: newMatches }; 3551 } else { 3552 newPartialMatches = matchRoutesImpl( 3553 routesToUse, 3554 pathname, 3555 basename, 3556 true 3557 ); 3558 let matchedDeeper = newPartialMatches && partialMatches.length < newPartialMatches.length && compareMatches( 3559 partialMatches, 3560 newPartialMatches.slice(0, partialMatches.length) 3561 ); 3562 if (!matchedDeeper) { 3563 return { type: "success", matches: newMatches }; 3564 } 3565 } 3566 } 3567 if (!newPartialMatches) { 3568 newPartialMatches = matchRoutesImpl( 3569 routesToUse, 3570 pathname, 3571 basename, 3572 true 3573 ); 3574 } 3575 if (!newPartialMatches || compareMatches(partialMatches, newPartialMatches)) { 3576 return { type: "success", matches: null }; 3577 } 3578 partialMatches = newPartialMatches; 3579 } 3580 } 3581 function compareMatches(a, b) { 3582 return a.length === b.length && a.every((m, i) => m.route.id === b[i].route.id); 3583 } 3584 function _internalSetRoutes(newRoutes) { 3585 manifest = {}; 3586 inFlightDataRoutes = convertRoutesToDataRoutes( 3587 newRoutes, 3588 mapRouteProperties2, 3589 void 0, 3590 manifest 3591 ); 3592 } 3593 function patchRoutes(routeId, children, unstable_allowElementMutations = false) { 3594 let isNonHMR = inFlightDataRoutes == null; 3595 let routesToUse = inFlightDataRoutes || dataRoutes; 3596 patchRoutesImpl( 3597 routeId, 3598 children, 3599 routesToUse, 3600 manifest, 3601 mapRouteProperties2, 3602 unstable_allowElementMutations 3603 ); 3604 if (isNonHMR) { 3605 dataRoutes = [...dataRoutes]; 3606 updateState({}); 3607 } 3608 } 3609 router2 = { 3610 get basename() { 3611 return basename; 3612 }, 3613 get future() { 3614 return future; 3615 }, 3616 get state() { 3617 return state; 3618 }, 3619 get routes() { 3620 return dataRoutes; 3621 }, 3622 get window() { 3623 return routerWindow; 3624 }, 3625 initialize, 3626 subscribe, 3627 enableScrollRestoration, 3628 navigate, 3629 fetch: fetch2, 3630 revalidate, 3631 // Passthrough to history-aware createHref used by useHref so we get proper 3632 // hash-aware URLs in DOM paths 3633 createHref: (to) => init.history.createHref(to), 3634 encodeLocation: (to) => init.history.encodeLocation(to), 3635 getFetcher, 3636 resetFetcher, 3637 deleteFetcher: queueFetcherForDeletion, 3638 dispose, 3639 getBlocker, 3640 deleteBlocker, 3641 patchRoutes, 3642 _internalFetchControllers: fetchControllers, 3643 // TODO: Remove setRoutes, it's temporary to avoid dealing with 3644 // updating the tree while validating the update algorithm. 3645 _internalSetRoutes, 3646 _internalSetStateDoNotUseOrYouWillBreakYourApp(newState) { 3647 updateState(newState); 3648 } 3649 }; 3650 if (init.unstable_instrumentations) { 3651 router2 = instrumentClientSideRouter( 3652 router2, 3653 init.unstable_instrumentations.map((i) => i.router).filter(Boolean) 3654 ); 3655 } 3656 return router2; 3657} 3658function createStaticHandler(routes, opts) { 3659 invariant( 3660 routes.length > 0, 3661 "You must provide a non-empty routes array to createStaticHandler" 3662 ); 3663 let manifest = {}; 3664 let basename = (opts ? opts.basename : null) || "/"; 3665 let _mapRouteProperties = opts?.mapRouteProperties || defaultMapRouteProperties; 3666 let mapRouteProperties2 = _mapRouteProperties; 3667 if (opts?.unstable_instrumentations) { 3668 let instrumentations = opts.unstable_instrumentations; 3669 mapRouteProperties2 = (route) => { 3670 return { 3671 ..._mapRouteProperties(route), 3672 ...getRouteInstrumentationUpdates( 3673 instrumentations.map((i) => i.route).filter(Boolean), 3674 route 3675 ) 3676 }; 3677 }; 3678 } 3679 let dataRoutes = convertRoutesToDataRoutes( 3680 routes, 3681 mapRouteProperties2, 3682 void 0, 3683 manifest 3684 ); 3685 async function query(request, { 3686 requestContext, 3687 filterMatchesToLoad, 3688 skipLoaderErrorBubbling, 3689 skipRevalidation, 3690 dataStrategy, 3691 generateMiddlewareResponse 3692 } = {}) { 3693 let url = new URL(request.url); 3694 let method = request.method; 3695 let location2 = createLocation("", createPath(url), null, "default"); 3696 let matches = matchRoutes(dataRoutes, location2, basename); 3697 requestContext = requestContext != null ? requestContext : new RouterContextProvider(); 3698 if (!isValidMethod(method) && method !== "HEAD") { 3699 let error = getInternalRouterError(405, { method }); 3700 let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes); 3701 let staticContext = { 3702 basename, 3703 location: location2, 3704 matches: methodNotAllowedMatches, 3705 loaderData: {}, 3706 actionData: null, 3707 errors: { 3708 [route.id]: error 3709 }, 3710 statusCode: error.status, 3711 loaderHeaders: {}, 3712 actionHeaders: {} 3713 }; 3714 return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext; 3715 } else if (!matches) { 3716 let error = getInternalRouterError(404, { pathname: location2.pathname }); 3717 let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes); 3718 let staticContext = { 3719 basename, 3720 location: location2, 3721 matches: notFoundMatches, 3722 loaderData: {}, 3723 actionData: null, 3724 errors: { 3725 [route.id]: error 3726 }, 3727 statusCode: error.status, 3728 loaderHeaders: {}, 3729 actionHeaders: {} 3730 }; 3731 return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext; 3732 } 3733 if (generateMiddlewareResponse) { 3734 invariant( 3735 requestContext instanceof RouterContextProvider, 3736 "When using middleware in `staticHandler.query()`, any provided `requestContext` must be an instance of `RouterContextProvider`" 3737 ); 3738 try { 3739 await loadLazyMiddlewareForMatches( 3740 matches, 3741 manifest, 3742 mapRouteProperties2 3743 ); 3744 let renderedStaticContext; 3745 let response = await runServerMiddlewarePipeline( 3746 { 3747 request, 3748 unstable_pattern: getRoutePattern(matches), 3749 matches, 3750 params: matches[0].params, 3751 // If we're calling middleware then it must be enabled so we can cast 3752 // this to the proper type knowing it's not an `AppLoadContext` 3753 context: requestContext 3754 }, 3755 async () => { 3756 let res = await generateMiddlewareResponse( 3757 async (revalidationRequest, opts2 = {}) => { 3758 let result2 = await queryImpl( 3759 revalidationRequest, 3760 location2, 3761 matches, 3762 requestContext, 3763 dataStrategy || null, 3764 skipLoaderErrorBubbling === true, 3765 null, 3766 "filterMatchesToLoad" in opts2 ? opts2.filterMatchesToLoad ?? null : filterMatchesToLoad ?? null, 3767 skipRevalidation === true 3768 ); 3769 if (isResponse(result2)) { 3770 return result2; 3771 } 3772 renderedStaticContext = { location: location2, basename, ...result2 }; 3773 return renderedStaticContext; 3774 } 3775 ); 3776 return res; 3777 }, 3778 async (error, routeId) => { 3779 if (isRedirectResponse(error)) { 3780 return error; 3781 } 3782 if (isResponse(error)) { 3783 try { 3784 error = new ErrorResponseImpl( 3785 error.status, 3786 error.statusText, 3787 await parseResponseBody(error) 3788 ); 3789 } catch (e) { 3790 error = e; 3791 } 3792 } 3793 if (isDataWithResponseInit(error)) { 3794 error = dataWithResponseInitToErrorResponse(error); 3795 } 3796 if (renderedStaticContext) { 3797 if (routeId in renderedStaticContext.loaderData) { 3798 renderedStaticContext.loaderData[routeId] = void 0; 3799 } 3800 let staticContext = getStaticContextFromError( 3801 dataRoutes, 3802 renderedStaticContext, 3803 error, 3804 skipLoaderErrorBubbling ? routeId : findNearestBoundary(matches, routeId).route.id 3805 ); 3806 return generateMiddlewareResponse( 3807 () => Promise.resolve(staticContext) 3808 ); 3809 } else { 3810 let boundaryRouteId = skipLoaderErrorBubbling ? routeId : findNearestBoundary( 3811 matches, 3812 matches.find( 3813 (m) => m.route.id === routeId || m.route.loader 3814 )?.route.id || routeId 3815 ).route.id; 3816 let staticContext = { 3817 matches, 3818 location: location2, 3819 basename, 3820 loaderData: {}, 3821 actionData: null, 3822 errors: { 3823 [boundaryRouteId]: error 3824 }, 3825 statusCode: isRouteErrorResponse(error) ? error.status : 500, 3826 actionHeaders: {}, 3827 loaderHeaders: {} 3828 }; 3829 return generateMiddlewareResponse( 3830 () => Promise.resolve(staticContext) 3831 ); 3832 } 3833 } 3834 ); 3835 invariant(isResponse(response), "Expected a response in query()"); 3836 return response; 3837 } catch (e) { 3838 if (isResponse(e)) { 3839 return e; 3840 } 3841 throw e; 3842 } 3843 } 3844 let result = await queryImpl( 3845 request, 3846 location2, 3847 matches, 3848 requestContext, 3849 dataStrategy || null, 3850 skipLoaderErrorBubbling === true, 3851 null, 3852 filterMatchesToLoad || null, 3853 skipRevalidation === true 3854 ); 3855 if (isResponse(result)) { 3856 return result; 3857 } 3858 return { location: location2, basename, ...result }; 3859 } 3860 async function queryRoute(request, { 3861 routeId, 3862 requestContext, 3863 dataStrategy, 3864 generateMiddlewareResponse 3865 } = {}) { 3866 let url = new URL(request.url); 3867 let method = request.method; 3868 let location2 = createLocation("", createPath(url), null, "default"); 3869 let matches = matchRoutes(dataRoutes, location2, basename); 3870 requestContext = requestContext != null ? requestContext : new RouterContextProvider(); 3871 if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") { 3872 throw getInternalRouterError(405, { method }); 3873 } else if (!matches) { 3874 throw getInternalRouterError(404, { pathname: location2.pathname }); 3875 } 3876 let match = routeId ? matches.find((m) => m.route.id === routeId) : getTargetMatch(matches, location2); 3877 if (routeId && !match) { 3878 throw getInternalRouterError(403, { 3879 pathname: location2.pathname, 3880 routeId 3881 }); 3882 } else if (!match) { 3883 throw getInternalRouterError(404, { pathname: location2.pathname }); 3884 } 3885 if (generateMiddlewareResponse) { 3886 invariant( 3887 requestContext instanceof RouterContextProvider, 3888 "When using middleware in `staticHandler.queryRoute()`, any provided `requestContext` must be an instance of `RouterContextProvider`" 3889 ); 3890 await loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2); 3891 let response = await runServerMiddlewarePipeline( 3892 { 3893 request, 3894 unstable_pattern: getRoutePattern(matches), 3895 matches, 3896 params: matches[0].params, 3897 // If we're calling middleware then it must be enabled so we can cast 3898 // this to the proper type knowing it's not an `AppLoadContext` 3899 context: requestContext 3900 }, 3901 async () => { 3902 let res = await generateMiddlewareResponse( 3903 async (innerRequest) => { 3904 let result2 = await queryImpl( 3905 innerRequest, 3906 location2, 3907 matches, 3908 requestContext, 3909 dataStrategy || null, 3910 false, 3911 match, 3912 null, 3913 false 3914 ); 3915 let processed = handleQueryResult(result2); 3916 return isResponse(processed) ? processed : typeof processed === "string" ? new Response(processed) : Response.json(processed); 3917 } 3918 ); 3919 return res; 3920 }, 3921 (error) => { 3922 if (isDataWithResponseInit(error)) { 3923 return Promise.resolve(dataWithResponseInitToResponse(error)); 3924 } 3925 if (isResponse(error)) { 3926 return Promise.resolve(error); 3927 } 3928 throw error; 3929 } 3930 ); 3931 return response; 3932 } 3933 let result = await queryImpl( 3934 request, 3935 location2, 3936 matches, 3937 requestContext, 3938 dataStrategy || null, 3939 false, 3940 match, 3941 null, 3942 false 3943 ); 3944 return handleQueryResult(result); 3945 function handleQueryResult(result2) { 3946 if (isResponse(result2)) { 3947 return result2; 3948 } 3949 let error = result2.errors ? Object.values(result2.errors)[0] : void 0; 3950 if (error !== void 0) { 3951 throw error; 3952 } 3953 if (result2.actionData) { 3954 return Object.values(result2.actionData)[0]; 3955 } 3956 if (result2.loaderData) { 3957 return Object.values(result2.loaderData)[0]; 3958 } 3959 return void 0; 3960 } 3961 } 3962 async function queryImpl(request, location2, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, skipRevalidation) { 3963 invariant( 3964 request.signal, 3965 "query()/queryRoute() requests must contain an AbortController signal" 3966 ); 3967 try { 3968 if (isMutationMethod(request.method)) { 3969 let result2 = await submit( 3970 request, 3971 matches, 3972 routeMatch || getTargetMatch(matches, location2), 3973 requestContext, 3974 dataStrategy, 3975 skipLoaderErrorBubbling, 3976 routeMatch != null, 3977 filterMatchesToLoad, 3978 skipRevalidation 3979 ); 3980 return result2; 3981 } 3982 let result = await loadRouteData( 3983 request, 3984 matches, 3985 requestContext, 3986 dataStrategy, 3987 skipLoaderErrorBubbling, 3988 routeMatch, 3989 filterMatchesToLoad 3990 ); 3991 return isResponse(result) ? result : { 3992 ...result, 3993 actionData: null, 3994 actionHeaders: {} 3995 }; 3996 } catch (e) { 3997 if (isDataStrategyResult(e) && isResponse(e.result)) { 3998 if (e.type === "error") { 3999 throw e.result; 4000 } 4001 return e.result; 4002 } 4003 if (isRedirectResponse(e)) { 4004 return e; 4005 } 4006 throw e; 4007 } 4008 } 4009 async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest, filterMatchesToLoad, skipRevalidation) { 4010 let result; 4011 if (!actionMatch.route.action && !actionMatch.route.lazy) { 4012 let error = getInternalRouterError(405, { 4013 method: request.method, 4014 pathname: new URL(request.url).pathname, 4015 routeId: actionMatch.route.id 4016 }); 4017 if (isRouteRequest) { 4018 throw error; 4019 } 4020 result = { 4021 type: "error", 4022 error 4023 }; 4024 } else { 4025 let dsMatches = getTargetedDataStrategyMatches( 4026 mapRouteProperties2, 4027 manifest, 4028 request, 4029 matches, 4030 actionMatch, 4031 [], 4032 requestContext 4033 ); 4034 let results = await callDataStrategy( 4035 request, 4036 dsMatches, 4037 isRouteRequest, 4038 requestContext, 4039 dataStrategy 4040 ); 4041 result = results[actionMatch.route.id]; 4042 if (request.signal.aborted) { 4043 throwStaticHandlerAbortedError(request, isRouteRequest); 4044 } 4045 } 4046 if (isRedirectResult(result)) { 4047 throw new Response(null, { 4048 status: result.response.status, 4049 headers: { 4050 Location: result.response.headers.get("Location") 4051 } 4052 }); 4053 } 4054 if (isRouteRequest) { 4055 if (isErrorResult(result)) { 4056 throw result.error; 4057 } 4058 return { 4059 matches: [actionMatch], 4060 loaderData: {}, 4061 actionData: { [actionMatch.route.id]: result.data }, 4062 errors: null, 4063 // Note: statusCode + headers are unused here since queryRoute will 4064 // return the raw Response or value 4065 statusCode: 200, 4066 loaderHeaders: {}, 4067 actionHeaders: {} 4068 }; 4069 } 4070 if (skipRevalidation) { 4071 if (isErrorResult(result)) { 4072 let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id); 4073 return { 4074 statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500, 4075 actionData: null, 4076 actionHeaders: { 4077 ...result.headers ? { [actionMatch.route.id]: result.headers } : {} 4078 }, 4079 matches, 4080 loaderData: {}, 4081 errors: { 4082 [boundaryMatch.route.id]: result.error 4083 }, 4084 loaderHeaders: {} 4085 }; 4086 } else { 4087 return { 4088 actionData: { 4089 [actionMatch.route.id]: result.data 4090 }, 4091 actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {}, 4092 matches, 4093 loaderData: {}, 4094 errors: null, 4095 statusCode: result.statusCode || 200, 4096 loaderHeaders: {} 4097 }; 4098 } 4099 } 4100 let loaderRequest = new Request(request.url, { 4101 headers: request.headers, 4102 redirect: request.redirect, 4103 signal: request.signal 4104 }); 4105 if (isErrorResult(result)) { 4106 let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id); 4107 let handlerContext2 = await loadRouteData( 4108 loaderRequest, 4109 matches, 4110 requestContext, 4111 dataStrategy, 4112 skipLoaderErrorBubbling, 4113 null, 4114 filterMatchesToLoad, 4115 [boundaryMatch.route.id, result] 4116 ); 4117 return { 4118 ...handlerContext2, 4119 statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500, 4120 actionData: null, 4121 actionHeaders: { 4122 ...result.headers ? { [actionMatch.route.id]: result.headers } : {} 4123 } 4124 }; 4125 } 4126 let handlerContext = await loadRouteData( 4127 loaderRequest, 4128 matches, 4129 requestContext, 4130 dataStrategy, 4131 skipLoaderErrorBubbling, 4132 null, 4133 filterMatchesToLoad 4134 ); 4135 return { 4136 ...handlerContext, 4137 actionData: { 4138 [actionMatch.route.id]: result.data 4139 }, 4140 // action status codes take precedence over loader status codes 4141 ...result.statusCode ? { statusCode: result.statusCode } : {}, 4142 actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {} 4143 }; 4144 } 4145 async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, pendingActionResult) { 4146 let isRouteRequest = routeMatch != null; 4147 if (isRouteRequest && !routeMatch?.route.loader && !routeMatch?.route.lazy) { 4148 throw getInternalRouterError(400, { 4149 method: request.method, 4150 pathname: new URL(request.url).pathname, 4151 routeId: routeMatch?.route.id 4152 }); 4153 } 4154 let dsMatches; 4155 if (routeMatch) { 4156 dsMatches = getTargetedDataStrategyMatches( 4157 mapRouteProperties2, 4158 manifest, 4159 request, 4160 matches, 4161 routeMatch, 4162 [], 4163 requestContext 4164 ); 4165 } else { 4166 let maxIdx = pendingActionResult && isErrorResult(pendingActionResult[1]) ? ( 4167 // Up to but not including the boundary 4168 matches.findIndex((m) => m.route.id === pendingActionResult[0]) - 1 4169 ) : void 0; 4170 let pattern = getRoutePattern(matches); 4171 dsMatches = matches.map((match, index) => { 4172 if (maxIdx != null && index > maxIdx) { 4173 return getDataStrategyMatch( 4174 mapRouteProperties2, 4175 manifest, 4176 request, 4177 pattern, 4178 match, 4179 [], 4180 requestContext, 4181 false 4182 ); 4183 } 4184 return getDataStrategyMatch( 4185 mapRouteProperties2, 4186 manifest, 4187 request, 4188 pattern, 4189 match, 4190 [], 4191 requestContext, 4192 (match.route.loader || match.route.lazy) != null && (!filterMatchesToLoad || filterMatchesToLoad(match)) 4193 ); 4194 }); 4195 } 4196 if (!dataStrategy && !dsMatches.some((m) => m.shouldLoad)) { 4197 return { 4198 matches, 4199 loaderData: {}, 4200 errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { 4201 [pendingActionResult[0]]: pendingActionResult[1].error 4202 } : null, 4203 statusCode: 200, 4204 loaderHeaders: {} 4205 }; 4206 } 4207 let results = await callDataStrategy( 4208 request, 4209 dsMatches, 4210 isRouteRequest, 4211 requestContext, 4212 dataStrategy 4213 ); 4214 if (request.signal.aborted) { 4215 throwStaticHandlerAbortedError(request, isRouteRequest); 4216 } 4217 let handlerContext = processRouteLoaderData( 4218 matches, 4219 results, 4220 pendingActionResult, 4221 true, 4222 skipLoaderErrorBubbling 4223 ); 4224 return { 4225 ...handlerContext, 4226 matches 4227 }; 4228 } 4229 async function callDataStrategy(request, matches, isRouteRequest, requestContext, dataStrategy) { 4230 let results = await callDataStrategyImpl( 4231 dataStrategy || defaultDataStrategy, 4232 request, 4233 matches, 4234 null, 4235 requestContext, 4236 true 4237 ); 4238 let dataResults = {}; 4239 await Promise.all( 4240 matches.map(async (match) => { 4241 if (!(match.route.id in results)) { 4242 return; 4243 } 4244 let result = results[match.route.id]; 4245 if (isRedirectDataStrategyResult(result)) { 4246 let response = result.result; 4247 throw normalizeRelativeRoutingRedirectResponse( 4248 response, 4249 request, 4250 match.route.id, 4251 matches, 4252 basename 4253 ); 4254 } 4255 if (isRouteRequest) { 4256 if (isResponse(result.result)) { 4257 throw result; 4258 } else if (isDataWithResponseInit(result.result)) { 4259 throw dataWithResponseInitToResponse(result.result); 4260 } 4261 } 4262 dataResults[match.route.id] = await convertDataStrategyResultToDataResult(result); 4263 }) 4264 ); 4265 return dataResults; 4266 } 4267 return { 4268 dataRoutes, 4269 query, 4270 queryRoute 4271 }; 4272} 4273function getStaticContextFromError(routes, handlerContext, error, boundaryId) { 4274 let errorBoundaryId = boundaryId || handlerContext._deepestRenderedBoundaryId || routes[0].id; 4275 return { 4276 ...handlerContext, 4277 statusCode: isRouteErrorResponse(error) ? error.status : 500, 4278 errors: { 4279 [errorBoundaryId]: error 4280 } 4281 }; 4282} 4283function throwStaticHandlerAbortedError(request, isRouteRequest) { 4284 if (request.signal.reason !== void 0) { 4285 throw request.signal.reason; 4286 } 4287 let method = isRouteRequest ? "queryRoute" : "query"; 4288 throw new Error( 4289 `${method}() call aborted without an \`AbortSignal.reason\`: ${request.method} ${request.url}` 4290 ); 4291} 4292function isSubmissionNavigation(opts) { 4293 return opts != null && ("formData" in opts && opts.formData != null || "body" in opts && opts.body !== void 0); 4294} 4295function normalizeTo(location2, matches, basename, to, fromRouteId, relative) { 4296 let contextualMatches; 4297 let activeRouteMatch; 4298 if (fromRouteId) { 4299 contextualMatches = []; 4300 for (let match of matches) { 4301 contextualMatches.push(match); 4302 if (match.route.id === fromRouteId) { 4303 activeRouteMatch = match; 4304 break; 4305 } 4306 } 4307 } else { 4308 contextualMatches = matches; 4309 activeRouteMatch = matches[matches.length - 1]; 4310 } 4311 let path = resolveTo( 4312 to ? to : ".", 4313 getResolveToMatches(contextualMatches), 4314 stripBasename(location2.pathname, basename) || location2.pathname, 4315 relative === "path" 4316 ); 4317 if (to == null) { 4318 path.search = location2.search; 4319 path.hash = location2.hash; 4320 } 4321 if ((to == null || to === "" || to === ".") && activeRouteMatch) { 4322 let nakedIndex = hasNakedIndexQuery(path.search); 4323 if (activeRouteMatch.route.index && !nakedIndex) { 4324 path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index"; 4325 } else if (!activeRouteMatch.route.index && nakedIndex) { 4326 let params = new URLSearchParams(path.search); 4327 let indexValues = params.getAll("index"); 4328 params.delete("index"); 4329 indexValues.filter((v) => v).forEach((v) => params.append("index", v)); 4330 let qs = params.toString(); 4331 path.search = qs ? `?${qs}` : ""; 4332 } 4333 } 4334 if (basename !== "/") { 4335 path.pathname = prependBasename({ basename, pathname: path.pathname }); 4336 } 4337 return createPath(path); 4338} 4339function normalizeNavigateOptions(isFetcher, path, opts) { 4340 if (!opts || !isSubmissionNavigation(opts)) { 4341 return { path }; 4342 } 4343 if (opts.formMethod && !isValidMethod(opts.formMethod)) { 4344 return { 4345 path, 4346 error: getInternalRouterError(405, { method: opts.formMethod }) 4347 }; 4348 } 4349 let getInvalidBodyError = () => ({ 4350 path, 4351 error: getInternalRouterError(400, { type: "invalid-body" }) 4352 }); 4353 let rawFormMethod = opts.formMethod || "get"; 4354 let formMethod = rawFormMethod.toUpperCase(); 4355 let formAction = stripHashFromPath(path); 4356 if (opts.body !== void 0) { 4357 if (opts.formEncType === "text/plain") { 4358 if (!isMutationMethod(formMethod)) { 4359 return getInvalidBodyError(); 4360 } 4361 let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? ( 4362 // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data 4363 Array.from(opts.body.entries()).reduce( 4364 (acc, [name, value]) => `${acc}${name}=${value} 4365`, 4366 "" 4367 ) 4368 ) : String(opts.body); 4369 return { 4370 path, 4371 submission: { 4372 formMethod, 4373 formAction, 4374 formEncType: opts.formEncType, 4375 formData: void 0, 4376 json: void 0, 4377 text 4378 } 4379 }; 4380 } else if (opts.formEncType === "application/json") { 4381 if (!isMutationMethod(formMethod)) { 4382 return getInvalidBodyError(); 4383 } 4384 try { 4385 let json = typeof opts.body === "string" ? JSON.parse(opts.body) : opts.body; 4386 return { 4387 path, 4388 submission: { 4389 formMethod, 4390 formAction, 4391 formEncType: opts.formEncType, 4392 formData: void 0, 4393 json, 4394 text: void 0 4395 } 4396 }; 4397 } catch (e) { 4398 return getInvalidBodyError(); 4399 } 4400 } 4401 } 4402 invariant( 4403 typeof FormData === "function", 4404 "FormData is not available in this environment" 4405 ); 4406 let searchParams; 4407 let formData; 4408 if (opts.formData) { 4409 searchParams = convertFormDataToSearchParams(opts.formData); 4410 formData = opts.formData; 4411 } else if (opts.body instanceof FormData) { 4412 searchParams = convertFormDataToSearchParams(opts.body); 4413 formData = opts.body; 4414 } else if (opts.body instanceof URLSearchParams) { 4415 searchParams = opts.body; 4416 formData = convertSearchParamsToFormData(searchParams); 4417 } else if (opts.body == null) { 4418 searchParams = new URLSearchParams(); 4419 formData = new FormData(); 4420 } else { 4421 try { 4422 searchParams = new URLSearchParams(opts.body); 4423 formData = convertSearchParamsToFormData(searchParams); 4424 } catch (e) { 4425 return getInvalidBodyError(); 4426 } 4427 } 4428 let submission = { 4429 formMethod, 4430 formAction, 4431 formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded", 4432 formData, 4433 json: void 0, 4434 text: void 0 4435 }; 4436 if (isMutationMethod(submission.formMethod)) { 4437 return { path, submission }; 4438 } 4439 let parsedPath = parsePath(path); 4440 if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) { 4441 searchParams.append("index", ""); 4442 } 4443 parsedPath.search = `?${searchParams}`; 4444 return { path: createPath(parsedPath), submission }; 4445} 4446function getMatchesToLoad(request, scopedContext, mapRouteProperties2, manifest, history, state, matches, submission, location2, lazyRoutePropertiesToSkip, initialHydration, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, hasPatchRoutesOnNavigation, pendingActionResult, callSiteDefaultShouldRevalidate) { 4447 let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : void 0; 4448 let currentUrl = history.createURL(state.location); 4449 let nextUrl = history.createURL(location2); 4450 let maxIdx; 4451 if (initialHydration && state.errors) { 4452 let boundaryId = Object.keys(state.errors)[0]; 4453 maxIdx = matches.findIndex((m) => m.route.id === boundaryId); 4454 } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) { 4455 let boundaryId = pendingActionResult[0]; 4456 maxIdx = matches.findIndex((m) => m.route.id === boundaryId) - 1; 4457 } 4458 let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : void 0; 4459 let shouldSkipRevalidation = actionStatus && actionStatus >= 400; 4460 let baseShouldRevalidateArgs = { 4461 currentUrl, 4462 currentParams: state.matches[0]?.params || {}, 4463 nextUrl, 4464 nextParams: matches[0].params, 4465 ...submission, 4466 actionResult, 4467 actionStatus 4468 }; 4469 let pattern = getRoutePattern(matches); 4470 let dsMatches = matches.map((match, index) => { 4471 let { route } = match; 4472 let forceShouldLoad = null; 4473 if (maxIdx != null && index > maxIdx) { 4474 forceShouldLoad = false; 4475 } else if (route.lazy) { 4476 forceShouldLoad = true; 4477 } else if (!routeHasLoaderOrMiddleware(route)) { 4478 forceShouldLoad = false; 4479 } else if (initialHydration) { 4480 let { shouldLoad: shouldLoad2 } = getRouteHydrationStatus( 4481 route, 4482 state.loaderData, 4483 state.errors 4484 ); 4485 forceShouldLoad = shouldLoad2; 4486 } else if (isNewLoader(state.loaderData, state.matches[index], match)) { 4487 forceShouldLoad = true; 4488 } 4489 if (forceShouldLoad !== null) { 4490 return getDataStrategyMatch( 4491 mapRouteProperties2, 4492 manifest, 4493 request, 4494 pattern, 4495 match, 4496 lazyRoutePropertiesToSkip, 4497 scopedContext, 4498 forceShouldLoad 4499 ); 4500 } 4501 let defaultShouldRevalidate = false; 4502 if (typeof callSiteDefaultShouldRevalidate === "boolean") { 4503 defaultShouldRevalidate = callSiteDefaultShouldRevalidate; 4504 } else if (shouldSkipRevalidation) { 4505 defaultShouldRevalidate = false; 4506 } else if (isRevalidationRequired) { 4507 defaultShouldRevalidate = true; 4508 } else if (currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search) { 4509 defaultShouldRevalidate = true; 4510 } else if (currentUrl.search !== nextUrl.search) { 4511 defaultShouldRevalidate = true; 4512 } else if (isNewRouteInstance(state.matches[index], match)) { 4513 defaultShouldRevalidate = true; 4514 } 4515 let shouldRevalidateArgs = { 4516 ...baseShouldRevalidateArgs, 4517 defaultShouldRevalidate 4518 }; 4519 let shouldLoad = shouldRevalidateLoader(match, shouldRevalidateArgs); 4520 return getDataStrategyMatch( 4521 mapRouteProperties2, 4522 manifest, 4523 request, 4524 pattern, 4525 match, 4526 lazyRoutePropertiesToSkip, 4527 scopedContext, 4528 shouldLoad, 4529 shouldRevalidateArgs, 4530 callSiteDefaultShouldRevalidate 4531 ); 4532 }); 4533 let revalidatingFetchers = []; 4534 fetchLoadMatches.forEach((f, key) => { 4535 if (initialHydration || !matches.some((m) => m.route.id === f.routeId) || fetchersQueuedForDeletion.has(key)) { 4536 return; 4537 } 4538 let fetcher = state.fetchers.get(key); 4539 let isMidInitialLoad = fetcher && fetcher.state !== "idle" && fetcher.data === void 0; 4540 let fetcherMatches = matchRoutes(routesToUse, f.path, basename); 4541 if (!fetcherMatches) { 4542 if (hasPatchRoutesOnNavigation && isMidInitialLoad) { 4543 return; 4544 } 4545 revalidatingFetchers.push({ 4546 key, 4547 routeId: f.routeId, 4548 path: f.path, 4549 matches: null, 4550 match: null, 4551 request: null, 4552 controller: null 4553 }); 4554 return; 4555 } 4556 if (fetchRedirectIds.has(key)) { 4557 return; 4558 } 4559 let fetcherMatch = getTargetMatch(fetcherMatches, f.path); 4560 let fetchController = new AbortController(); 4561 let fetchRequest = createClientSideRequest( 4562 history, 4563 f.path, 4564 fetchController.signal 4565 ); 4566 let fetcherDsMatches = null; 4567 if (cancelledFetcherLoads.has(key)) { 4568 cancelledFetcherLoads.delete(key); 4569 fetcherDsMatches = getTargetedDataStrategyMatches( 4570 mapRouteProperties2, 4571 manifest, 4572 fetchRequest, 4573 fetcherMatches, 4574 fetcherMatch, 4575 lazyRoutePropertiesToSkip, 4576 scopedContext 4577 ); 4578 } else if (isMidInitialLoad) { 4579 if (isRevalidationRequired) { 4580 fetcherDsMatches = getTargetedDataStrategyMatches( 4581 mapRouteProperties2, 4582 manifest, 4583 fetchRequest, 4584 fetcherMatches, 4585 fetcherMatch, 4586 lazyRoutePropertiesToSkip, 4587 scopedContext 4588 ); 4589 } 4590 } else { 4591 let defaultShouldRevalidate; 4592 if (typeof callSiteDefaultShouldRevalidate === "boolean") { 4593 defaultShouldRevalidate = callSiteDefaultShouldRevalidate; 4594 } else if (shouldSkipRevalidation) { 4595 defaultShouldRevalidate = false; 4596 } else { 4597 defaultShouldRevalidate = isRevalidationRequired; 4598 } 4599 let shouldRevalidateArgs = { 4600 ...baseShouldRevalidateArgs, 4601 defaultShouldRevalidate 4602 }; 4603 if (shouldRevalidateLoader(fetcherMatch, shouldRevalidateArgs)) { 4604 fetcherDsMatches = getTargetedDataStrategyMatches( 4605 mapRouteProperties2, 4606 manifest, 4607 fetchRequest, 4608 fetcherMatches, 4609 fetcherMatch, 4610 lazyRoutePropertiesToSkip, 4611 scopedContext, 4612 shouldRevalidateArgs 4613 ); 4614 } 4615 } 4616 if (fetcherDsMatches) { 4617 revalidatingFetchers.push({ 4618 key, 4619 routeId: f.routeId, 4620 path: f.path, 4621 matches: fetcherDsMatches, 4622 match: fetcherMatch, 4623 request: fetchRequest, 4624 controller: fetchController 4625 }); 4626 } 4627 }); 4628 return { dsMatches, revalidatingFetchers }; 4629} 4630function routeHasLoaderOrMiddleware(route) { 4631 return route.loader != null || route.middleware != null && route.middleware.length > 0; 4632} 4633function getRouteHydrationStatus(route, loaderData, errors) { 4634 if (route.lazy) { 4635 return { shouldLoad: true, renderFallback: true }; 4636 } 4637 if (!routeHasLoaderOrMiddleware(route)) { 4638 return { shouldLoad: false, renderFallback: false }; 4639 } 4640 let hasData = loaderData != null && route.id in loaderData; 4641 let hasError = errors != null && errors[route.id] !== void 0; 4642 if (!hasData && hasError) { 4643 return { shouldLoad: false, renderFallback: false }; 4644 } 4645 if (typeof route.loader === "function" && route.loader.hydrate === true) { 4646 return { shouldLoad: true, renderFallback: !hasData }; 4647 } 4648 let shouldLoad = !hasData && !hasError; 4649 return { shouldLoad, renderFallback: shouldLoad }; 4650} 4651function isNewLoader(currentLoaderData, currentMatch, match) { 4652 let isNew = ( 4653 // [a] -> [a, b] 4654 !currentMatch || // [a, b] -> [a, c] 4655 match.route.id !== currentMatch.route.id 4656 ); 4657 let isMissingData = !currentLoaderData.hasOwnProperty(match.route.id); 4658 return isNew || isMissingData; 4659} 4660function isNewRouteInstance(currentMatch, match) { 4661 let currentPath = currentMatch.route.path; 4662 return ( 4663 // param change for this match, /users/123 -> /users/456 4664 currentMatch.pathname !== match.pathname || // splat param changed, which is not present in match.path 4665 // e.g. /files/images/avatar.jpg -> files/finances.xls 4666 currentPath != null && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"] 4667 ); 4668} 4669function shouldRevalidateLoader(loaderMatch, arg) { 4670 if (loaderMatch.route.shouldRevalidate) { 4671 let routeChoice = loaderMatch.route.shouldRevalidate(arg); 4672 if (typeof routeChoice === "boolean") { 4673 return routeChoice; 4674 } 4675 } 4676 return arg.defaultShouldRevalidate; 4677} 4678function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties2, allowElementMutations) { 4679 let childrenToPatch; 4680 if (routeId) { 4681 let route = manifest[routeId]; 4682 invariant( 4683 route, 4684 `No route found to patch children into: routeId = ${routeId}` 4685 ); 4686 if (!route.children) { 4687 route.children = []; 4688 } 4689 childrenToPatch = route.children; 4690 } else { 4691 childrenToPatch = routesToUse; 4692 } 4693 let uniqueChildren = []; 4694 let existingChildren = []; 4695 children.forEach((newRoute) => { 4696 let existingRoute = childrenToPatch.find( 4697 (existingRoute2) => isSameRoute(newRoute, existingRoute2) 4698 ); 4699 if (existingRoute) { 4700 existingChildren.push({ existingRoute, newRoute }); 4701 } else { 4702 uniqueChildren.push(newRoute); 4703 } 4704 }); 4705 if (uniqueChildren.length > 0) { 4706 let newRoutes = convertRoutesToDataRoutes( 4707 uniqueChildren, 4708 mapRouteProperties2, 4709 [routeId || "_", "patch", String(childrenToPatch?.length || "0")], 4710 manifest 4711 ); 4712 childrenToPatch.push(...newRoutes); 4713 } 4714 if (allowElementMutations && existingChildren.length > 0) { 4715 for (let i = 0; i < existingChildren.length; i++) { 4716 let { existingRoute, newRoute } = existingChildren[i]; 4717 let existingRouteTyped = existingRoute; 4718 let [newRouteTyped] = convertRoutesToDataRoutes( 4719 [newRoute], 4720 mapRouteProperties2, 4721 [], 4722 // Doesn't matter for mutated routes since they already have an id 4723 {}, 4724 // Don't touch the manifest here since we're updating in place 4725 true 4726 ); 4727 Object.assign(existingRouteTyped, { 4728 element: newRouteTyped.element ? newRouteTyped.element : existingRouteTyped.element, 4729 errorElement: newRouteTyped.errorElement ? newRouteTyped.errorElement : existingRouteTyped.errorElement, 4730 hydrateFallbackElement: newRouteTyped.hydrateFallbackElement ? newRouteTyped.hydrateFallbackElement : existingRouteTyped.hydrateFallbackElement 4731 }); 4732 } 4733 } 4734} 4735function isSameRoute(newRoute, existingRoute) { 4736 if ("id" in newRoute && "id" in existingRoute && newRoute.id === existingRoute.id) { 4737 return true; 4738 } 4739 if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) { 4740 return false; 4741 } 4742 if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) { 4743 return true; 4744 } 4745 return newRoute.children?.every( 4746 (aChild, i) => existingRoute.children?.some((bChild) => isSameRoute(aChild, bChild)) 4747 ) ?? false; 4748} 4749var lazyRoutePropertyCache = /* @__PURE__ */ new WeakMap(); 4750var loadLazyRouteProperty = ({ 4751 key, 4752 route, 4753 manifest, 4754 mapRouteProperties: mapRouteProperties2 4755}) => { 4756 let routeToUpdate = manifest[route.id]; 4757 invariant(routeToUpdate, "No route found in manifest"); 4758 if (!routeToUpdate.lazy || typeof routeToUpdate.lazy !== "object") { 4759 return; 4760 } 4761 let lazyFn = routeToUpdate.lazy[key]; 4762 if (!lazyFn) { 4763 return; 4764 } 4765 let cache = lazyRoutePropertyCache.get(routeToUpdate); 4766 if (!cache) { 4767 cache = {}; 4768 lazyRoutePropertyCache.set(routeToUpdate, cache); 4769 } 4770 let cachedPromise = cache[key]; 4771 if (cachedPromise) { 4772 return cachedPromise; 4773 } 4774 let propertyPromise = (async () => { 4775 let isUnsupported = isUnsupportedLazyRouteObjectKey(key); 4776 let staticRouteValue = routeToUpdate[key]; 4777 let isStaticallyDefined = staticRouteValue !== void 0 && key !== "hasErrorBoundary"; 4778 if (isUnsupported) { 4779 warning( 4780 !isUnsupported, 4781 "Route property " + key + " is not a supported lazy route property. This property will be ignored." 4782 ); 4783 cache[key] = Promise.resolve(); 4784 } else if (isStaticallyDefined) { 4785 warning( 4786 false, 4787 `Route "${routeToUpdate.id}" has a static property "${key}" defined. The lazy property will be ignored.` 4788 ); 4789 } else { 4790 let value = await lazyFn(); 4791 if (value != null) { 4792 Object.assign(routeToUpdate, { [key]: value }); 4793 Object.assign(routeToUpdate, mapRouteProperties2(routeToUpdate)); 4794 } 4795 } 4796 if (typeof routeToUpdate.lazy === "object") { 4797 routeToUpdate.lazy[key] = void 0; 4798 if (Object.values(routeToUpdate.lazy).every((value) => value === void 0)) { 4799 routeToUpdate.lazy = void 0; 4800 } 4801 } 4802 })(); 4803 cache[key] = propertyPromise; 4804 return propertyPromise; 4805}; 4806var lazyRouteFunctionCache = /* @__PURE__ */ new WeakMap(); 4807function loadLazyRoute(route, type, manifest, mapRouteProperties2, lazyRoutePropertiesToSkip) { 4808 let routeToUpdate = manifest[route.id]; 4809 invariant(routeToUpdate, "No route found in manifest"); 4810 if (!route.lazy) { 4811 return { 4812 lazyRoutePromise: void 0, 4813 lazyHandlerPromise: void 0 4814 }; 4815 } 4816 if (typeof route.lazy === "function") { 4817 let cachedPromise = lazyRouteFunctionCache.get(routeToUpdate); 4818 if (cachedPromise) { 4819 return { 4820 lazyRoutePromise: cachedPromise, 4821 lazyHandlerPromise: cachedPromise 4822 }; 4823 } 4824 let lazyRoutePromise2 = (async () => { 4825 invariant( 4826 typeof route.lazy === "function", 4827 "No lazy route function found" 4828 ); 4829 let lazyRoute = await route.lazy(); 4830 let routeUpdates = {}; 4831 for (let lazyRouteProperty in lazyRoute) { 4832 let lazyValue = lazyRoute[lazyRouteProperty]; 4833 if (lazyValue === void 0) { 4834 continue; 4835 } 4836 let isUnsupported = isUnsupportedLazyRouteFunctionKey(lazyRouteProperty); 4837 let staticRouteValue = routeToUpdate[lazyRouteProperty]; 4838 let isStaticallyDefined = staticRouteValue !== void 0 && // This property isn't static since it should always be updated based 4839 // on the route updates 4840 lazyRouteProperty !== "hasErrorBoundary"; 4841 if (isUnsupported) { 4842 warning( 4843 !isUnsupported, 4844 "Route property " + lazyRouteProperty + " is not a supported property to be returned from a lazy route function. This property will be ignored." 4845 ); 4846 } else if (isStaticallyDefined) { 4847 warning( 4848 !isStaticallyDefined, 4849 `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.` 4850 ); 4851 } else { 4852 routeUpdates[lazyRouteProperty] = lazyValue; 4853 } 4854 } 4855 Object.assign(routeToUpdate, routeUpdates); 4856 Object.assign(routeToUpdate, { 4857 // To keep things framework agnostic, we use the provided `mapRouteProperties` 4858 // function to set the framework-aware properties (`element`/`hasErrorBoundary`) 4859 // since the logic will differ between frameworks. 4860 ...mapRouteProperties2(routeToUpdate), 4861 lazy: void 0 4862 }); 4863 })(); 4864 lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise2); 4865 lazyRoutePromise2.catch(() => { 4866 }); 4867 return { 4868 lazyRoutePromise: lazyRoutePromise2, 4869 lazyHandlerPromise: lazyRoutePromise2 4870 }; 4871 } 4872 let lazyKeys = Object.keys(route.lazy); 4873 let lazyPropertyPromises = []; 4874 let lazyHandlerPromise = void 0; 4875 for (let key of lazyKeys) { 4876 if (lazyRoutePropertiesToSkip && lazyRoutePropertiesToSkip.includes(key)) { 4877 continue; 4878 } 4879 let promise = loadLazyRouteProperty({ 4880 key, 4881 route, 4882 manifest, 4883 mapRouteProperties: mapRouteProperties2 4884 }); 4885 if (promise) { 4886 lazyPropertyPromises.push(promise); 4887 if (key === type) { 4888 lazyHandlerPromise = promise; 4889 } 4890 } 4891 } 4892 let lazyRoutePromise = lazyPropertyPromises.length > 0 ? Promise.all(lazyPropertyPromises).then(() => { 4893 }) : void 0; 4894 lazyRoutePromise?.catch(() => { 4895 }); 4896 lazyHandlerPromise?.catch(() => { 4897 }); 4898 return { 4899 lazyRoutePromise, 4900 lazyHandlerPromise 4901 }; 4902} 4903function isNonNullable(value) { 4904 return value !== void 0; 4905} 4906function loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2) { 4907 let promises = matches.map(({ route }) => { 4908 if (typeof route.lazy !== "object" || !route.lazy.middleware) { 4909 return void 0; 4910 } 4911 return loadLazyRouteProperty({ 4912 key: "middleware", 4913 route, 4914 manifest, 4915 mapRouteProperties: mapRouteProperties2 4916 }); 4917 }).filter(isNonNullable); 4918 return promises.length > 0 ? Promise.all(promises) : void 0; 4919} 4920async function defaultDataStrategy(args) { 4921 let matchesToLoad = args.matches.filter((m) => m.shouldLoad); 4922 let keyedResults = {}; 4923 let results = await Promise.all(matchesToLoad.map((m) => m.resolve())); 4924 results.forEach((result, i) => { 4925 keyedResults[matchesToLoad[i].route.id] = result; 4926 }); 4927 return keyedResults; 4928} 4929async function defaultDataStrategyWithMiddleware(args) { 4930 if (!args.matches.some((m) => m.route.middleware)) { 4931 return defaultDataStrategy(args); 4932 } 4933 return runClientMiddlewarePipeline(args, () => defaultDataStrategy(args)); 4934} 4935function runServerMiddlewarePipeline(args, handler, errorHandler) { 4936 return runMiddlewarePipeline( 4937 args, 4938 handler, 4939 processResult, 4940 isResponse, 4941 errorHandler 4942 ); 4943 function processResult(result) { 4944 return isDataWithResponseInit(result) ? dataWithResponseInitToResponse(result) : result; 4945 } 4946} 4947function runClientMiddlewarePipeline(args, handler) { 4948 return runMiddlewarePipeline( 4949 args, 4950 handler, 4951 (r) => { 4952 if (isRedirectResponse(r)) { 4953 throw r; 4954 } 4955 return r; 4956 }, 4957 isDataStrategyResults, 4958 errorHandler 4959 ); 4960 function errorHandler(error, routeId, nextResult) { 4961 if (nextResult) { 4962 return Promise.resolve( 4963 Object.assign(nextResult.value, { 4964 [routeId]: { type: "error", result: error } 4965 }) 4966 ); 4967 } else { 4968 let { matches } = args; 4969 let maxBoundaryIdx = Math.min( 4970 // Throwing route 4971 Math.max( 4972 matches.findIndex((m) => m.route.id === routeId), 4973 0 4974 ), 4975 // or the shallowest route that needs to load data 4976 Math.max( 4977 matches.findIndex((m) => m.shouldCallHandler()), 4978 0 4979 ) 4980 ); 4981 let boundaryRouteId = findNearestBoundary( 4982 matches, 4983 matches[maxBoundaryIdx].route.id 4984 ).route.id; 4985 return Promise.resolve({ 4986 [boundaryRouteId]: { type: "error", result: error } 4987 }); 4988 } 4989 } 4990} 4991async function runMiddlewarePipeline(args, handler, processResult, isResult, errorHandler) { 4992 let { matches, request, params, context, unstable_pattern } = args; 4993 let tuples = matches.flatMap( 4994 (m) => m.route.middleware ? m.route.middleware.map((fn) => [m.route.id, fn]) : [] 4995 ); 4996 let result = await callRouteMiddleware( 4997 { 4998 request, 4999 params, 5000 context, 5001 unstable_pattern 5002 }, 5003 tuples, 5004 handler, 5005 processResult, 5006 isResult, 5007 errorHandler 5008 ); 5009 return result; 5010} 5011async function callRouteMiddleware(args, middlewares, handler, processResult, isResult, errorHandler, idx = 0) { 5012 let { request } = args; 5013 if (request.signal.aborted) { 5014 throw request.signal.reason ?? new Error(`Request aborted: ${request.method} ${request.url}`); 5015 } 5016 let tuple = middlewares[idx]; 5017 if (!tuple) { 5018 let result = await handler(); 5019 return result; 5020 } 5021 let [routeId, middleware] = tuple; 5022 let nextResult; 5023 let next = async () => { 5024 if (nextResult) { 5025 throw new Error("You may only call `next()` once per middleware"); 5026 } 5027 try { 5028 let result = await callRouteMiddleware( 5029 args, 5030 middlewares, 5031 handler, 5032 processResult, 5033 isResult, 5034 errorHandler, 5035 idx + 1 5036 ); 5037 nextResult = { value: result }; 5038 return nextResult.value; 5039 } catch (error) { 5040 nextResult = { value: await errorHandler(error, routeId, nextResult) }; 5041 return nextResult.value; 5042 } 5043 }; 5044 try { 5045 let value = await middleware(args, next); 5046 let result = value != null ? processResult(value) : void 0; 5047 if (isResult(result)) { 5048 return result; 5049 } else if (nextResult) { 5050 return result ?? nextResult.value; 5051 } else { 5052 nextResult = { value: await next() }; 5053 return nextResult.value; 5054 } 5055 } catch (error) { 5056 let response = await errorHandler(error, routeId, nextResult); 5057 return response; 5058 } 5059} 5060function getDataStrategyMatchLazyPromises(mapRouteProperties2, manifest, request, match, lazyRoutePropertiesToSkip) { 5061 let lazyMiddlewarePromise = loadLazyRouteProperty({ 5062 key: "middleware", 5063 route: match.route, 5064 manifest, 5065 mapRouteProperties: mapRouteProperties2 5066 }); 5067 let lazyRoutePromises = loadLazyRoute( 5068 match.route, 5069 isMutationMethod(request.method) ? "action" : "loader", 5070 manifest, 5071 mapRouteProperties2, 5072 lazyRoutePropertiesToSkip 5073 ); 5074 return { 5075 middleware: lazyMiddlewarePromise, 5076 route: lazyRoutePromises.lazyRoutePromise, 5077 handler: lazyRoutePromises.lazyHandlerPromise 5078 }; 5079} 5080function getDataStrategyMatch(mapRouteProperties2, manifest, request, unstable_pattern, match, lazyRoutePropertiesToSkip, scopedContext, shouldLoad, shouldRevalidateArgs = null, callSiteDefaultShouldRevalidate) { 5081 let isUsingNewApi = false; 5082 let _lazyPromises = getDataStrategyMatchLazyPromises( 5083 mapRouteProperties2, 5084 manifest, 5085 request, 5086 match, 5087 lazyRoutePropertiesToSkip 5088 ); 5089 return { 5090 ...match, 5091 _lazyPromises, 5092 shouldLoad, 5093 shouldRevalidateArgs, 5094 shouldCallHandler(defaultShouldRevalidate) { 5095 isUsingNewApi = true; 5096 if (!shouldRevalidateArgs) { 5097 return shouldLoad; 5098 } 5099 if (typeof callSiteDefaultShouldRevalidate === "boolean") { 5100 return shouldRevalidateLoader(match, { 5101 ...shouldRevalidateArgs, 5102 defaultShouldRevalidate: callSiteDefaultShouldRevalidate 5103 }); 5104 } 5105 if (typeof defaultShouldRevalidate === "boolean") { 5106 return shouldRevalidateLoader(match, { 5107 ...shouldRevalidateArgs, 5108 defaultShouldRevalidate 5109 }); 5110 } 5111 return shouldRevalidateLoader(match, shouldRevalidateArgs); 5112 }, 5113 resolve(handlerOverride) { 5114 let { lazy, loader, middleware } = match.route; 5115 let callHandler = isUsingNewApi || shouldLoad || handlerOverride && !isMutationMethod(request.method) && (lazy || loader); 5116 let isMiddlewareOnlyRoute = middleware && middleware.length > 0 && !loader && !lazy; 5117 if (callHandler && (isMutationMethod(request.method) || !isMiddlewareOnlyRoute)) { 5118 return callLoaderOrAction({ 5119 request, 5120 unstable_pattern, 5121 match, 5122 lazyHandlerPromise: _lazyPromises?.handler, 5123 lazyRoutePromise: _lazyPromises?.route, 5124 handlerOverride, 5125 scopedContext 5126 }); 5127 } 5128 return Promise.resolve({ type: "data", result: void 0 }); 5129 } 5130 }; 5131} 5132function getTargetedDataStrategyMatches(mapRouteProperties2, manifest, request, matches, targetMatch, lazyRoutePropertiesToSkip, scopedContext, shouldRevalidateArgs = null) { 5133 return matches.map((match) => { 5134 if (match.route.id !== targetMatch.route.id) { 5135 return { 5136 ...match, 5137 shouldLoad: false, 5138 shouldRevalidateArgs, 5139 shouldCallHandler: () => false, 5140 _lazyPromises: getDataStrategyMatchLazyPromises( 5141 mapRouteProperties2, 5142 manifest, 5143 request, 5144 match, 5145 lazyRoutePropertiesToSkip 5146 ), 5147 resolve: () => Promise.resolve({ type: "data", result: void 0 }) 5148 }; 5149 } 5150 return getDataStrategyMatch( 5151 mapRouteProperties2, 5152 manifest, 5153 request, 5154 getRoutePattern(matches), 5155 match, 5156 lazyRoutePropertiesToSkip, 5157 scopedContext, 5158 true, 5159 shouldRevalidateArgs 5160 ); 5161 }); 5162} 5163async function callDataStrategyImpl(dataStrategyImpl, request, matches, fetcherKey, scopedContext, isStaticHandler) { 5164 if (matches.some((m) => m._lazyPromises?.middleware)) { 5165 await Promise.all(matches.map((m) => m._lazyPromises?.middleware)); 5166 } 5167 let dataStrategyArgs = { 5168 request, 5169 unstable_pattern: getRoutePattern(matches), 5170 params: matches[0].params, 5171 context: scopedContext, 5172 matches 5173 }; 5174 let runClientMiddleware = isStaticHandler ? () => { 5175 throw new Error( 5176 "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`" 5177 ); 5178 } : (cb) => { 5179 let typedDataStrategyArgs = dataStrategyArgs; 5180 return runClientMiddlewarePipeline(typedDataStrategyArgs, () => { 5181 return cb({ 5182 ...typedDataStrategyArgs, 5183 fetcherKey, 5184 runClientMiddleware: () => { 5185 throw new Error( 5186 "Cannot call `runClientMiddleware()` from within an `runClientMiddleware` handler" 5187 ); 5188 } 5189 }); 5190 }); 5191 }; 5192 let results = await dataStrategyImpl({ 5193 ...dataStrategyArgs, 5194 fetcherKey, 5195 runClientMiddleware 5196 }); 5197 try { 5198 await Promise.all( 5199 matches.flatMap((m) => [ 5200 m._lazyPromises?.handler, 5201 m._lazyPromises?.route 5202 ]) 5203 ); 5204 } catch (e) { 5205 } 5206 return results; 5207} 5208async function callLoaderOrAction({ 5209 request, 5210 unstable_pattern, 5211 match, 5212 lazyHandlerPromise, 5213 lazyRoutePromise, 5214 handlerOverride, 5215 scopedContext 5216}) { 5217 let result; 5218 let onReject; 5219 let isAction = isMutationMethod(request.method); 5220 let type = isAction ? "action" : "loader"; 5221 let runHandler = (handler) => { 5222 let reject; 5223 let abortPromise = new Promise((_, r) => reject = r); 5224 onReject = () => reject(); 5225 request.signal.addEventListener("abort", onReject); 5226 let actualHandler = (ctx) => { 5227 if (typeof handler !== "function") { 5228 return Promise.reject( 5229 new Error( 5230 `You cannot call the handler for a route which defines a boolean "${type}" [routeId: ${match.route.id}]` 5231 ) 5232 ); 5233 } 5234 return handler( 5235 { 5236 request, 5237 unstable_pattern, 5238 params: match.params, 5239 context: scopedContext 5240 }, 5241 ...ctx !== void 0 ? [ctx] : [] 5242 ); 5243 }; 5244 let handlerPromise = (async () => { 5245 try { 5246 let val = await (handlerOverride ? handlerOverride((ctx) => actualHandler(ctx)) : actualHandler()); 5247 return { type: "data", result: val }; 5248 } catch (e) { 5249 return { type: "error", result: e }; 5250 } 5251 })(); 5252 return Promise.race([handlerPromise, abortPromise]); 5253 }; 5254 try { 5255 let handler = isAction ? match.route.action : match.route.loader; 5256 if (lazyHandlerPromise || lazyRoutePromise) { 5257 if (handler) { 5258 let handlerError; 5259 let [value] = await Promise.all([ 5260 // If the handler throws, don't let it immediately bubble out, 5261 // since we need to let the lazy() execution finish so we know if this 5262 // route has a boundary that can handle the error 5263 runHandler(handler).catch((e) => { 5264 handlerError = e; 5265 }), 5266 // Ensure all lazy route promises are resolved before continuing 5267 lazyHandlerPromise, 5268 lazyRoutePromise 5269 ]); 5270 if (handlerError !== void 0) { 5271 throw handlerError; 5272 } 5273 result = value; 5274 } else { 5275 await lazyHandlerPromise; 5276 let handler2 = isAction ? match.route.action : match.route.loader; 5277 if (handler2) { 5278 [result] = await Promise.all([runHandler(handler2), lazyRoutePromise]); 5279 } else if (type === "action") { 5280 let url = new URL(request.url); 5281 let pathname = url.pathname + url.search; 5282 throw getInternalRouterError(405, { 5283 method: request.method, 5284 pathname, 5285 routeId: match.route.id 5286 }); 5287 } else { 5288 return { type: "data", result: void 0 }; 5289 } 5290 } 5291 } else if (!handler) { 5292 let url = new URL(request.url); 5293 let pathname = url.pathname + url.search; 5294 throw getInternalRouterError(404, { 5295 pathname 5296 }); 5297 } else { 5298 result = await runHandler(handler); 5299 } 5300 } catch (e) { 5301 return { type: "error", result: e }; 5302 } finally { 5303 if (onReject) { 5304 request.signal.removeEventListener("abort", onReject); 5305 } 5306 } 5307 return result; 5308} 5309async function parseResponseBody(response) { 5310 let contentType = response.headers.get("Content-Type"); 5311 if (contentType && /\bapplication\/json\b/.test(contentType)) { 5312 return response.body == null ? null : response.json(); 5313 } 5314 return response.text(); 5315} 5316async function convertDataStrategyResultToDataResult(dataStrategyResult) { 5317 let { result, type } = dataStrategyResult; 5318 if (isResponse(result)) { 5319 let data2; 5320 try { 5321 data2 = await parseResponseBody(result); 5322 } catch (e) { 5323 return { type: "error", error: e }; 5324 } 5325 if (type === "error") { 5326 return { 5327 type: "error", 5328 error: new ErrorResponseImpl(result.status, result.statusText, data2), 5329 statusCode: result.status, 5330 headers: result.headers 5331 }; 5332 } 5333 return { 5334 type: "data", 5335 data: data2, 5336 statusCode: result.status, 5337 headers: result.headers 5338 }; 5339 } 5340 if (type === "error") { 5341 if (isDataWithResponseInit(result)) { 5342 if (result.data instanceof Error) { 5343 return { 5344 type: "error", 5345 error: result.data, 5346 statusCode: result.init?.status, 5347 headers: result.init?.headers ? new Headers(result.init.headers) : void 0 5348 }; 5349 } 5350 return { 5351 type: "error", 5352 error: dataWithResponseInitToErrorResponse(result), 5353 statusCode: isRouteErrorResponse(result) ? result.status : void 0, 5354 headers: result.init?.headers ? new Headers(result.init.headers) : void 0 5355 }; 5356 } 5357 return { 5358 type: "error", 5359 error: result, 5360 statusCode: isRouteErrorResponse(result) ? result.status : void 0 5361 }; 5362 } 5363 if (isDataWithResponseInit(result)) { 5364 return { 5365 type: "data", 5366 data: result.data, 5367 statusCode: result.init?.status, 5368 headers: result.init?.headers ? new Headers(result.init.headers) : void 0 5369 }; 5370 } 5371 return { type: "data", data: result }; 5372} 5373function normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename) { 5374 let location2 = response.headers.get("Location"); 5375 invariant( 5376 location2, 5377 "Redirects returned/thrown from loaders/actions must have a Location header" 5378 ); 5379 if (!isAbsoluteUrl(location2)) { 5380 let trimmedMatches = matches.slice( 5381 0, 5382 matches.findIndex((m) => m.route.id === routeId) + 1 5383 ); 5384 location2 = normalizeTo( 5385 new URL(request.url), 5386 trimmedMatches, 5387 basename, 5388 location2 5389 ); 5390 response.headers.set("Location", location2); 5391 } 5392 return response; 5393} 5394function normalizeRedirectLocation(location2, currentUrl, basename, historyInstance) { 5395 let invalidProtocols = [ 5396 "about:", 5397 "blob:", 5398 "chrome:", 5399 "chrome-untrusted:", 5400 "content:", 5401 "data:", 5402 "devtools:", 5403 "file:", 5404 "filesystem:", 5405 // eslint-disable-next-line no-script-url 5406 "javascript:" 5407 ]; 5408 if (isAbsoluteUrl(location2)) { 5409 let normalizedLocation = location2; 5410 let url = normalizedLocation.startsWith("//") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation); 5411 if (invalidProtocols.includes(url.protocol)) { 5412 throw new Error("Invalid redirect location"); 5413 } 5414 let isSameBasename = stripBasename(url.pathname, basename) != null; 5415 if (url.origin === currentUrl.origin && isSameBasename) { 5416 return url.pathname + url.search + url.hash; 5417 } 5418 } 5419 try { 5420 let url = historyInstance.createURL(location2); 5421 if (invalidProtocols.includes(url.protocol)) { 5422 throw new Error("Invalid redirect location"); 5423 } 5424 } catch (e) { 5425 } 5426 return location2; 5427} 5428function createClientSideRequest(history, location2, signal, submission) { 5429 let url = history.createURL(stripHashFromPath(location2)).toString(); 5430 let init = { signal }; 5431 if (submission && isMutationMethod(submission.formMethod)) { 5432 let { formMethod, formEncType } = submission; 5433 init.method = formMethod.toUpperCase(); 5434 if (formEncType === "application/json") { 5435 init.headers = new Headers({ "Content-Type": formEncType }); 5436 init.body = JSON.stringify(submission.json); 5437 } else if (formEncType === "text/plain") { 5438 init.body = submission.text; 5439 } else if (formEncType === "application/x-www-form-urlencoded" && submission.formData) { 5440 init.body = convertFormDataToSearchParams(submission.formData); 5441 } else { 5442 init.body = submission.formData; 5443 } 5444 } 5445 return new Request(url, init); 5446} 5447function convertFormDataToSearchParams(formData) { 5448 let searchParams = new URLSearchParams(); 5449 for (let [key, value] of formData.entries()) { 5450 searchParams.append(key, typeof value === "string" ? value : value.name); 5451 } 5452 return searchParams; 5453} 5454function convertSearchParamsToFormData(searchParams) { 5455 let formData = new FormData(); 5456 for (let [key, value] of searchParams.entries()) { 5457 formData.append(key, value); 5458 } 5459 return formData; 5460} 5461function processRouteLoaderData(matches, results, pendingActionResult, isStaticHandler = false, skipLoaderErrorBubbling = false) { 5462 let loaderData = {}; 5463 let errors = null; 5464 let statusCode; 5465 let foundError = false; 5466 let loaderHeaders = {}; 5467 let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : void 0; 5468 matches.forEach((match) => { 5469 if (!(match.route.id in results)) { 5470 return; 5471 } 5472 let id = match.route.id; 5473 let result = results[id]; 5474 invariant( 5475 !isRedirectResult(result), 5476 "Cannot handle redirect results in processLoaderData" 5477 ); 5478 if (isErrorResult(result)) { 5479 let error = result.error; 5480 if (pendingError !== void 0) { 5481 error = pendingError; 5482 pendingError = void 0; 5483 } 5484 errors = errors || {}; 5485 if (skipLoaderErrorBubbling) { 5486 errors[id] = error; 5487 } else { 5488 let boundaryMatch = findNearestBoundary(matches, id); 5489 if (errors[boundaryMatch.route.id] == null) { 5490 errors[boundaryMatch.route.id] = error; 5491 } 5492 } 5493 if (!isStaticHandler) { 5494 loaderData[id] = ResetLoaderDataSymbol; 5495 } 5496 if (!foundError) { 5497 foundError = true; 5498 statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500; 5499 } 5500 if (result.headers) { 5501 loaderHeaders[id] = result.headers; 5502 } 5503 } else { 5504 loaderData[id] = result.data; 5505 if (result.statusCode && result.statusCode !== 200 && !foundError) { 5506 statusCode = result.statusCode; 5507 } 5508 if (result.headers) { 5509 loaderHeaders[id] = result.headers; 5510 } 5511 } 5512 }); 5513 if (pendingError !== void 0 && pendingActionResult) { 5514 errors = { [pendingActionResult[0]]: pendingError }; 5515 if (pendingActionResult[2]) { 5516 loaderData[pendingActionResult[2]] = void 0; 5517 } 5518 } 5519 return { 5520 loaderData, 5521 errors, 5522 statusCode: statusCode || 200, 5523 loaderHeaders 5524 }; 5525} 5526function processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults) { 5527 let { loaderData, errors } = processRouteLoaderData( 5528 matches, 5529 results, 5530 pendingActionResult 5531 ); 5532 revalidatingFetchers.filter((f) => !f.matches || f.matches.some((m) => m.shouldLoad)).forEach((rf) => { 5533 let { key, match, controller } = rf; 5534 if (controller && controller.signal.aborted) { 5535 return; 5536 } 5537 let result = fetcherResults[key]; 5538 invariant(result, "Did not find corresponding fetcher result"); 5539 if (isErrorResult(result)) { 5540 let boundaryMatch = findNearestBoundary(state.matches, match?.route.id); 5541 if (!(errors && errors[boundaryMatch.route.id])) { 5542 errors = { 5543 ...errors, 5544 [boundaryMatch.route.id]: result.error 5545 }; 5546 } 5547 state.fetchers.delete(key); 5548 } else if (isRedirectResult(result)) { 5549 invariant(false, "Unhandled fetcher revalidation redirect"); 5550 } else { 5551 let doneFetcher = getDoneFetcher(result.data); 5552 state.fetchers.set(key, doneFetcher); 5553 } 5554 }); 5555 return { loaderData, errors }; 5556} 5557function mergeLoaderData(loaderData, newLoaderData, matches, errors) { 5558 let mergedLoaderData = Object.entries(newLoaderData).filter(([, v]) => v !== ResetLoaderDataSymbol).reduce((merged, [k, v]) => { 5559 merged[k] = v; 5560 return merged; 5561 }, {}); 5562 for (let match of matches) { 5563 let id = match.route.id; 5564 if (!newLoaderData.hasOwnProperty(id) && loaderData.hasOwnProperty(id) && match.route.loader) { 5565 mergedLoaderData[id] = loaderData[id]; 5566 } 5567 if (errors && errors.hasOwnProperty(id)) { 5568 break; 5569 } 5570 } 5571 return mergedLoaderData; 5572} 5573function getActionDataForCommit(pendingActionResult) { 5574 if (!pendingActionResult) { 5575 return {}; 5576 } 5577 return isErrorResult(pendingActionResult[1]) ? { 5578 // Clear out prior actionData on errors 5579 actionData: {} 5580 } : { 5581 actionData: { 5582 [pendingActionResult[0]]: pendingActionResult[1].data 5583 } 5584 }; 5585} 5586function findNearestBoundary(matches, routeId) { 5587 let eligibleMatches = routeId ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1) : [...matches]; 5588 return eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) || matches[0]; 5589} 5590function getShortCircuitMatches(routes) { 5591 let route = routes.length === 1 ? routes[0] : routes.find((r) => r.index || !r.path || r.path === "/") || { 5592 id: `__shim-error-route__` 5593 }; 5594 return { 5595 matches: [ 5596 { 5597 params: {}, 5598 pathname: "", 5599 pathnameBase: "", 5600 route 5601 } 5602 ], 5603 route 5604 }; 5605} 5606function getInternalRouterError(status, { 5607 pathname, 5608 routeId, 5609 method, 5610 type, 5611 message 5612} = {}) { 5613 let statusText = "Unknown Server Error"; 5614 let errorMessage = "Unknown @remix-run/router error"; 5615 if (status === 400) { 5616 statusText = "Bad Request"; 5617 if (method && pathname && routeId) { 5618 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.`; 5619 } else if (type === "invalid-body") { 5620 errorMessage = "Unable to encode submission body"; 5621 } 5622 } else if (status === 403) { 5623 statusText = "Forbidden"; 5624 errorMessage = `Route "${routeId}" does not match URL "${pathname}"`; 5625 } else if (status === 404) { 5626 statusText = "Not Found"; 5627 errorMessage = `No route matches URL "${pathname}"`; 5628 } else if (status === 405) { 5629 statusText = "Method Not Allowed"; 5630 if (method && pathname && routeId) { 5631 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.`; 5632 } else if (method) { 5633 errorMessage = `Invalid request method "${method.toUpperCase()}"`; 5634 } 5635 } 5636 return new ErrorResponseImpl( 5637 status || 500, 5638 statusText, 5639 new Error(errorMessage), 5640 true 5641 ); 5642} 5643function findRedirect(results) { 5644 let entries = Object.entries(results); 5645 for (let i = entries.length - 1; i >= 0; i--) { 5646 let [key, result] = entries[i]; 5647 if (isRedirectResult(result)) { 5648 return { key, result }; 5649 } 5650 } 5651} 5652function stripHashFromPath(path) { 5653 let parsedPath = typeof path === "string" ? parsePath(path) : path; 5654 return createPath({ ...parsedPath, hash: "" }); 5655} 5656function isHashChangeOnly(a, b) { 5657 if (a.pathname !== b.pathname || a.search !== b.search) { 5658 return false; 5659 } 5660 if (a.hash === "") { 5661 return b.hash !== ""; 5662 } else if (a.hash === b.hash) { 5663 return true; 5664 } else if (b.hash !== "") { 5665 return true; 5666 } 5667 return false; 5668} 5669function dataWithResponseInitToResponse(data2) { 5670 return Response.json(data2.data, data2.init ?? void 0); 5671} 5672function dataWithResponseInitToErrorResponse(data2) { 5673 return new ErrorResponseImpl( 5674 data2.init?.status ?? 500, 5675 data2.init?.statusText ?? "Internal Server Error", 5676 data2.data 5677 ); 5678} 5679function isDataStrategyResults(result) { 5680 return result != null && typeof result === "object" && Object.entries(result).every( 5681 ([key, value]) => typeof key === "string" && isDataStrategyResult(value) 5682 ); 5683} 5684function isDataStrategyResult(result) { 5685 return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === "data" || result.type === "error"); 5686} 5687function isRedirectDataStrategyResult(result) { 5688 return isResponse(result.result) && redirectStatusCodes.has(result.result.status); 5689} 5690function isErrorResult(result) { 5691 return result.type === "error"; 5692} 5693function isRedirectResult(result) { 5694 return (result && result.type) === "redirect"; 5695} 5696function isDataWithResponseInit(value) { 5697 return typeof value === "object" && value != null && "type" in value && "data" in value && "init" in value && value.type === "DataWithResponseInit"; 5698} 5699function isResponse(value) { 5700 return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined"; 5701} 5702function isRedirectStatusCode(statusCode) { 5703 return redirectStatusCodes.has(statusCode); 5704} 5705function isRedirectResponse(result) { 5706 return isResponse(result) && isRedirectStatusCode(result.status) && result.headers.has("Location"); 5707} 5708function isValidMethod(method) { 5709 return validRequestMethods.has(method.toUpperCase()); 5710} 5711function isMutationMethod(method) { 5712 return validMutationMethods.has(method.toUpperCase()); 5713} 5714function hasNakedIndexQuery(search) { 5715 return new URLSearchParams(search).getAll("index").some((v) => v === ""); 5716} 5717function getTargetMatch(matches, location2) { 5718 let search = typeof location2 === "string" ? parsePath(location2).search : location2.search; 5719 if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) { 5720 return matches[matches.length - 1]; 5721 } 5722 let pathMatches = getPathContributingMatches(matches); 5723 return pathMatches[pathMatches.length - 1]; 5724} 5725function getSubmissionFromNavigation(navigation) { 5726 let { formMethod, formAction, formEncType, text, formData, json } = navigation; 5727 if (!formMethod || !formAction || !formEncType) { 5728 return; 5729 } 5730 if (text != null) { 5731 return { 5732 formMethod, 5733 formAction, 5734 formEncType, 5735 formData: void 0, 5736 json: void 0, 5737 text 5738 }; 5739 } else if (formData != null) { 5740 return { 5741 formMethod, 5742 formAction, 5743 formEncType, 5744 formData, 5745 json: void 0, 5746 text: void 0 5747 }; 5748 } else if (json !== void 0) { 5749 return { 5750 formMethod, 5751 formAction, 5752 formEncType, 5753 formData: void 0, 5754 json, 5755 text: void 0 5756 }; 5757 } 5758} 5759function getLoadingNavigation(location2, submission) { 5760 if (submission) { 5761 let navigation = { 5762 state: "loading", 5763 location: location2, 5764 formMethod: submission.formMethod, 5765 formAction: submission.formAction, 5766 formEncType: submission.formEncType, 5767 formData: submission.formData, 5768 json: submission.json, 5769 text: submission.text 5770 }; 5771 return navigation; 5772 } else { 5773 let navigation = { 5774 state: "loading", 5775 location: location2, 5776 formMethod: void 0, 5777 formAction: void 0, 5778 formEncType: void 0, 5779 formData: void 0, 5780 json: void 0, 5781 text: void 0 5782 }; 5783 return navigation; 5784 } 5785} 5786function getSubmittingNavigation(location2, submission) { 5787 let navigation = { 5788 state: "submitting", 5789 location: location2, 5790 formMethod: submission.formMethod, 5791 formAction: submission.formAction, 5792 formEncType: submission.formEncType, 5793 formData: submission.formData, 5794 json: submission.json, 5795 text: submission.text 5796 }; 5797 return navigation; 5798} 5799function getLoadingFetcher(submission, data2) { 5800 if (submission) { 5801 let fetcher = { 5802 state: "loading", 5803 formMethod: submission.formMethod, 5804 formAction: submission.formAction, 5805 formEncType: submission.formEncType, 5806 formData: submission.formData, 5807 json: submission.json, 5808 text: submission.text, 5809 data: data2 5810 }; 5811 return fetcher; 5812 } else { 5813 let fetcher = { 5814 state: "loading", 5815 formMethod: void 0, 5816 formAction: void 0, 5817 formEncType: void 0, 5818 formData: void 0, 5819 json: void 0, 5820 text: void 0, 5821 data: data2 5822 }; 5823 return fetcher; 5824 } 5825} 5826function getSubmittingFetcher(submission, existingFetcher) { 5827 let fetcher = { 5828 state: "submitting", 5829 formMethod: submission.formMethod, 5830 formAction: submission.formAction, 5831 formEncType: submission.formEncType, 5832 formData: submission.formData, 5833 json: submission.json, 5834 text: submission.text, 5835 data: existingFetcher ? existingFetcher.data : void 0 5836 }; 5837 return fetcher; 5838} 5839function getDoneFetcher(data2) { 5840 let fetcher = { 5841 state: "idle", 5842 formMethod: void 0, 5843 formAction: void 0, 5844 formEncType: void 0, 5845 formData: void 0, 5846 json: void 0, 5847 text: void 0, 5848 data: data2 5849 }; 5850 return fetcher; 5851} 5852function restoreAppliedTransitions(_window, transitions) { 5853 try { 5854 let sessionPositions = _window.sessionStorage.getItem( 5855 TRANSITIONS_STORAGE_KEY 5856 ); 5857 if (sessionPositions) { 5858 let json = JSON.parse(sessionPositions); 5859 for (let [k, v] of Object.entries(json || {})) { 5860 if (v && Array.isArray(v)) { 5861 transitions.set(k, new Set(v || [])); 5862 } 5863 } 5864 } 5865 } catch (e) { 5866 } 5867} 5868function persistAppliedTransitions(_window, transitions) { 5869 if (transitions.size > 0) { 5870 let json = {}; 5871 for (let [k, v] of transitions) { 5872 json[k] = [...v]; 5873 } 5874 try { 5875 _window.sessionStorage.setItem( 5876 TRANSITIONS_STORAGE_KEY, 5877 JSON.stringify(json) 5878 ); 5879 } catch (error) { 5880 warning( 5881 false, 5882 `Failed to save applied view transitions in sessionStorage (${error}).` 5883 ); 5884 } 5885 } 5886} 5887function createDeferred() { 5888 let resolve; 5889 let reject; 5890 let promise = new Promise((res, rej) => { 5891 resolve = async (val) => { 5892 res(val); 5893 try { 5894 await promise; 5895 } catch (e) { 5896 } 5897 }; 5898 reject = async (error) => { 5899 rej(error); 5900 try { 5901 await promise; 5902 } catch (e) { 5903 } 5904 }; 5905 }); 5906 return { 5907 promise, 5908 //@ts-ignore 5909 resolve, 5910 //@ts-ignore 5911 reject 5912 }; 5913} 5914var DataRouterContext = React.createContext(null); 5915DataRouterContext.displayName = "DataRouter"; 5916var DataRouterStateContext = React.createContext(null); 5917DataRouterStateContext.displayName = "DataRouterState"; 5918var RSCRouterContext = React.createContext(false); 5919function useIsRSCRouterContext() { 5920 return React.useContext(RSCRouterContext); 5921} 5922var ViewTransitionContext = React.createContext({ 5923 isTransitioning: false 5924}); 5925ViewTransitionContext.displayName = "ViewTransition"; 5926var FetchersContext = React.createContext( 5927 /* @__PURE__ */ new Map() 5928); 5929FetchersContext.displayName = "Fetchers"; 5930var AwaitContext = React.createContext(null); 5931AwaitContext.displayName = "Await"; 5932var AwaitContextProvider = (props) => React.createElement(AwaitContext.Provider, props); 5933var NavigationContext = React.createContext( 5934 null 5935); 5936NavigationContext.displayName = "Navigation"; 5937var LocationContext = React.createContext( 5938 null 5939); 5940LocationContext.displayName = "Location"; 5941var RouteContext = React.createContext({ 5942 outlet: null, 5943 matches: [], 5944 isDataRoute: false 5945}); 5946RouteContext.displayName = "Route"; 5947var RouteErrorContext = React.createContext(null); 5948RouteErrorContext.displayName = "RouteError"; 5949var ENABLE_DEV_WARNINGS = true; 5950var ERROR_DIGEST_BASE = "REACT_ROUTER_ERROR"; 5951var ERROR_DIGEST_REDIRECT = "REDIRECT"; 5952var ERROR_DIGEST_ROUTE_ERROR_RESPONSE = "ROUTE_ERROR_RESPONSE"; 5953function decodeRedirectErrorDigest(digest) { 5954 if (digest.startsWith(`${ERROR_DIGEST_BASE}:${ERROR_DIGEST_REDIRECT}:{`)) { 5955 try { 5956 let parsed = JSON.parse(digest.slice(28)); 5957 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") { 5958 return parsed; 5959 } 5960 } catch { 5961 } 5962 } 5963} 5964function decodeRouteErrorResponseDigest(digest) { 5965 if (digest.startsWith( 5966 `${ERROR_DIGEST_BASE}:${ERROR_DIGEST_ROUTE_ERROR_RESPONSE}:{` 5967 )) { 5968 try { 5969 let parsed = JSON.parse(digest.slice(40)); 5970 if (typeof parsed === "object" && parsed && typeof parsed.status === "number" && typeof parsed.statusText === "string") { 5971 return new ErrorResponseImpl( 5972 parsed.status, 5973 parsed.statusText, 5974 parsed.data 5975 ); 5976 } 5977 } catch { 5978 } 5979 } 5980} 5981function useHref(to, { relative } = {}) { 5982 invariant( 5983 useInRouterContext(), 5984 // TODO: This error is probably because they somehow have 2 versions of the 5985 // router loaded. We can help them understand how to avoid that. 5986 `useHref() may be used only in the context of a <Router> component.` 5987 ); 5988 let { basename, navigator } = React2.useContext(NavigationContext); 5989 let { hash, pathname, search } = useResolvedPath(to, { relative }); 5990 let joinedPathname = pathname; 5991 if (basename !== "/") { 5992 joinedPathname = pathname === "/" ? basename : joinPaths([basename, pathname]); 5993 } 5994 return navigator.createHref({ pathname: joinedPathname, search, hash }); 5995} 5996function useInRouterContext() { 5997 return React2.useContext(LocationContext) != null; 5998} 5999function useLocation() { 6000 invariant( 6001 useInRouterContext(), 6002 // TODO: This error is probably because they somehow have 2 versions of the 6003 // router loaded. We can help them understand how to avoid that. 6004 `useLocation() may be used only in the context of a <Router> component.` 6005 ); 6006 return React2.useContext(LocationContext).location; 6007} 6008function useNavigationType() { 6009 return React2.useContext(LocationContext).navigationType; 6010} 6011function useMatch(pattern) { 6012 invariant( 6013 useInRouterContext(), 6014 // TODO: This error is probably because they somehow have 2 versions of the 6015 // router loaded. We can help them understand how to avoid that. 6016 `useMatch() may be used only in the context of a <Router> component.` 6017 ); 6018 let { pathname } = useLocation(); 6019 return React2.useMemo( 6020 () => matchPath(pattern, decodePath(pathname)), 6021 [pathname, pattern] 6022 ); 6023} 6024var navigateEffectWarning = `You should call navigate() in a React.useEffect(), not when your component is first rendered.`; 6025function useIsomorphicLayoutEffect(cb) { 6026 let isStatic = React2.useContext(NavigationContext).static; 6027 if (!isStatic) { 6028 React2.useLayoutEffect(cb); 6029 } 6030} 6031function useNavigate() { 6032 let { isDataRoute } = React2.useContext(RouteContext); 6033 return isDataRoute ? useNavigateStable() : useNavigateUnstable(); 6034} 6035function useNavigateUnstable() { 6036 invariant( 6037 useInRouterContext(), 6038 // TODO: This error is probably because they somehow have 2 versions of the 6039 // router loaded. We can help them understand how to avoid that. 6040 `useNavigate() may be used only in the context of a <Router> component.` 6041 ); 6042 let dataRouterContext = React2.useContext(DataRouterContext); 6043 let { basename, navigator } = React2.useContext(NavigationContext); 6044 let { matches } = React2.useContext(RouteContext); 6045 let { pathname: locationPathname } = useLocation(); 6046 let routePathnamesJson = JSON.stringify(getResolveToMatches(matches)); 6047 let activeRef = React2.useRef(false); 6048 useIsomorphicLayoutEffect(() => { 6049 activeRef.current = true; 6050 }); 6051 let navigate = React2.useCallback( 6052 (to, options = {}) => { 6053 warning(activeRef.current, navigateEffectWarning); 6054 if (!activeRef.current) return; 6055 if (typeof to === "number") { 6056 navigator.go(to); 6057 return; 6058 } 6059 let path = resolveTo( 6060 to, 6061 JSON.parse(routePathnamesJson), 6062 locationPathname, 6063 options.relative === "path" 6064 ); 6065 if (dataRouterContext == null && basename !== "/") { 6066 path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]); 6067 } 6068 (!!options.replace ? navigator.replace : navigator.push)( 6069 path, 6070 options.state, 6071 options 6072 ); 6073 }, 6074 [ 6075 basename, 6076 navigator, 6077 routePathnamesJson, 6078 locationPathname, 6079 dataRouterContext 6080 ] 6081 ); 6082 return navigate; 6083} 6084var OutletContext = React2.createContext(null); 6085function useOutletContext() { 6086 return React2.useContext(OutletContext); 6087} 6088function useOutlet(context) { 6089 let outlet = React2.useContext(RouteContext).outlet; 6090 return React2.useMemo( 6091 () => outlet && React2.createElement(OutletContext.Provider, { value: context }, outlet), 6092 [outlet, context] 6093 ); 6094} 6095function useParams() { 6096 let { matches } = React2.useContext(RouteContext); 6097 let routeMatch = matches[matches.length - 1]; 6098 return routeMatch ? routeMatch.params : {}; 6099} 6100function useResolvedPath(to, { relative } = {}) { 6101 let { matches } = React2.useContext(RouteContext); 6102 let { pathname: locationPathname } = useLocation(); 6103 let routePathnamesJson = JSON.stringify(getResolveToMatches(matches)); 6104 return React2.useMemo( 6105 () => resolveTo( 6106 to, 6107 JSON.parse(routePathnamesJson), 6108 locationPathname, 6109 relative === "path" 6110 ), 6111 [to, routePathnamesJson, locationPathname, relative] 6112 ); 6113} 6114function useRoutes(routes, locationArg) { 6115 return useRoutesImpl(routes, locationArg); 6116} 6117function useRoutesImpl(routes, locationArg, dataRouterOpts) { 6118 invariant( 6119 useInRouterContext(), 6120 // TODO: This error is probably because they somehow have 2 versions of the 6121 // router loaded. We can help them understand how to avoid that. 6122 `useRoutes() may be used only in the context of a <Router> component.` 6123 ); 6124 let { navigator } = React2.useContext(NavigationContext); 6125 let { matches: parentMatches } = React2.useContext(RouteContext); 6126 let routeMatch = parentMatches[parentMatches.length - 1]; 6127 let parentParams = routeMatch ? routeMatch.params : {}; 6128 let parentPathname = routeMatch ? routeMatch.pathname : "/"; 6129 let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/"; 6130 let parentRoute = routeMatch && routeMatch.route; 6131 if (ENABLE_DEV_WARNINGS) { 6132 let parentPath = parentRoute && parentRoute.path || ""; 6133 warningOnce( 6134 parentPathname, 6135 !parentRoute || parentPath.endsWith("*") || parentPath.endsWith("*?"), 6136 `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. 6137 6138Please change the parent <Route path="${parentPath}"> to <Route path="${parentPath === "/" ? "*" : `${parentPath}/*`}">.` 6139 ); 6140 } 6141 let locationFromContext = useLocation(); 6142 let location2; 6143 if (locationArg) { 6144 let parsedLocationArg = typeof locationArg === "string" ? parsePath(locationArg) : locationArg; 6145 invariant( 6146 parentPathnameBase === "/" || parsedLocationArg.pathname?.startsWith(parentPathnameBase), 6147 `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.` 6148 ); 6149 location2 = parsedLocationArg; 6150 } else { 6151 location2 = locationFromContext; 6152 } 6153 let pathname = location2.pathname || "/"; 6154 let remainingPathname = pathname; 6155 if (parentPathnameBase !== "/") { 6156 let parentSegments = parentPathnameBase.replace(/^\//, "").split("/"); 6157 let segments = pathname.replace(/^\//, "").split("/"); 6158 remainingPathname = "/" + segments.slice(parentSegments.length).join("/"); 6159 } 6160 let matches = matchRoutes(routes, { pathname: remainingPathname }); 6161 if (ENABLE_DEV_WARNINGS) { 6162 warning( 6163 parentRoute || matches != null, 6164 `No routes matched location "${location2.pathname}${location2.search}${location2.hash}" ` 6165 ); 6166 warning( 6167 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, 6168 `Matched leaf route at location "${location2.pathname}${location2.search}${location2.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.` 6169 ); 6170 } 6171 let renderedMatches = _renderMatches( 6172 matches && matches.map( 6173 (match) => Object.assign({}, match, { 6174 params: Object.assign({}, parentParams, match.params), 6175 pathname: joinPaths([ 6176 parentPathnameBase, 6177 // Re-encode pathnames that were decoded inside matchRoutes. 6178 // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses 6179 // `new URL()` internally and we need to prevent it from treating 6180 // them as separators 6181 navigator.encodeLocation ? navigator.encodeLocation( 6182 match.pathname.replace(/\?/g, "%3F").replace(/#/g, "%23") 6183 ).pathname : match.pathname 6184 ]), 6185 pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([ 6186 parentPathnameBase, 6187 // Re-encode pathnames that were decoded inside matchRoutes 6188 // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses 6189 // `new URL()` internally and we need to prevent it from treating 6190 // them as separators 6191 navigator.encodeLocation ? navigator.encodeLocation( 6192 match.pathnameBase.replace(/\?/g, "%3F").replace(/#/g, "%23") 6193 ).pathname : match.pathnameBase 6194 ]) 6195 }) 6196 ), 6197 parentMatches, 6198 dataRouterOpts 6199 ); 6200 if (locationArg && renderedMatches) { 6201 return React2.createElement( 6202 LocationContext.Provider, 6203 { 6204 value: { 6205 location: { 6206 pathname: "/", 6207 search: "", 6208 hash: "", 6209 state: null, 6210 key: "default", 6211 unstable_mask: void 0, 6212 ...location2 6213 }, 6214 navigationType: "POP" 6215 /* Pop */ 6216 } 6217 }, 6218 renderedMatches 6219 ); 6220 } 6221 return renderedMatches; 6222} 6223function DefaultErrorComponent() { 6224 let error = useRouteError(); 6225 let message = isRouteErrorResponse(error) ? `${error.status} ${error.statusText}` : error instanceof Error ? error.message : JSON.stringify(error); 6226 let stack = error instanceof Error ? error.stack : null; 6227 let lightgrey = "rgba(200,200,200, 0.5)"; 6228 let preStyles = { padding: "0.5rem", backgroundColor: lightgrey }; 6229 let codeStyles = { padding: "2px 4px", backgroundColor: lightgrey }; 6230 let devInfo = null; 6231 if (ENABLE_DEV_WARNINGS) { 6232 console.error( 6233 "Error handled by React Router default ErrorBoundary:", 6234 error 6235 ); 6236 devInfo = React2.createElement(React2.Fragment, null, React2.createElement("p", null, "💿 Hey developer 👋"), React2.createElement("p", null, "You can provide a way better UX than this when your app throws errors by providing your own ", React2.createElement("code", { style: codeStyles }, "ErrorBoundary"), " or", " ", React2.createElement("code", { style: codeStyles }, "errorElement"), " prop on your route.")); 6237 } 6238 return React2.createElement(React2.Fragment, null, React2.createElement("h2", null, "Unexpected Application Error!"), React2.createElement("h3", { style: { fontStyle: "italic" } }, message), stack ? React2.createElement("pre", { style: preStyles }, stack) : null, devInfo); 6239} 6240var defaultErrorElement = React2.createElement(DefaultErrorComponent, null); 6241var RenderErrorBoundary = class extends React2.Component { 6242 constructor(props) { 6243 super(props); 6244 this.state = { 6245 location: props.location, 6246 revalidation: props.revalidation, 6247 error: props.error 6248 }; 6249 } 6250 static getDerivedStateFromError(error) { 6251 return { error }; 6252 } 6253 static getDerivedStateFromProps(props, state) { 6254 if (state.location !== props.location || state.revalidation !== "idle" && props.revalidation === "idle") { 6255 return { 6256 error: props.error, 6257 location: props.location, 6258 revalidation: props.revalidation 6259 }; 6260 } 6261 return { 6262 error: props.error !== void 0 ? props.error : state.error, 6263 location: state.location, 6264 revalidation: props.revalidation || state.revalidation 6265 }; 6266 } 6267 componentDidCatch(error, errorInfo) { 6268 if (this.props.onError) { 6269 this.props.onError(error, errorInfo); 6270 } else { 6271 console.error( 6272 "React Router caught the following error during render", 6273 error 6274 ); 6275 } 6276 } 6277 render() { 6278 let error = this.state.error; 6279 if (this.context && typeof error === "object" && error && "digest" in error && typeof error.digest === "string") { 6280 const decoded = decodeRouteErrorResponseDigest(error.digest); 6281 if (decoded) error = decoded; 6282 } 6283 let result = error !== void 0 ? React2.createElement(RouteContext.Provider, { value: this.props.routeContext }, React2.createElement( 6284 RouteErrorContext.Provider, 6285 { 6286 value: error, 6287 children: this.props.component 6288 } 6289 )) : this.props.children; 6290 if (this.context) { 6291 return React2.createElement(RSCErrorHandler, { error }, result); 6292 } 6293 return result; 6294 } 6295}; 6296RenderErrorBoundary.contextType = RSCRouterContext; 6297var errorRedirectHandledMap = /* @__PURE__ */ new WeakMap(); 6298function RSCErrorHandler({ 6299 children, 6300 error 6301}) { 6302 let { basename } = React2.useContext(NavigationContext); 6303 if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") { 6304 let redirect2 = decodeRedirectErrorDigest(error.digest); 6305 if (redirect2) { 6306 let existingRedirect = errorRedirectHandledMap.get(error); 6307 if (existingRedirect) throw existingRedirect; 6308 let parsed = parseToInfo(redirect2.location, basename); 6309 if (isBrowser && !errorRedirectHandledMap.get(error)) { 6310 if (parsed.isExternal || redirect2.reloadDocument) { 6311 window.location.href = parsed.absoluteURL || parsed.to; 6312 } else { 6313 const redirectPromise = Promise.resolve().then( 6314 () => window.__reactRouterDataRouter.navigate(parsed.to, { 6315 replace: redirect2.replace 6316 }) 6317 ); 6318 errorRedirectHandledMap.set(error, redirectPromise); 6319 throw redirectPromise; 6320 } 6321 } 6322 return React2.createElement( 6323 "meta", 6324 { 6325 httpEquiv: "refresh", 6326 content: `0;url=${parsed.absoluteURL || parsed.to}` 6327 } 6328 ); 6329 } 6330 } 6331 return children; 6332} 6333function RenderedRoute({ routeContext, match, children }) { 6334 let dataRouterContext = React2.useContext(DataRouterContext); 6335 if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) { 6336 dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id; 6337 } 6338 return React2.createElement(RouteContext.Provider, { value: routeContext }, children); 6339} 6340function _renderMatches(matches, parentMatches = [], dataRouterOpts) { 6341 let dataRouterState = dataRouterOpts?.state; 6342 if (matches == null) { 6343 if (!dataRouterState) { 6344 return null; 6345 } 6346 if (dataRouterState.errors) { 6347 matches = dataRouterState.matches; 6348 } else if (parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) { 6349 matches = dataRouterState.matches; 6350 } else { 6351 return null; 6352 } 6353 } 6354 let renderedMatches = matches; 6355 let errors = dataRouterState?.errors; 6356 if (errors != null) { 6357 let errorIndex = renderedMatches.findIndex( 6358 (m) => m.route.id && errors?.[m.route.id] !== void 0 6359 ); 6360 invariant( 6361 errorIndex >= 0, 6362 `Could not find a matching route for errors on route IDs: ${Object.keys( 6363 errors 6364 ).join(",")}` 6365 ); 6366 renderedMatches = renderedMatches.slice( 6367 0, 6368 Math.min(renderedMatches.length, errorIndex + 1) 6369 ); 6370 } 6371 let renderFallback = false; 6372 let fallbackIndex = -1; 6373 if (dataRouterOpts && dataRouterState) { 6374 renderFallback = dataRouterState.renderFallback; 6375 for (let i = 0; i < renderedMatches.length; i++) { 6376 let match = renderedMatches[i]; 6377 if (match.route.HydrateFallback || match.route.hydrateFallbackElement) { 6378 fallbackIndex = i; 6379 } 6380 if (match.route.id) { 6381 let { loaderData, errors: errors2 } = dataRouterState; 6382 let needsToRunLoader = match.route.loader && !loaderData.hasOwnProperty(match.route.id) && (!errors2 || errors2[match.route.id] === void 0); 6383 if (match.route.lazy || needsToRunLoader) { 6384 if (dataRouterOpts.isStatic) { 6385 renderFallback = true; 6386 } 6387 if (fallbackIndex >= 0) { 6388 renderedMatches = renderedMatches.slice(0, fallbackIndex + 1); 6389 } else { 6390 renderedMatches = [renderedMatches[0]]; 6391 } 6392 break; 6393 } 6394 } 6395 } 6396 } 6397 let onErrorHandler = dataRouterOpts?.onError; 6398 let onError = dataRouterState && onErrorHandler ? (error, errorInfo) => { 6399 onErrorHandler(error, { 6400 location: dataRouterState.location, 6401 params: dataRouterState.matches?.[0]?.params ?? {}, 6402 unstable_pattern: getRoutePattern(dataRouterState.matches), 6403 errorInfo 6404 }); 6405 } : void 0; 6406 return renderedMatches.reduceRight( 6407 (outlet, match, index) => { 6408 let error; 6409 let shouldRenderHydrateFallback = false; 6410 let errorElement = null; 6411 let hydrateFallbackElement = null; 6412 if (dataRouterState) { 6413 error = errors && match.route.id ? errors[match.route.id] : void 0; 6414 errorElement = match.route.errorElement || defaultErrorElement; 6415 if (renderFallback) { 6416 if (fallbackIndex < 0 && index === 0) { 6417 warningOnce( 6418 "route-fallback", 6419 false, 6420 "No `HydrateFallback` element provided to render during initial hydration" 6421 ); 6422 shouldRenderHydrateFallback = true; 6423 hydrateFallbackElement = null; 6424 } else if (fallbackIndex === index) { 6425 shouldRenderHydrateFallback = true; 6426 hydrateFallbackElement = match.route.hydrateFallbackElement || null; 6427 } 6428 } 6429 } 6430 let matches2 = parentMatches.concat(renderedMatches.slice(0, index + 1)); 6431 let getChildren = () => { 6432 let children; 6433 if (error) { 6434 children = errorElement; 6435 } else if (shouldRenderHydrateFallback) { 6436 children = hydrateFallbackElement; 6437 } else if (match.route.Component) { 6438 children = React2.createElement(match.route.Component, null); 6439 } else if (match.route.element) { 6440 children = match.route.element; 6441 } else { 6442 children = outlet; 6443 } 6444 return React2.createElement( 6445 RenderedRoute, 6446 { 6447 match, 6448 routeContext: { 6449 outlet, 6450 matches: matches2, 6451 isDataRoute: dataRouterState != null 6452 }, 6453 children 6454 } 6455 ); 6456 }; 6457 return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? React2.createElement( 6458 RenderErrorBoundary, 6459 { 6460 location: dataRouterState.location, 6461 revalidation: dataRouterState.revalidation, 6462 component: errorElement, 6463 error, 6464 children: getChildren(), 6465 routeContext: { outlet: null, matches: matches2, isDataRoute: true }, 6466 onError 6467 } 6468 ) : getChildren(); 6469 }, 6470 null 6471 ); 6472} 6473function getDataRouterConsoleError(hookName) { 6474 return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`; 6475} 6476function useDataRouterContext(hookName) { 6477 let ctx = React2.useContext(DataRouterContext); 6478 invariant(ctx, getDataRouterConsoleError(hookName)); 6479 return ctx; 6480} 6481function useDataRouterState(hookName) { 6482 let state = React2.useContext(DataRouterStateContext); 6483 invariant(state, getDataRouterConsoleError(hookName)); 6484 return state; 6485} 6486function useRouteContext(hookName) { 6487 let route = React2.useContext(RouteContext); 6488 invariant(route, getDataRouterConsoleError(hookName)); 6489 return route; 6490} 6491function useCurrentRouteId(hookName) { 6492 let route = useRouteContext(hookName); 6493 let thisRoute = route.matches[route.matches.length - 1]; 6494 invariant( 6495 thisRoute.route.id, 6496 `${hookName} can only be used on routes that contain a unique "id"` 6497 ); 6498 return thisRoute.route.id; 6499} 6500function useRouteId() { 6501 return useCurrentRouteId( 6502 "useRouteId" 6503 /* UseRouteId */ 6504 ); 6505} 6506function useNavigation() { 6507 let state = useDataRouterState( 6508 "useNavigation" 6509 /* UseNavigation */ 6510 ); 6511 return state.navigation; 6512} 6513function useRevalidator() { 6514 let dataRouterContext = useDataRouterContext( 6515 "useRevalidator" 6516 /* UseRevalidator */ 6517 ); 6518 let state = useDataRouterState( 6519 "useRevalidator" 6520 /* UseRevalidator */ 6521 ); 6522 let revalidate = React2.useCallback(async () => { 6523 await dataRouterContext.router.revalidate(); 6524 }, [dataRouterContext.router]); 6525 return React2.useMemo( 6526 () => ({ revalidate, state: state.revalidation }), 6527 [revalidate, state.revalidation] 6528 ); 6529} 6530function useMatches() { 6531 let { matches, loaderData } = useDataRouterState( 6532 "useMatches" 6533 /* UseMatches */ 6534 ); 6535 return React2.useMemo( 6536 () => matches.map((m) => convertRouteMatchToUiMatch(m, loaderData)), 6537 [matches, loaderData] 6538 ); 6539} 6540function useLoaderData() { 6541 let state = useDataRouterState( 6542 "useLoaderData" 6543 /* UseLoaderData */ 6544 ); 6545 let routeId = useCurrentRouteId( 6546 "useLoaderData" 6547 /* UseLoaderData */ 6548 ); 6549 return state.loaderData[routeId]; 6550} 6551function useRouteLoaderData(routeId) { 6552 let state = useDataRouterState( 6553 "useRouteLoaderData" 6554 /* UseRouteLoaderData */ 6555 ); 6556 return state.loaderData[routeId]; 6557} 6558function useActionData() { 6559 let state = useDataRouterState( 6560 "useActionData" 6561 /* UseActionData */ 6562 ); 6563 let routeId = useCurrentRouteId( 6564 "useLoaderData" 6565 /* UseLoaderData */ 6566 ); 6567 return state.actionData ? state.actionData[routeId] : void 0; 6568} 6569function useRouteError() { 6570 let error = React2.useContext(RouteErrorContext); 6571 let state = useDataRouterState( 6572 "useRouteError" 6573 /* UseRouteError */ 6574 ); 6575 let routeId = useCurrentRouteId( 6576 "useRouteError" 6577 /* UseRouteError */ 6578 ); 6579 if (error !== void 0) { 6580 return error; 6581 } 6582 return state.errors?.[routeId]; 6583} 6584function useAsyncValue() { 6585 let value = React2.useContext(AwaitContext); 6586 return value?._data; 6587} 6588function useAsyncError() { 6589 let value = React2.useContext(AwaitContext); 6590 return value?._error; 6591} 6592var blockerId = 0; 6593function useBlocker(shouldBlock) { 6594 let { router: router2, basename } = useDataRouterContext( 6595 "useBlocker" 6596 /* UseBlocker */ 6597 ); 6598 let state = useDataRouterState( 6599 "useBlocker" 6600 /* UseBlocker */ 6601 ); 6602 let [blockerKey, setBlockerKey] = React2.useState(""); 6603 let blockerFunction = React2.useCallback( 6604 (arg) => { 6605 if (typeof shouldBlock !== "function") { 6606 return !!shouldBlock; 6607 } 6608 if (basename === "/") { 6609 return shouldBlock(arg); 6610 } 6611 let { currentLocation, nextLocation, historyAction } = arg; 6612 return shouldBlock({ 6613 currentLocation: { 6614 ...currentLocation, 6615 pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname 6616 }, 6617 nextLocation: { 6618 ...nextLocation, 6619 pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname 6620 }, 6621 historyAction 6622 }); 6623 }, 6624 [basename, shouldBlock] 6625 ); 6626 React2.useEffect(() => { 6627 let key = String(++blockerId); 6628 setBlockerKey(key); 6629 return () => router2.deleteBlocker(key); 6630 }, [router2]); 6631 React2.useEffect(() => { 6632 if (blockerKey !== "") { 6633 router2.getBlocker(blockerKey, blockerFunction); 6634 } 6635 }, [router2, blockerKey, blockerFunction]); 6636 return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER; 6637} 6638function useNavigateStable() { 6639 let { router: router2 } = useDataRouterContext( 6640 "useNavigate" 6641 /* UseNavigateStable */ 6642 ); 6643 let id = useCurrentRouteId( 6644 "useNavigate" 6645 /* UseNavigateStable */ 6646 ); 6647 let activeRef = React2.useRef(false); 6648 useIsomorphicLayoutEffect(() => { 6649 activeRef.current = true; 6650 }); 6651 let navigate = React2.useCallback( 6652 async (to, options = {}) => { 6653 warning(activeRef.current, navigateEffectWarning); 6654 if (!activeRef.current) return; 6655 if (typeof to === "number") { 6656 await router2.navigate(to); 6657 } else { 6658 await router2.navigate(to, { fromRouteId: id, ...options }); 6659 } 6660 }, 6661 [router2, id] 6662 ); 6663 return navigate; 6664} 6665var alreadyWarned = {}; 6666function warningOnce(key, cond, message) { 6667 if (!cond && !alreadyWarned[key]) { 6668 alreadyWarned[key] = true; 6669 warning(false, message); 6670 } 6671} 6672function useRoute(...args) { 6673 const currentRouteId = useCurrentRouteId( 6674 "useRoute" 6675 /* UseRoute */ 6676 ); 6677 const id = args[0] ?? currentRouteId; 6678 const state = useDataRouterState( 6679 "useRoute" 6680 /* UseRoute */ 6681 ); 6682 const route = state.matches.find(({ route: route2 }) => route2.id === id); 6683 if (route === void 0) return void 0; 6684 return { 6685 handle: route.route.handle, 6686 loaderData: state.loaderData[id], 6687 actionData: state.actionData?.[id] 6688 }; 6689} 6690var alreadyWarned2 = {}; 6691function warnOnce(condition, message) { 6692 if (!condition && !alreadyWarned2[message]) { 6693 alreadyWarned2[message] = true; 6694 console.warn(message); 6695 } 6696} 6697var USE_OPTIMISTIC = "useOptimistic"; 6698var useOptimisticImpl = React3[USE_OPTIMISTIC]; 6699var stableUseOptimisticSetter = () => void 0; 6700function useOptimisticSafe(val) { 6701 if (useOptimisticImpl) { 6702 return useOptimisticImpl(val); 6703 } else { 6704 return [val, stableUseOptimisticSetter]; 6705 } 6706} 6707function mapRouteProperties(route) { 6708 let updates = { 6709 // Note: this check also occurs in createRoutesFromChildren so update 6710 // there if you change this -- please and thank you! 6711 hasErrorBoundary: route.hasErrorBoundary || route.ErrorBoundary != null || route.errorElement != null 6712 }; 6713 if (route.Component) { 6714 if (ENABLE_DEV_WARNINGS) { 6715 if (route.element) { 6716 warning( 6717 false, 6718 "You should not include both `Component` and `element` on your route - `Component` will be used." 6719 ); 6720 } 6721 } 6722 Object.assign(updates, { 6723 element: React3.createElement(route.Component), 6724 Component: void 0 6725 }); 6726 } 6727 if (route.HydrateFallback) { 6728 if (ENABLE_DEV_WARNINGS) { 6729 if (route.hydrateFallbackElement) { 6730 warning( 6731 false, 6732 "You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used." 6733 ); 6734 } 6735 } 6736 Object.assign(updates, { 6737 hydrateFallbackElement: React3.createElement(route.HydrateFallback), 6738 HydrateFallback: void 0 6739 }); 6740 } 6741 if (route.ErrorBoundary) { 6742 if (ENABLE_DEV_WARNINGS) { 6743 if (route.errorElement) { 6744 warning( 6745 false, 6746 "You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used." 6747 ); 6748 } 6749 } 6750 Object.assign(updates, { 6751 errorElement: React3.createElement(route.ErrorBoundary), 6752 ErrorBoundary: void 0 6753 }); 6754 } 6755 return updates; 6756} 6757var hydrationRouteProperties = [ 6758 "HydrateFallback", 6759 "hydrateFallbackElement" 6760]; 6761function createMemoryRouter(routes, opts) { 6762 return createRouter({ 6763 basename: opts?.basename, 6764 getContext: opts?.getContext, 6765 future: opts?.future, 6766 history: createMemoryHistory({ 6767 initialEntries: opts?.initialEntries, 6768 initialIndex: opts?.initialIndex 6769 }), 6770 hydrationData: opts?.hydrationData, 6771 routes, 6772 hydrationRouteProperties, 6773 mapRouteProperties, 6774 dataStrategy: opts?.dataStrategy, 6775 patchRoutesOnNavigation: opts?.patchRoutesOnNavigation, 6776 unstable_instrumentations: opts?.unstable_instrumentations 6777 }).initialize(); 6778} 6779var Deferred = class { 6780 constructor() { 6781 this.status = "pending"; 6782 this.promise = new Promise((resolve, reject) => { 6783 this.resolve = (value) => { 6784 if (this.status === "pending") { 6785 this.status = "resolved"; 6786 resolve(value); 6787 } 6788 }; 6789 this.reject = (reason) => { 6790 if (this.status === "pending") { 6791 this.status = "rejected"; 6792 reject(reason); 6793 } 6794 }; 6795 }); 6796 } 6797}; 6798function RouterProvider({ 6799 router: router2, 6800 flushSync: reactDomFlushSyncImpl, 6801 onError, 6802 unstable_useTransitions 6803}) { 6804 let unstable_rsc = useIsRSCRouterContext(); 6805 unstable_useTransitions = unstable_rsc || unstable_useTransitions; 6806 let [_state, setStateImpl] = React3.useState(router2.state); 6807 let [state, setOptimisticState] = useOptimisticSafe(_state); 6808 let [pendingState, setPendingState] = React3.useState(); 6809 let [vtContext, setVtContext] = React3.useState({ 6810 isTransitioning: false 6811 }); 6812 let [renderDfd, setRenderDfd] = React3.useState(); 6813 let [transition, setTransition] = React3.useState(); 6814 let [interruption, setInterruption] = React3.useState(); 6815 let fetcherData = React3.useRef(/* @__PURE__ */ new Map()); 6816 let setState = React3.useCallback( 6817 (newState, { deletedFetchers, newErrors, flushSync: flushSync3, viewTransitionOpts }) => { 6818 if (newErrors && onError) { 6819 Object.values(newErrors).forEach( 6820 (error) => onError(error, { 6821 location: newState.location, 6822 params: newState.matches[0]?.params ?? {}, 6823 unstable_pattern: getRoutePattern(newState.matches) 6824 }) 6825 ); 6826 } 6827 newState.fetchers.forEach((fetcher, key) => { 6828 if (fetcher.data !== void 0) { 6829 fetcherData.current.set(key, fetcher.data); 6830 } 6831 }); 6832 deletedFetchers.forEach((key) => fetcherData.current.delete(key)); 6833 warnOnce( 6834 flushSync3 === false || reactDomFlushSyncImpl != null, 6835 '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.' 6836 ); 6837 let isViewTransitionAvailable = router2.window != null && router2.window.document != null && typeof router2.window.document.startViewTransition === "function"; 6838 warnOnce( 6839 viewTransitionOpts == null || isViewTransitionAvailable, 6840 "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." 6841 ); 6842 if (!viewTransitionOpts || !isViewTransitionAvailable) { 6843 if (reactDomFlushSyncImpl && flushSync3) { 6844 reactDomFlushSyncImpl(() => setStateImpl(newState)); 6845 } else if (unstable_useTransitions === false) { 6846 setStateImpl(newState); 6847 } else { 6848 React3.startTransition(() => { 6849 if (unstable_useTransitions === true) { 6850 setOptimisticState((s) => getOptimisticRouterState(s, newState)); 6851 } 6852 setStateImpl(newState); 6853 }); 6854 } 6855 return; 6856 } 6857 if (reactDomFlushSyncImpl && flushSync3) { 6858 reactDomFlushSyncImpl(() => { 6859 if (transition) { 6860 renderDfd?.resolve(); 6861 transition.skipTransition(); 6862 } 6863 setVtContext({ 6864 isTransitioning: true, 6865 flushSync: true, 6866 currentLocation: viewTransitionOpts.currentLocation, 6867 nextLocation: viewTransitionOpts.nextLocation 6868 }); 6869 }); 6870 let t = router2.window.document.startViewTransition(() => { 6871 reactDomFlushSyncImpl(() => setStateImpl(newState)); 6872 }); 6873 t.finished.finally(() => { 6874 reactDomFlushSyncImpl(() => { 6875 setRenderDfd(void 0); 6876 setTransition(void 0); 6877 setPendingState(void 0); 6878 setVtContext({ isTransitioning: false }); 6879 }); 6880 }); 6881 reactDomFlushSyncImpl(() => setTransition(t)); 6882 return; 6883 } 6884 if (transition) { 6885 renderDfd?.resolve(); 6886 transition.skipTransition(); 6887 setInterruption({ 6888 state: newState, 6889 currentLocation: viewTransitionOpts.currentLocation, 6890 nextLocation: viewTransitionOpts.nextLocation 6891 }); 6892 } else { 6893 setPendingState(newState); 6894 setVtContext({ 6895 isTransitioning: true, 6896 flushSync: false, 6897 currentLocation: viewTransitionOpts.currentLocation, 6898 nextLocation: viewTransitionOpts.nextLocation 6899 }); 6900 } 6901 }, 6902 [ 6903 router2.window, 6904 reactDomFlushSyncImpl, 6905 transition, 6906 renderDfd, 6907 unstable_useTransitions, 6908 setOptimisticState, 6909 onError 6910 ] 6911 ); 6912 React3.useLayoutEffect(() => router2.subscribe(setState), [router2, setState]); 6913 React3.useEffect(() => { 6914 if (vtContext.isTransitioning && !vtContext.flushSync) { 6915 setRenderDfd(new Deferred()); 6916 } 6917 }, [vtContext]); 6918 React3.useEffect(() => { 6919 if (renderDfd && pendingState && router2.window) { 6920 let newState = pendingState; 6921 let renderPromise = renderDfd.promise; 6922 let transition2 = router2.window.document.startViewTransition(async () => { 6923 if (unstable_useTransitions === false) { 6924 setStateImpl(newState); 6925 } else { 6926 React3.startTransition(() => { 6927 if (unstable_useTransitions === true) { 6928 setOptimisticState((s) => getOptimisticRouterState(s, newState)); 6929 } 6930 setStateImpl(newState); 6931 }); 6932 } 6933 await renderPromise; 6934 }); 6935 transition2.finished.finally(() => { 6936 setRenderDfd(void 0); 6937 setTransition(void 0); 6938 setPendingState(void 0); 6939 setVtContext({ isTransitioning: false }); 6940 }); 6941 setTransition(transition2); 6942 } 6943 }, [ 6944 pendingState, 6945 renderDfd, 6946 router2.window, 6947 unstable_useTransitions, 6948 setOptimisticState 6949 ]); 6950 React3.useEffect(() => { 6951 if (renderDfd && pendingState && state.location.key === pendingState.location.key) { 6952 renderDfd.resolve(); 6953 } 6954 }, [renderDfd, transition, state.location, pendingState]); 6955 React3.useEffect(() => { 6956 if (!vtContext.isTransitioning && interruption) { 6957 setPendingState(interruption.state); 6958 setVtContext({ 6959 isTransitioning: true, 6960 flushSync: false, 6961 currentLocation: interruption.currentLocation, 6962 nextLocation: interruption.nextLocation 6963 }); 6964 setInterruption(void 0); 6965 } 6966 }, [vtContext.isTransitioning, interruption]); 6967 let navigator = React3.useMemo(() => { 6968 return { 6969 createHref: router2.createHref, 6970 encodeLocation: router2.encodeLocation, 6971 go: (n) => router2.navigate(n), 6972 push: (to, state2, opts) => router2.navigate(to, { 6973 state: state2, 6974 preventScrollReset: opts?.preventScrollReset 6975 }), 6976 replace: (to, state2, opts) => router2.navigate(to, { 6977 replace: true, 6978 state: state2, 6979 preventScrollReset: opts?.preventScrollReset 6980 }) 6981 }; 6982 }, [router2]); 6983 let basename = router2.basename || "/"; 6984 let dataRouterContext = React3.useMemo( 6985 () => ({ 6986 router: router2, 6987 navigator, 6988 static: false, 6989 basename, 6990 onError 6991 }), 6992 [router2, navigator, basename, onError] 6993 ); 6994 return React3.createElement(React3.Fragment, null, React3.createElement(DataRouterContext.Provider, { value: dataRouterContext }, React3.createElement(DataRouterStateContext.Provider, { value: state }, React3.createElement(FetchersContext.Provider, { value: fetcherData.current }, React3.createElement(ViewTransitionContext.Provider, { value: vtContext }, React3.createElement( 6995 Router, 6996 { 6997 basename, 6998 location: state.location, 6999 navigationType: state.historyAction, 7000 navigator, 7001 unstable_useTransitions 7002 }, 7003 React3.createElement( 7004 MemoizedDataRoutes, 7005 { 7006 routes: router2.routes, 7007 future: router2.future, 7008 state, 7009 isStatic: false, 7010 onError 7011 } 7012 ) 7013 ))))), null); 7014} 7015function getOptimisticRouterState(currentState, newState) { 7016 return { 7017 // Don't surface "current location specific" stuff mid-navigation 7018 // (historyAction, location, matches, loaderData, errors, initialized, 7019 // restoreScroll, preventScrollReset, blockers, etc.) 7020 ...currentState, 7021 // Only surface "pending/in-flight stuff" 7022 // (navigation, revalidation, actionData, fetchers, ) 7023 navigation: newState.navigation.state !== "idle" ? newState.navigation : currentState.navigation, 7024 revalidation: newState.revalidation !== "idle" ? newState.revalidation : currentState.revalidation, 7025 actionData: newState.navigation.state !== "submitting" ? newState.actionData : currentState.actionData, 7026 fetchers: newState.fetchers 7027 }; 7028} 7029var MemoizedDataRoutes = React3.memo(DataRoutes); 7030function DataRoutes({ 7031 routes, 7032 future, 7033 state, 7034 isStatic, 7035 onError 7036}) { 7037 return useRoutesImpl(routes, void 0, { state, isStatic, onError, future }); 7038} 7039function MemoryRouter({ 7040 basename, 7041 children, 7042 initialEntries, 7043 initialIndex, 7044 unstable_useTransitions 7045}) { 7046 let historyRef = React3.useRef(); 7047 if (historyRef.current == null) { 7048 historyRef.current = createMemoryHistory({ 7049 initialEntries, 7050 initialIndex, 7051 v5Compat: true 7052 }); 7053 } 7054 let history = historyRef.current; 7055 let [state, setStateImpl] = React3.useState({ 7056 action: history.action, 7057 location: history.location 7058 }); 7059 let setState = React3.useCallback( 7060 (newState) => { 7061 if (unstable_useTransitions === false) { 7062 setStateImpl(newState); 7063 } else { 7064 React3.startTransition(() => setStateImpl(newState)); 7065 } 7066 }, 7067 [unstable_useTransitions] 7068 ); 7069 React3.useLayoutEffect(() => history.listen(setState), [history, setState]); 7070 return React3.createElement( 7071 Router, 7072 { 7073 basename, 7074 children, 7075 location: state.location, 7076 navigationType: state.action, 7077 navigator: history, 7078 unstable_useTransitions 7079 } 7080 ); 7081} 7082function Navigate({ 7083 to, 7084 replace: replace2, 7085 state, 7086 relative 7087}) { 7088 invariant( 7089 useInRouterContext(), 7090 // TODO: This error is probably because they somehow have 2 versions of 7091 // the router loaded. We can help them understand how to avoid that. 7092 `<Navigate> may be used only in the context of a <Router> component.` 7093 ); 7094 let { static: isStatic } = React3.useContext(NavigationContext); 7095 warning( 7096 !isStatic, 7097 `<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.` 7098 ); 7099 let { matches } = React3.useContext(RouteContext); 7100 let { pathname: locationPathname } = useLocation(); 7101 let navigate = useNavigate(); 7102 let path = resolveTo( 7103 to, 7104 getResolveToMatches(matches), 7105 locationPathname, 7106 relative === "path" 7107 ); 7108 let jsonPath = JSON.stringify(path); 7109 React3.useEffect(() => { 7110 navigate(JSON.parse(jsonPath), { replace: replace2, state, relative }); 7111 }, [navigate, jsonPath, relative, replace2, state]); 7112 return null; 7113} 7114function Outlet(props) { 7115 return useOutlet(props.context); 7116} 7117function Route(props) { 7118 invariant( 7119 false, 7120 `A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.` 7121 ); 7122} 7123function Router({ 7124 basename: basenameProp = "/", 7125 children = null, 7126 location: locationProp, 7127 navigationType = "POP", 7128 navigator, 7129 static: staticProp = false, 7130 unstable_useTransitions 7131}) { 7132 invariant( 7133 !useInRouterContext(), 7134 `You cannot render a <Router> inside another <Router>. You should never have more than one in your app.` 7135 ); 7136 let basename = basenameProp.replace(/^\/*/, "/"); 7137 let navigationContext = React3.useMemo( 7138 () => ({ 7139 basename, 7140 navigator, 7141 static: staticProp, 7142 unstable_useTransitions, 7143 future: {} 7144 }), 7145 [basename, navigator, staticProp, unstable_useTransitions] 7146 ); 7147 if (typeof locationProp === "string") { 7148 locationProp = parsePath(locationProp); 7149 } 7150 let { 7151 pathname = "/", 7152 search = "", 7153 hash = "", 7154 state = null, 7155 key = "default", 7156 unstable_mask 7157 } = locationProp; 7158 let locationContext = React3.useMemo(() => { 7159 let trailingPathname = stripBasename(pathname, basename); 7160 if (trailingPathname == null) { 7161 return null; 7162 } 7163 return { 7164 location: { 7165 pathname: trailingPathname, 7166 search, 7167 hash, 7168 state, 7169 key, 7170 unstable_mask 7171 }, 7172 navigationType 7173 }; 7174 }, [ 7175 basename, 7176 pathname, 7177 search, 7178 hash, 7179 state, 7180 key, 7181 navigationType, 7182 unstable_mask 7183 ]); 7184 warning( 7185 locationContext != null, 7186 `<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.` 7187 ); 7188 if (locationContext == null) { 7189 return null; 7190 } 7191 return React3.createElement(NavigationContext.Provider, { value: navigationContext }, React3.createElement(LocationContext.Provider, { children, value: locationContext })); 7192} 7193function Routes({ 7194 children, 7195 location: location2 7196}) { 7197 return useRoutes(createRoutesFromChildren(children), location2); 7198} 7199function Await({ 7200 children, 7201 errorElement, 7202 resolve 7203}) { 7204 let dataRouterContext = React3.useContext(DataRouterContext); 7205 let dataRouterStateContext = React3.useContext(DataRouterStateContext); 7206 let onError = React3.useCallback( 7207 (error, errorInfo) => { 7208 if (dataRouterContext && dataRouterContext.onError && dataRouterStateContext) { 7209 dataRouterContext.onError(error, { 7210 location: dataRouterStateContext.location, 7211 params: dataRouterStateContext.matches[0]?.params || {}, 7212 unstable_pattern: getRoutePattern(dataRouterStateContext.matches), 7213 errorInfo 7214 }); 7215 } 7216 }, 7217 [dataRouterContext, dataRouterStateContext] 7218 ); 7219 return React3.createElement( 7220 AwaitErrorBoundary, 7221 { 7222 resolve, 7223 errorElement, 7224 onError 7225 }, 7226 React3.createElement(ResolveAwait, null, children) 7227 ); 7228} 7229var AwaitErrorBoundary = class extends React3.Component { 7230 constructor(props) { 7231 super(props); 7232 this.state = { error: null }; 7233 } 7234 static getDerivedStateFromError(error) { 7235 return { error }; 7236 } 7237 componentDidCatch(error, errorInfo) { 7238 if (this.props.onError) { 7239 this.props.onError(error, errorInfo); 7240 } else { 7241 console.error( 7242 "<Await> caught the following error during render", 7243 error, 7244 errorInfo 7245 ); 7246 } 7247 } 7248 render() { 7249 let { children, errorElement, resolve } = this.props; 7250 let promise = null; 7251 let status = 0; 7252 if (!(resolve instanceof Promise)) { 7253 status = 1; 7254 promise = Promise.resolve(); 7255 Object.defineProperty(promise, "_tracked", { get: () => true }); 7256 Object.defineProperty(promise, "_data", { get: () => resolve }); 7257 } else if (this.state.error) { 7258 status = 2; 7259 let renderError = this.state.error; 7260 promise = Promise.reject().catch(() => { 7261 }); 7262 Object.defineProperty(promise, "_tracked", { get: () => true }); 7263 Object.defineProperty(promise, "_error", { get: () => renderError }); 7264 } else if (resolve._tracked) { 7265 promise = resolve; 7266 status = "_error" in promise ? 2 : "_data" in promise ? 1 : 0; 7267 } else { 7268 status = 0; 7269 Object.defineProperty(resolve, "_tracked", { get: () => true }); 7270 promise = resolve.then( 7271 (data2) => Object.defineProperty(resolve, "_data", { get: () => data2 }), 7272 (error) => { 7273 this.props.onError?.(error); 7274 Object.defineProperty(resolve, "_error", { get: () => error }); 7275 } 7276 ); 7277 } 7278 if (status === 2 && !errorElement) { 7279 throw promise._error; 7280 } 7281 if (status === 2) { 7282 return React3.createElement(AwaitContext.Provider, { value: promise, children: errorElement }); 7283 } 7284 if (status === 1) { 7285 return React3.createElement(AwaitContext.Provider, { value: promise, children }); 7286 } 7287 throw promise; 7288 } 7289}; 7290function ResolveAwait({ 7291 children 7292}) { 7293 let data2 = useAsyncValue(); 7294 let toRender = typeof children === "function" ? children(data2) : children; 7295 return React3.createElement(React3.Fragment, null, toRender); 7296} 7297function createRoutesFromChildren(children, parentPath = []) { 7298 let routes = []; 7299 React3.Children.forEach(children, (element, index) => { 7300 if (!React3.isValidElement(element)) { 7301 return; 7302 } 7303 let treePath = [...parentPath, index]; 7304 if (element.type === React3.Fragment) { 7305 routes.push.apply( 7306 routes, 7307 createRoutesFromChildren(element.props.children, treePath) 7308 ); 7309 return; 7310 } 7311 invariant( 7312 element.type === Route, 7313 `[${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>` 7314 ); 7315 invariant( 7316 !element.props.index || !element.props.children, 7317 "An index route cannot have child routes." 7318 ); 7319 let route = { 7320 id: element.props.id || treePath.join("-"), 7321 caseSensitive: element.props.caseSensitive, 7322 element: element.props.element, 7323 Component: element.props.Component, 7324 index: element.props.index, 7325 path: element.props.path, 7326 middleware: element.props.middleware, 7327 loader: element.props.loader, 7328 action: element.props.action, 7329 hydrateFallbackElement: element.props.hydrateFallbackElement, 7330 HydrateFallback: element.props.HydrateFallback, 7331 errorElement: element.props.errorElement, 7332 ErrorBoundary: element.props.ErrorBoundary, 7333 hasErrorBoundary: element.props.hasErrorBoundary === true || element.props.ErrorBoundary != null || element.props.errorElement != null, 7334 shouldRevalidate: element.props.shouldRevalidate, 7335 handle: element.props.handle, 7336 lazy: element.props.lazy 7337 }; 7338 if (element.props.children) { 7339 route.children = createRoutesFromChildren( 7340 element.props.children, 7341 treePath 7342 ); 7343 } 7344 routes.push(route); 7345 }); 7346 return routes; 7347} 7348var createRoutesFromElements = createRoutesFromChildren; 7349function renderMatches(matches) { 7350 return _renderMatches(matches); 7351} 7352function useRouteComponentProps() { 7353 return { 7354 params: useParams(), 7355 loaderData: useLoaderData(), 7356 actionData: useActionData(), 7357 matches: useMatches() 7358 }; 7359} 7360function WithComponentProps({ 7361 children 7362}) { 7363 const props = useRouteComponentProps(); 7364 return React3.cloneElement(children, props); 7365} 7366function withComponentProps(Component4) { 7367 return function WithComponentProps2() { 7368 const props = useRouteComponentProps(); 7369 return React3.createElement(Component4, props); 7370 }; 7371} 7372function useHydrateFallbackProps() { 7373 return { 7374 params: useParams(), 7375 loaderData: useLoaderData(), 7376 actionData: useActionData() 7377 }; 7378} 7379function WithHydrateFallbackProps({ 7380 children 7381}) { 7382 const props = useHydrateFallbackProps(); 7383 return React3.cloneElement(children, props); 7384} 7385function withHydrateFallbackProps(HydrateFallback) { 7386 return function WithHydrateFallbackProps2() { 7387 const props = useHydrateFallbackProps(); 7388 return React3.createElement(HydrateFallback, props); 7389 }; 7390} 7391function useErrorBoundaryProps() { 7392 return { 7393 params: useParams(), 7394 loaderData: useLoaderData(), 7395 actionData: useActionData(), 7396 error: useRouteError() 7397 }; 7398} 7399function WithErrorBoundaryProps({ 7400 children 7401}) { 7402 const props = useErrorBoundaryProps(); 7403 return React3.cloneElement(children, props); 7404} 7405function withErrorBoundaryProps(ErrorBoundary) { 7406 return function WithErrorBoundaryProps2() { 7407 const props = useErrorBoundaryProps(); 7408 return React3.createElement(ErrorBoundary, props); 7409 }; 7410} 7411var defaultMethod = "get"; 7412var defaultEncType = "application/x-www-form-urlencoded"; 7413function isHtmlElement(object) { 7414 return typeof HTMLElement !== "undefined" && object instanceof HTMLElement; 7415} 7416function isButtonElement(object) { 7417 return isHtmlElement(object) && object.tagName.toLowerCase() === "button"; 7418} 7419function isFormElement(object) { 7420 return isHtmlElement(object) && object.tagName.toLowerCase() === "form"; 7421} 7422function isInputElement(object) { 7423 return isHtmlElement(object) && object.tagName.toLowerCase() === "input"; 7424} 7425function isModifiedEvent(event) { 7426 return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); 7427} 7428function shouldProcessLinkClick(event, target) { 7429 return event.button === 0 && // Ignore everything but left clicks 7430 (!target || target === "_self") && // Let browser handle "target=_blank" etc. 7431 !isModifiedEvent(event); 7432} 7433function createSearchParams(init = "") { 7434 return new URLSearchParams( 7435 typeof init === "string" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo2, key) => { 7436 let value = init[key]; 7437 return memo2.concat( 7438 Array.isArray(value) ? value.map((v) => [key, v]) : [[key, value]] 7439 ); 7440 }, []) 7441 ); 7442} 7443function getSearchParamsForLocation(locationSearch, defaultSearchParams) { 7444 let searchParams = createSearchParams(locationSearch); 7445 if (defaultSearchParams) { 7446 defaultSearchParams.forEach((_, key) => { 7447 if (!searchParams.has(key)) { 7448 defaultSearchParams.getAll(key).forEach((value) => { 7449 searchParams.append(key, value); 7450 }); 7451 } 7452 }); 7453 } 7454 return searchParams; 7455} 7456var _formDataSupportsSubmitter = null; 7457function isFormDataSubmitterSupported() { 7458 if (_formDataSupportsSubmitter === null) { 7459 try { 7460 new FormData( 7461 document.createElement("form"), 7462 // @ts-expect-error if FormData supports the submitter parameter, this will throw 7463 0 7464 ); 7465 _formDataSupportsSubmitter = false; 7466 } catch (e) { 7467 _formDataSupportsSubmitter = true; 7468 } 7469 } 7470 return _formDataSupportsSubmitter; 7471} 7472var supportedFormEncTypes = /* @__PURE__ */ new Set([ 7473 "application/x-www-form-urlencoded", 7474 "multipart/form-data", 7475 "text/plain" 7476]); 7477function getFormEncType(encType) { 7478 if (encType != null && !supportedFormEncTypes.has(encType)) { 7479 warning( 7480 false, 7481 `"${encType}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${defaultEncType}"` 7482 ); 7483 return null; 7484 } 7485 return encType; 7486} 7487function getFormSubmissionInfo(target, basename) { 7488 let method; 7489 let action; 7490 let encType; 7491 let formData; 7492 let body; 7493 if (isFormElement(target)) { 7494 let attr = target.getAttribute("action"); 7495 action = attr ? stripBasename(attr, basename) : null; 7496 method = target.getAttribute("method") || defaultMethod; 7497 encType = getFormEncType(target.getAttribute("enctype")) || defaultEncType; 7498 formData = new FormData(target); 7499 } else if (isButtonElement(target) || isInputElement(target) && (target.type === "submit" || target.type === "image")) { 7500 let form = target.form; 7501 if (form == null) { 7502 throw new Error( 7503 `Cannot submit a <button> or <input type="submit"> without a <form>` 7504 ); 7505 } 7506 let attr = target.getAttribute("formaction") || form.getAttribute("action"); 7507 action = attr ? stripBasename(attr, basename) : null; 7508 method = target.getAttribute("formmethod") || form.getAttribute("method") || defaultMethod; 7509 encType = getFormEncType(target.getAttribute("formenctype")) || getFormEncType(form.getAttribute("enctype")) || defaultEncType; 7510 formData = new FormData(form, target); 7511 if (!isFormDataSubmitterSupported()) { 7512 let { name, type, value } = target; 7513 if (type === "image") { 7514 let prefix = name ? `${name}.` : ""; 7515 formData.append(`${prefix}x`, "0"); 7516 formData.append(`${prefix}y`, "0"); 7517 } else if (name) { 7518 formData.append(name, value); 7519 } 7520 } 7521 } else if (isHtmlElement(target)) { 7522 throw new Error( 7523 `Cannot submit element that is not <form>, <button>, or <input type="submit|image">` 7524 ); 7525 } else { 7526 method = defaultMethod; 7527 action = null; 7528 encType = defaultEncType; 7529 body = target; 7530 } 7531 if (formData && encType === "text/plain") { 7532 body = formData; 7533 formData = void 0; 7534 } 7535 return { action, method: method.toLowerCase(), encType, formData, body }; 7536} 7537var HOLE = -1; 7538var NAN = -2; 7539var NEGATIVE_INFINITY = -3; 7540var NEGATIVE_ZERO = -4; 7541var NULL = -5; 7542var POSITIVE_INFINITY = -6; 7543var UNDEFINED = -7; 7544var TYPE_BIGINT = "B"; 7545var TYPE_DATE = "D"; 7546var TYPE_ERROR = "E"; 7547var TYPE_MAP = "M"; 7548var TYPE_NULL_OBJECT = "N"; 7549var TYPE_PROMISE = "P"; 7550var TYPE_REGEXP = "R"; 7551var TYPE_SET = "S"; 7552var TYPE_SYMBOL = "Y"; 7553var TYPE_URL = "U"; 7554var TYPE_PREVIOUS_RESOLVED = "Z"; 7555var Deferred2 = class { 7556 constructor() { 7557 this.promise = new Promise((resolve, reject) => { 7558 this.resolve = resolve; 7559 this.reject = reject; 7560 }); 7561 } 7562}; 7563function createLineSplittingTransform() { 7564 const decoder = new TextDecoder(); 7565 let leftover = ""; 7566 return new TransformStream({ 7567 transform(chunk, controller) { 7568 const str = decoder.decode(chunk, { stream: true }); 7569 const parts = (leftover + str).split("\n"); 7570 leftover = parts.pop() || ""; 7571 for (const part of parts) { 7572 controller.enqueue(part); 7573 } 7574 }, 7575 flush(controller) { 7576 if (leftover) { 7577 controller.enqueue(leftover); 7578 } 7579 } 7580 }); 7581} 7582function flatten(input) { 7583 const { indices } = this; 7584 const existing = indices.get(input); 7585 if (existing) return [existing]; 7586 if (input === void 0) return UNDEFINED; 7587 if (input === null) return NULL; 7588 if (Number.isNaN(input)) return NAN; 7589 if (input === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY; 7590 if (input === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY; 7591 if (input === 0 && 1 / input < 0) return NEGATIVE_ZERO; 7592 const index = this.index++; 7593 indices.set(input, index); 7594 stringify.call(this, input, index); 7595 return index; 7596} 7597function stringify(input, index) { 7598 const { deferred, plugins, postPlugins } = this; 7599 const str = this.stringified; 7600 const stack = [[input, index]]; 7601 while (stack.length > 0) { 7602 const [input2, index2] = stack.pop(); 7603 const partsForObj = (obj) => Object.keys(obj).map((k) => `"_${flatten.call(this, k)}":${flatten.call(this, obj[k])}`).join(","); 7604 let error = null; 7605 switch (typeof input2) { 7606 case "boolean": 7607 case "number": 7608 case "string": 7609 str[index2] = JSON.stringify(input2); 7610 break; 7611 case "bigint": 7612 str[index2] = `["${TYPE_BIGINT}","${input2}"]`; 7613 break; 7614 case "symbol": { 7615 const keyFor = Symbol.keyFor(input2); 7616 if (!keyFor) { 7617 error = new Error( 7618 "Cannot encode symbol unless created with Symbol.for()" 7619 ); 7620 } else { 7621 str[index2] = `["${TYPE_SYMBOL}",${JSON.stringify(keyFor)}]`; 7622 } 7623 break; 7624 } 7625 case "object": { 7626 if (!input2) { 7627 str[index2] = `${NULL}`; 7628 break; 7629 } 7630 const isArray = Array.isArray(input2); 7631 let pluginHandled = false; 7632 if (!isArray && plugins) { 7633 for (const plugin of plugins) { 7634 const pluginResult = plugin(input2); 7635 if (Array.isArray(pluginResult)) { 7636 pluginHandled = true; 7637 const [pluginIdentifier, ...rest] = pluginResult; 7638 str[index2] = `[${JSON.stringify(pluginIdentifier)}`; 7639 if (rest.length > 0) { 7640 str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(",")}`; 7641 } 7642 str[index2] += "]"; 7643 break; 7644 } 7645 } 7646 } 7647 if (!pluginHandled) { 7648 let result = isArray ? "[" : "{"; 7649 if (isArray) { 7650 for (let i = 0; i < input2.length; i++) 7651 result += (i ? "," : "") + (i in input2 ? flatten.call(this, input2[i]) : HOLE); 7652 str[index2] = `${result}]`; 7653 } else if (input2 instanceof Date) { 7654 const dateTime = input2.getTime(); 7655 str[index2] = `["${TYPE_DATE}",${Number.isNaN(dateTime) ? JSON.stringify("invalid") : dateTime}]`; 7656 } else if (input2 instanceof URL) { 7657 str[index2] = `["${TYPE_URL}",${JSON.stringify(input2.href)}]`; 7658 } else if (input2 instanceof RegExp) { 7659 str[index2] = `["${TYPE_REGEXP}",${JSON.stringify( 7660 input2.source 7661 )},${JSON.stringify(input2.flags)}]`; 7662 } else if (input2 instanceof Set) { 7663 if (input2.size > 0) { 7664 str[index2] = `["${TYPE_SET}",${[...input2].map((val) => flatten.call(this, val)).join(",")}]`; 7665 } else { 7666 str[index2] = `["${TYPE_SET}"]`; 7667 } 7668 } else if (input2 instanceof Map) { 7669 if (input2.size > 0) { 7670 str[index2] = `["${TYPE_MAP}",${[...input2].flatMap(([k, v]) => [ 7671 flatten.call(this, k), 7672 flatten.call(this, v) 7673 ]).join(",")}]`; 7674 } else { 7675 str[index2] = `["${TYPE_MAP}"]`; 7676 } 7677 } else if (input2 instanceof Promise) { 7678 str[index2] = `["${TYPE_PROMISE}",${index2}]`; 7679 deferred[index2] = input2; 7680 } else if (input2 instanceof Error) { 7681 str[index2] = `["${TYPE_ERROR}",${JSON.stringify(input2.message)}`; 7682 if (input2.name !== "Error") { 7683 str[index2] += `,${JSON.stringify(input2.name)}`; 7684 } 7685 str[index2] += "]"; 7686 } else if (Object.getPrototypeOf(input2) === null) { 7687 str[index2] = `["${TYPE_NULL_OBJECT}",{${partsForObj(input2)}}]`; 7688 } else if (isPlainObject2(input2)) { 7689 str[index2] = `{${partsForObj(input2)}}`; 7690 } else { 7691 error = new Error("Cannot encode object with prototype"); 7692 } 7693 } 7694 break; 7695 } 7696 default: { 7697 const isArray = Array.isArray(input2); 7698 let pluginHandled = false; 7699 if (!isArray && plugins) { 7700 for (const plugin of plugins) { 7701 const pluginResult = plugin(input2); 7702 if (Array.isArray(pluginResult)) { 7703 pluginHandled = true; 7704 const [pluginIdentifier, ...rest] = pluginResult; 7705 str[index2] = `[${JSON.stringify(pluginIdentifier)}`; 7706 if (rest.length > 0) { 7707 str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(",")}`; 7708 } 7709 str[index2] += "]"; 7710 break; 7711 } 7712 } 7713 } 7714 if (!pluginHandled) { 7715 error = new Error("Cannot encode function or unexpected type"); 7716 } 7717 } 7718 } 7719 if (error) { 7720 let pluginHandled = false; 7721 if (postPlugins) { 7722 for (const plugin of postPlugins) { 7723 const pluginResult = plugin(input2); 7724 if (Array.isArray(pluginResult)) { 7725 pluginHandled = true; 7726 const [pluginIdentifier, ...rest] = pluginResult; 7727 str[index2] = `[${JSON.stringify(pluginIdentifier)}`; 7728 if (rest.length > 0) { 7729 str[index2] += `,${rest.map((v) => flatten.call(this, v)).join(",")}`; 7730 } 7731 str[index2] += "]"; 7732 break; 7733 } 7734 } 7735 } 7736 if (!pluginHandled) { 7737 throw error; 7738 } 7739 } 7740 } 7741} 7742var objectProtoNames2 = Object.getOwnPropertyNames(Object.prototype).sort().join("\0"); 7743function isPlainObject2(thing) { 7744 const proto = Object.getPrototypeOf(thing); 7745 return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames2; 7746} 7747var globalObj = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : void 0; 7748function unflatten(parsed) { 7749 const { hydrated, values } = this; 7750 if (typeof parsed === "number") return hydrate.call(this, parsed); 7751 if (!Array.isArray(parsed) || !parsed.length) throw new SyntaxError(); 7752 const startIndex = values.length; 7753 for (const value of parsed) { 7754 values.push(value); 7755 } 7756 hydrated.length = values.length; 7757 return hydrate.call(this, startIndex); 7758} 7759function hydrate(index) { 7760 const { hydrated, values, deferred, plugins } = this; 7761 let result; 7762 const stack = [ 7763 [ 7764 index, 7765 (v) => { 7766 result = v; 7767 } 7768 ] 7769 ]; 7770 let postRun = []; 7771 while (stack.length > 0) { 7772 const [index2, set] = stack.pop(); 7773 switch (index2) { 7774 case UNDEFINED: 7775 set(void 0); 7776 continue; 7777 case NULL: 7778 set(null); 7779 continue; 7780 case NAN: 7781 set(NaN); 7782 continue; 7783 case POSITIVE_INFINITY: 7784 set(Infinity); 7785 continue; 7786 case NEGATIVE_INFINITY: 7787 set(-Infinity); 7788 continue; 7789 case NEGATIVE_ZERO: 7790 set(-0); 7791 continue; 7792 } 7793 if (hydrated[index2]) { 7794 set(hydrated[index2]); 7795 continue; 7796 } 7797 const value = values[index2]; 7798 if (!value || typeof value !== "object") { 7799 hydrated[index2] = value; 7800 set(value); 7801 continue; 7802 } 7803 if (Array.isArray(value)) { 7804 if (typeof value[0] === "string") { 7805 const [type, b, c] = value; 7806 switch (type) { 7807 case TYPE_DATE: 7808 set(hydrated[index2] = new Date(b)); 7809 continue; 7810 case TYPE_URL: 7811 set(hydrated[index2] = new URL(b)); 7812 continue; 7813 case TYPE_BIGINT: 7814 set(hydrated[index2] = BigInt(b)); 7815 continue; 7816 case TYPE_REGEXP: 7817 set(hydrated[index2] = new RegExp(b, c)); 7818 continue; 7819 case TYPE_SYMBOL: 7820 set(hydrated[index2] = Symbol.for(b)); 7821 continue; 7822 case TYPE_SET: 7823 const newSet = /* @__PURE__ */ new Set(); 7824 hydrated[index2] = newSet; 7825 for (let i = value.length - 1; i > 0; i--) 7826 stack.push([ 7827 value[i], 7828 (v) => { 7829 newSet.add(v); 7830 } 7831 ]); 7832 set(newSet); 7833 continue; 7834 case TYPE_MAP: 7835 const map = /* @__PURE__ */ new Map(); 7836 hydrated[index2] = map; 7837 for (let i = value.length - 2; i > 0; i -= 2) { 7838 const r = []; 7839 stack.push([ 7840 value[i + 1], 7841 (v) => { 7842 r[1] = v; 7843 } 7844 ]); 7845 stack.push([ 7846 value[i], 7847 (k) => { 7848 r[0] = k; 7849 } 7850 ]); 7851 postRun.push(() => { 7852 map.set(r[0], r[1]); 7853 }); 7854 } 7855 set(map); 7856 continue; 7857 case TYPE_NULL_OBJECT: 7858 const obj = /* @__PURE__ */ Object.create(null); 7859 hydrated[index2] = obj; 7860 for (const key of Object.keys(b).reverse()) { 7861 const r = []; 7862 stack.push([ 7863 b[key], 7864 (v) => { 7865 r[1] = v; 7866 } 7867 ]); 7868 stack.push([ 7869 Number(key.slice(1)), 7870 (k) => { 7871 r[0] = k; 7872 } 7873 ]); 7874 postRun.push(() => { 7875 obj[r[0]] = r[1]; 7876 }); 7877 } 7878 set(obj); 7879 continue; 7880 case TYPE_PROMISE: 7881 if (hydrated[b]) { 7882 set(hydrated[index2] = hydrated[b]); 7883 } else { 7884 const d = new Deferred2(); 7885 deferred[b] = d; 7886 set(hydrated[index2] = d.promise); 7887 } 7888 continue; 7889 case TYPE_ERROR: 7890 const [, message, errorType] = value; 7891 let error = errorType && globalObj && globalObj[errorType] ? new globalObj[errorType](message) : new Error(message); 7892 hydrated[index2] = error; 7893 set(error); 7894 continue; 7895 case TYPE_PREVIOUS_RESOLVED: 7896 set(hydrated[index2] = hydrated[b]); 7897 continue; 7898 default: 7899 if (Array.isArray(plugins)) { 7900 const r = []; 7901 const vals = value.slice(1); 7902 for (let i = 0; i < vals.length; i++) { 7903 const v = vals[i]; 7904 stack.push([ 7905 v, 7906 (v2) => { 7907 r[i] = v2; 7908 } 7909 ]); 7910 } 7911 postRun.push(() => { 7912 for (const plugin of plugins) { 7913 const result2 = plugin(value[0], ...r); 7914 if (result2) { 7915 set(hydrated[index2] = result2.value); 7916 return; 7917 } 7918 } 7919 throw new SyntaxError(); 7920 }); 7921 continue; 7922 } 7923 throw new SyntaxError(); 7924 } 7925 } else { 7926 const array = []; 7927 hydrated[index2] = array; 7928 for (let i = 0; i < value.length; i++) { 7929 const n = value[i]; 7930 if (n !== HOLE) { 7931 stack.push([ 7932 n, 7933 (v) => { 7934 array[i] = v; 7935 } 7936 ]); 7937 } 7938 } 7939 set(array); 7940 continue; 7941 } 7942 } else { 7943 const object = {}; 7944 hydrated[index2] = object; 7945 for (const key of Object.keys(value).reverse()) { 7946 const r = []; 7947 stack.push([ 7948 value[key], 7949 (v) => { 7950 r[1] = v; 7951 } 7952 ]); 7953 stack.push([ 7954 Number(key.slice(1)), 7955 (k) => { 7956 r[0] = k; 7957 } 7958 ]); 7959 postRun.push(() => { 7960 object[r[0]] = r[1]; 7961 }); 7962 } 7963 set(object); 7964 continue; 7965 } 7966 } 7967 while (postRun.length > 0) { 7968 postRun.pop()(); 7969 } 7970 return result; 7971} 7972async function decode(readable, options) { 7973 const { plugins } = options ?? {}; 7974 const done = new Deferred2(); 7975 const reader = readable.pipeThrough(createLineSplittingTransform()).getReader(); 7976 const decoder = { 7977 values: [], 7978 hydrated: [], 7979 deferred: {}, 7980 plugins 7981 }; 7982 const decoded = await decodeInitial.call(decoder, reader); 7983 let donePromise = done.promise; 7984 if (decoded.done) { 7985 done.resolve(); 7986 } else { 7987 donePromise = decodeDeferred.call(decoder, reader).then(done.resolve).catch((reason) => { 7988 for (const deferred of Object.values(decoder.deferred)) { 7989 deferred.reject(reason); 7990 } 7991 done.reject(reason); 7992 }); 7993 } 7994 return { 7995 done: donePromise.then(() => reader.closed), 7996 value: decoded.value 7997 }; 7998} 7999async function decodeInitial(reader) { 8000 const read = await reader.read(); 8001 if (!read.value) { 8002 throw new SyntaxError(); 8003 } 8004 let line; 8005 try { 8006 line = JSON.parse(read.value); 8007 } catch (reason) { 8008 throw new SyntaxError(); 8009 } 8010 return { 8011 done: read.done, 8012 value: unflatten.call(this, line) 8013 }; 8014} 8015async function decodeDeferred(reader) { 8016 let read = await reader.read(); 8017 while (!read.done) { 8018 if (!read.value) continue; 8019 const line = read.value; 8020 switch (line[0]) { 8021 case TYPE_PROMISE: { 8022 const colonIndex = line.indexOf(":"); 8023 const deferredId = Number(line.slice(1, colonIndex)); 8024 const deferred = this.deferred[deferredId]; 8025 if (!deferred) { 8026 throw new Error(`Deferred ID ${deferredId} not found in stream`); 8027 } 8028 const lineData = line.slice(colonIndex + 1); 8029 let jsonLine; 8030 try { 8031 jsonLine = JSON.parse(lineData); 8032 } catch (reason) { 8033 throw new SyntaxError(); 8034 } 8035 const value = unflatten.call(this, jsonLine); 8036 deferred.resolve(value); 8037 break; 8038 } 8039 case TYPE_ERROR: { 8040 const colonIndex = line.indexOf(":"); 8041 const deferredId = Number(line.slice(1, colonIndex)); 8042 const deferred = this.deferred[deferredId]; 8043 if (!deferred) { 8044 throw new Error(`Deferred ID ${deferredId} not found in stream`); 8045 } 8046 const lineData = line.slice(colonIndex + 1); 8047 let jsonLine; 8048 try { 8049 jsonLine = JSON.parse(lineData); 8050 } catch (reason) { 8051 throw new SyntaxError(); 8052 } 8053 const value = unflatten.call(this, jsonLine); 8054 deferred.reject(value); 8055 break; 8056 } 8057 default: 8058 throw new SyntaxError(); 8059 } 8060 read = await reader.read(); 8061 } 8062} 8063function encode(input, options) { 8064 const { plugins, postPlugins, signal, onComplete } = options ?? {}; 8065 const encoder3 = { 8066 deferred: {}, 8067 index: 0, 8068 indices: /* @__PURE__ */ new Map(), 8069 stringified: [], 8070 plugins, 8071 postPlugins, 8072 signal 8073 }; 8074 const textEncoder = new TextEncoder(); 8075 let lastSentIndex = 0; 8076 const readable = new ReadableStream({ 8077 async start(controller) { 8078 const id = flatten.call(encoder3, input); 8079 if (Array.isArray(id)) { 8080 throw new Error("This should never happen"); 8081 } 8082 if (id < 0) { 8083 controller.enqueue(textEncoder.encode(`${id} 8084`)); 8085 } else { 8086 controller.enqueue( 8087 textEncoder.encode(`[${encoder3.stringified.join(",")}] 8088`) 8089 ); 8090 lastSentIndex = encoder3.stringified.length - 1; 8091 } 8092 const seenPromises = /* @__PURE__ */ new WeakSet(); 8093 if (Object.keys(encoder3.deferred).length) { 8094 let raceDone; 8095 const racePromise = new Promise((resolve, reject) => { 8096 raceDone = resolve; 8097 if (signal) { 8098 const rejectPromise = () => reject(signal.reason || new Error("Signal was aborted.")); 8099 if (signal.aborted) { 8100 rejectPromise(); 8101 } else { 8102 signal.addEventListener("abort", (event) => { 8103 rejectPromise(); 8104 }); 8105 } 8106 } 8107 }); 8108 while (Object.keys(encoder3.deferred).length > 0) { 8109 for (const [deferredId, deferred] of Object.entries( 8110 encoder3.deferred 8111 )) { 8112 if (seenPromises.has(deferred)) continue; 8113 seenPromises.add( 8114 // biome-ignore lint/suspicious/noAssignInExpressions: <explanation> 8115 encoder3.deferred[Number(deferredId)] = Promise.race([ 8116 racePromise, 8117 deferred 8118 ]).then( 8119 (resolved) => { 8120 const id2 = flatten.call(encoder3, resolved); 8121 if (Array.isArray(id2)) { 8122 controller.enqueue( 8123 textEncoder.encode( 8124 `${TYPE_PROMISE}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]] 8125` 8126 ) 8127 ); 8128 encoder3.index++; 8129 lastSentIndex++; 8130 } else if (id2 < 0) { 8131 controller.enqueue( 8132 textEncoder.encode( 8133 `${TYPE_PROMISE}${deferredId}:${id2} 8134` 8135 ) 8136 ); 8137 } else { 8138 const values = encoder3.stringified.slice(lastSentIndex + 1).join(","); 8139 controller.enqueue( 8140 textEncoder.encode( 8141 `${TYPE_PROMISE}${deferredId}:[${values}] 8142` 8143 ) 8144 ); 8145 lastSentIndex = encoder3.stringified.length - 1; 8146 } 8147 }, 8148 (reason) => { 8149 if (!reason || typeof reason !== "object" || !(reason instanceof Error)) { 8150 reason = new Error("An unknown error occurred"); 8151 } 8152 const id2 = flatten.call(encoder3, reason); 8153 if (Array.isArray(id2)) { 8154 controller.enqueue( 8155 textEncoder.encode( 8156 `${TYPE_ERROR}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]] 8157` 8158 ) 8159 ); 8160 encoder3.index++; 8161 lastSentIndex++; 8162 } else if (id2 < 0) { 8163 controller.enqueue( 8164 textEncoder.encode( 8165 `${TYPE_ERROR}${deferredId}:${id2} 8166` 8167 ) 8168 ); 8169 } else { 8170 const values = encoder3.stringified.slice(lastSentIndex + 1).join(","); 8171 controller.enqueue( 8172 textEncoder.encode( 8173 `${TYPE_ERROR}${deferredId}:[${values}] 8174` 8175 ) 8176 ); 8177 lastSentIndex = encoder3.stringified.length - 1; 8178 } 8179 } 8180 ).finally(() => { 8181 delete encoder3.deferred[Number(deferredId)]; 8182 }) 8183 ); 8184 } 8185 await Promise.race(Object.values(encoder3.deferred)); 8186 } 8187 raceDone(); 8188 } 8189 await Promise.all(Object.values(encoder3.deferred)); 8190 onComplete?.(); 8191 controller.close(); 8192 } 8193 }); 8194 return readable; 8195} 8196async function createRequestInit(request) { 8197 let init = { signal: request.signal }; 8198 if (request.method !== "GET") { 8199 init.method = request.method; 8200 let contentType = request.headers.get("Content-Type"); 8201 if (contentType && /\bapplication\/json\b/.test(contentType)) { 8202 init.headers = { "Content-Type": contentType }; 8203 init.body = JSON.stringify(await request.json()); 8204 } else if (contentType && /\btext\/plain\b/.test(contentType)) { 8205 init.headers = { "Content-Type": contentType }; 8206 init.body = await request.text(); 8207 } else if (contentType && /\bapplication\/x-www-form-urlencoded\b/.test(contentType)) { 8208 init.body = new URLSearchParams(await request.text()); 8209 } else { 8210 init.body = await request.formData(); 8211 } 8212 } 8213 return init; 8214} 8215var ESCAPE_LOOKUP = { 8216 "&": "\\u0026", 8217 ">": "\\u003e", 8218 "<": "\\u003c", 8219 "\u2028": "\\u2028", 8220 "\u2029": "\\u2029" 8221}; 8222var ESCAPE_REGEX = /[&><\u2028\u2029]/g; 8223function escapeHtml(html) { 8224 return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]); 8225} 8226function invariant2(value, message) { 8227 if (value === false || value === null || typeof value === "undefined") { 8228 throw new Error(message); 8229 } 8230} 8231var SingleFetchRedirectSymbol = /* @__PURE__ */ Symbol("SingleFetchRedirect"); 8232var SingleFetchNoResultError = class extends Error { 8233}; 8234var SINGLE_FETCH_REDIRECT_STATUS = 202; 8235var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205]); 8236function StreamTransfer({ 8237 context, 8238 identifier, 8239 reader, 8240 textDecoder, 8241 nonce 8242}) { 8243 if (!context.renderMeta || !context.renderMeta.didRenderScripts) { 8244 return null; 8245 } 8246 if (!context.renderMeta.streamCache) { 8247 context.renderMeta.streamCache = {}; 8248 } 8249 let { streamCache } = context.renderMeta; 8250 let promise = streamCache[identifier]; 8251 if (!promise) { 8252 promise = streamCache[identifier] = reader.read().then((result) => { 8253 streamCache[identifier].result = { 8254 done: result.done, 8255 value: textDecoder.decode(result.value, { stream: true }) 8256 }; 8257 }).catch((e) => { 8258 streamCache[identifier].error = e; 8259 }); 8260 } 8261 if (promise.error) { 8262 throw promise.error; 8263 } 8264 if (promise.result === void 0) { 8265 throw promise; 8266 } 8267 let { done, value } = promise.result; 8268 let scriptTag = value ? React4.createElement( 8269 "script", 8270 { 8271 nonce, 8272 dangerouslySetInnerHTML: { 8273 __html: `window.__reactRouterContext.streamController.enqueue(${escapeHtml( 8274 JSON.stringify(value) 8275 )});` 8276 } 8277 } 8278 ) : null; 8279 if (done) { 8280 return React4.createElement(React4.Fragment, null, scriptTag, React4.createElement( 8281 "script", 8282 { 8283 nonce, 8284 dangerouslySetInnerHTML: { 8285 __html: `window.__reactRouterContext.streamController.close();` 8286 } 8287 } 8288 )); 8289 } else { 8290 return React4.createElement(React4.Fragment, null, scriptTag, React4.createElement(React4.Suspense, null, React4.createElement( 8291 StreamTransfer, 8292 { 8293 context, 8294 identifier: identifier + 1, 8295 reader, 8296 textDecoder, 8297 nonce 8298 } 8299 ))); 8300 } 8301} 8302function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr, basename, trailingSlashAware) { 8303 let dataStrategy = getSingleFetchDataStrategyImpl( 8304 getRouter, 8305 (match) => { 8306 let manifestRoute = manifest.routes[match.route.id]; 8307 invariant2(manifestRoute, "Route not found in manifest"); 8308 let routeModule = routeModules[match.route.id]; 8309 return { 8310 hasLoader: manifestRoute.hasLoader, 8311 hasClientLoader: manifestRoute.hasClientLoader, 8312 hasShouldRevalidate: Boolean(routeModule?.shouldRevalidate) 8313 }; 8314 }, 8315 fetchAndDecodeViaTurboStream, 8316 ssr, 8317 basename, 8318 trailingSlashAware 8319 ); 8320 return async (args) => args.runClientMiddleware(dataStrategy); 8321} 8322function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, basename, trailingSlashAware, shouldAllowOptOut = () => true) { 8323 return async (args) => { 8324 let { request, matches, fetcherKey } = args; 8325 let router2 = getRouter(); 8326 if (request.method !== "GET") { 8327 return singleFetchActionStrategy( 8328 args, 8329 fetchAndDecode, 8330 basename, 8331 trailingSlashAware 8332 ); 8333 } 8334 let foundRevalidatingServerLoader = matches.some((m) => { 8335 let { hasLoader, hasClientLoader } = getRouteInfo(m); 8336 return m.shouldCallHandler() && hasLoader && !hasClientLoader; 8337 }); 8338 if (!ssr && !foundRevalidatingServerLoader) { 8339 return nonSsrStrategy( 8340 args, 8341 getRouteInfo, 8342 fetchAndDecode, 8343 basename, 8344 trailingSlashAware 8345 ); 8346 } 8347 if (fetcherKey) { 8348 return singleFetchLoaderFetcherStrategy( 8349 args, 8350 fetchAndDecode, 8351 basename, 8352 trailingSlashAware 8353 ); 8354 } 8355 return singleFetchLoaderNavigationStrategy( 8356 args, 8357 router2, 8358 getRouteInfo, 8359 fetchAndDecode, 8360 ssr, 8361 basename, 8362 trailingSlashAware, 8363 shouldAllowOptOut 8364 ); 8365 }; 8366} 8367async function singleFetchActionStrategy(args, fetchAndDecode, basename, trailingSlashAware) { 8368 let actionMatch = args.matches.find((m) => m.shouldCallHandler()); 8369 invariant2(actionMatch, "No action match found"); 8370 let actionStatus = void 0; 8371 let result = await actionMatch.resolve(async (handler) => { 8372 let result2 = await handler(async () => { 8373 let { data: data2, status } = await fetchAndDecode( 8374 args, 8375 basename, 8376 trailingSlashAware, 8377 [actionMatch.route.id] 8378 ); 8379 actionStatus = status; 8380 return unwrapSingleFetchResult(data2, actionMatch.route.id); 8381 }); 8382 return result2; 8383 }); 8384 if (isResponse(result.result) || isRouteErrorResponse(result.result) || isDataWithResponseInit(result.result)) { 8385 return { [actionMatch.route.id]: result }; 8386 } 8387 return { 8388 [actionMatch.route.id]: { 8389 type: result.type, 8390 result: data(result.result, actionStatus) 8391 } 8392 }; 8393} 8394async function nonSsrStrategy(args, getRouteInfo, fetchAndDecode, basename, trailingSlashAware) { 8395 let matchesToLoad = args.matches.filter((m) => m.shouldCallHandler()); 8396 let results = {}; 8397 await Promise.all( 8398 matchesToLoad.map( 8399 (m) => m.resolve(async (handler) => { 8400 try { 8401 let { hasClientLoader } = getRouteInfo(m); 8402 let routeId = m.route.id; 8403 let result = hasClientLoader ? await handler(async () => { 8404 let { data: data2 } = await fetchAndDecode( 8405 args, 8406 basename, 8407 trailingSlashAware, 8408 [routeId] 8409 ); 8410 return unwrapSingleFetchResult(data2, routeId); 8411 }) : await handler(); 8412 results[m.route.id] = { type: "data", result }; 8413 } catch (e) { 8414 results[m.route.id] = { type: "error", result: e }; 8415 } 8416 }) 8417 ) 8418 ); 8419 return results; 8420} 8421async function singleFetchLoaderNavigationStrategy(args, router2, getRouteInfo, fetchAndDecode, ssr, basename, trailingSlashAware, shouldAllowOptOut = () => true) { 8422 let routesParams = /* @__PURE__ */ new Set(); 8423 let foundOptOutRoute = false; 8424 let routeDfds = args.matches.map(() => createDeferred2()); 8425 let singleFetchDfd = createDeferred2(); 8426 let results = {}; 8427 let resolvePromise = Promise.all( 8428 args.matches.map( 8429 async (m, i) => m.resolve(async (handler) => { 8430 routeDfds[i].resolve(); 8431 let routeId = m.route.id; 8432 let { hasLoader, hasClientLoader, hasShouldRevalidate } = getRouteInfo(m); 8433 let defaultShouldRevalidate = !m.shouldRevalidateArgs || m.shouldRevalidateArgs.actionStatus == null || m.shouldRevalidateArgs.actionStatus < 400; 8434 let shouldCall = m.shouldCallHandler(defaultShouldRevalidate); 8435 if (!shouldCall) { 8436 foundOptOutRoute || (foundOptOutRoute = m.shouldRevalidateArgs != null && // This is a revalidation, 8437 hasLoader && // for a route with a server loader, 8438 hasShouldRevalidate === true); 8439 return; 8440 } 8441 if (shouldAllowOptOut(m) && hasClientLoader) { 8442 if (hasLoader) { 8443 foundOptOutRoute = true; 8444 } 8445 try { 8446 let result = await handler(async () => { 8447 let { data: data2 } = await fetchAndDecode( 8448 args, 8449 basename, 8450 trailingSlashAware, 8451 [routeId] 8452 ); 8453 return unwrapSingleFetchResult(data2, routeId); 8454 }); 8455 results[routeId] = { type: "data", result }; 8456 } catch (e) { 8457 results[routeId] = { type: "error", result: e }; 8458 } 8459 return; 8460 } 8461 if (hasLoader) { 8462 routesParams.add(routeId); 8463 } 8464 try { 8465 let result = await handler(async () => { 8466 let data2 = await singleFetchDfd.promise; 8467 return unwrapSingleFetchResult(data2, routeId); 8468 }); 8469 results[routeId] = { type: "data", result }; 8470 } catch (e) { 8471 results[routeId] = { type: "error", result: e }; 8472 } 8473 }) 8474 ) 8475 ); 8476 await Promise.all(routeDfds.map((d) => d.promise)); 8477 let isInitialLoad = !router2.state.initialized && router2.state.navigation.state === "idle"; 8478 if ((isInitialLoad || routesParams.size === 0) && !window.__reactRouterHdrActive) { 8479 singleFetchDfd.resolve({ routes: {} }); 8480 } else { 8481 let targetRoutes = ssr && foundOptOutRoute && routesParams.size > 0 ? [...routesParams.keys()] : void 0; 8482 try { 8483 let data2 = await fetchAndDecode( 8484 args, 8485 basename, 8486 trailingSlashAware, 8487 targetRoutes 8488 ); 8489 singleFetchDfd.resolve(data2.data); 8490 } catch (e) { 8491 singleFetchDfd.reject(e); 8492 } 8493 } 8494 await resolvePromise; 8495 await bubbleMiddlewareErrors( 8496 singleFetchDfd.promise, 8497 args.matches, 8498 routesParams, 8499 results 8500 ); 8501 return results; 8502} 8503async function bubbleMiddlewareErrors(singleFetchPromise, matches, routesParams, results) { 8504 try { 8505 let middlewareError; 8506 let fetchedData = await singleFetchPromise; 8507 if ("routes" in fetchedData) { 8508 for (let match of matches) { 8509 if (match.route.id in fetchedData.routes) { 8510 let routeResult = fetchedData.routes[match.route.id]; 8511 if ("error" in routeResult) { 8512 middlewareError = routeResult.error; 8513 if (results[match.route.id]?.result == null) { 8514 results[match.route.id] = { 8515 type: "error", 8516 result: middlewareError 8517 }; 8518 } 8519 break; 8520 } 8521 } 8522 } 8523 } 8524 if (middlewareError !== void 0) { 8525 Array.from(routesParams.values()).forEach((routeId) => { 8526 if (results[routeId].result instanceof SingleFetchNoResultError) { 8527 results[routeId].result = middlewareError; 8528 } 8529 }); 8530 } 8531 } catch (e) { 8532 } 8533} 8534async function singleFetchLoaderFetcherStrategy(args, fetchAndDecode, basename, trailingSlashAware) { 8535 let fetcherMatch = args.matches.find((m) => m.shouldCallHandler()); 8536 invariant2(fetcherMatch, "No fetcher match found"); 8537 let routeId = fetcherMatch.route.id; 8538 let result = await fetcherMatch.resolve( 8539 async (handler) => handler(async () => { 8540 let { data: data2 } = await fetchAndDecode(args, basename, trailingSlashAware, [ 8541 routeId 8542 ]); 8543 return unwrapSingleFetchResult(data2, routeId); 8544 }) 8545 ); 8546 return { [fetcherMatch.route.id]: result }; 8547} 8548function stripIndexParam(url) { 8549 let indexValues = url.searchParams.getAll("index"); 8550 url.searchParams.delete("index"); 8551 let indexValuesToKeep = []; 8552 for (let indexValue of indexValues) { 8553 if (indexValue) { 8554 indexValuesToKeep.push(indexValue); 8555 } 8556 } 8557 for (let toKeep of indexValuesToKeep) { 8558 url.searchParams.append("index", toKeep); 8559 } 8560 return url; 8561} 8562function singleFetchUrl(reqUrl, basename, trailingSlashAware, extension) { 8563 let url = typeof reqUrl === "string" ? new URL( 8564 reqUrl, 8565 // This can be called during the SSR flow via PrefetchPageLinksImpl so 8566 // don't assume window is available 8567 typeof window === "undefined" ? "server://singlefetch/" : window.location.origin 8568 ) : reqUrl; 8569 if (trailingSlashAware) { 8570 if (url.pathname.endsWith("/")) { 8571 url.pathname = `${url.pathname}_.${extension}`; 8572 } else { 8573 url.pathname = `${url.pathname}.${extension}`; 8574 } 8575 } else { 8576 if (url.pathname === "/") { 8577 url.pathname = `_root.${extension}`; 8578 } else if (basename && stripBasename(url.pathname, basename) === "/") { 8579 url.pathname = `${basename.replace(/\/$/, "")}/_root.${extension}`; 8580 } else { 8581 url.pathname = `${url.pathname.replace(/\/$/, "")}.${extension}`; 8582 } 8583 } 8584 return url; 8585} 8586async function fetchAndDecodeViaTurboStream(args, basename, trailingSlashAware, targetRoutes) { 8587 let { request } = args; 8588 let url = singleFetchUrl(request.url, basename, trailingSlashAware, "data"); 8589 if (request.method === "GET") { 8590 url = stripIndexParam(url); 8591 if (targetRoutes) { 8592 url.searchParams.set("_routes", targetRoutes.join(",")); 8593 } 8594 } 8595 let res = await fetch(url, await createRequestInit(request)); 8596 if (res.status >= 400 && !res.headers.has("X-Remix-Response")) { 8597 throw new ErrorResponseImpl(res.status, res.statusText, await res.text()); 8598 } 8599 if (res.status === 204 && res.headers.has("X-Remix-Redirect")) { 8600 return { 8601 status: SINGLE_FETCH_REDIRECT_STATUS, 8602 data: { 8603 redirect: { 8604 redirect: res.headers.get("X-Remix-Redirect"), 8605 status: Number(res.headers.get("X-Remix-Status") || "302"), 8606 revalidate: res.headers.get("X-Remix-Revalidate") === "true", 8607 reload: res.headers.get("X-Remix-Reload-Document") === "true", 8608 replace: res.headers.get("X-Remix-Replace") === "true" 8609 } 8610 } 8611 }; 8612 } 8613 if (NO_BODY_STATUS_CODES.has(res.status)) { 8614 let routes = {}; 8615 if (targetRoutes && request.method !== "GET") { 8616 routes[targetRoutes[0]] = { data: void 0 }; 8617 } 8618 return { 8619 status: res.status, 8620 data: { routes } 8621 }; 8622 } 8623 invariant2(res.body, "No response body to decode"); 8624 try { 8625 let decoded = await decodeViaTurboStream(res.body, window); 8626 let data2; 8627 if (request.method === "GET") { 8628 let typed = decoded.value; 8629 if (SingleFetchRedirectSymbol in typed) { 8630 data2 = { redirect: typed[SingleFetchRedirectSymbol] }; 8631 } else { 8632 data2 = { routes: typed }; 8633 } 8634 } else { 8635 let typed = decoded.value; 8636 let routeId = targetRoutes?.[0]; 8637 invariant2(routeId, "No routeId found for single fetch call decoding"); 8638 if ("redirect" in typed) { 8639 data2 = { redirect: typed }; 8640 } else { 8641 data2 = { routes: { [routeId]: typed } }; 8642 } 8643 } 8644 return { status: res.status, data: data2 }; 8645 } catch (e) { 8646 throw new Error("Unable to decode turbo-stream response"); 8647 } 8648} 8649function decodeViaTurboStream(body, global2) { 8650 return decode(body, { 8651 plugins: [ 8652 (type, ...rest) => { 8653 if (type === "SanitizedError") { 8654 let [name, message, stack] = rest; 8655 let Constructor = Error; 8656 if (name && name in global2 && typeof global2[name] === "function") { 8657 Constructor = global2[name]; 8658 } 8659 let error = new Constructor(message); 8660 error.stack = stack; 8661 return { value: error }; 8662 } 8663 if (type === "ErrorResponse") { 8664 let [data2, status, statusText] = rest; 8665 return { 8666 value: new ErrorResponseImpl(status, statusText, data2) 8667 }; 8668 } 8669 if (type === "SingleFetchRedirect") { 8670 return { value: { [SingleFetchRedirectSymbol]: rest[0] } }; 8671 } 8672 if (type === "SingleFetchClassInstance") { 8673 return { value: rest[0] }; 8674 } 8675 if (type === "SingleFetchFallback") { 8676 return { value: void 0 }; 8677 } 8678 } 8679 ] 8680 }); 8681} 8682function unwrapSingleFetchResult(result, routeId) { 8683 if ("redirect" in result) { 8684 let { 8685 redirect: location2, 8686 revalidate, 8687 reload, 8688 replace: replace2, 8689 status 8690 } = result.redirect; 8691 throw redirect(location2, { 8692 status, 8693 headers: { 8694 // Three R's of redirecting (lol Veep) 8695 ...revalidate ? { "X-Remix-Revalidate": "yes" } : null, 8696 ...reload ? { "X-Remix-Reload-Document": "yes" } : null, 8697 ...replace2 ? { "X-Remix-Replace": "yes" } : null 8698 } 8699 }); 8700 } 8701 let routeResult = result.routes[routeId]; 8702 if (routeResult == null) { 8703 throw new SingleFetchNoResultError( 8704 `No result found for routeId "${routeId}"` 8705 ); 8706 } else if ("error" in routeResult) { 8707 throw routeResult.error; 8708 } else if ("data" in routeResult) { 8709 return routeResult.data; 8710 } else { 8711 throw new Error(`Invalid response found for routeId "${routeId}"`); 8712 } 8713} 8714function createDeferred2() { 8715 let resolve; 8716 let reject; 8717 let promise = new Promise((res, rej) => { 8718 resolve = async (val) => { 8719 res(val); 8720 try { 8721 await promise; 8722 } catch (e) { 8723 } 8724 }; 8725 reject = async (error) => { 8726 rej(error); 8727 try { 8728 await promise; 8729 } catch (e) { 8730 } 8731 }; 8732 }); 8733 return { 8734 promise, 8735 //@ts-ignore 8736 resolve, 8737 //@ts-ignore 8738 reject 8739 }; 8740} 8741async function loadRouteModule(route, routeModulesCache) { 8742 if (route.id in routeModulesCache) { 8743 return routeModulesCache[route.id]; 8744 } 8745 try { 8746 let routeModule = await import( 8747 /* @vite-ignore */ 8748 /* webpackIgnore: true */ 8749 __vite__injectQuery(route.module, 'import') 8750 ); 8751 routeModulesCache[route.id] = routeModule; 8752 return routeModule; 8753 } catch (error) { 8754 console.error( 8755 `Error loading route module \`${route.module}\`, reloading page...` 8756 ); 8757 console.error(error); 8758 if (window.__reactRouterContext && window.__reactRouterContext.isSpaMode && // @ts-expect-error 8759 import.meta.hot) { 8760 throw error; 8761 } 8762 window.location.reload(); 8763 return new Promise(() => { 8764 }); 8765 } 8766} 8767function getKeyedLinksForMatches(matches, routeModules, manifest) { 8768 let descriptors = matches.map((match) => { 8769 let module = routeModules[match.route.id]; 8770 let route = manifest.routes[match.route.id]; 8771 return [ 8772 route && route.css ? route.css.map((href2) => ({ rel: "stylesheet", href: href2 })) : [], 8773 module?.links?.() || [] 8774 ]; 8775 }).flat(2); 8776 let preloads = getModuleLinkHrefs(matches, manifest); 8777 return dedupeLinkDescriptors(descriptors, preloads); 8778} 8779function getRouteCssDescriptors(route) { 8780 if (!route.css) return []; 8781 return route.css.map((href2) => ({ rel: "stylesheet", href: href2 })); 8782} 8783async function prefetchRouteCss(route) { 8784 if (!route.css) return; 8785 let descriptors = getRouteCssDescriptors(route); 8786 await Promise.all(descriptors.map(prefetchStyleLink)); 8787} 8788async function prefetchStyleLinks(route, routeModule) { 8789 if (!route.css && !routeModule.links || !isPreloadSupported()) return; 8790 let descriptors = []; 8791 if (route.css) { 8792 descriptors.push(...getRouteCssDescriptors(route)); 8793 } 8794 if (routeModule.links) { 8795 descriptors.push(...routeModule.links()); 8796 } 8797 if (descriptors.length === 0) return; 8798 let styleLinks = []; 8799 for (let descriptor of descriptors) { 8800 if (!isPageLinkDescriptor(descriptor) && descriptor.rel === "stylesheet") { 8801 styleLinks.push({ 8802 ...descriptor, 8803 rel: "preload", 8804 as: "style" 8805 }); 8806 } 8807 } 8808 await Promise.all(styleLinks.map(prefetchStyleLink)); 8809} 8810async function prefetchStyleLink(descriptor) { 8811 return new Promise((resolve) => { 8812 if (descriptor.media && !window.matchMedia(descriptor.media).matches || document.querySelector( 8813 `link[rel="stylesheet"][href="${descriptor.href}"]` 8814 )) { 8815 return resolve(); 8816 } 8817 let link = document.createElement("link"); 8818 Object.assign(link, descriptor); 8819 function removeLink() { 8820 if (document.head.contains(link)) { 8821 document.head.removeChild(link); 8822 } 8823 } 8824 link.onload = () => { 8825 removeLink(); 8826 resolve(); 8827 }; 8828 link.onerror = () => { 8829 removeLink(); 8830 resolve(); 8831 }; 8832 document.head.appendChild(link); 8833 }); 8834} 8835function isPageLinkDescriptor(object) { 8836 return object != null && typeof object.page === "string"; 8837} 8838function isHtmlLinkDescriptor(object) { 8839 if (object == null) { 8840 return false; 8841 } 8842 if (object.href == null) { 8843 return object.rel === "preload" && typeof object.imageSrcSet === "string" && typeof object.imageSizes === "string"; 8844 } 8845 return typeof object.rel === "string" && typeof object.href === "string"; 8846} 8847async function getKeyedPrefetchLinks(matches, manifest, routeModules) { 8848 let links = await Promise.all( 8849 matches.map(async (match) => { 8850 let route = manifest.routes[match.route.id]; 8851 if (route) { 8852 let mod = await loadRouteModule(route, routeModules); 8853 return mod.links ? mod.links() : []; 8854 } 8855 return []; 8856 }) 8857 ); 8858 return dedupeLinkDescriptors( 8859 links.flat(1).filter(isHtmlLinkDescriptor).filter((link) => link.rel === "stylesheet" || link.rel === "preload").map( 8860 (link) => link.rel === "stylesheet" ? { ...link, rel: "prefetch", as: "style" } : { ...link, rel: "prefetch" } 8861 ) 8862 ); 8863} 8864function getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, location2, mode) { 8865 let isNew = (match, index) => { 8866 if (!currentMatches[index]) return true; 8867 return match.route.id !== currentMatches[index].route.id; 8868 }; 8869 let matchPathChanged = (match, index) => { 8870 return ( 8871 // param change, /users/123 -> /users/456 8872 currentMatches[index].pathname !== match.pathname || // splat param changed, which is not present in match.path 8873 // e.g. /files/images/avatar.jpg -> files/finances.xls 8874 currentMatches[index].route.path?.endsWith("*") && currentMatches[index].params["*"] !== match.params["*"] 8875 ); 8876 }; 8877 if (mode === "assets") { 8878 return nextMatches.filter( 8879 (match, index) => isNew(match, index) || matchPathChanged(match, index) 8880 ); 8881 } 8882 if (mode === "data") { 8883 return nextMatches.filter((match, index) => { 8884 let manifestRoute = manifest.routes[match.route.id]; 8885 if (!manifestRoute || !manifestRoute.hasLoader) { 8886 return false; 8887 } 8888 if (isNew(match, index) || matchPathChanged(match, index)) { 8889 return true; 8890 } 8891 if (match.route.shouldRevalidate) { 8892 let routeChoice = match.route.shouldRevalidate({ 8893 currentUrl: new URL( 8894 location2.pathname + location2.search + location2.hash, 8895 window.origin 8896 ), 8897 currentParams: currentMatches[0]?.params || {}, 8898 nextUrl: new URL(page, window.origin), 8899 nextParams: match.params, 8900 defaultShouldRevalidate: true 8901 }); 8902 if (typeof routeChoice === "boolean") { 8903 return routeChoice; 8904 } 8905 } 8906 return true; 8907 }); 8908 } 8909 return []; 8910} 8911function getModuleLinkHrefs(matches, manifest, { includeHydrateFallback } = {}) { 8912 return dedupeHrefs( 8913 matches.map((match) => { 8914 let route = manifest.routes[match.route.id]; 8915 if (!route) return []; 8916 let hrefs = [route.module]; 8917 if (route.clientActionModule) { 8918 hrefs = hrefs.concat(route.clientActionModule); 8919 } 8920 if (route.clientLoaderModule) { 8921 hrefs = hrefs.concat(route.clientLoaderModule); 8922 } 8923 if (includeHydrateFallback && route.hydrateFallbackModule) { 8924 hrefs = hrefs.concat(route.hydrateFallbackModule); 8925 } 8926 if (route.imports) { 8927 hrefs = hrefs.concat(route.imports); 8928 } 8929 return hrefs; 8930 }).flat(1) 8931 ); 8932} 8933function dedupeHrefs(hrefs) { 8934 return [...new Set(hrefs)]; 8935} 8936function sortKeys(obj) { 8937 let sorted = {}; 8938 let keys = Object.keys(obj).sort(); 8939 for (let key of keys) { 8940 sorted[key] = obj[key]; 8941 } 8942 return sorted; 8943} 8944function dedupeLinkDescriptors(descriptors, preloads) { 8945 let set = /* @__PURE__ */ new Set(); 8946 let preloadsSet = new Set(preloads); 8947 return descriptors.reduce((deduped, descriptor) => { 8948 let alreadyModulePreload = preloads && !isPageLinkDescriptor(descriptor) && descriptor.as === "script" && descriptor.href && preloadsSet.has(descriptor.href); 8949 if (alreadyModulePreload) { 8950 return deduped; 8951 } 8952 let key = JSON.stringify(sortKeys(descriptor)); 8953 if (!set.has(key)) { 8954 set.add(key); 8955 deduped.push({ key, link: descriptor }); 8956 } 8957 return deduped; 8958 }, []); 8959} 8960var _isPreloadSupported; 8961function isPreloadSupported() { 8962 if (_isPreloadSupported !== void 0) { 8963 return _isPreloadSupported; 8964 } 8965 let el = document.createElement("link"); 8966 _isPreloadSupported = el.relList.supports("preload"); 8967 el = null; 8968 return _isPreloadSupported; 8969} 8970function RemixRootDefaultHydrateFallback() { 8971 return React5.createElement(BoundaryShell, { title: "Loading...", renderScripts: true }, ENABLE_DEV_WARNINGS ? React5.createElement( 8972 "script", 8973 { 8974 dangerouslySetInnerHTML: { 8975 __html: ` 8976 console.log( 8977 "💿 Hey developer 👋. You can provide a way better UX than this " + 8978 "when your app is loading JS modules and/or running \`clientLoader\` " + 8979 "functions. Check out https://reactrouter.com/start/framework/route-module#hydratefallback " + 8980 "for more information." 8981 ); 8982 ` 8983 } 8984 } 8985 ) : null); 8986} 8987function groupRoutesByParentId(manifest) { 8988 let routes = {}; 8989 Object.values(manifest).forEach((route) => { 8990 if (route) { 8991 let parentId = route.parentId || ""; 8992 if (!routes[parentId]) { 8993 routes[parentId] = []; 8994 } 8995 routes[parentId].push(route); 8996 } 8997 }); 8998 return routes; 8999} 9000function getRouteComponents(route, routeModule, isSpaMode) { 9001 let Component4 = getRouteModuleComponent(routeModule); 9002 let HydrateFallback = routeModule.HydrateFallback && (!isSpaMode || route.id === "root") ? routeModule.HydrateFallback : route.id === "root" ? RemixRootDefaultHydrateFallback : void 0; 9003 let ErrorBoundary = routeModule.ErrorBoundary ? routeModule.ErrorBoundary : route.id === "root" ? () => React6.createElement(RemixRootDefaultErrorBoundary, { error: useRouteError() }) : void 0; 9004 if (route.id === "root" && routeModule.Layout) { 9005 return { 9006 ...Component4 ? { 9007 element: React6.createElement(routeModule.Layout, null, React6.createElement(Component4, null)) 9008 } : { Component: Component4 }, 9009 ...ErrorBoundary ? { 9010 errorElement: React6.createElement(routeModule.Layout, null, React6.createElement(ErrorBoundary, null)) 9011 } : { ErrorBoundary }, 9012 ...HydrateFallback ? { 9013 hydrateFallbackElement: React6.createElement(routeModule.Layout, null, React6.createElement(HydrateFallback, null)) 9014 } : { HydrateFallback } 9015 }; 9016 } 9017 return { Component: Component4, ErrorBoundary, HydrateFallback }; 9018} 9019function createServerRoutes(manifest, routeModules, future, isSpaMode, parentId = "", routesByParentId = groupRoutesByParentId(manifest), spaModeLazyPromise = Promise.resolve({ Component: () => null })) { 9020 return (routesByParentId[parentId] || []).map((route) => { 9021 let routeModule = routeModules[route.id]; 9022 invariant2( 9023 routeModule, 9024 "No `routeModule` available to create server routes" 9025 ); 9026 let dataRoute = { 9027 ...getRouteComponents(route, routeModule, isSpaMode), 9028 caseSensitive: route.caseSensitive, 9029 id: route.id, 9030 index: route.index, 9031 path: route.path, 9032 handle: routeModule.handle, 9033 // For SPA Mode, all routes are lazy except root. However we tell the 9034 // router root is also lazy here too since we don't need a full 9035 // implementation - we just need a `lazy` prop to tell the RR rendering 9036 // where to stop which is always at the root route in SPA mode 9037 lazy: isSpaMode ? () => spaModeLazyPromise : void 0, 9038 // For partial hydration rendering, we need to indicate when the route 9039 // has a loader/clientLoader, but it won't ever be called during the static 9040 // render, so just give it a no-op function so we can render down to the 9041 // proper fallback 9042 loader: route.hasLoader || route.hasClientLoader ? () => null : void 0 9043 // We don't need middleware/action/shouldRevalidate on these routes since 9044 // they're for a static render 9045 }; 9046 let children = createServerRoutes( 9047 manifest, 9048 routeModules, 9049 future, 9050 isSpaMode, 9051 route.id, 9052 routesByParentId, 9053 spaModeLazyPromise 9054 ); 9055 if (children.length > 0) dataRoute.children = children; 9056 return dataRoute; 9057 }); 9058} 9059function createClientRoutesWithHMRRevalidationOptOut(needsRevalidation, manifest, routeModulesCache, initialState, ssr, isSpaMode) { 9060 return createClientRoutes( 9061 manifest, 9062 routeModulesCache, 9063 initialState, 9064 ssr, 9065 isSpaMode, 9066 "", 9067 groupRoutesByParentId(manifest), 9068 needsRevalidation 9069 ); 9070} 9071function preventInvalidServerHandlerCall(type, route) { 9072 if (type === "loader" && !route.hasLoader || type === "action" && !route.hasAction) { 9073 let fn = type === "action" ? "serverAction()" : "serverLoader()"; 9074 let msg = `You are trying to call ${fn} on a route that does not have a server ${type} (routeId: "${route.id}")`; 9075 console.error(msg); 9076 throw new ErrorResponseImpl(400, "Bad Request", new Error(msg), true); 9077 } 9078} 9079function noActionDefinedError(type, routeId) { 9080 let article = type === "clientAction" ? "a" : "an"; 9081 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`; 9082 console.error(msg); 9083 throw new ErrorResponseImpl(405, "Method Not Allowed", new Error(msg), true); 9084} 9085function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSpaMode, parentId = "", routesByParentId = groupRoutesByParentId(manifest), needsRevalidation) { 9086 return (routesByParentId[parentId] || []).map((route) => { 9087 let routeModule = routeModulesCache[route.id]; 9088 function fetchServerHandler(singleFetch) { 9089 invariant2( 9090 typeof singleFetch === "function", 9091 "No single fetch function available for route handler" 9092 ); 9093 return singleFetch(); 9094 } 9095 function fetchServerLoader(singleFetch) { 9096 if (!route.hasLoader) return Promise.resolve(null); 9097 return fetchServerHandler(singleFetch); 9098 } 9099 function fetchServerAction(singleFetch) { 9100 if (!route.hasAction) { 9101 throw noActionDefinedError("action", route.id); 9102 } 9103 return fetchServerHandler(singleFetch); 9104 } 9105 function prefetchModule(modulePath) { 9106 import( 9107 /* @vite-ignore */ 9108 /* webpackIgnore: true */ 9109 __vite__injectQuery(modulePath, 'import') 9110 ); 9111 } 9112 function prefetchRouteModuleChunks(route2) { 9113 if (route2.clientActionModule) { 9114 prefetchModule(route2.clientActionModule); 9115 } 9116 if (route2.clientLoaderModule) { 9117 prefetchModule(route2.clientLoaderModule); 9118 } 9119 } 9120 async function prefetchStylesAndCallHandler(handler) { 9121 let cachedModule = routeModulesCache[route.id]; 9122 let linkPrefetchPromise = cachedModule ? prefetchStyleLinks(route, cachedModule) : Promise.resolve(); 9123 try { 9124 return handler(); 9125 } finally { 9126 await linkPrefetchPromise; 9127 } 9128 } 9129 let dataRoute = { 9130 id: route.id, 9131 index: route.index, 9132 path: route.path 9133 }; 9134 if (routeModule) { 9135 Object.assign(dataRoute, { 9136 ...dataRoute, 9137 ...getRouteComponents(route, routeModule, isSpaMode), 9138 middleware: routeModule.clientMiddleware, 9139 handle: routeModule.handle, 9140 shouldRevalidate: getShouldRevalidateFunction( 9141 dataRoute.path, 9142 routeModule, 9143 route, 9144 ssr, 9145 needsRevalidation 9146 ) 9147 }); 9148 let hasInitialData = initialState && initialState.loaderData && route.id in initialState.loaderData; 9149 let initialData = hasInitialData ? initialState?.loaderData?.[route.id] : void 0; 9150 let hasInitialError = initialState && initialState.errors && route.id in initialState.errors; 9151 let initialError = hasInitialError ? initialState?.errors?.[route.id] : void 0; 9152 let isHydrationRequest = needsRevalidation == null && (routeModule.clientLoader?.hydrate === true || !route.hasLoader); 9153 dataRoute.loader = async ({ request, params, context, unstable_pattern }, singleFetch) => { 9154 try { 9155 let result = await prefetchStylesAndCallHandler(async () => { 9156 invariant2( 9157 routeModule, 9158 "No `routeModule` available for critical-route loader" 9159 ); 9160 if (!routeModule.clientLoader) { 9161 return fetchServerLoader(singleFetch); 9162 } 9163 return routeModule.clientLoader({ 9164 request, 9165 params, 9166 context, 9167 unstable_pattern, 9168 async serverLoader() { 9169 preventInvalidServerHandlerCall("loader", route); 9170 if (isHydrationRequest) { 9171 if (hasInitialData) { 9172 return initialData; 9173 } 9174 if (hasInitialError) { 9175 throw initialError; 9176 } 9177 } 9178 return fetchServerLoader(singleFetch); 9179 } 9180 }); 9181 }); 9182 return result; 9183 } finally { 9184 isHydrationRequest = false; 9185 } 9186 }; 9187 dataRoute.loader.hydrate = shouldHydrateRouteLoader( 9188 route.id, 9189 routeModule.clientLoader, 9190 route.hasLoader, 9191 isSpaMode 9192 ); 9193 dataRoute.action = ({ request, params, context, unstable_pattern }, singleFetch) => { 9194 return prefetchStylesAndCallHandler(async () => { 9195 invariant2( 9196 routeModule, 9197 "No `routeModule` available for critical-route action" 9198 ); 9199 if (!routeModule.clientAction) { 9200 if (isSpaMode) { 9201 throw noActionDefinedError("clientAction", route.id); 9202 } 9203 return fetchServerAction(singleFetch); 9204 } 9205 return routeModule.clientAction({ 9206 request, 9207 params, 9208 context, 9209 unstable_pattern, 9210 async serverAction() { 9211 preventInvalidServerHandlerCall("action", route); 9212 return fetchServerAction(singleFetch); 9213 } 9214 }); 9215 }); 9216 }; 9217 } else { 9218 if (!route.hasClientLoader) { 9219 dataRoute.loader = (_, singleFetch) => prefetchStylesAndCallHandler(() => { 9220 return fetchServerLoader(singleFetch); 9221 }); 9222 } 9223 if (!route.hasClientAction) { 9224 dataRoute.action = (_, singleFetch) => prefetchStylesAndCallHandler(() => { 9225 if (isSpaMode) { 9226 throw noActionDefinedError("clientAction", route.id); 9227 } 9228 return fetchServerAction(singleFetch); 9229 }); 9230 } 9231 let lazyRoutePromise; 9232 async function getLazyRoute() { 9233 if (lazyRoutePromise) { 9234 return await lazyRoutePromise; 9235 } 9236 lazyRoutePromise = (async () => { 9237 if (route.clientLoaderModule || route.clientActionModule) { 9238 await new Promise((resolve) => setTimeout(resolve, 0)); 9239 } 9240 let routeModulePromise = loadRouteModuleWithBlockingLinks( 9241 route, 9242 routeModulesCache 9243 ); 9244 prefetchRouteModuleChunks(route); 9245 return await routeModulePromise; 9246 })(); 9247 return await lazyRoutePromise; 9248 } 9249 dataRoute.lazy = { 9250 loader: route.hasClientLoader ? async () => { 9251 let { clientLoader } = route.clientLoaderModule ? await import( 9252 /* @vite-ignore */ 9253 /* webpackIgnore: true */ 9254 __vite__injectQuery(route.clientLoaderModule, 'import') 9255 ) : await getLazyRoute(); 9256 invariant2(clientLoader, "No `clientLoader` export found"); 9257 return (args, singleFetch) => clientLoader({ 9258 ...args, 9259 async serverLoader() { 9260 preventInvalidServerHandlerCall("loader", route); 9261 return fetchServerLoader(singleFetch); 9262 } 9263 }); 9264 } : void 0, 9265 action: route.hasClientAction ? async () => { 9266 let clientActionPromise = route.clientActionModule ? import( 9267 /* @vite-ignore */ 9268 /* webpackIgnore: true */ 9269 __vite__injectQuery(route.clientActionModule, 'import') 9270 ) : getLazyRoute(); 9271 prefetchRouteModuleChunks(route); 9272 let { clientAction } = await clientActionPromise; 9273 invariant2(clientAction, "No `clientAction` export found"); 9274 return (args, singleFetch) => clientAction({ 9275 ...args, 9276 async serverAction() { 9277 preventInvalidServerHandlerCall("action", route); 9278 return fetchServerAction(singleFetch); 9279 } 9280 }); 9281 } : void 0, 9282 middleware: route.hasClientMiddleware ? async () => { 9283 let { clientMiddleware } = route.clientMiddlewareModule ? await import( 9284 /* @vite-ignore */ 9285 /* webpackIgnore: true */ 9286 __vite__injectQuery(route.clientMiddlewareModule, 'import') 9287 ) : await getLazyRoute(); 9288 invariant2(clientMiddleware, "No `clientMiddleware` export found"); 9289 return clientMiddleware; 9290 } : void 0, 9291 shouldRevalidate: async () => { 9292 let lazyRoute = await getLazyRoute(); 9293 return getShouldRevalidateFunction( 9294 dataRoute.path, 9295 lazyRoute, 9296 route, 9297 ssr, 9298 needsRevalidation 9299 ); 9300 }, 9301 handle: async () => (await getLazyRoute()).handle, 9302 // No need to wrap these in layout since the root route is never 9303 // loaded via route.lazy() 9304 Component: async () => (await getLazyRoute()).Component, 9305 ErrorBoundary: route.hasErrorBoundary ? async () => (await getLazyRoute()).ErrorBoundary : void 0 9306 }; 9307 } 9308 let children = createClientRoutes( 9309 manifest, 9310 routeModulesCache, 9311 initialState, 9312 ssr, 9313 isSpaMode, 9314 route.id, 9315 routesByParentId, 9316 needsRevalidation 9317 ); 9318 if (children.length > 0) dataRoute.children = children; 9319 return dataRoute; 9320 }); 9321} 9322function getShouldRevalidateFunction(path, route, manifestRoute, ssr, needsRevalidation) { 9323 if (needsRevalidation) { 9324 return wrapShouldRevalidateForHdr( 9325 manifestRoute.id, 9326 route.shouldRevalidate, 9327 needsRevalidation 9328 ); 9329 } 9330 if (!ssr && manifestRoute.hasLoader && !manifestRoute.hasClientLoader) { 9331 let myParams = path ? compilePath(path)[1].map((p) => p.paramName) : []; 9332 const didParamsChange = (opts) => myParams.some((p) => opts.currentParams[p] !== opts.nextParams[p]); 9333 if (route.shouldRevalidate) { 9334 let fn = route.shouldRevalidate; 9335 return (opts) => fn({ 9336 ...opts, 9337 defaultShouldRevalidate: didParamsChange(opts) 9338 }); 9339 } else { 9340 return (opts) => didParamsChange(opts); 9341 } 9342 } 9343 return route.shouldRevalidate; 9344} 9345function wrapShouldRevalidateForHdr(routeId, routeShouldRevalidate, needsRevalidation) { 9346 let handledRevalidation = false; 9347 return (arg) => { 9348 if (!handledRevalidation) { 9349 handledRevalidation = true; 9350 return needsRevalidation.has(routeId); 9351 } 9352 return routeShouldRevalidate ? routeShouldRevalidate(arg) : arg.defaultShouldRevalidate; 9353 }; 9354} 9355async function loadRouteModuleWithBlockingLinks(route, routeModules) { 9356 let routeModulePromise = loadRouteModule(route, routeModules); 9357 let prefetchRouteCssPromise = prefetchRouteCss(route); 9358 let routeModule = await routeModulePromise; 9359 await Promise.all([ 9360 prefetchRouteCssPromise, 9361 prefetchStyleLinks(route, routeModule) 9362 ]); 9363 return { 9364 Component: getRouteModuleComponent(routeModule), 9365 ErrorBoundary: routeModule.ErrorBoundary, 9366 clientMiddleware: routeModule.clientMiddleware, 9367 clientAction: routeModule.clientAction, 9368 clientLoader: routeModule.clientLoader, 9369 handle: routeModule.handle, 9370 links: routeModule.links, 9371 meta: routeModule.meta, 9372 shouldRevalidate: routeModule.shouldRevalidate 9373 }; 9374} 9375function getRouteModuleComponent(routeModule) { 9376 if (routeModule.default == null) return void 0; 9377 let isEmptyObject = typeof routeModule.default === "object" && Object.keys(routeModule.default).length === 0; 9378 if (!isEmptyObject) { 9379 return routeModule.default; 9380 } 9381} 9382function shouldHydrateRouteLoader(routeId, clientLoader, hasLoader, isSpaMode) { 9383 return isSpaMode && routeId !== "root" || clientLoader != null && (clientLoader.hydrate === true || hasLoader !== true); 9384} 9385var nextPaths = /* @__PURE__ */ new Set(); 9386var discoveredPathsMaxSize = 1e3; 9387var discoveredPaths = /* @__PURE__ */ new Set(); 9388var URL_LIMIT = 7680; 9389function isFogOfWarEnabled(routeDiscovery, ssr) { 9390 return routeDiscovery.mode === "lazy" && ssr === true; 9391} 9392function getPartialManifest({ sri, ...manifest }, router2) { 9393 let routeIds = new Set(router2.state.matches.map((m) => m.route.id)); 9394 let segments = router2.state.location.pathname.split("/").filter(Boolean); 9395 let paths = ["/"]; 9396 segments.pop(); 9397 while (segments.length > 0) { 9398 paths.push(`/${segments.join("/")}`); 9399 segments.pop(); 9400 } 9401 paths.forEach((path) => { 9402 let matches = matchRoutes(router2.routes, path, router2.basename); 9403 if (matches) { 9404 matches.forEach((m) => routeIds.add(m.route.id)); 9405 } 9406 }); 9407 let initialRoutes = [...routeIds].reduce( 9408 (acc, id) => Object.assign(acc, { [id]: manifest.routes[id] }), 9409 {} 9410 ); 9411 return { 9412 ...manifest, 9413 routes: initialRoutes, 9414 sri: sri ? true : void 0 9415 }; 9416} 9417function getPatchRoutesOnNavigationFunction(getRouter, manifest, routeModules, ssr, routeDiscovery, isSpaMode, basename) { 9418 if (!isFogOfWarEnabled(routeDiscovery, ssr)) { 9419 return void 0; 9420 } 9421 return async ({ path, patch, signal, fetcherKey }) => { 9422 if (discoveredPaths.has(path)) { 9423 return; 9424 } 9425 let { state } = getRouter(); 9426 await fetchAndApplyManifestPatches( 9427 [path], 9428 // If we're patching for a fetcher call, reload the current location 9429 // Otherwise prefer any ongoing navigation location 9430 fetcherKey ? window.location.href : createPath(state.navigation.location || state.location), 9431 manifest, 9432 routeModules, 9433 ssr, 9434 isSpaMode, 9435 basename, 9436 routeDiscovery.manifestPath, 9437 patch, 9438 signal 9439 ); 9440 }; 9441} 9442function useFogOFWarDiscovery(router2, manifest, routeModules, ssr, routeDiscovery, isSpaMode) { 9443 React7.useEffect(() => { 9444 if (!isFogOfWarEnabled(routeDiscovery, ssr) || // @ts-expect-error - TS doesn't know about this yet 9445 window.navigator?.connection?.saveData === true) { 9446 return; 9447 } 9448 function registerElement(el) { 9449 let path = el.tagName === "FORM" ? el.getAttribute("action") : el.getAttribute("href"); 9450 if (!path) { 9451 return; 9452 } 9453 let pathname = el.tagName === "A" ? el.pathname : new URL(path, window.location.origin).pathname; 9454 if (!discoveredPaths.has(pathname)) { 9455 nextPaths.add(pathname); 9456 } 9457 } 9458 async function fetchPatches() { 9459 document.querySelectorAll("a[data-discover], form[data-discover]").forEach(registerElement); 9460 let lazyPaths = Array.from(nextPaths.keys()).filter((path) => { 9461 if (discoveredPaths.has(path)) { 9462 nextPaths.delete(path); 9463 return false; 9464 } 9465 return true; 9466 }); 9467 if (lazyPaths.length === 0) { 9468 return; 9469 } 9470 try { 9471 await fetchAndApplyManifestPatches( 9472 lazyPaths, 9473 null, 9474 manifest, 9475 routeModules, 9476 ssr, 9477 isSpaMode, 9478 router2.basename, 9479 routeDiscovery.manifestPath, 9480 router2.patchRoutes 9481 ); 9482 } catch (e) { 9483 console.error("Failed to fetch manifest patches", e); 9484 } 9485 } 9486 let debouncedFetchPatches = debounce(fetchPatches, 100); 9487 fetchPatches(); 9488 let observer = new MutationObserver(() => debouncedFetchPatches()); 9489 observer.observe(document.documentElement, { 9490 subtree: true, 9491 childList: true, 9492 attributes: true, 9493 attributeFilter: ["data-discover", "href", "action"] 9494 }); 9495 return () => observer.disconnect(); 9496 }, [ssr, isSpaMode, manifest, routeModules, router2, routeDiscovery]); 9497} 9498function getManifestPath(_manifestPath, basename) { 9499 let manifestPath = _manifestPath || "/__manifest"; 9500 if (basename == null) { 9501 return manifestPath; 9502 } 9503 return `${basename}${manifestPath}`.replace(/\/+/g, "/"); 9504} 9505var MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version"; 9506async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) { 9507 const searchParams = new URLSearchParams(); 9508 searchParams.set("paths", paths.sort().join(",")); 9509 searchParams.set("version", manifest.version); 9510 let url = new URL( 9511 getManifestPath(manifestPath, basename), 9512 window.location.origin 9513 ); 9514 url.search = searchParams.toString(); 9515 if (url.toString().length > URL_LIMIT) { 9516 nextPaths.clear(); 9517 return; 9518 } 9519 let serverPatches; 9520 try { 9521 let res = await fetch(url, { signal }); 9522 if (!res.ok) { 9523 throw new Error(`${res.status} ${res.statusText}`); 9524 } else if (res.status === 204 && res.headers.has("X-Remix-Reload-Document")) { 9525 if (!errorReloadPath) { 9526 console.warn( 9527 "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." 9528 ); 9529 return; 9530 } 9531 try { 9532 if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) { 9533 console.error( 9534 "Unable to discover routes due to manifest version mismatch." 9535 ); 9536 return; 9537 } 9538 sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version); 9539 } catch { 9540 } 9541 window.location.href = errorReloadPath; 9542 console.warn("Detected manifest version mismatch, reloading..."); 9543 await new Promise(() => { 9544 }); 9545 } else if (res.status >= 400) { 9546 throw new Error(await res.text()); 9547 } 9548 try { 9549 sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY); 9550 } catch { 9551 } 9552 serverPatches = await res.json(); 9553 } catch (e) { 9554 if (signal?.aborted) return; 9555 throw e; 9556 } 9557 let knownRoutes = new Set(Object.keys(manifest.routes)); 9558 let patches = Object.values(serverPatches).reduce((acc, route) => { 9559 if (route && !knownRoutes.has(route.id)) { 9560 acc[route.id] = route; 9561 } 9562 return acc; 9563 }, {}); 9564 Object.assign(manifest.routes, patches); 9565 paths.forEach((p) => addToFifoQueue(p, discoveredPaths)); 9566 let parentIds = /* @__PURE__ */ new Set(); 9567 Object.values(patches).forEach((patch) => { 9568 if (patch && (!patch.parentId || !patches[patch.parentId])) { 9569 parentIds.add(patch.parentId); 9570 } 9571 }); 9572 parentIds.forEach( 9573 (parentId) => patchRoutes( 9574 parentId || null, 9575 createClientRoutes(patches, routeModules, null, ssr, isSpaMode, parentId) 9576 ) 9577 ); 9578} 9579function addToFifoQueue(path, queue) { 9580 if (queue.size >= discoveredPathsMaxSize) { 9581 let first = queue.values().next().value; 9582 queue.delete(first); 9583 } 9584 queue.add(path); 9585} 9586function debounce(callback, wait) { 9587 let timeoutId; 9588 return (...args) => { 9589 window.clearTimeout(timeoutId); 9590 timeoutId = window.setTimeout(() => callback(...args), wait); 9591 }; 9592} 9593function useDataRouterContext2() { 9594 let context = React8.useContext(DataRouterContext); 9595 invariant2( 9596 context, 9597 "You must render this element inside a <DataRouterContext.Provider> element" 9598 ); 9599 return context; 9600} 9601function useDataRouterStateContext() { 9602 let context = React8.useContext(DataRouterStateContext); 9603 invariant2( 9604 context, 9605 "You must render this element inside a <DataRouterStateContext.Provider> element" 9606 ); 9607 return context; 9608} 9609var FrameworkContext = React8.createContext(void 0); 9610FrameworkContext.displayName = "FrameworkContext"; 9611function useFrameworkContext() { 9612 let context = React8.useContext(FrameworkContext); 9613 invariant2( 9614 context, 9615 "You must render this element inside a <HydratedRouter> element" 9616 ); 9617 return context; 9618} 9619function usePrefetchBehavior(prefetch, theirElementProps) { 9620 let frameworkContext = React8.useContext(FrameworkContext); 9621 let [maybePrefetch, setMaybePrefetch] = React8.useState(false); 9622 let [shouldPrefetch, setShouldPrefetch] = React8.useState(false); 9623 let { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps; 9624 let ref = React8.useRef(null); 9625 React8.useEffect(() => { 9626 if (prefetch === "render") { 9627 setShouldPrefetch(true); 9628 } 9629 if (prefetch === "viewport") { 9630 let callback = (entries) => { 9631 entries.forEach((entry) => { 9632 setShouldPrefetch(entry.isIntersecting); 9633 }); 9634 }; 9635 let observer = new IntersectionObserver(callback, { threshold: 0.5 }); 9636 if (ref.current) observer.observe(ref.current); 9637 return () => { 9638 observer.disconnect(); 9639 }; 9640 } 9641 }, [prefetch]); 9642 React8.useEffect(() => { 9643 if (maybePrefetch) { 9644 let id = setTimeout(() => { 9645 setShouldPrefetch(true); 9646 }, 100); 9647 return () => { 9648 clearTimeout(id); 9649 }; 9650 } 9651 }, [maybePrefetch]); 9652 let setIntent = () => { 9653 setMaybePrefetch(true); 9654 }; 9655 let cancelIntent = () => { 9656 setMaybePrefetch(false); 9657 setShouldPrefetch(false); 9658 }; 9659 if (!frameworkContext) { 9660 return [false, ref, {}]; 9661 } 9662 if (prefetch !== "intent") { 9663 return [shouldPrefetch, ref, {}]; 9664 } 9665 return [ 9666 shouldPrefetch, 9667 ref, 9668 { 9669 onFocus: composeEventHandlers(onFocus, setIntent), 9670 onBlur: composeEventHandlers(onBlur, cancelIntent), 9671 onMouseEnter: composeEventHandlers(onMouseEnter, setIntent), 9672 onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent), 9673 onTouchStart: composeEventHandlers(onTouchStart, setIntent) 9674 } 9675 ]; 9676} 9677function composeEventHandlers(theirHandler, ourHandler) { 9678 return (event) => { 9679 theirHandler && theirHandler(event); 9680 if (!event.defaultPrevented) { 9681 ourHandler(event); 9682 } 9683 }; 9684} 9685function getActiveMatches(matches, errors, isSpaMode) { 9686 if (isSpaMode && !isHydrated) { 9687 return [matches[0]]; 9688 } 9689 if (errors) { 9690 let errorIdx = matches.findIndex((m) => errors[m.route.id] !== void 0); 9691 return matches.slice(0, errorIdx + 1); 9692 } 9693 return matches; 9694} 9695var CRITICAL_CSS_DATA_ATTRIBUTE = "data-react-router-critical-css"; 9696function Links({ nonce, crossOrigin }) { 9697 let { isSpaMode, manifest, routeModules, criticalCss } = useFrameworkContext(); 9698 let { errors, matches: routerMatches } = useDataRouterStateContext(); 9699 let matches = getActiveMatches(routerMatches, errors, isSpaMode); 9700 let keyedLinks = React8.useMemo( 9701 () => getKeyedLinksForMatches(matches, routeModules, manifest), 9702 [matches, routeModules, manifest] 9703 ); 9704 return React8.createElement(React8.Fragment, null, typeof criticalCss === "string" ? React8.createElement( 9705 "style", 9706 { 9707 ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: "" }, 9708 nonce, 9709 dangerouslySetInnerHTML: { __html: criticalCss } 9710 } 9711 ) : null, typeof criticalCss === "object" ? React8.createElement( 9712 "link", 9713 { 9714 ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: "" }, 9715 rel: "stylesheet", 9716 href: criticalCss.href, 9717 nonce, 9718 crossOrigin 9719 } 9720 ) : null, keyedLinks.map( 9721 ({ key, link }) => isPageLinkDescriptor(link) ? React8.createElement( 9722 PrefetchPageLinks, 9723 { 9724 key, 9725 nonce, 9726 ...link, 9727 crossOrigin: link.crossOrigin ?? crossOrigin 9728 } 9729 ) : React8.createElement( 9730 "link", 9731 { 9732 key, 9733 nonce, 9734 ...link, 9735 crossOrigin: link.crossOrigin ?? crossOrigin 9736 } 9737 ) 9738 )); 9739} 9740function PrefetchPageLinks({ page, ...linkProps }) { 9741 let { router: router2 } = useDataRouterContext2(); 9742 let matches = React8.useMemo( 9743 () => matchRoutes(router2.routes, page, router2.basename), 9744 [router2.routes, page, router2.basename] 9745 ); 9746 if (!matches) { 9747 return null; 9748 } 9749 return React8.createElement(PrefetchPageLinksImpl, { page, matches, ...linkProps }); 9750} 9751function useKeyedPrefetchLinks(matches) { 9752 let { manifest, routeModules } = useFrameworkContext(); 9753 let [keyedPrefetchLinks, setKeyedPrefetchLinks] = React8.useState([]); 9754 React8.useEffect(() => { 9755 let interrupted = false; 9756 void getKeyedPrefetchLinks(matches, manifest, routeModules).then( 9757 (links) => { 9758 if (!interrupted) { 9759 setKeyedPrefetchLinks(links); 9760 } 9761 } 9762 ); 9763 return () => { 9764 interrupted = true; 9765 }; 9766 }, [matches, manifest, routeModules]); 9767 return keyedPrefetchLinks; 9768} 9769function PrefetchPageLinksImpl({ 9770 page, 9771 matches: nextMatches, 9772 ...linkProps 9773}) { 9774 let location2 = useLocation(); 9775 let { future, manifest, routeModules } = useFrameworkContext(); 9776 let { basename } = useDataRouterContext2(); 9777 let { loaderData, matches } = useDataRouterStateContext(); 9778 let newMatchesForData = React8.useMemo( 9779 () => getNewMatchesForLinks( 9780 page, 9781 nextMatches, 9782 matches, 9783 manifest, 9784 location2, 9785 "data" 9786 ), 9787 [page, nextMatches, matches, manifest, location2] 9788 ); 9789 let newMatchesForAssets = React8.useMemo( 9790 () => getNewMatchesForLinks( 9791 page, 9792 nextMatches, 9793 matches, 9794 manifest, 9795 location2, 9796 "assets" 9797 ), 9798 [page, nextMatches, matches, manifest, location2] 9799 ); 9800 let dataHrefs = React8.useMemo(() => { 9801 if (page === location2.pathname + location2.search + location2.hash) { 9802 return []; 9803 } 9804 let routesParams = /* @__PURE__ */ new Set(); 9805 let foundOptOutRoute = false; 9806 nextMatches.forEach((m) => { 9807 let manifestRoute = manifest.routes[m.route.id]; 9808 if (!manifestRoute || !manifestRoute.hasLoader) { 9809 return; 9810 } 9811 if (!newMatchesForData.some((m2) => m2.route.id === m.route.id) && m.route.id in loaderData && routeModules[m.route.id]?.shouldRevalidate) { 9812 foundOptOutRoute = true; 9813 } else if (manifestRoute.hasClientLoader) { 9814 foundOptOutRoute = true; 9815 } else { 9816 routesParams.add(m.route.id); 9817 } 9818 }); 9819 if (routesParams.size === 0) { 9820 return []; 9821 } 9822 let url = singleFetchUrl( 9823 page, 9824 basename, 9825 future.unstable_trailingSlashAwareDataRequests, 9826 "data" 9827 ); 9828 if (foundOptOutRoute && routesParams.size > 0) { 9829 url.searchParams.set( 9830 "_routes", 9831 nextMatches.filter((m) => routesParams.has(m.route.id)).map((m) => m.route.id).join(",") 9832 ); 9833 } 9834 return [url.pathname + url.search]; 9835 }, [ 9836 basename, 9837 future.unstable_trailingSlashAwareDataRequests, 9838 loaderData, 9839 location2, 9840 manifest, 9841 newMatchesForData, 9842 nextMatches, 9843 page, 9844 routeModules 9845 ]); 9846 let moduleHrefs = React8.useMemo( 9847 () => getModuleLinkHrefs(newMatchesForAssets, manifest), 9848 [newMatchesForAssets, manifest] 9849 ); 9850 let keyedPrefetchLinks = useKeyedPrefetchLinks(newMatchesForAssets); 9851 return React8.createElement(React8.Fragment, null, dataHrefs.map((href2) => React8.createElement("link", { key: href2, rel: "prefetch", as: "fetch", href: href2, ...linkProps })), moduleHrefs.map((href2) => React8.createElement("link", { key: href2, rel: "modulepreload", href: href2, ...linkProps })), keyedPrefetchLinks.map(({ key, link }) => ( 9852 // these don't spread `linkProps` because they are full link descriptors 9853 // already with their own props 9854 React8.createElement( 9855 "link", 9856 { 9857 key, 9858 nonce: linkProps.nonce, 9859 ...link, 9860 crossOrigin: link.crossOrigin ?? linkProps.crossOrigin 9861 } 9862 ) 9863 ))); 9864} 9865function Meta() { 9866 let { isSpaMode, routeModules } = useFrameworkContext(); 9867 let { 9868 errors, 9869 matches: routerMatches, 9870 loaderData 9871 } = useDataRouterStateContext(); 9872 let location2 = useLocation(); 9873 let _matches = getActiveMatches(routerMatches, errors, isSpaMode); 9874 let error = null; 9875 if (errors) { 9876 error = errors[_matches[_matches.length - 1].route.id]; 9877 } 9878 let meta = []; 9879 let leafMeta = null; 9880 let matches = []; 9881 for (let i = 0; i < _matches.length; i++) { 9882 let _match = _matches[i]; 9883 let routeId = _match.route.id; 9884 let data2 = loaderData[routeId]; 9885 let params = _match.params; 9886 let routeModule = routeModules[routeId]; 9887 let routeMeta = []; 9888 let match = { 9889 id: routeId, 9890 data: data2, 9891 loaderData: data2, 9892 meta: [], 9893 params: _match.params, 9894 pathname: _match.pathname, 9895 handle: _match.route.handle, 9896 error 9897 }; 9898 matches[i] = match; 9899 if (routeModule?.meta) { 9900 routeMeta = typeof routeModule.meta === "function" ? routeModule.meta({ 9901 data: data2, 9902 loaderData: data2, 9903 params, 9904 location: location2, 9905 matches, 9906 error 9907 }) : Array.isArray(routeModule.meta) ? [...routeModule.meta] : routeModule.meta; 9908 } else if (leafMeta) { 9909 routeMeta = [...leafMeta]; 9910 } 9911 routeMeta = routeMeta || []; 9912 if (!Array.isArray(routeMeta)) { 9913 throw new Error( 9914 "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" 9915 ); 9916 } 9917 match.meta = routeMeta; 9918 matches[i] = match; 9919 meta = [...routeMeta]; 9920 leafMeta = meta; 9921 } 9922 return React8.createElement(React8.Fragment, null, meta.flat().map((metaProps) => { 9923 if (!metaProps) { 9924 return null; 9925 } 9926 if ("tagName" in metaProps) { 9927 let { tagName, ...rest } = metaProps; 9928 if (!isValidMetaTag(tagName)) { 9929 console.warn( 9930 `A meta object uses an invalid tagName: ${tagName}. Expected either 'link' or 'meta'` 9931 ); 9932 return null; 9933 } 9934 let Comp = tagName; 9935 return React8.createElement(Comp, { key: JSON.stringify(rest), ...rest }); 9936 } 9937 if ("title" in metaProps) { 9938 return React8.createElement("title", { key: "title" }, String(metaProps.title)); 9939 } 9940 if ("charset" in metaProps) { 9941 metaProps.charSet ?? (metaProps.charSet = metaProps.charset); 9942 delete metaProps.charset; 9943 } 9944 if ("charSet" in metaProps && metaProps.charSet != null) { 9945 return typeof metaProps.charSet === "string" ? React8.createElement("meta", { key: "charSet", charSet: metaProps.charSet }) : null; 9946 } 9947 if ("script:ld+json" in metaProps) { 9948 try { 9949 let json = JSON.stringify(metaProps["script:ld+json"]); 9950 return React8.createElement( 9951 "script", 9952 { 9953 key: `script:ld+json:${json}`, 9954 type: "application/ld+json", 9955 dangerouslySetInnerHTML: { __html: escapeHtml(json) } 9956 } 9957 ); 9958 } catch (err) { 9959 return null; 9960 } 9961 } 9962 return React8.createElement("meta", { key: JSON.stringify(metaProps), ...metaProps }); 9963 })); 9964} 9965function isValidMetaTag(tagName) { 9966 return typeof tagName === "string" && /^(meta|link)$/.test(tagName); 9967} 9968var isHydrated = false; 9969function setIsHydrated() { 9970 isHydrated = true; 9971} 9972function Scripts(scriptProps) { 9973 let { 9974 manifest, 9975 serverHandoffString, 9976 isSpaMode, 9977 renderMeta, 9978 routeDiscovery, 9979 ssr 9980 } = useFrameworkContext(); 9981 let { router: router2, static: isStatic, staticContext } = useDataRouterContext2(); 9982 let { matches: routerMatches } = useDataRouterStateContext(); 9983 let isRSCRouterContext = useIsRSCRouterContext(); 9984 let enableFogOfWar = isFogOfWarEnabled(routeDiscovery, ssr); 9985 if (renderMeta) { 9986 renderMeta.didRenderScripts = true; 9987 } 9988 let matches = getActiveMatches(routerMatches, null, isSpaMode); 9989 React8.useEffect(() => { 9990 setIsHydrated(); 9991 }, []); 9992 let initialScripts = React8.useMemo(() => { 9993 if (isRSCRouterContext) { 9994 return null; 9995 } 9996 let streamScript = "window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());"; 9997 let contextScript = staticContext ? `window.__reactRouterContext = ${serverHandoffString};${streamScript}` : " "; 9998 let routeModulesScript = !isStatic ? " " : `${manifest.hmr?.runtime ? `import ${JSON.stringify(manifest.hmr.runtime)};` : ""}${!enableFogOfWar ? `import ${JSON.stringify(manifest.url)}` : ""}; 9999${matches.map((match, routeIndex) => { 10000 let routeVarName = `route${routeIndex}`; 10001 let manifestEntry = manifest.routes[match.route.id]; 10002 invariant2(manifestEntry, `Route ${match.route.id} not found in manifest`); 10003 let { 10004 clientActionModule, 10005 clientLoaderModule, 10006 clientMiddlewareModule, 10007 hydrateFallbackModule, 10008 module 10009 } = manifestEntry; 10010 let chunks = [ 10011 ...clientActionModule ? [ 10012 { 10013 module: clientActionModule, 10014 varName: `${routeVarName}_clientAction` 10015 } 10016 ] : [], 10017 ...clientLoaderModule ? [ 10018 { 10019 module: clientLoaderModule, 10020 varName: `${routeVarName}_clientLoader` 10021 } 10022 ] : [], 10023 ...clientMiddlewareModule ? [ 10024 { 10025 module: clientMiddlewareModule, 10026 varName: `${routeVarName}_clientMiddleware` 10027 } 10028 ] : [], 10029 ...hydrateFallbackModule ? [ 10030 { 10031 module: hydrateFallbackModule, 10032 varName: `${routeVarName}_HydrateFallback` 10033 } 10034 ] : [], 10035 { module, varName: `${routeVarName}_main` } 10036 ]; 10037 if (chunks.length === 1) { 10038 return `import * as ${routeVarName} from ${JSON.stringify(module)};`; 10039 } 10040 let chunkImportsSnippet = chunks.map((chunk) => `import * as ${chunk.varName} from "${chunk.module}";`).join("\n"); 10041 let mergedChunksSnippet = `const ${routeVarName} = {${chunks.map((chunk) => `...${chunk.varName}`).join(",")}};`; 10042 return [chunkImportsSnippet, mergedChunksSnippet].join("\n"); 10043 }).join("\n")} 10044 ${enableFogOfWar ? ( 10045 // Inline a minimal manifest with the SSR matches 10046 `window.__reactRouterManifest = ${JSON.stringify( 10047 getPartialManifest(manifest, router2), 10048 null, 10049 2 10050 )};` 10051 ) : ""} 10052 window.__reactRouterRouteModules = {${matches.map((match, index) => `${JSON.stringify(match.route.id)}:route${index}`).join(",")}}; 10053 10054import(${JSON.stringify(manifest.entry.module)});`; 10055 return React8.createElement(React8.Fragment, null, React8.createElement( 10056 "script", 10057 { 10058 ...scriptProps, 10059 suppressHydrationWarning: true, 10060 dangerouslySetInnerHTML: { __html: contextScript }, 10061 type: void 0 10062 } 10063 ), React8.createElement( 10064 "script", 10065 { 10066 ...scriptProps, 10067 suppressHydrationWarning: true, 10068 dangerouslySetInnerHTML: { __html: routeModulesScript }, 10069 type: "module", 10070 async: true 10071 } 10072 )); 10073 }, []); 10074 let preloads = isHydrated || isRSCRouterContext ? [] : dedupe( 10075 manifest.entry.imports.concat( 10076 getModuleLinkHrefs(matches, manifest, { 10077 includeHydrateFallback: true 10078 }) 10079 ) 10080 ); 10081 let sri = typeof manifest.sri === "object" ? manifest.sri : {}; 10082 warnOnce( 10083 !isRSCRouterContext, 10084 "The <Scripts /> element is a no-op when using RSC and can be safely removed." 10085 ); 10086 return isHydrated || isRSCRouterContext ? null : React8.createElement(React8.Fragment, null, typeof manifest.sri === "object" ? React8.createElement( 10087 "script", 10088 { 10089 ...scriptProps, 10090 "rr-importmap": "", 10091 type: "importmap", 10092 suppressHydrationWarning: true, 10093 dangerouslySetInnerHTML: { 10094 __html: JSON.stringify({ 10095 integrity: sri 10096 }) 10097 } 10098 } 10099 ) : null, !enableFogOfWar ? React8.createElement( 10100 "link", 10101 { 10102 rel: "modulepreload", 10103 href: manifest.url, 10104 crossOrigin: scriptProps.crossOrigin, 10105 integrity: sri[manifest.url], 10106 suppressHydrationWarning: true 10107 } 10108 ) : null, React8.createElement( 10109 "link", 10110 { 10111 rel: "modulepreload", 10112 href: manifest.entry.module, 10113 crossOrigin: scriptProps.crossOrigin, 10114 integrity: sri[manifest.entry.module], 10115 suppressHydrationWarning: true 10116 } 10117 ), preloads.map((path) => React8.createElement( 10118 "link", 10119 { 10120 key: path, 10121 rel: "modulepreload", 10122 href: path, 10123 crossOrigin: scriptProps.crossOrigin, 10124 integrity: sri[path], 10125 suppressHydrationWarning: true 10126 } 10127 )), initialScripts); 10128} 10129function dedupe(array) { 10130 return [...new Set(array)]; 10131} 10132function mergeRefs(...refs) { 10133 return (value) => { 10134 refs.forEach((ref) => { 10135 if (typeof ref === "function") { 10136 ref(value); 10137 } else if (ref != null) { 10138 ref.current = value; 10139 } 10140 }); 10141 }; 10142} 10143var RemixErrorBoundary = class extends React9.Component { 10144 constructor(props) { 10145 super(props); 10146 this.state = { error: props.error || null, location: props.location }; 10147 } 10148 static getDerivedStateFromError(error) { 10149 return { error }; 10150 } 10151 static getDerivedStateFromProps(props, state) { 10152 if (state.location !== props.location) { 10153 return { error: props.error || null, location: props.location }; 10154 } 10155 return { error: props.error || state.error, location: state.location }; 10156 } 10157 render() { 10158 if (this.state.error) { 10159 return React9.createElement( 10160 RemixRootDefaultErrorBoundary, 10161 { 10162 error: this.state.error, 10163 isOutsideRemixApp: true 10164 } 10165 ); 10166 } else { 10167 return this.props.children; 10168 } 10169 } 10170}; 10171function RemixRootDefaultErrorBoundary({ 10172 error, 10173 isOutsideRemixApp 10174}) { 10175 console.error(error); 10176 let heyDeveloper = React9.createElement( 10177 "script", 10178 { 10179 dangerouslySetInnerHTML: { 10180 __html: ` 10181 console.log( 10182 "💿 Hey developer 👋. 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." 10183 ); 10184 ` 10185 } 10186 } 10187 ); 10188 if (isRouteErrorResponse(error)) { 10189 return React9.createElement(BoundaryShell, { title: "Unhandled Thrown Response!" }, React9.createElement("h1", { style: { fontSize: "24px" } }, error.status, " ", error.statusText), ENABLE_DEV_WARNINGS ? heyDeveloper : null); 10190 } 10191 let errorInstance; 10192 if (error instanceof Error) { 10193 errorInstance = error; 10194 } else { 10195 let errorString = error == null ? "Unknown Error" : typeof error === "object" && "toString" in error ? error.toString() : JSON.stringify(error); 10196 errorInstance = new Error(errorString); 10197 } 10198 return React9.createElement( 10199 BoundaryShell, 10200 { 10201 title: "Application Error!", 10202 isOutsideRemixApp 10203 }, 10204 React9.createElement("h1", { style: { fontSize: "24px" } }, "Application Error"), 10205 React9.createElement( 10206 "pre", 10207 { 10208 style: { 10209 padding: "2rem", 10210 background: "hsla(10, 50%, 50%, 0.1)", 10211 color: "red", 10212 overflow: "auto" 10213 } 10214 }, 10215 errorInstance.stack 10216 ), 10217 heyDeveloper 10218 ); 10219} 10220function BoundaryShell({ 10221 title, 10222 renderScripts, 10223 isOutsideRemixApp, 10224 children 10225}) { 10226 let { routeModules } = useFrameworkContext(); 10227 if (routeModules.root?.Layout && !isOutsideRemixApp) { 10228 return children; 10229 } 10230 return React9.createElement("html", { lang: "en" }, React9.createElement("head", null, React9.createElement("meta", { charSet: "utf-8" }), React9.createElement( 10231 "meta", 10232 { 10233 name: "viewport", 10234 content: "width=device-width,initial-scale=1,viewport-fit=cover" 10235 } 10236 ), React9.createElement("title", null, title)), React9.createElement("body", null, React9.createElement("main", { style: { fontFamily: "system-ui, sans-serif", padding: "2rem" } }, children, renderScripts ? React9.createElement(Scripts, null) : null))); 10237} 10238var isBrowser2 = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"; 10239try { 10240 if (isBrowser2) { 10241 window.__reactRouterVersion = // @ts-expect-error 10242 "7.13.1"; 10243 } 10244} catch (e) { 10245} 10246function createBrowserRouter(routes, opts) { 10247 return createRouter({ 10248 basename: opts?.basename, 10249 getContext: opts?.getContext, 10250 future: opts?.future, 10251 history: createBrowserHistory({ window: opts?.window }), 10252 hydrationData: opts?.hydrationData || parseHydrationData(), 10253 routes, 10254 mapRouteProperties, 10255 hydrationRouteProperties, 10256 dataStrategy: opts?.dataStrategy, 10257 patchRoutesOnNavigation: opts?.patchRoutesOnNavigation, 10258 window: opts?.window, 10259 unstable_instrumentations: opts?.unstable_instrumentations 10260 }).initialize(); 10261} 10262function createHashRouter(routes, opts) { 10263 return createRouter({ 10264 basename: opts?.basename, 10265 getContext: opts?.getContext, 10266 future: opts?.future, 10267 history: createHashHistory({ window: opts?.window }), 10268 hydrationData: opts?.hydrationData || parseHydrationData(), 10269 routes, 10270 mapRouteProperties, 10271 hydrationRouteProperties, 10272 dataStrategy: opts?.dataStrategy, 10273 patchRoutesOnNavigation: opts?.patchRoutesOnNavigation, 10274 window: opts?.window, 10275 unstable_instrumentations: opts?.unstable_instrumentations 10276 }).initialize(); 10277} 10278function parseHydrationData() { 10279 let state = window?.__staticRouterHydrationData; 10280 if (state && state.errors) { 10281 state = { 10282 ...state, 10283 errors: deserializeErrors(state.errors) 10284 }; 10285 } 10286 return state; 10287} 10288function deserializeErrors(errors) { 10289 if (!errors) return null; 10290 let entries = Object.entries(errors); 10291 let serialized = {}; 10292 for (let [key, val] of entries) { 10293 if (val && val.__type === "RouteErrorResponse") { 10294 serialized[key] = new ErrorResponseImpl( 10295 val.status, 10296 val.statusText, 10297 val.data, 10298 val.internal === true 10299 ); 10300 } else if (val && val.__type === "Error") { 10301 if (val.__subType) { 10302 let ErrorConstructor = window[val.__subType]; 10303 if (typeof ErrorConstructor === "function") { 10304 try { 10305 let error = new ErrorConstructor(val.message); 10306 error.stack = ""; 10307 serialized[key] = error; 10308 } catch (e) { 10309 } 10310 } 10311 } 10312 if (serialized[key] == null) { 10313 let error = new Error(val.message); 10314 error.stack = ""; 10315 serialized[key] = error; 10316 } 10317 } else { 10318 serialized[key] = val; 10319 } 10320 } 10321 return serialized; 10322} 10323function BrowserRouter({ 10324 basename, 10325 children, 10326 unstable_useTransitions, 10327 window: window2 10328}) { 10329 let historyRef = React10.useRef(); 10330 if (historyRef.current == null) { 10331 historyRef.current = createBrowserHistory({ window: window2, v5Compat: true }); 10332 } 10333 let history = historyRef.current; 10334 let [state, setStateImpl] = React10.useState({ 10335 action: history.action, 10336 location: history.location 10337 }); 10338 let setState = React10.useCallback( 10339 (newState) => { 10340 if (unstable_useTransitions === false) { 10341 setStateImpl(newState); 10342 } else { 10343 React10.startTransition(() => setStateImpl(newState)); 10344 } 10345 }, 10346 [unstable_useTransitions] 10347 ); 10348 React10.useLayoutEffect(() => history.listen(setState), [history, setState]); 10349 return React10.createElement( 10350 Router, 10351 { 10352 basename, 10353 children, 10354 location: state.location, 10355 navigationType: state.action, 10356 navigator: history, 10357 unstable_useTransitions 10358 } 10359 ); 10360} 10361function HashRouter({ 10362 basename, 10363 children, 10364 unstable_useTransitions, 10365 window: window2 10366}) { 10367 let historyRef = React10.useRef(); 10368 if (historyRef.current == null) { 10369 historyRef.current = createHashHistory({ window: window2, v5Compat: true }); 10370 } 10371 let history = historyRef.current; 10372 let [state, setStateImpl] = React10.useState({ 10373 action: history.action, 10374 location: history.location 10375 }); 10376 let setState = React10.useCallback( 10377 (newState) => { 10378 if (unstable_useTransitions === false) { 10379 setStateImpl(newState); 10380 } else { 10381 React10.startTransition(() => setStateImpl(newState)); 10382 } 10383 }, 10384 [unstable_useTransitions] 10385 ); 10386 React10.useLayoutEffect(() => history.listen(setState), [history, setState]); 10387 return React10.createElement( 10388 Router, 10389 { 10390 basename, 10391 children, 10392 location: state.location, 10393 navigationType: state.action, 10394 navigator: history, 10395 unstable_useTransitions 10396 } 10397 ); 10398} 10399function HistoryRouter({ 10400 basename, 10401 children, 10402 history, 10403 unstable_useTransitions 10404}) { 10405 let [state, setStateImpl] = React10.useState({ 10406 action: history.action, 10407 location: history.location 10408 }); 10409 let setState = React10.useCallback( 10410 (newState) => { 10411 if (unstable_useTransitions === false) { 10412 setStateImpl(newState); 10413 } else { 10414 React10.startTransition(() => setStateImpl(newState)); 10415 } 10416 }, 10417 [unstable_useTransitions] 10418 ); 10419 React10.useLayoutEffect(() => history.listen(setState), [history, setState]); 10420 return React10.createElement( 10421 Router, 10422 { 10423 basename, 10424 children, 10425 location: state.location, 10426 navigationType: state.action, 10427 navigator: history, 10428 unstable_useTransitions 10429 } 10430 ); 10431} 10432HistoryRouter.displayName = "unstable_HistoryRouter"; 10433var ABSOLUTE_URL_REGEX2 = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; 10434var Link = React10.forwardRef( 10435 function LinkWithRef({ 10436 onClick, 10437 discover = "render", 10438 prefetch = "none", 10439 relative, 10440 reloadDocument, 10441 replace: replace2, 10442 unstable_mask, 10443 state, 10444 target, 10445 to, 10446 preventScrollReset, 10447 viewTransition, 10448 unstable_defaultShouldRevalidate, 10449 ...rest 10450 }, forwardedRef) { 10451 let { basename, navigator, unstable_useTransitions } = React10.useContext(NavigationContext); 10452 let isAbsolute = typeof to === "string" && ABSOLUTE_URL_REGEX2.test(to); 10453 let parsed = parseToInfo(to, basename); 10454 to = parsed.to; 10455 let href2 = useHref(to, { relative }); 10456 let location2 = useLocation(); 10457 let maskedHref = null; 10458 if (unstable_mask) { 10459 let resolved = resolveTo( 10460 unstable_mask, 10461 [], 10462 location2.unstable_mask ? location2.unstable_mask.pathname : "/", 10463 true 10464 ); 10465 if (basename !== "/") { 10466 resolved.pathname = resolved.pathname === "/" ? basename : joinPaths([basename, resolved.pathname]); 10467 } 10468 maskedHref = navigator.createHref(resolved); 10469 } 10470 let [shouldPrefetch, prefetchRef, prefetchHandlers] = usePrefetchBehavior( 10471 prefetch, 10472 rest 10473 ); 10474 let internalOnClick = useLinkClickHandler(to, { 10475 replace: replace2, 10476 unstable_mask, 10477 state, 10478 target, 10479 preventScrollReset, 10480 relative, 10481 viewTransition, 10482 unstable_defaultShouldRevalidate, 10483 unstable_useTransitions 10484 }); 10485 function handleClick(event) { 10486 if (onClick) onClick(event); 10487 if (!event.defaultPrevented) { 10488 internalOnClick(event); 10489 } 10490 } 10491 let isSpaLink = !(parsed.isExternal || reloadDocument); 10492 let link = ( 10493 // eslint-disable-next-line jsx-a11y/anchor-has-content 10494 React10.createElement( 10495 "a", 10496 { 10497 ...rest, 10498 ...prefetchHandlers, 10499 href: (isSpaLink ? maskedHref : void 0) || parsed.absoluteURL || href2, 10500 onClick: isSpaLink ? handleClick : onClick, 10501 ref: mergeRefs(forwardedRef, prefetchRef), 10502 target, 10503 "data-discover": !isAbsolute && discover === "render" ? "true" : void 0 10504 } 10505 ) 10506 ); 10507 return shouldPrefetch && !isAbsolute ? React10.createElement(React10.Fragment, null, link, React10.createElement(PrefetchPageLinks, { page: href2 })) : link; 10508 } 10509); 10510Link.displayName = "Link"; 10511var NavLink = React10.forwardRef( 10512 function NavLinkWithRef({ 10513 "aria-current": ariaCurrentProp = "page", 10514 caseSensitive = false, 10515 className: classNameProp = "", 10516 end = false, 10517 style: styleProp, 10518 to, 10519 viewTransition, 10520 children, 10521 ...rest 10522 }, ref) { 10523 let path = useResolvedPath(to, { relative: rest.relative }); 10524 let location2 = useLocation(); 10525 let routerState = React10.useContext(DataRouterStateContext); 10526 let { navigator, basename } = React10.useContext(NavigationContext); 10527 let isTransitioning = routerState != null && // Conditional usage is OK here because the usage of a data router is static 10528 // eslint-disable-next-line react-hooks/rules-of-hooks 10529 useViewTransitionState(path) && viewTransition === true; 10530 let toPathname = navigator.encodeLocation ? navigator.encodeLocation(path).pathname : path.pathname; 10531 let locationPathname = location2.pathname; 10532 let nextLocationPathname = routerState && routerState.navigation && routerState.navigation.location ? routerState.navigation.location.pathname : null; 10533 if (!caseSensitive) { 10534 locationPathname = locationPathname.toLowerCase(); 10535 nextLocationPathname = nextLocationPathname ? nextLocationPathname.toLowerCase() : null; 10536 toPathname = toPathname.toLowerCase(); 10537 } 10538 if (nextLocationPathname && basename) { 10539 nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname; 10540 } 10541 const endSlashPosition = toPathname !== "/" && toPathname.endsWith("/") ? toPathname.length - 1 : toPathname.length; 10542 let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === "/"; 10543 let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(toPathname.length) === "/"); 10544 let renderProps = { 10545 isActive, 10546 isPending, 10547 isTransitioning 10548 }; 10549 let ariaCurrent = isActive ? ariaCurrentProp : void 0; 10550 let className; 10551 if (typeof classNameProp === "function") { 10552 className = classNameProp(renderProps); 10553 } else { 10554 className = [ 10555 classNameProp, 10556 isActive ? "active" : null, 10557 isPending ? "pending" : null, 10558 isTransitioning ? "transitioning" : null 10559 ].filter(Boolean).join(" "); 10560 } 10561 let style = typeof styleProp === "function" ? styleProp(renderProps) : styleProp; 10562 return React10.createElement( 10563 Link, 10564 { 10565 ...rest, 10566 "aria-current": ariaCurrent, 10567 className, 10568 ref, 10569 style, 10570 to, 10571 viewTransition 10572 }, 10573 typeof children === "function" ? children(renderProps) : children 10574 ); 10575 } 10576); 10577NavLink.displayName = "NavLink"; 10578var Form = React10.forwardRef( 10579 ({ 10580 discover = "render", 10581 fetcherKey, 10582 navigate, 10583 reloadDocument, 10584 replace: replace2, 10585 state, 10586 method = defaultMethod, 10587 action, 10588 onSubmit, 10589 relative, 10590 preventScrollReset, 10591 viewTransition, 10592 unstable_defaultShouldRevalidate, 10593 ...props 10594 }, forwardedRef) => { 10595 let { unstable_useTransitions } = React10.useContext(NavigationContext); 10596 let submit = useSubmit(); 10597 let formAction = useFormAction(action, { relative }); 10598 let formMethod = method.toLowerCase() === "get" ? "get" : "post"; 10599 let isAbsolute = typeof action === "string" && ABSOLUTE_URL_REGEX2.test(action); 10600 let submitHandler = (event) => { 10601 onSubmit && onSubmit(event); 10602 if (event.defaultPrevented) return; 10603 event.preventDefault(); 10604 let submitter = event.nativeEvent.submitter; 10605 let submitMethod = submitter?.getAttribute("formmethod") || method; 10606 let doSubmit = () => submit(submitter || event.currentTarget, { 10607 fetcherKey, 10608 method: submitMethod, 10609 navigate, 10610 replace: replace2, 10611 state, 10612 relative, 10613 preventScrollReset, 10614 viewTransition, 10615 unstable_defaultShouldRevalidate 10616 }); 10617 if (unstable_useTransitions && navigate !== false) { 10618 React10.startTransition(() => doSubmit()); 10619 } else { 10620 doSubmit(); 10621 } 10622 }; 10623 return React10.createElement( 10624 "form", 10625 { 10626 ref: forwardedRef, 10627 method: formMethod, 10628 action: formAction, 10629 onSubmit: reloadDocument ? onSubmit : submitHandler, 10630 ...props, 10631 "data-discover": !isAbsolute && discover === "render" ? "true" : void 0 10632 } 10633 ); 10634 } 10635); 10636Form.displayName = "Form"; 10637function ScrollRestoration({ 10638 getKey, 10639 storageKey, 10640 ...props 10641}) { 10642 let remixContext = React10.useContext(FrameworkContext); 10643 let { basename } = React10.useContext(NavigationContext); 10644 let location2 = useLocation(); 10645 let matches = useMatches(); 10646 useScrollRestoration({ getKey, storageKey }); 10647 let ssrKey = React10.useMemo( 10648 () => { 10649 if (!remixContext || !getKey) return null; 10650 let userKey = getScrollRestorationKey( 10651 location2, 10652 matches, 10653 basename, 10654 getKey 10655 ); 10656 return userKey !== location2.key ? userKey : null; 10657 }, 10658 // Nah, we only need this the first time for the SSR render 10659 // eslint-disable-next-line react-hooks/exhaustive-deps 10660 [] 10661 ); 10662 if (!remixContext || remixContext.isSpaMode) { 10663 return null; 10664 } 10665 let restoreScroll = ((storageKey2, restoreKey) => { 10666 if (!window.history.state || !window.history.state.key) { 10667 let key = Math.random().toString(32).slice(2); 10668 window.history.replaceState({ key }, ""); 10669 } 10670 try { 10671 let positions = JSON.parse(sessionStorage.getItem(storageKey2) || "{}"); 10672 let storedY = positions[restoreKey || window.history.state.key]; 10673 if (typeof storedY === "number") { 10674 window.scrollTo(0, storedY); 10675 } 10676 } catch (error) { 10677 console.error(error); 10678 sessionStorage.removeItem(storageKey2); 10679 } 10680 }).toString(); 10681 return React10.createElement( 10682 "script", 10683 { 10684 ...props, 10685 suppressHydrationWarning: true, 10686 dangerouslySetInnerHTML: { 10687 __html: `(${restoreScroll})(${escapeHtml( 10688 JSON.stringify(storageKey || SCROLL_RESTORATION_STORAGE_KEY) 10689 )}, ${escapeHtml(JSON.stringify(ssrKey))})` 10690 } 10691 } 10692 ); 10693} 10694ScrollRestoration.displayName = "ScrollRestoration"; 10695function getDataRouterConsoleError2(hookName) { 10696 return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`; 10697} 10698function useDataRouterContext3(hookName) { 10699 let ctx = React10.useContext(DataRouterContext); 10700 invariant(ctx, getDataRouterConsoleError2(hookName)); 10701 return ctx; 10702} 10703function useDataRouterState2(hookName) { 10704 let state = React10.useContext(DataRouterStateContext); 10705 invariant(state, getDataRouterConsoleError2(hookName)); 10706 return state; 10707} 10708function useLinkClickHandler(to, { 10709 target, 10710 replace: replaceProp, 10711 unstable_mask, 10712 state, 10713 preventScrollReset, 10714 relative, 10715 viewTransition, 10716 unstable_defaultShouldRevalidate, 10717 unstable_useTransitions 10718} = {}) { 10719 let navigate = useNavigate(); 10720 let location2 = useLocation(); 10721 let path = useResolvedPath(to, { relative }); 10722 return React10.useCallback( 10723 (event) => { 10724 if (shouldProcessLinkClick(event, target)) { 10725 event.preventDefault(); 10726 let replace2 = replaceProp !== void 0 ? replaceProp : createPath(location2) === createPath(path); 10727 let doNavigate = () => navigate(to, { 10728 replace: replace2, 10729 unstable_mask, 10730 state, 10731 preventScrollReset, 10732 relative, 10733 viewTransition, 10734 unstable_defaultShouldRevalidate 10735 }); 10736 if (unstable_useTransitions) { 10737 React10.startTransition(() => doNavigate()); 10738 } else { 10739 doNavigate(); 10740 } 10741 } 10742 }, 10743 [ 10744 location2, 10745 navigate, 10746 path, 10747 replaceProp, 10748 unstable_mask, 10749 state, 10750 target, 10751 to, 10752 preventScrollReset, 10753 relative, 10754 viewTransition, 10755 unstable_defaultShouldRevalidate, 10756 unstable_useTransitions 10757 ] 10758 ); 10759} 10760function useSearchParams(defaultInit) { 10761 warning( 10762 typeof URLSearchParams !== "undefined", 10763 `You cannot use the \`useSearchParams\` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.` 10764 ); 10765 let defaultSearchParamsRef = React10.useRef(createSearchParams(defaultInit)); 10766 let hasSetSearchParamsRef = React10.useRef(false); 10767 let location2 = useLocation(); 10768 let searchParams = React10.useMemo( 10769 () => ( 10770 // Only merge in the defaults if we haven't yet called setSearchParams. 10771 // Once we call that we want those to take precedence, otherwise you can't 10772 // remove a param with setSearchParams({}) if it has an initial value 10773 getSearchParamsForLocation( 10774 location2.search, 10775 hasSetSearchParamsRef.current ? null : defaultSearchParamsRef.current 10776 ) 10777 ), 10778 [location2.search] 10779 ); 10780 let navigate = useNavigate(); 10781 let setSearchParams = React10.useCallback( 10782 (nextInit, navigateOptions) => { 10783 const newSearchParams = createSearchParams( 10784 typeof nextInit === "function" ? nextInit(new URLSearchParams(searchParams)) : nextInit 10785 ); 10786 hasSetSearchParamsRef.current = true; 10787 navigate("?" + newSearchParams, navigateOptions); 10788 }, 10789 [navigate, searchParams] 10790 ); 10791 return [searchParams, setSearchParams]; 10792} 10793var fetcherId = 0; 10794var getUniqueFetcherId = () => `__${String(++fetcherId)}__`; 10795function useSubmit() { 10796 let { router: router2 } = useDataRouterContext3( 10797 "useSubmit" 10798 /* UseSubmit */ 10799 ); 10800 let { basename } = React10.useContext(NavigationContext); 10801 let currentRouteId = useRouteId(); 10802 let routerFetch = router2.fetch; 10803 let routerNavigate = router2.navigate; 10804 return React10.useCallback( 10805 async (target, options = {}) => { 10806 let { action, method, encType, formData, body } = getFormSubmissionInfo( 10807 target, 10808 basename 10809 ); 10810 if (options.navigate === false) { 10811 let key = options.fetcherKey || getUniqueFetcherId(); 10812 await routerFetch(key, currentRouteId, options.action || action, { 10813 unstable_defaultShouldRevalidate: options.unstable_defaultShouldRevalidate, 10814 preventScrollReset: options.preventScrollReset, 10815 formData, 10816 body, 10817 formMethod: options.method || method, 10818 formEncType: options.encType || encType, 10819 flushSync: options.flushSync 10820 }); 10821 } else { 10822 await routerNavigate(options.action || action, { 10823 unstable_defaultShouldRevalidate: options.unstable_defaultShouldRevalidate, 10824 preventScrollReset: options.preventScrollReset, 10825 formData, 10826 body, 10827 formMethod: options.method || method, 10828 formEncType: options.encType || encType, 10829 replace: options.replace, 10830 state: options.state, 10831 fromRouteId: currentRouteId, 10832 flushSync: options.flushSync, 10833 viewTransition: options.viewTransition 10834 }); 10835 } 10836 }, 10837 [routerFetch, routerNavigate, basename, currentRouteId] 10838 ); 10839} 10840function useFormAction(action, { relative } = {}) { 10841 let { basename } = React10.useContext(NavigationContext); 10842 let routeContext = React10.useContext(RouteContext); 10843 invariant(routeContext, "useFormAction must be used inside a RouteContext"); 10844 let [match] = routeContext.matches.slice(-1); 10845 let path = { ...useResolvedPath(action ? action : ".", { relative }) }; 10846 let location2 = useLocation(); 10847 if (action == null) { 10848 path.search = location2.search; 10849 let params = new URLSearchParams(path.search); 10850 let indexValues = params.getAll("index"); 10851 let hasNakedIndexParam = indexValues.some((v) => v === ""); 10852 if (hasNakedIndexParam) { 10853 params.delete("index"); 10854 indexValues.filter((v) => v).forEach((v) => params.append("index", v)); 10855 let qs = params.toString(); 10856 path.search = qs ? `?${qs}` : ""; 10857 } 10858 } 10859 if ((!action || action === ".") && match.route.index) { 10860 path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index"; 10861 } 10862 if (basename !== "/") { 10863 path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]); 10864 } 10865 return createPath(path); 10866} 10867function useFetcher({ 10868 key 10869} = {}) { 10870 let { router: router2 } = useDataRouterContext3( 10871 "useFetcher" 10872 /* UseFetcher */ 10873 ); 10874 let state = useDataRouterState2( 10875 "useFetcher" 10876 /* UseFetcher */ 10877 ); 10878 let fetcherData = React10.useContext(FetchersContext); 10879 let route = React10.useContext(RouteContext); 10880 let routeId = route.matches[route.matches.length - 1]?.route.id; 10881 invariant(fetcherData, `useFetcher must be used inside a FetchersContext`); 10882 invariant(route, `useFetcher must be used inside a RouteContext`); 10883 invariant( 10884 routeId != null, 10885 `useFetcher can only be used on routes that contain a unique "id"` 10886 ); 10887 let defaultKey = React10.useId(); 10888 let [fetcherKey, setFetcherKey] = React10.useState(key || defaultKey); 10889 if (key && key !== fetcherKey) { 10890 setFetcherKey(key); 10891 } 10892 let { deleteFetcher, getFetcher, resetFetcher, fetch: routerFetch } = router2; 10893 React10.useEffect(() => { 10894 getFetcher(fetcherKey); 10895 return () => deleteFetcher(fetcherKey); 10896 }, [deleteFetcher, getFetcher, fetcherKey]); 10897 let load = React10.useCallback( 10898 async (href2, opts) => { 10899 invariant(routeId, "No routeId available for fetcher.load()"); 10900 await routerFetch(fetcherKey, routeId, href2, opts); 10901 }, 10902 [fetcherKey, routeId, routerFetch] 10903 ); 10904 let submitImpl = useSubmit(); 10905 let submit = React10.useCallback( 10906 async (target, opts) => { 10907 await submitImpl(target, { 10908 ...opts, 10909 navigate: false, 10910 fetcherKey 10911 }); 10912 }, 10913 [fetcherKey, submitImpl] 10914 ); 10915 let reset = React10.useCallback( 10916 (opts) => resetFetcher(fetcherKey, opts), 10917 [resetFetcher, fetcherKey] 10918 ); 10919 let FetcherForm = React10.useMemo(() => { 10920 let FetcherForm2 = React10.forwardRef( 10921 (props, ref) => { 10922 return React10.createElement(Form, { ...props, navigate: false, fetcherKey, ref }); 10923 } 10924 ); 10925 FetcherForm2.displayName = "fetcher.Form"; 10926 return FetcherForm2; 10927 }, [fetcherKey]); 10928 let fetcher = state.fetchers.get(fetcherKey) || IDLE_FETCHER; 10929 let data2 = fetcherData.get(fetcherKey); 10930 let fetcherWithComponents = React10.useMemo( 10931 () => ({ 10932 Form: FetcherForm, 10933 submit, 10934 load, 10935 reset, 10936 ...fetcher, 10937 data: data2 10938 }), 10939 [FetcherForm, submit, load, reset, fetcher, data2] 10940 ); 10941 return fetcherWithComponents; 10942} 10943function useFetchers() { 10944 let state = useDataRouterState2( 10945 "useFetchers" 10946 /* UseFetchers */ 10947 ); 10948 return Array.from(state.fetchers.entries()).map(([key, fetcher]) => ({ 10949 ...fetcher, 10950 key 10951 })); 10952} 10953var SCROLL_RESTORATION_STORAGE_KEY = "react-router-scroll-positions"; 10954var savedScrollPositions = {}; 10955function getScrollRestorationKey(location2, matches, basename, getKey) { 10956 let key = null; 10957 if (getKey) { 10958 if (basename !== "/") { 10959 key = getKey( 10960 { 10961 ...location2, 10962 pathname: stripBasename(location2.pathname, basename) || location2.pathname 10963 }, 10964 matches 10965 ); 10966 } else { 10967 key = getKey(location2, matches); 10968 } 10969 } 10970 if (key == null) { 10971 key = location2.key; 10972 } 10973 return key; 10974} 10975function useScrollRestoration({ 10976 getKey, 10977 storageKey 10978} = {}) { 10979 let { router: router2 } = useDataRouterContext3( 10980 "useScrollRestoration" 10981 /* UseScrollRestoration */ 10982 ); 10983 let { restoreScrollPosition, preventScrollReset } = useDataRouterState2( 10984 "useScrollRestoration" 10985 /* UseScrollRestoration */ 10986 ); 10987 let { basename } = React10.useContext(NavigationContext); 10988 let location2 = useLocation(); 10989 let matches = useMatches(); 10990 let navigation = useNavigation(); 10991 React10.useEffect(() => { 10992 window.history.scrollRestoration = "manual"; 10993 return () => { 10994 window.history.scrollRestoration = "auto"; 10995 }; 10996 }, []); 10997 usePageHide( 10998 React10.useCallback(() => { 10999 if (navigation.state === "idle") { 11000 let key = getScrollRestorationKey(location2, matches, basename, getKey); 11001 savedScrollPositions[key] = window.scrollY; 11002 } 11003 try { 11004 sessionStorage.setItem( 11005 storageKey || SCROLL_RESTORATION_STORAGE_KEY, 11006 JSON.stringify(savedScrollPositions) 11007 ); 11008 } catch (error) { 11009 warning( 11010 false, 11011 `Failed to save scroll positions in sessionStorage, <ScrollRestoration /> will not work properly (${error}).` 11012 ); 11013 } 11014 window.history.scrollRestoration = "auto"; 11015 }, [navigation.state, getKey, basename, location2, matches, storageKey]) 11016 ); 11017 if (typeof document !== "undefined") { 11018 React10.useLayoutEffect(() => { 11019 try { 11020 let sessionPositions = sessionStorage.getItem( 11021 storageKey || SCROLL_RESTORATION_STORAGE_KEY 11022 ); 11023 if (sessionPositions) { 11024 savedScrollPositions = JSON.parse(sessionPositions); 11025 } 11026 } catch (e) { 11027 } 11028 }, [storageKey]); 11029 React10.useLayoutEffect(() => { 11030 let disableScrollRestoration = router2?.enableScrollRestoration( 11031 savedScrollPositions, 11032 () => window.scrollY, 11033 getKey ? (location22, matches2) => getScrollRestorationKey(location22, matches2, basename, getKey) : void 0 11034 ); 11035 return () => disableScrollRestoration && disableScrollRestoration(); 11036 }, [router2, basename, getKey]); 11037 React10.useLayoutEffect(() => { 11038 if (restoreScrollPosition === false) { 11039 return; 11040 } 11041 if (typeof restoreScrollPosition === "number") { 11042 window.scrollTo(0, restoreScrollPosition); 11043 return; 11044 } 11045 try { 11046 if (location2.hash) { 11047 let el = document.getElementById( 11048 decodeURIComponent(location2.hash.slice(1)) 11049 ); 11050 if (el) { 11051 el.scrollIntoView(); 11052 return; 11053 } 11054 } 11055 } catch { 11056 warning( 11057 false, 11058 `"${location2.hash.slice( 11059 1 11060 )}" is not a decodable element ID. The view will not scroll to it.` 11061 ); 11062 } 11063 if (preventScrollReset === true) { 11064 return; 11065 } 11066 window.scrollTo(0, 0); 11067 }, [location2, restoreScrollPosition, preventScrollReset]); 11068 } 11069} 11070function useBeforeUnload(callback, options) { 11071 let { capture } = options || {}; 11072 React10.useEffect(() => { 11073 let opts = capture != null ? { capture } : void 0; 11074 window.addEventListener("beforeunload", callback, opts); 11075 return () => { 11076 window.removeEventListener("beforeunload", callback, opts); 11077 }; 11078 }, [callback, capture]); 11079} 11080function usePageHide(callback, options) { 11081 let { capture } = options || {}; 11082 React10.useEffect(() => { 11083 let opts = capture != null ? { capture } : void 0; 11084 window.addEventListener("pagehide", callback, opts); 11085 return () => { 11086 window.removeEventListener("pagehide", callback, opts); 11087 }; 11088 }, [callback, capture]); 11089} 11090function usePrompt({ 11091 when, 11092 message 11093}) { 11094 let blocker = useBlocker(when); 11095 React10.useEffect(() => { 11096 if (blocker.state === "blocked") { 11097 let proceed = window.confirm(message); 11098 if (proceed) { 11099 setTimeout(blocker.proceed, 0); 11100 } else { 11101 blocker.reset(); 11102 } 11103 } 11104 }, [blocker, message]); 11105 React10.useEffect(() => { 11106 if (blocker.state === "blocked" && !when) { 11107 blocker.reset(); 11108 } 11109 }, [blocker, when]); 11110} 11111function useViewTransitionState(to, { relative } = {}) { 11112 let vtContext = React10.useContext(ViewTransitionContext); 11113 invariant( 11114 vtContext != null, 11115 "`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?" 11116 ); 11117 let { basename } = useDataRouterContext3( 11118 "useViewTransitionState" 11119 /* useViewTransitionState */ 11120 ); 11121 let path = useResolvedPath(to, { relative }); 11122 if (!vtContext.isTransitioning) { 11123 return false; 11124 } 11125 let currentPath = stripBasename(vtContext.currentLocation.pathname, basename) || vtContext.currentLocation.pathname; 11126 let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname; 11127 return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null; 11128} 11129function StaticRouter({ 11130 basename, 11131 children, 11132 location: locationProp = "/" 11133}) { 11134 if (typeof locationProp === "string") { 11135 locationProp = parsePath(locationProp); 11136 } 11137 let action = "POP"; 11138 let location2 = { 11139 pathname: locationProp.pathname || "/", 11140 search: locationProp.search || "", 11141 hash: locationProp.hash || "", 11142 state: locationProp.state != null ? locationProp.state : null, 11143 key: locationProp.key || "default", 11144 unstable_mask: void 0 11145 }; 11146 let staticNavigator = getStatelessNavigator(); 11147 return React11.createElement( 11148 Router, 11149 { 11150 basename, 11151 children, 11152 location: location2, 11153 navigationType: action, 11154 navigator: staticNavigator, 11155 static: true, 11156 unstable_useTransitions: false 11157 } 11158 ); 11159} 11160function StaticRouterProvider({ 11161 context, 11162 router: router2, 11163 hydrate: hydrate2 = true, 11164 nonce 11165}) { 11166 invariant( 11167 router2 && context, 11168 "You must provide `router` and `context` to <StaticRouterProvider>" 11169 ); 11170 let dataRouterContext = { 11171 router: router2, 11172 navigator: getStatelessNavigator(), 11173 static: true, 11174 staticContext: context, 11175 basename: context.basename || "/" 11176 }; 11177 let fetchersContext = /* @__PURE__ */ new Map(); 11178 let hydrateScript = ""; 11179 if (hydrate2 !== false) { 11180 let data2 = { 11181 loaderData: context.loaderData, 11182 actionData: context.actionData, 11183 errors: serializeErrors(context.errors) 11184 }; 11185 let json = escapeHtml(JSON.stringify(JSON.stringify(data2))); 11186 hydrateScript = `window.__staticRouterHydrationData = JSON.parse(${json});`; 11187 } 11188 let { state } = dataRouterContext.router; 11189 return React11.createElement(React11.Fragment, null, React11.createElement(DataRouterContext.Provider, { value: dataRouterContext }, React11.createElement(DataRouterStateContext.Provider, { value: state }, React11.createElement(FetchersContext.Provider, { value: fetchersContext }, React11.createElement(ViewTransitionContext.Provider, { value: { isTransitioning: false } }, React11.createElement( 11190 Router, 11191 { 11192 basename: dataRouterContext.basename, 11193 location: state.location, 11194 navigationType: state.historyAction, 11195 navigator: dataRouterContext.navigator, 11196 static: dataRouterContext.static, 11197 unstable_useTransitions: false 11198 }, 11199 React11.createElement( 11200 DataRoutes, 11201 { 11202 routes: router2.routes, 11203 future: router2.future, 11204 state, 11205 isStatic: true 11206 } 11207 ) 11208 ))))), hydrateScript ? React11.createElement( 11209 "script", 11210 { 11211 suppressHydrationWarning: true, 11212 nonce, 11213 dangerouslySetInnerHTML: { __html: hydrateScript } 11214 } 11215 ) : null); 11216} 11217function serializeErrors(errors) { 11218 if (!errors) return null; 11219 let entries = Object.entries(errors); 11220 let serialized = {}; 11221 for (let [key, val] of entries) { 11222 if (isRouteErrorResponse(val)) { 11223 serialized[key] = { ...val, __type: "RouteErrorResponse" }; 11224 } else if (val instanceof Error) { 11225 serialized[key] = { 11226 message: val.message, 11227 __type: "Error", 11228 // If this is a subclass (i.e., ReferenceError), send up the type so we 11229 // can re-create the same type during hydration. 11230 ...val.name !== "Error" ? { 11231 __subType: val.name 11232 } : {} 11233 }; 11234 } else { 11235 serialized[key] = val; 11236 } 11237 } 11238 return serialized; 11239} 11240function getStatelessNavigator() { 11241 return { 11242 createHref, 11243 encodeLocation, 11244 push(to) { 11245 throw new Error( 11246 `You cannot use navigator.push() on the server because it is a stateless environment. This error was probably triggered when you did a \`navigate(${JSON.stringify(to)})\` somewhere in your app.` 11247 ); 11248 }, 11249 replace(to) { 11250 throw new Error( 11251 `You cannot use navigator.replace() on the server because it is a stateless environment. This error was probably triggered when you did a \`navigate(${JSON.stringify(to)}, { replace: true })\` somewhere in your app.` 11252 ); 11253 }, 11254 go(delta) { 11255 throw new Error( 11256 `You cannot use navigator.go() on the server because it is a stateless environment. This error was probably triggered when you did a \`navigate(${delta})\` somewhere in your app.` 11257 ); 11258 }, 11259 back() { 11260 throw new Error( 11261 `You cannot use navigator.back() on the server because it is a stateless environment.` 11262 ); 11263 }, 11264 forward() { 11265 throw new Error( 11266 `You cannot use navigator.forward() on the server because it is a stateless environment.` 11267 ); 11268 } 11269 }; 11270} 11271function createStaticHandler2(routes, opts) { 11272 return createStaticHandler(routes, { 11273 ...opts, 11274 mapRouteProperties 11275 }); 11276} 11277function createStaticRouter(routes, context, opts = {}) { 11278 let manifest = {}; 11279 let dataRoutes = convertRoutesToDataRoutes( 11280 routes, 11281 mapRouteProperties, 11282 void 0, 11283 manifest 11284 ); 11285 let matches = context.matches.map((match) => { 11286 let route = manifest[match.route.id] || match.route; 11287 return { 11288 ...match, 11289 route 11290 }; 11291 }); 11292 let msg = (method) => `You cannot use router.${method}() on the server because it is a stateless environment`; 11293 return { 11294 get basename() { 11295 return context.basename; 11296 }, 11297 get future() { 11298 return { 11299 v8_middleware: false, 11300 ...opts?.future 11301 }; 11302 }, 11303 get state() { 11304 return { 11305 historyAction: "POP", 11306 location: context.location, 11307 matches, 11308 loaderData: context.loaderData, 11309 actionData: context.actionData, 11310 errors: context.errors, 11311 initialized: true, 11312 renderFallback: false, 11313 navigation: IDLE_NAVIGATION, 11314 restoreScrollPosition: null, 11315 preventScrollReset: false, 11316 revalidation: "idle", 11317 fetchers: /* @__PURE__ */ new Map(), 11318 blockers: /* @__PURE__ */ new Map() 11319 }; 11320 }, 11321 get routes() { 11322 return dataRoutes; 11323 }, 11324 get window() { 11325 return void 0; 11326 }, 11327 initialize() { 11328 throw msg("initialize"); 11329 }, 11330 subscribe() { 11331 throw msg("subscribe"); 11332 }, 11333 enableScrollRestoration() { 11334 throw msg("enableScrollRestoration"); 11335 }, 11336 navigate() { 11337 throw msg("navigate"); 11338 }, 11339 fetch() { 11340 throw msg("fetch"); 11341 }, 11342 revalidate() { 11343 throw msg("revalidate"); 11344 }, 11345 createHref, 11346 encodeLocation, 11347 getFetcher() { 11348 return IDLE_FETCHER; 11349 }, 11350 deleteFetcher() { 11351 throw msg("deleteFetcher"); 11352 }, 11353 resetFetcher() { 11354 throw msg("resetFetcher"); 11355 }, 11356 dispose() { 11357 throw msg("dispose"); 11358 }, 11359 getBlocker() { 11360 return IDLE_BLOCKER; 11361 }, 11362 deleteBlocker() { 11363 throw msg("deleteBlocker"); 11364 }, 11365 patchRoutes() { 11366 throw msg("patchRoutes"); 11367 }, 11368 _internalFetchControllers: /* @__PURE__ */ new Map(), 11369 _internalSetRoutes() { 11370 throw msg("_internalSetRoutes"); 11371 }, 11372 _internalSetStateDoNotUseOrYouWillBreakYourApp() { 11373 throw msg("_internalSetStateDoNotUseOrYouWillBreakYourApp"); 11374 } 11375 }; 11376} 11377function createHref(to) { 11378 return typeof to === "string" ? to : createPath(to); 11379} 11380function encodeLocation(to) { 11381 let href2 = typeof to === "string" ? to : createPath(to); 11382 href2 = href2.replace(/ $/, "%20"); 11383 let encoded = ABSOLUTE_URL_REGEX3.test(href2) ? new URL(href2) : new URL(href2, "http://localhost"); 11384 return { 11385 pathname: encoded.pathname, 11386 search: encoded.search, 11387 hash: encoded.hash 11388 }; 11389} 11390var ABSOLUTE_URL_REGEX3 = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; 11391
vendor: 75,796 bytes, lines 11392-13775
11392// node_modules/react-router/dist/development/chunk-JPUPSTYD.mjs 11393var React12 = __toESM(require_react(), 1); 11394var React22 = __toESM(require_react(), 1); 11395var import_cookie = __toESM(require_dist(), 1); 11396var import_set_cookie_parser = __toESM(require_set_cookie(), 1); 11397var React42 = __toESM(require_react(), 1); 11398var import_react = __toESM(require_react(), 1); 11399function ServerRouter({ 11400 context, 11401 url, 11402 nonce 11403}) { 11404 if (typeof url === "string") { 11405 url = new URL(url); 11406 } 11407 let { manifest, routeModules, criticalCss, serverHandoffString } = context; 11408 let routes = createServerRoutes( 11409 manifest.routes, 11410 routeModules, 11411 context.future, 11412 context.isSpaMode 11413 ); 11414 context.staticHandlerContext.loaderData = { 11415 ...context.staticHandlerContext.loaderData 11416 }; 11417 for (let match of context.staticHandlerContext.matches) { 11418 let routeId = match.route.id; 11419 let route = routeModules[routeId]; 11420 let manifestRoute = context.manifest.routes[routeId]; 11421 if (route && manifestRoute && shouldHydrateRouteLoader( 11422 routeId, 11423 route.clientLoader, 11424 manifestRoute.hasLoader, 11425 context.isSpaMode 11426 ) && (route.HydrateFallback || !manifestRoute.hasLoader)) { 11427 delete context.staticHandlerContext.loaderData[routeId]; 11428 } 11429 } 11430 let router2 = createStaticRouter(routes, context.staticHandlerContext); 11431 return React12.createElement(React12.Fragment, null, React12.createElement( 11432 FrameworkContext.Provider, 11433 { 11434 value: { 11435 manifest, 11436 routeModules, 11437 criticalCss, 11438 serverHandoffString, 11439 future: context.future, 11440 ssr: context.ssr, 11441 isSpaMode: context.isSpaMode, 11442 routeDiscovery: context.routeDiscovery, 11443 serializeError: context.serializeError, 11444 renderMeta: context.renderMeta 11445 } 11446 }, 11447 React12.createElement(RemixErrorBoundary, { location: router2.state.location }, React12.createElement( 11448 StaticRouterProvider, 11449 { 11450 router: router2, 11451 context: context.staticHandlerContext, 11452 hydrate: false 11453 } 11454 )) 11455 ), context.serverHandoffStream ? React12.createElement(React12.Suspense, null, React12.createElement( 11456 StreamTransfer, 11457 { 11458 context, 11459 identifier: 0, 11460 reader: context.serverHandoffStream.getReader(), 11461 textDecoder: new TextDecoder(), 11462 nonce 11463 } 11464 )) : null); 11465} 11466function createRoutesStub(routes, _context) { 11467 return function RoutesTestStub({ 11468 initialEntries, 11469 initialIndex, 11470 hydrationData, 11471 future 11472 }) { 11473 let routerRef = React22.useRef(); 11474 let frameworkContextRef = React22.useRef(); 11475 if (routerRef.current == null) { 11476 frameworkContextRef.current = { 11477 future: { 11478 unstable_subResourceIntegrity: future?.unstable_subResourceIntegrity === true, 11479 v8_middleware: future?.v8_middleware === true, 11480 unstable_trailingSlashAwareDataRequests: future?.unstable_trailingSlashAwareDataRequests === true 11481 }, 11482 manifest: { 11483 routes: {}, 11484 entry: { imports: [], module: "" }, 11485 url: "", 11486 version: "" 11487 }, 11488 routeModules: {}, 11489 ssr: false, 11490 isSpaMode: false, 11491 routeDiscovery: { mode: "lazy", manifestPath: "/__manifest" } 11492 }; 11493 let patched = processRoutes( 11494 // @ts-expect-error `StubRouteObject` is stricter about `loader`/`action` 11495 // types compared to `AgnosticRouteObject` 11496 convertRoutesToDataRoutes(routes, (r) => r), 11497 _context !== void 0 ? _context : future?.v8_middleware ? new RouterContextProvider() : {}, 11498 frameworkContextRef.current.manifest, 11499 frameworkContextRef.current.routeModules 11500 ); 11501 routerRef.current = createMemoryRouter(patched, { 11502 initialEntries, 11503 initialIndex, 11504 hydrationData 11505 }); 11506 } 11507 return React22.createElement(FrameworkContext.Provider, { value: frameworkContextRef.current }, React22.createElement(RouterProvider, { router: routerRef.current })); 11508 }; 11509} 11510function processRoutes(routes, context, manifest, routeModules, parentId) { 11511 return routes.map((route) => { 11512 if (!route.id) { 11513 throw new Error( 11514 "Expected a route.id in react-router processRoutes() function" 11515 ); 11516 } 11517 let newRoute = { 11518 id: route.id, 11519 path: route.path, 11520 index: route.index, 11521 Component: route.Component ? withComponentProps(route.Component) : void 0, 11522 HydrateFallback: route.HydrateFallback ? withHydrateFallbackProps(route.HydrateFallback) : void 0, 11523 ErrorBoundary: route.ErrorBoundary ? withErrorBoundaryProps(route.ErrorBoundary) : void 0, 11524 action: route.action ? (args) => route.action({ ...args, context }) : void 0, 11525 loader: route.loader ? (args) => route.loader({ ...args, context }) : void 0, 11526 middleware: route.middleware ? route.middleware.map( 11527 (mw) => (...args) => mw( 11528 { ...args[0], context }, 11529 args[1] 11530 ) 11531 ) : void 0, 11532 handle: route.handle, 11533 shouldRevalidate: route.shouldRevalidate 11534 }; 11535 let entryRoute = { 11536 id: route.id, 11537 path: route.path, 11538 index: route.index, 11539 parentId, 11540 hasAction: route.action != null, 11541 hasLoader: route.loader != null, 11542 // When testing routes, you should be stubbing loader/action/middleware, 11543 // not trying to re-implement the full loader/clientLoader/SSR/hydration 11544 // flow. That is better tested via E2E tests. 11545 hasClientAction: false, 11546 hasClientLoader: false, 11547 hasClientMiddleware: false, 11548 hasErrorBoundary: route.ErrorBoundary != null, 11549 // any need for these? 11550 module: "build/stub-path-to-module.js", 11551 clientActionModule: void 0, 11552 clientLoaderModule: void 0, 11553 clientMiddlewareModule: void 0, 11554 hydrateFallbackModule: void 0 11555 }; 11556 manifest.routes[newRoute.id] = entryRoute; 11557 routeModules[route.id] = { 11558 default: newRoute.Component || Outlet, 11559 ErrorBoundary: newRoute.ErrorBoundary || void 0, 11560 handle: route.handle, 11561 links: route.links, 11562 meta: route.meta, 11563 shouldRevalidate: route.shouldRevalidate 11564 }; 11565 if (route.children) { 11566 newRoute.children = processRoutes( 11567 route.children, 11568 context, 11569 manifest, 11570 routeModules, 11571 newRoute.id 11572 ); 11573 } 11574 return newRoute; 11575 }); 11576} 11577var encoder = new TextEncoder(); 11578var sign = async (value, secret) => { 11579 let data2 = encoder.encode(value); 11580 let key = await createKey2(secret, ["sign"]); 11581 let signature = await crypto.subtle.sign("HMAC", key, data2); 11582 let hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace( 11583 /=+$/, 11584 "" 11585 ); 11586 return value + "." + hash; 11587}; 11588var unsign = async (cookie, secret) => { 11589 let index = cookie.lastIndexOf("."); 11590 let value = cookie.slice(0, index); 11591 let hash = cookie.slice(index + 1); 11592 let data2 = encoder.encode(value); 11593 let key = await createKey2(secret, ["verify"]); 11594 try { 11595 let signature = byteStringToUint8Array(atob(hash)); 11596 let valid = await crypto.subtle.verify("HMAC", key, signature, data2); 11597 return valid ? value : false; 11598 } catch (error) { 11599 return false; 11600 } 11601}; 11602var createKey2 = async (secret, usages) => crypto.subtle.importKey( 11603 "raw", 11604 encoder.encode(secret), 11605 { name: "HMAC", hash: "SHA-256" }, 11606 false, 11607 usages 11608); 11609function byteStringToUint8Array(byteString) { 11610 let array = new Uint8Array(byteString.length); 11611 for (let i = 0; i < byteString.length; i++) { 11612 array[i] = byteString.charCodeAt(i); 11613 } 11614 return array; 11615} 11616var createCookie = (name, cookieOptions = {}) => { 11617 let { secrets = [], ...options } = { 11618 path: "/", 11619 sameSite: "lax", 11620 ...cookieOptions 11621 }; 11622 warnOnceAboutExpiresCookie(name, options.expires); 11623 return { 11624 get name() { 11625 return name; 11626 }, 11627 get isSigned() { 11628 return secrets.length > 0; 11629 }, 11630 get expires() { 11631 return typeof options.maxAge !== "undefined" ? new Date(Date.now() + options.maxAge * 1e3) : options.expires; 11632 }, 11633 async parse(cookieHeader, parseOptions) { 11634 if (!cookieHeader) return null; 11635 let cookies = (0, import_cookie.parse)(cookieHeader, { ...options, ...parseOptions }); 11636 if (name in cookies) { 11637 let value = cookies[name]; 11638 if (typeof value === "string" && value !== "") { 11639 let decoded = await decodeCookieValue(value, secrets); 11640 return decoded; 11641 } else { 11642 return ""; 11643 } 11644 } else { 11645 return null; 11646 } 11647 }, 11648 async serialize(value, serializeOptions) { 11649 return (0, import_cookie.serialize)( 11650 name, 11651 value === "" ? "" : await encodeCookieValue(value, secrets), 11652 { 11653 ...options, 11654 ...serializeOptions 11655 } 11656 ); 11657 } 11658 }; 11659}; 11660var isCookie = (object) => { 11661 return object != null && typeof object.name === "string" && typeof object.isSigned === "boolean" && typeof object.parse === "function" && typeof object.serialize === "function"; 11662}; 11663async function encodeCookieValue(value, secrets) { 11664 let encoded = encodeData(value); 11665 if (secrets.length > 0) { 11666 encoded = await sign(encoded, secrets[0]); 11667 } 11668 return encoded; 11669} 11670async function decodeCookieValue(value, secrets) { 11671 if (secrets.length > 0) { 11672 for (let secret of secrets) { 11673 let unsignedValue = await unsign(value, secret); 11674 if (unsignedValue !== false) { 11675 return decodeData(unsignedValue); 11676 } 11677 } 11678 return null; 11679 } 11680 return decodeData(value); 11681} 11682function encodeData(value) { 11683 return btoa(myUnescape(encodeURIComponent(JSON.stringify(value)))); 11684} 11685function decodeData(value) { 11686 try { 11687 return JSON.parse(decodeURIComponent(myEscape(atob(value)))); 11688 } catch (error) { 11689 return {}; 11690 } 11691} 11692function myEscape(value) { 11693 let str = value.toString(); 11694 let result = ""; 11695 let index = 0; 11696 let chr, code; 11697 while (index < str.length) { 11698 chr = str.charAt(index++); 11699 if (/[\w*+\-./@]/.exec(chr)) { 11700 result += chr; 11701 } else { 11702 code = chr.charCodeAt(0); 11703 if (code < 256) { 11704 result += "%" + hex(code, 2); 11705 } else { 11706 result += "%u" + hex(code, 4).toUpperCase(); 11707 } 11708 } 11709 } 11710 return result; 11711} 11712function hex(code, length) { 11713 let result = code.toString(16); 11714 while (result.length < length) result = "0" + result; 11715 return result; 11716} 11717function myUnescape(value) { 11718 let str = value.toString(); 11719 let result = ""; 11720 let index = 0; 11721 let chr, part; 11722 while (index < str.length) { 11723 chr = str.charAt(index++); 11724 if (chr === "%") { 11725 if (str.charAt(index) === "u") { 11726 part = str.slice(index + 1, index + 5); 11727 if (/^[\da-f]{4}$/i.exec(part)) { 11728 result += String.fromCharCode(parseInt(part, 16)); 11729 index += 5; 11730 continue; 11731 } 11732 } else { 11733 part = str.slice(index, index + 2); 11734 if (/^[\da-f]{2}$/i.exec(part)) { 11735 result += String.fromCharCode(parseInt(part, 16)); 11736 index += 2; 11737 continue; 11738 } 11739 } 11740 } 11741 result += chr; 11742 } 11743 return result; 11744} 11745function warnOnceAboutExpiresCookie(name, expires) { 11746 warnOnce( 11747 !expires, 11748 `The "${name}" cookie has an "expires" property set. This will cause the expires value to not be updated when the session is committed. Instead, you should set the expires value when serializing the cookie. You can use \`commitSession(session, { expires })\` if using a session storage object, or \`cookie.serialize("value", { expires })\` if you're using the cookie directly.` 11749 ); 11750} 11751function createEntryRouteModules(manifest) { 11752 return Object.keys(manifest).reduce((memo2, routeId) => { 11753 let route = manifest[routeId]; 11754 if (route) { 11755 memo2[routeId] = route.module; 11756 } 11757 return memo2; 11758 }, {}); 11759} 11760var ServerMode = ((ServerMode2) => { 11761 ServerMode2["Development"] = "development"; 11762 ServerMode2["Production"] = "production"; 11763 ServerMode2["Test"] = "test"; 11764 return ServerMode2; 11765})(ServerMode || {}); 11766function isServerMode(value) { 11767 return value === "development" || value === "production" || value === "test"; 11768} 11769function sanitizeError(error, serverMode) { 11770 if (error instanceof Error && serverMode !== "development") { 11771 let sanitized = new Error("Unexpected Server Error"); 11772 sanitized.stack = void 0; 11773 return sanitized; 11774 } 11775 return error; 11776} 11777function sanitizeErrors(errors, serverMode) { 11778 return Object.entries(errors).reduce((acc, [routeId, error]) => { 11779 return Object.assign(acc, { [routeId]: sanitizeError(error, serverMode) }); 11780 }, {}); 11781} 11782function serializeError(error, serverMode) { 11783 let sanitized = sanitizeError(error, serverMode); 11784 return { 11785 message: sanitized.message, 11786 stack: sanitized.stack 11787 }; 11788} 11789function serializeErrors2(errors, serverMode) { 11790 if (!errors) return null; 11791 let entries = Object.entries(errors); 11792 let serialized = {}; 11793 for (let [key, val] of entries) { 11794 if (isRouteErrorResponse(val)) { 11795 serialized[key] = { ...val, __type: "RouteErrorResponse" }; 11796 } else if (val instanceof Error) { 11797 let sanitized = sanitizeError(val, serverMode); 11798 serialized[key] = { 11799 message: sanitized.message, 11800 stack: sanitized.stack, 11801 __type: "Error", 11802 // If this is a subclass (i.e., ReferenceError), send up the type so we 11803 // can re-create the same type during hydration. This will only apply 11804 // in dev mode since all production errors are sanitized to normal 11805 // Error instances 11806 ...sanitized.name !== "Error" ? { 11807 __subType: sanitized.name 11808 } : {} 11809 }; 11810 } else { 11811 serialized[key] = val; 11812 } 11813 } 11814 return serialized; 11815} 11816function matchServerRoutes(routes, pathname, basename) { 11817 let matches = matchRoutes( 11818 routes, 11819 pathname, 11820 basename 11821 ); 11822 if (!matches) return null; 11823 return matches.map((match) => ({ 11824 params: match.params, 11825 pathname: match.pathname, 11826 route: match.route 11827 })); 11828} 11829async function callRouteHandler(handler, args) { 11830 let result = await handler({ 11831 request: stripRoutesParam(stripIndexParam2(args.request)), 11832 params: args.params, 11833 context: args.context, 11834 unstable_pattern: args.unstable_pattern 11835 }); 11836 if (isDataWithResponseInit(result) && result.init && result.init.status && isRedirectStatusCode(result.init.status)) { 11837 throw new Response(null, result.init); 11838 } 11839 return result; 11840} 11841function stripIndexParam2(request) { 11842 let url = new URL(request.url); 11843 let indexValues = url.searchParams.getAll("index"); 11844 url.searchParams.delete("index"); 11845 let indexValuesToKeep = []; 11846 for (let indexValue of indexValues) { 11847 if (indexValue) { 11848 indexValuesToKeep.push(indexValue); 11849 } 11850 } 11851 for (let toKeep of indexValuesToKeep) { 11852 url.searchParams.append("index", toKeep); 11853 } 11854 let init = { 11855 method: request.method, 11856 body: request.body, 11857 headers: request.headers, 11858 signal: request.signal 11859 }; 11860 if (init.body) { 11861 init.duplex = "half"; 11862 } 11863 return new Request(url.href, init); 11864} 11865function stripRoutesParam(request) { 11866 let url = new URL(request.url); 11867 url.searchParams.delete("_routes"); 11868 let init = { 11869 method: request.method, 11870 body: request.body, 11871 headers: request.headers, 11872 signal: request.signal 11873 }; 11874 if (init.body) { 11875 init.duplex = "half"; 11876 } 11877 return new Request(url.href, init); 11878} 11879function invariant3(value, message) { 11880 if (value === false || value === null || typeof value === "undefined") { 11881 console.error( 11882 "The following error is a bug in React Router; please open an issue! https://github.com/remix-run/react-router/issues/new/choose" 11883 ); 11884 throw new Error(message); 11885 } 11886} 11887var globalDevServerHooksKey = "__reactRouterDevServerHooks"; 11888function setDevServerHooks(devServerHooks) { 11889 globalThis[globalDevServerHooksKey] = devServerHooks; 11890} 11891function getDevServerHooks() { 11892 return globalThis[globalDevServerHooksKey]; 11893} 11894function getBuildTimeHeader(request, headerName) { 11895 if (typeof process !== "undefined") { 11896 try { 11897 if (process.env?.IS_RR_BUILD_REQUEST === "yes") { 11898 return request.headers.get(headerName); 11899 } 11900 } catch (e) { 11901 } 11902 } 11903 return null; 11904} 11905function groupRoutesByParentId2(manifest) { 11906 let routes = {}; 11907 Object.values(manifest).forEach((route) => { 11908 if (route) { 11909 let parentId = route.parentId || ""; 11910 if (!routes[parentId]) { 11911 routes[parentId] = []; 11912 } 11913 routes[parentId].push(route); 11914 } 11915 }); 11916 return routes; 11917} 11918function createRoutes(manifest, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) { 11919 return (routesByParentId[parentId] || []).map((route) => ({ 11920 ...route, 11921 children: createRoutes(manifest, route.id, routesByParentId) 11922 })); 11923} 11924function createStaticHandlerDataRoutes(manifest, future, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) { 11925 return (routesByParentId[parentId] || []).map((route) => { 11926 let commonRoute = { 11927 // Always include root due to default boundaries 11928 hasErrorBoundary: route.id === "root" || route.module.ErrorBoundary != null, 11929 id: route.id, 11930 path: route.path, 11931 middleware: route.module.middleware, 11932 // Need to use RR's version in the param typed here to permit the optional 11933 // context even though we know it'll always be provided in remix 11934 loader: route.module.loader ? async (args) => { 11935 let preRenderedData = getBuildTimeHeader( 11936 args.request, 11937 "X-React-Router-Prerender-Data" 11938 ); 11939 if (preRenderedData != null) { 11940 let encoded = preRenderedData ? decodeURI(preRenderedData) : preRenderedData; 11941 invariant3(encoded, "Missing prerendered data for route"); 11942 let uint8array = new TextEncoder().encode(encoded); 11943 let stream = new ReadableStream({ 11944 start(controller) { 11945 controller.enqueue(uint8array); 11946 controller.close(); 11947 } 11948 }); 11949 let decoded = await decodeViaTurboStream(stream, global); 11950 let data2 = decoded.value; 11951 if (data2 && SingleFetchRedirectSymbol in data2) { 11952 let result = data2[SingleFetchRedirectSymbol]; 11953 let init = { status: result.status }; 11954 if (result.reload) { 11955 throw redirectDocument(result.redirect, init); 11956 } else if (result.replace) { 11957 throw replace(result.redirect, init); 11958 } else { 11959 throw redirect(result.redirect, init); 11960 } 11961 } else { 11962 invariant3( 11963 data2 && route.id in data2, 11964 "Unable to decode prerendered data" 11965 ); 11966 let result = data2[route.id]; 11967 invariant3( 11968 "data" in result, 11969 "Unable to process prerendered data" 11970 ); 11971 return result.data; 11972 } 11973 } 11974 let val = await callRouteHandler(route.module.loader, args); 11975 return val; 11976 } : void 0, 11977 action: route.module.action ? (args) => callRouteHandler(route.module.action, args) : void 0, 11978 handle: route.module.handle 11979 }; 11980 return route.index ? { 11981 index: true, 11982 ...commonRoute 11983 } : { 11984 caseSensitive: route.caseSensitive, 11985 children: createStaticHandlerDataRoutes( 11986 manifest, 11987 future, 11988 route.id, 11989 routesByParentId 11990 ), 11991 ...commonRoute 11992 }; 11993 }); 11994} 11995function createServerHandoffString(serverHandoff) { 11996 return escapeHtml(JSON.stringify(serverHandoff)); 11997} 11998function getDocumentHeaders(context, build) { 11999 return getDocumentHeadersImpl(context, (m) => { 12000 let route = build.routes[m.route.id]; 12001 invariant3(route, `Route with id "${m.route.id}" not found in build`); 12002 return route.module.headers; 12003 }); 12004} 12005function getDocumentHeadersImpl(context, getRouteHeadersFn, _defaultHeaders) { 12006 let boundaryIdx = context.errors ? context.matches.findIndex((m) => context.errors[m.route.id]) : -1; 12007 let matches = boundaryIdx >= 0 ? context.matches.slice(0, boundaryIdx + 1) : context.matches; 12008 let errorHeaders; 12009 if (boundaryIdx >= 0) { 12010 let { actionHeaders, actionData, loaderHeaders, loaderData } = context; 12011 context.matches.slice(boundaryIdx).some((match) => { 12012 let id = match.route.id; 12013 if (actionHeaders[id] && (!actionData || !actionData.hasOwnProperty(id))) { 12014 errorHeaders = actionHeaders[id]; 12015 } else if (loaderHeaders[id] && !loaderData.hasOwnProperty(id)) { 12016 errorHeaders = loaderHeaders[id]; 12017 } 12018 return errorHeaders != null; 12019 }); 12020 } 12021 const defaultHeaders = new Headers(_defaultHeaders); 12022 return matches.reduce((parentHeaders, match, idx) => { 12023 let { id } = match.route; 12024 let loaderHeaders = context.loaderHeaders[id] || new Headers(); 12025 let actionHeaders = context.actionHeaders[id] || new Headers(); 12026 let includeErrorHeaders = errorHeaders != null && idx === matches.length - 1; 12027 let includeErrorCookies = includeErrorHeaders && errorHeaders !== loaderHeaders && errorHeaders !== actionHeaders; 12028 let headersFn = getRouteHeadersFn(match); 12029 if (headersFn == null) { 12030 let headers2 = new Headers(parentHeaders); 12031 if (includeErrorCookies) { 12032 prependCookies(errorHeaders, headers2); 12033 } 12034 prependCookies(actionHeaders, headers2); 12035 prependCookies(loaderHeaders, headers2); 12036 return headers2; 12037 } 12038 let headers = new Headers( 12039 typeof headersFn === "function" ? headersFn({ 12040 loaderHeaders, 12041 parentHeaders, 12042 actionHeaders, 12043 errorHeaders: includeErrorHeaders ? errorHeaders : void 0 12044 }) : headersFn 12045 ); 12046 if (includeErrorCookies) { 12047 prependCookies(errorHeaders, headers); 12048 } 12049 prependCookies(actionHeaders, headers); 12050 prependCookies(loaderHeaders, headers); 12051 prependCookies(parentHeaders, headers); 12052 return headers; 12053 }, new Headers(defaultHeaders)); 12054} 12055function prependCookies(parentHeaders, childHeaders) { 12056 let parentSetCookieString = parentHeaders.get("Set-Cookie"); 12057 if (parentSetCookieString) { 12058 let cookies = (0, import_set_cookie_parser.splitCookiesString)(parentSetCookieString); 12059 let childCookies = new Set(childHeaders.getSetCookie()); 12060 cookies.forEach((cookie) => { 12061 if (!childCookies.has(cookie)) { 12062 childHeaders.append("Set-Cookie", cookie); 12063 } 12064 }); 12065 } 12066} 12067function throwIfPotentialCSRFAttack(headers, allowedActionOrigins) { 12068 let originHeader = headers.get("origin"); 12069 let originDomain = null; 12070 try { 12071 originDomain = typeof originHeader === "string" && originHeader !== "null" ? new URL(originHeader).host : originHeader; 12072 } catch { 12073 throw new Error( 12074 `\`origin\` header is not a valid URL. Aborting the action.` 12075 ); 12076 } 12077 let host = parseHostHeader(headers); 12078 if (originDomain && (!host || originDomain !== host.value)) { 12079 if (!isAllowedOrigin(originDomain, allowedActionOrigins)) { 12080 if (host) { 12081 throw new Error( 12082 `${host.type} header does not match \`origin\` header from a forwarded action request. Aborting the action.` 12083 ); 12084 } else { 12085 throw new Error( 12086 "`x-forwarded-host` or `host` headers are not provided. One of these is needed to compare the `origin` header from a forwarded action request. Aborting the action." 12087 ); 12088 } 12089 } 12090 } 12091} 12092function matchWildcardDomain(domain, pattern) { 12093 const domainParts = domain.split("."); 12094 const patternParts = pattern.split("."); 12095 if (patternParts.length < 1) { 12096 return false; 12097 } 12098 if (domainParts.length < patternParts.length) { 12099 return false; 12100 } 12101 while (patternParts.length) { 12102 const patternPart = patternParts.pop(); 12103 const domainPart = domainParts.pop(); 12104 switch (patternPart) { 12105 case "": { 12106 return false; 12107 } 12108 case "*": { 12109 if (domainPart) { 12110 continue; 12111 } else { 12112 return false; 12113 } 12114 } 12115 case "**": { 12116 if (patternParts.length > 0) { 12117 return false; 12118 } 12119 return domainPart !== void 0; 12120 } 12121 case void 0: 12122 default: { 12123 if (domainPart !== patternPart) { 12124 return false; 12125 } 12126 } 12127 } 12128 } 12129 return domainParts.length === 0; 12130} 12131function isAllowedOrigin(originDomain, allowedActionOrigins = []) { 12132 return allowedActionOrigins.some( 12133 (allowedOrigin) => allowedOrigin && (allowedOrigin === originDomain || matchWildcardDomain(originDomain, allowedOrigin)) 12134 ); 12135} 12136function parseHostHeader(headers) { 12137 let forwardedHostHeader = headers.get("x-forwarded-host"); 12138 let forwardedHostValue = forwardedHostHeader?.split(",")[0]?.trim(); 12139 let hostHeader = headers.get("host"); 12140 return forwardedHostValue ? { 12141 type: "x-forwarded-host", 12142 value: forwardedHostValue 12143 } : hostHeader ? { 12144 type: "host", 12145 value: hostHeader 12146 } : void 0; 12147} 12148var SERVER_NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([ 12149 ...NO_BODY_STATUS_CODES, 12150 304 12151]); 12152async function singleFetchAction(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) { 12153 try { 12154 try { 12155 throwIfPotentialCSRFAttack( 12156 request.headers, 12157 Array.isArray(build.allowedActionOrigins) ? build.allowedActionOrigins : [] 12158 ); 12159 } catch (e) { 12160 return handleQueryError(new Error("Bad Request"), 400); 12161 } 12162 let handlerRequest = new Request(handlerUrl, { 12163 method: request.method, 12164 body: request.body, 12165 headers: request.headers, 12166 signal: request.signal, 12167 ...request.body ? { duplex: "half" } : void 0 12168 }); 12169 let result = await staticHandler.query(handlerRequest, { 12170 requestContext: loadContext, 12171 skipLoaderErrorBubbling: true, 12172 skipRevalidation: true, 12173 generateMiddlewareResponse: build.future.v8_middleware ? async (query) => { 12174 try { 12175 let innerResult = await query(handlerRequest); 12176 return handleQueryResult(innerResult); 12177 } catch (error) { 12178 return handleQueryError(error); 12179 } 12180 } : void 0 12181 }); 12182 return handleQueryResult(result); 12183 } catch (error) { 12184 return handleQueryError(error); 12185 } 12186 function handleQueryResult(result) { 12187 return isResponse(result) ? result : staticContextToResponse(result); 12188 } 12189 function handleQueryError(error, status = 500) { 12190 handleError(error); 12191 return generateSingleFetchResponse(request, build, serverMode, { 12192 result: { error }, 12193 headers: new Headers(), 12194 status 12195 }); 12196 } 12197 function staticContextToResponse(context) { 12198 let headers = getDocumentHeaders(context, build); 12199 if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) { 12200 return new Response(null, { status: context.statusCode, headers }); 12201 } 12202 if (context.errors) { 12203 Object.values(context.errors).forEach((err) => { 12204 if (!isRouteErrorResponse(err) || err.error) { 12205 handleError(err); 12206 } 12207 }); 12208 context.errors = sanitizeErrors(context.errors, serverMode); 12209 } 12210 let singleFetchResult; 12211 if (context.errors) { 12212 singleFetchResult = { error: Object.values(context.errors)[0] }; 12213 } else { 12214 singleFetchResult = { 12215 data: Object.values(context.actionData || {})[0] 12216 }; 12217 } 12218 return generateSingleFetchResponse(request, build, serverMode, { 12219 result: singleFetchResult, 12220 headers, 12221 status: context.statusCode 12222 }); 12223 } 12224} 12225async function singleFetchLoaders(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) { 12226 let routesParam = new URL(request.url).searchParams.get("_routes"); 12227 let loadRouteIds = routesParam ? new Set(routesParam.split(",")) : null; 12228 try { 12229 let handlerRequest = new Request(handlerUrl, { 12230 headers: request.headers, 12231 signal: request.signal 12232 }); 12233 let result = await staticHandler.query(handlerRequest, { 12234 requestContext: loadContext, 12235 filterMatchesToLoad: (m) => !loadRouteIds || loadRouteIds.has(m.route.id), 12236 skipLoaderErrorBubbling: true, 12237 generateMiddlewareResponse: build.future.v8_middleware ? async (query) => { 12238 try { 12239 let innerResult = await query(handlerRequest); 12240 return handleQueryResult(innerResult); 12241 } catch (error) { 12242 return handleQueryError(error); 12243 } 12244 } : void 0 12245 }); 12246 return handleQueryResult(result); 12247 } catch (error) { 12248 return handleQueryError(error); 12249 } 12250 function handleQueryResult(result) { 12251 return isResponse(result) ? result : staticContextToResponse(result); 12252 } 12253 function handleQueryError(error) { 12254 handleError(error); 12255 return generateSingleFetchResponse(request, build, serverMode, { 12256 result: { error }, 12257 headers: new Headers(), 12258 status: 500 12259 }); 12260 } 12261 function staticContextToResponse(context) { 12262 let headers = getDocumentHeaders(context, build); 12263 if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) { 12264 return new Response(null, { status: context.statusCode, headers }); 12265 } 12266 if (context.errors) { 12267 Object.values(context.errors).forEach((err) => { 12268 if (!isRouteErrorResponse(err) || err.error) { 12269 handleError(err); 12270 } 12271 }); 12272 context.errors = sanitizeErrors(context.errors, serverMode); 12273 } 12274 let results = {}; 12275 let loadedMatches = new Set( 12276 context.matches.filter( 12277 (m) => loadRouteIds ? loadRouteIds.has(m.route.id) : m.route.loader != null 12278 ).map((m) => m.route.id) 12279 ); 12280 if (context.errors) { 12281 for (let [id, error] of Object.entries(context.errors)) { 12282 results[id] = { error }; 12283 } 12284 } 12285 for (let [id, data2] of Object.entries(context.loaderData)) { 12286 if (!(id in results) && loadedMatches.has(id)) { 12287 results[id] = { data: data2 }; 12288 } 12289 } 12290 return generateSingleFetchResponse(request, build, serverMode, { 12291 result: results, 12292 headers, 12293 status: context.statusCode 12294 }); 12295 } 12296} 12297function generateSingleFetchResponse(request, build, serverMode, { 12298 result, 12299 headers, 12300 status 12301}) { 12302 let resultHeaders = new Headers(headers); 12303 resultHeaders.set("X-Remix-Response", "yes"); 12304 if (SERVER_NO_BODY_STATUS_CODES.has(status)) { 12305 return new Response(null, { status, headers: resultHeaders }); 12306 } 12307 resultHeaders.set("Content-Type", "text/x-script"); 12308 resultHeaders.delete("Content-Length"); 12309 return new Response( 12310 encodeViaTurboStream( 12311 result, 12312 request.signal, 12313 build.entry.module.streamTimeout, 12314 serverMode 12315 ), 12316 { 12317 status: status || 200, 12318 headers: resultHeaders 12319 } 12320 ); 12321} 12322function generateSingleFetchRedirectResponse(redirectResponse, request, build, serverMode) { 12323 let redirect2 = getSingleFetchRedirect( 12324 redirectResponse.status, 12325 redirectResponse.headers, 12326 build.basename 12327 ); 12328 let headers = new Headers(redirectResponse.headers); 12329 headers.delete("Location"); 12330 headers.set("Content-Type", "text/x-script"); 12331 return generateSingleFetchResponse(request, build, serverMode, { 12332 result: request.method === "GET" ? { [SingleFetchRedirectSymbol]: redirect2 } : redirect2, 12333 headers, 12334 status: SINGLE_FETCH_REDIRECT_STATUS 12335 }); 12336} 12337function getSingleFetchRedirect(status, headers, basename) { 12338 let redirect2 = headers.get("Location"); 12339 if (basename) { 12340 redirect2 = stripBasename(redirect2, basename) || redirect2; 12341 } 12342 return { 12343 redirect: redirect2, 12344 status, 12345 revalidate: ( 12346 // Technically X-Remix-Revalidate isn't needed here - that was an implementation 12347 // detail of ?_data requests as our way to tell the front end to revalidate when 12348 // we didn't have a response body to include that information in. 12349 // With single fetch, we tell the front end via this revalidate boolean field. 12350 // However, we're respecting it for now because it may be something folks have 12351 // used in their own responses 12352 // TODO(v3): Consider removing or making this official public API 12353 headers.has("X-Remix-Revalidate") || headers.has("Set-Cookie") 12354 ), 12355 reload: headers.has("X-Remix-Reload-Document"), 12356 replace: headers.has("X-Remix-Replace") 12357 }; 12358} 12359function encodeViaTurboStream(data2, requestSignal, streamTimeout, serverMode) { 12360 let controller = new AbortController(); 12361 let timeoutId = setTimeout( 12362 () => controller.abort(new Error("Server Timeout")), 12363 typeof streamTimeout === "number" ? streamTimeout : 4950 12364 ); 12365 let clearStreamTimeout = () => clearTimeout(timeoutId); 12366 requestSignal.addEventListener("abort", clearStreamTimeout); 12367 return encode(data2, { 12368 signal: controller.signal, 12369 onComplete: clearStreamTimeout, 12370 plugins: [ 12371 (value) => { 12372 if (value instanceof Error) { 12373 let { name, message, stack } = serverMode === "production" ? sanitizeError(value, serverMode) : value; 12374 return ["SanitizedError", name, message, stack]; 12375 } 12376 if (value instanceof ErrorResponseImpl) { 12377 let { data: data3, status, statusText } = value; 12378 return ["ErrorResponse", data3, status, statusText]; 12379 } 12380 if (value && typeof value === "object" && SingleFetchRedirectSymbol in value) { 12381 return ["SingleFetchRedirect", value[SingleFetchRedirectSymbol]]; 12382 } 12383 } 12384 ], 12385 postPlugins: [ 12386 (value) => { 12387 if (!value) return; 12388 if (typeof value !== "object") return; 12389 return [ 12390 "SingleFetchClassInstance", 12391 Object.fromEntries(Object.entries(value)) 12392 ]; 12393 }, 12394 () => ["SingleFetchFallback"] 12395 ] 12396 }); 12397} 12398function derive(build, mode) { 12399 let routes = createRoutes(build.routes); 12400 let dataRoutes = createStaticHandlerDataRoutes(build.routes, build.future); 12401 let serverMode = isServerMode(mode) ? mode : "production"; 12402 let staticHandler = createStaticHandler(dataRoutes, { 12403 basename: build.basename, 12404 unstable_instrumentations: build.entry.module.unstable_instrumentations 12405 }); 12406 let errorHandler = build.entry.module.handleError || ((error, { request }) => { 12407 if (serverMode !== "test" && !request.signal.aborted) { 12408 console.error( 12409 // @ts-expect-error This is "private" from users but intended for internal use 12410 isRouteErrorResponse(error) && error.error ? error.error : error 12411 ); 12412 } 12413 }); 12414 let requestHandler = async (request, initialContext) => { 12415 let params = {}; 12416 let loadContext; 12417 let handleError = (error) => { 12418 if (mode === "development") { 12419 getDevServerHooks()?.processRequestError?.(error); 12420 } 12421 errorHandler(error, { 12422 context: loadContext, 12423 params, 12424 request 12425 }); 12426 }; 12427 if (build.future.v8_middleware) { 12428 if (initialContext && !(initialContext instanceof RouterContextProvider)) { 12429 let error = new Error( 12430 "Invalid `context` value provided to `handleRequest`. When middleware is enabled you must return an instance of `RouterContextProvider` from your `getLoadContext` function." 12431 ); 12432 handleError(error); 12433 return returnLastResortErrorResponse(error, serverMode); 12434 } 12435 loadContext = initialContext || new RouterContextProvider(); 12436 } else { 12437 loadContext = initialContext || {}; 12438 } 12439 let url = new URL(request.url); 12440 let normalizedBasename = build.basename || "/"; 12441 let normalizedPath = url.pathname; 12442 if (build.future.unstable_trailingSlashAwareDataRequests) { 12443 if (normalizedPath.endsWith("/_.data")) { 12444 normalizedPath = normalizedPath.replace(/_.data$/, ""); 12445 } else { 12446 normalizedPath = normalizedPath.replace(/\.data$/, ""); 12447 } 12448 } else { 12449 if (stripBasename(normalizedPath, normalizedBasename) === "/_root.data") { 12450 normalizedPath = normalizedBasename; 12451 } else if (normalizedPath.endsWith(".data")) { 12452 normalizedPath = normalizedPath.replace(/\.data$/, ""); 12453 } 12454 if (stripBasename(normalizedPath, normalizedBasename) !== "/" && normalizedPath.endsWith("/")) { 12455 normalizedPath = normalizedPath.slice(0, -1); 12456 } 12457 } 12458 let isSpaMode = getBuildTimeHeader(request, "X-React-Router-SPA-Mode") === "yes"; 12459 if (!build.ssr) { 12460 let decodedPath = decodeURI(normalizedPath); 12461 if (normalizedBasename !== "/") { 12462 let strippedPath = stripBasename(decodedPath, normalizedBasename); 12463 if (strippedPath == null) { 12464 errorHandler( 12465 new ErrorResponseImpl( 12466 404, 12467 "Not Found", 12468 `Refusing to prerender the \`${decodedPath}\` path because it does not start with the basename \`${normalizedBasename}\`` 12469 ), 12470 { 12471 context: loadContext, 12472 params, 12473 request 12474 } 12475 ); 12476 return new Response("Not Found", { 12477 status: 404, 12478 statusText: "Not Found" 12479 }); 12480 } 12481 decodedPath = strippedPath; 12482 } 12483 if (build.prerender.length === 0) { 12484 isSpaMode = true; 12485 } else if (!build.prerender.includes(decodedPath) && !build.prerender.includes(decodedPath + "/")) { 12486 if (url.pathname.endsWith(".data")) { 12487 errorHandler( 12488 new ErrorResponseImpl( 12489 404, 12490 "Not Found", 12491 `Refusing to SSR the path \`${decodedPath}\` because \`ssr:false\` is set and the path is not included in the \`prerender\` config, so in production the path will be a 404.` 12492 ), 12493 { 12494 context: loadContext, 12495 params, 12496 request 12497 } 12498 ); 12499 return new Response("Not Found", { 12500 status: 404, 12501 statusText: "Not Found" 12502 }); 12503 } else { 12504 isSpaMode = true; 12505 } 12506 } 12507 } 12508 let manifestUrl = getManifestPath( 12509 build.routeDiscovery.manifestPath, 12510 normalizedBasename 12511 ); 12512 if (url.pathname === manifestUrl) { 12513 try { 12514 let res = await handleManifestRequest(build, routes, url); 12515 return res; 12516 } catch (e) { 12517 handleError(e); 12518 return new Response("Unknown Server Error", { status: 500 }); 12519 } 12520 } 12521 let matches = matchServerRoutes(routes, normalizedPath, build.basename); 12522 if (matches && matches.length > 0) { 12523 Object.assign(params, matches[0].params); 12524 } 12525 let response; 12526 if (url.pathname.endsWith(".data")) { 12527 let handlerUrl = new URL(request.url); 12528 handlerUrl.pathname = normalizedPath; 12529 let singleFetchMatches = matchServerRoutes( 12530 routes, 12531 handlerUrl.pathname, 12532 build.basename 12533 ); 12534 response = await handleSingleFetchRequest( 12535 serverMode, 12536 build, 12537 staticHandler, 12538 request, 12539 handlerUrl, 12540 loadContext, 12541 handleError 12542 ); 12543 if (isRedirectResponse(response)) { 12544 response = generateSingleFetchRedirectResponse( 12545 response, 12546 request, 12547 build, 12548 serverMode 12549 ); 12550 } 12551 if (build.entry.module.handleDataRequest) { 12552 response = await build.entry.module.handleDataRequest(response, { 12553 context: loadContext, 12554 params: singleFetchMatches ? singleFetchMatches[0].params : {}, 12555 request 12556 }); 12557 if (isRedirectResponse(response)) { 12558 response = generateSingleFetchRedirectResponse( 12559 response, 12560 request, 12561 build, 12562 serverMode 12563 ); 12564 } 12565 } 12566 } else if (!isSpaMode && matches && matches[matches.length - 1].route.module.default == null && matches[matches.length - 1].route.module.ErrorBoundary == null) { 12567 response = await handleResourceRequest( 12568 serverMode, 12569 build, 12570 staticHandler, 12571 matches.slice(-1)[0].route.id, 12572 request, 12573 loadContext, 12574 handleError 12575 ); 12576 } else { 12577 let { pathname } = url; 12578 let criticalCss = void 0; 12579 if (build.unstable_getCriticalCss) { 12580 criticalCss = await build.unstable_getCriticalCss({ pathname }); 12581 } else if (mode === "development" && getDevServerHooks()?.getCriticalCss) { 12582 criticalCss = await getDevServerHooks()?.getCriticalCss?.(pathname); 12583 } 12584 response = await handleDocumentRequest( 12585 serverMode, 12586 build, 12587 staticHandler, 12588 request, 12589 loadContext, 12590 handleError, 12591 isSpaMode, 12592 criticalCss 12593 ); 12594 } 12595 if (request.method === "HEAD") { 12596 return new Response(null, { 12597 headers: response.headers, 12598 status: response.status, 12599 statusText: response.statusText 12600 }); 12601 } 12602 return response; 12603 }; 12604 if (build.entry.module.unstable_instrumentations) { 12605 requestHandler = instrumentHandler( 12606 requestHandler, 12607 build.entry.module.unstable_instrumentations.map((i) => i.handler).filter(Boolean) 12608 ); 12609 } 12610 return { 12611 routes, 12612 dataRoutes, 12613 serverMode, 12614 staticHandler, 12615 errorHandler, 12616 requestHandler 12617 }; 12618} 12619var createRequestHandler = (build, mode) => { 12620 let _build; 12621 let routes; 12622 let serverMode; 12623 let staticHandler; 12624 let errorHandler; 12625 let _requestHandler; 12626 return async function requestHandler(request, initialContext) { 12627 _build = typeof build === "function" ? await build() : build; 12628 if (typeof build === "function") { 12629 let derived = derive(_build, mode); 12630 routes = derived.routes; 12631 serverMode = derived.serverMode; 12632 staticHandler = derived.staticHandler; 12633 errorHandler = derived.errorHandler; 12634 _requestHandler = derived.requestHandler; 12635 } else if (!routes || !serverMode || !staticHandler || !errorHandler || !_requestHandler) { 12636 let derived = derive(_build, mode); 12637 routes = derived.routes; 12638 serverMode = derived.serverMode; 12639 staticHandler = derived.staticHandler; 12640 errorHandler = derived.errorHandler; 12641 _requestHandler = derived.requestHandler; 12642 } 12643 return _requestHandler(request, initialContext); 12644 }; 12645}; 12646async function handleManifestRequest(build, routes, url) { 12647 if (build.assets.version !== url.searchParams.get("version")) { 12648 return new Response(null, { 12649 status: 204, 12650 headers: { 12651 "X-Remix-Reload-Document": "true" 12652 } 12653 }); 12654 } 12655 let patches = {}; 12656 if (url.searchParams.has("paths")) { 12657 let paths = /* @__PURE__ */ new Set(); 12658 let pathParam = url.searchParams.get("paths") || ""; 12659 let requestedPaths = pathParam.split(",").filter(Boolean); 12660 requestedPaths.forEach((path) => { 12661 if (!path.startsWith("/")) { 12662 path = `/${path}`; 12663 } 12664 let segments = path.split("/").slice(1); 12665 segments.forEach((_, i) => { 12666 let partialPath = segments.slice(0, i + 1).join("/"); 12667 paths.add(`/${partialPath}`); 12668 }); 12669 }); 12670 for (let path of paths) { 12671 let matches = matchServerRoutes(routes, path, build.basename); 12672 if (matches) { 12673 for (let match of matches) { 12674 let routeId = match.route.id; 12675 let route = build.assets.routes[routeId]; 12676 if (route) { 12677 patches[routeId] = route; 12678 } 12679 } 12680 } 12681 } 12682 return Response.json(patches, { 12683 headers: { 12684 "Cache-Control": "public, max-age=31536000, immutable" 12685 } 12686 }); 12687 } 12688 return new Response("Invalid Request", { status: 400 }); 12689} 12690async function handleSingleFetchRequest(serverMode, build, staticHandler, request, handlerUrl, loadContext, handleError) { 12691 let response = request.method !== "GET" ? await singleFetchAction( 12692 build, 12693 serverMode, 12694 staticHandler, 12695 request, 12696 handlerUrl, 12697 loadContext, 12698 handleError 12699 ) : await singleFetchLoaders( 12700 build, 12701 serverMode, 12702 staticHandler, 12703 request, 12704 handlerUrl, 12705 loadContext, 12706 handleError 12707 ); 12708 return response; 12709} 12710async function handleDocumentRequest(serverMode, build, staticHandler, request, loadContext, handleError, isSpaMode, criticalCss) { 12711 try { 12712 if (request.method === "POST") { 12713 try { 12714 throwIfPotentialCSRFAttack( 12715 request.headers, 12716 Array.isArray(build.allowedActionOrigins) ? build.allowedActionOrigins : [] 12717 ); 12718 } catch (e) { 12719 handleError(e); 12720 return new Response("Bad Request", { status: 400 }); 12721 } 12722 } 12723 let result = await staticHandler.query(request, { 12724 requestContext: loadContext, 12725 generateMiddlewareResponse: build.future.v8_middleware ? async (query) => { 12726 try { 12727 let innerResult = await query(request); 12728 if (!isResponse(innerResult)) { 12729 innerResult = await renderHtml(innerResult, isSpaMode); 12730 } 12731 return innerResult; 12732 } catch (error) { 12733 handleError(error); 12734 return new Response(null, { status: 500 }); 12735 } 12736 } : void 0 12737 }); 12738 if (!isResponse(result)) { 12739 result = await renderHtml(result, isSpaMode); 12740 } 12741 return result; 12742 } catch (error) { 12743 handleError(error); 12744 return new Response(null, { status: 500 }); 12745 } 12746 async function renderHtml(context, isSpaMode2) { 12747 let headers = getDocumentHeaders(context, build); 12748 if (SERVER_NO_BODY_STATUS_CODES.has(context.statusCode)) { 12749 return new Response(null, { status: context.statusCode, headers }); 12750 } 12751 if (context.errors) { 12752 Object.values(context.errors).forEach((err) => { 12753 if (!isRouteErrorResponse(err) || err.error) { 12754 handleError(err); 12755 } 12756 }); 12757 context.errors = sanitizeErrors(context.errors, serverMode); 12758 } 12759 let state = { 12760 loaderData: context.loaderData, 12761 actionData: context.actionData, 12762 errors: serializeErrors2(context.errors, serverMode) 12763 }; 12764 let baseServerHandoff = { 12765 basename: build.basename, 12766 future: build.future, 12767 routeDiscovery: build.routeDiscovery, 12768 ssr: build.ssr, 12769 isSpaMode: isSpaMode2 12770 }; 12771 let entryContext = { 12772 manifest: build.assets, 12773 routeModules: createEntryRouteModules(build.routes), 12774 staticHandlerContext: context, 12775 criticalCss, 12776 serverHandoffString: createServerHandoffString({ 12777 ...baseServerHandoff, 12778 criticalCss 12779 }), 12780 serverHandoffStream: encodeViaTurboStream( 12781 state, 12782 request.signal, 12783 build.entry.module.streamTimeout, 12784 serverMode 12785 ), 12786 renderMeta: {}, 12787 future: build.future, 12788 ssr: build.ssr, 12789 routeDiscovery: build.routeDiscovery, 12790 isSpaMode: isSpaMode2, 12791 serializeError: (err) => serializeError(err, serverMode) 12792 }; 12793 let handleDocumentRequestFunction = build.entry.module.default; 12794 try { 12795 return await handleDocumentRequestFunction( 12796 request, 12797 context.statusCode, 12798 headers, 12799 entryContext, 12800 loadContext 12801 ); 12802 } catch (error) { 12803 handleError(error); 12804 let errorForSecondRender = error; 12805 if (isResponse(error)) { 12806 try { 12807 let data2 = await unwrapResponse(error); 12808 errorForSecondRender = new ErrorResponseImpl( 12809 error.status, 12810 error.statusText, 12811 data2 12812 ); 12813 } catch (e) { 12814 } 12815 } 12816 context = getStaticContextFromError( 12817 staticHandler.dataRoutes, 12818 context, 12819 errorForSecondRender 12820 ); 12821 if (context.errors) { 12822 context.errors = sanitizeErrors(context.errors, serverMode); 12823 } 12824 let state2 = { 12825 loaderData: context.loaderData, 12826 actionData: context.actionData, 12827 errors: serializeErrors2(context.errors, serverMode) 12828 }; 12829 entryContext = { 12830 ...entryContext, 12831 staticHandlerContext: context, 12832 serverHandoffString: createServerHandoffString(baseServerHandoff), 12833 serverHandoffStream: encodeViaTurboStream( 12834 state2, 12835 request.signal, 12836 build.entry.module.streamTimeout, 12837 serverMode 12838 ), 12839 renderMeta: {} 12840 }; 12841 try { 12842 return await handleDocumentRequestFunction( 12843 request, 12844 context.statusCode, 12845 headers, 12846 entryContext, 12847 loadContext 12848 ); 12849 } catch (error2) { 12850 handleError(error2); 12851 return returnLastResortErrorResponse(error2, serverMode); 12852 } 12853 } 12854 } 12855} 12856async function handleResourceRequest(serverMode, build, staticHandler, routeId, request, loadContext, handleError) { 12857 try { 12858 let result = await staticHandler.queryRoute(request, { 12859 routeId, 12860 requestContext: loadContext, 12861 generateMiddlewareResponse: build.future.v8_middleware ? async (queryRoute) => { 12862 try { 12863 let innerResult = await queryRoute(request); 12864 return handleQueryRouteResult(innerResult); 12865 } catch (error) { 12866 return handleQueryRouteError(error); 12867 } 12868 } : void 0 12869 }); 12870 return handleQueryRouteResult(result); 12871 } catch (error) { 12872 return handleQueryRouteError(error); 12873 } 12874 function handleQueryRouteResult(result) { 12875 if (isResponse(result)) { 12876 return result; 12877 } 12878 if (typeof result === "string") { 12879 return new Response(result); 12880 } 12881 return Response.json(result); 12882 } 12883 function handleQueryRouteError(error) { 12884 if (isResponse(error)) { 12885 return error; 12886 } 12887 if (isRouteErrorResponse(error)) { 12888 handleError(error); 12889 return errorResponseToJson(error, serverMode); 12890 } 12891 if (error instanceof Error && error.message === "Expected a response from queryRoute") { 12892 let newError = new Error( 12893 "Expected a Response to be returned from resource route handler" 12894 ); 12895 handleError(newError); 12896 return returnLastResortErrorResponse(newError, serverMode); 12897 } 12898 handleError(error); 12899 return returnLastResortErrorResponse(error, serverMode); 12900 } 12901} 12902function errorResponseToJson(errorResponse, serverMode) { 12903 return Response.json( 12904 serializeError( 12905 // @ts-expect-error This is "private" from users but intended for internal use 12906 errorResponse.error || new Error("Unexpected Server Error"), 12907 serverMode 12908 ), 12909 { 12910 status: errorResponse.status, 12911 statusText: errorResponse.statusText 12912 } 12913 ); 12914} 12915function returnLastResortErrorResponse(error, serverMode) { 12916 let message = "Unexpected Server Error"; 12917 if (serverMode !== "production") { 12918 message += ` 12919 12920${String(error)}`; 12921 } 12922 return new Response(message, { 12923 status: 500, 12924 headers: { 12925 "Content-Type": "text/plain" 12926 } 12927 }); 12928} 12929function unwrapResponse(response) { 12930 let contentType = response.headers.get("Content-Type"); 12931 return contentType && /\bapplication\/json\b/.test(contentType) ? response.body == null ? null : response.json() : response.text(); 12932} 12933function flash(name) { 12934 return `__flash_${name}__`; 12935} 12936var createSession = (initialData = {}, id = "") => { 12937 let map = new Map(Object.entries(initialData)); 12938 return { 12939 get id() { 12940 return id; 12941 }, 12942 get data() { 12943 return Object.fromEntries(map); 12944 }, 12945 has(name) { 12946 return map.has(name) || map.has(flash(name)); 12947 }, 12948 get(name) { 12949 if (map.has(name)) return map.get(name); 12950 let flashName = flash(name); 12951 if (map.has(flashName)) { 12952 let value = map.get(flashName); 12953 map.delete(flashName); 12954 return value; 12955 } 12956 return void 0; 12957 }, 12958 set(name, value) { 12959 map.set(name, value); 12960 }, 12961 flash(name, value) { 12962 map.set(flash(name), value); 12963 }, 12964 unset(name) { 12965 map.delete(name); 12966 } 12967 }; 12968}; 12969var isSession = (object) => { 12970 return object != null && typeof object.id === "string" && typeof object.data !== "undefined" && typeof object.has === "function" && typeof object.get === "function" && typeof object.set === "function" && typeof object.flash === "function" && typeof object.unset === "function"; 12971}; 12972function createSessionStorage({ 12973 cookie: cookieArg, 12974 createData, 12975 readData, 12976 updateData, 12977 deleteData 12978}) { 12979 let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg); 12980 warnOnceAboutSigningSessionCookie(cookie); 12981 return { 12982 async getSession(cookieHeader, options) { 12983 let id = cookieHeader && await cookie.parse(cookieHeader, options); 12984 let data2 = id && await readData(id); 12985 return createSession(data2 || {}, id || ""); 12986 }, 12987 async commitSession(session, options) { 12988 let { id, data: data2 } = session; 12989 let expires = options?.maxAge != null ? new Date(Date.now() + options.maxAge * 1e3) : options?.expires != null ? options.expires : cookie.expires; 12990 if (id) { 12991 await updateData(id, data2, expires); 12992 } else { 12993 id = await createData(data2, expires); 12994 } 12995 return cookie.serialize(id, options); 12996 }, 12997 async destroySession(session, options) { 12998 await deleteData(session.id); 12999 return cookie.serialize("", { 13000 ...options, 13001 maxAge: void 0, 13002 expires: /* @__PURE__ */ new Date(0) 13003 }); 13004 } 13005 }; 13006} 13007function warnOnceAboutSigningSessionCookie(cookie) { 13008 warnOnce( 13009 cookie.isSigned, 13010 `The "${cookie.name}" cookie is not signed, but session cookies should be signed to prevent tampering on the client before they are sent back to the server. See https://reactrouter.com/explanation/sessions-and-cookies#signing-cookies for more information.` 13011 ); 13012} 13013function createCookieSessionStorage({ cookie: cookieArg } = {}) { 13014 let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg); 13015 warnOnceAboutSigningSessionCookie(cookie); 13016 return { 13017 async getSession(cookieHeader, options) { 13018 return createSession( 13019 cookieHeader && await cookie.parse(cookieHeader, options) || {} 13020 ); 13021 }, 13022 async commitSession(session, options) { 13023 let serializedCookie = await cookie.serialize(session.data, options); 13024 if (serializedCookie.length > 4096) { 13025 throw new Error( 13026 "Cookie length will exceed browser maximum. Length: " + serializedCookie.length 13027 ); 13028 } 13029 return serializedCookie; 13030 }, 13031 async destroySession(_session, options) { 13032 return cookie.serialize("", { 13033 ...options, 13034 maxAge: void 0, 13035 expires: /* @__PURE__ */ new Date(0) 13036 }); 13037 } 13038 }; 13039} 13040function createMemorySessionStorage({ cookie } = {}) { 13041 let map = /* @__PURE__ */ new Map(); 13042 return createSessionStorage({ 13043 cookie, 13044 async createData(data2, expires) { 13045 let id = Math.random().toString(36).substring(2, 10); 13046 map.set(id, { data: data2, expires }); 13047 return id; 13048 }, 13049 async readData(id) { 13050 if (map.has(id)) { 13051 let { data: data2, expires } = map.get(id); 13052 if (!expires || expires > /* @__PURE__ */ new Date()) { 13053 return data2; 13054 } 13055 if (expires) map.delete(id); 13056 } 13057 return null; 13058 }, 13059 async updateData(id, data2, expires) { 13060 map.set(id, { data: data2, expires }); 13061 }, 13062 async deleteData(id) { 13063 map.delete(id); 13064 } 13065 }); 13066} 13067function href(path, ...args) { 13068 let params = args[0]; 13069 let result = trimTrailingSplat(path).replace( 13070 /\/:([\w-]+)(\?)?/g, 13071 // same regex as in .\router\utils.ts: compilePath(). 13072 (_, param, questionMark) => { 13073 const isRequired = questionMark === void 0; 13074 const value = params?.[param]; 13075 if (isRequired && value === void 0) { 13076 throw new Error( 13077 `Path '${path}' requires param '${param}' but it was not provided` 13078 ); 13079 } 13080 return value === void 0 ? "" : "/" + value; 13081 } 13082 ); 13083 if (path.endsWith("*")) { 13084 const value = params?.["*"]; 13085 if (value !== void 0) { 13086 result += "/" + value; 13087 } 13088 } 13089 return result || "/"; 13090} 13091function trimTrailingSplat(path) { 13092 let i = path.length - 1; 13093 let char = path[i]; 13094 if (char !== "*" && char !== "/") return path; 13095 i--; 13096 for (; i >= 0; i--) { 13097 if (path[i] !== "/") break; 13098 } 13099 return path.slice(0, i + 1); 13100} 13101var encoder2 = new TextEncoder(); 13102var trailer = "</body></html>"; 13103function injectRSCPayload(rscStream) { 13104 let decoder = new TextDecoder(); 13105 let resolveFlightDataPromise; 13106 let flightDataPromise = new Promise( 13107 (resolve) => resolveFlightDataPromise = resolve 13108 ); 13109 let startedRSC = false; 13110 let buffered = []; 13111 let timeout = null; 13112 function flushBufferedChunks(controller) { 13113 for (let chunk of buffered) { 13114 let buf = decoder.decode(chunk, { stream: true }); 13115 if (buf.endsWith(trailer)) { 13116 buf = buf.slice(0, -trailer.length); 13117 } 13118 controller.enqueue(encoder2.encode(buf)); 13119 } 13120 buffered.length = 0; 13121 timeout = null; 13122 } 13123 return new TransformStream({ 13124 transform(chunk, controller) { 13125 buffered.push(chunk); 13126 if (timeout) { 13127 return; 13128 } 13129 timeout = setTimeout(async () => { 13130 flushBufferedChunks(controller); 13131 if (!startedRSC) { 13132 startedRSC = true; 13133 writeRSCStream(rscStream, controller).catch((err) => controller.error(err)).then(resolveFlightDataPromise); 13134 } 13135 }, 0); 13136 }, 13137 async flush(controller) { 13138 await flightDataPromise; 13139 if (timeout) { 13140 clearTimeout(timeout); 13141 flushBufferedChunks(controller); 13142 } 13143 controller.enqueue(encoder2.encode("</body></html>")); 13144 } 13145 }); 13146} 13147async function writeRSCStream(rscStream, controller) { 13148 let decoder = new TextDecoder("utf-8", { fatal: true }); 13149 const reader = rscStream.getReader(); 13150 try { 13151 let read; 13152 while ((read = await reader.read()) && !read.done) { 13153 const chunk = read.value; 13154 try { 13155 writeChunk( 13156 JSON.stringify(decoder.decode(chunk, { stream: true })), 13157 controller 13158 ); 13159 } catch (err) { 13160 let base64 = JSON.stringify(btoa(String.fromCodePoint(...chunk))); 13161 writeChunk( 13162 `Uint8Array.from(atob(${base64}), m => m.codePointAt(0))`, 13163 controller 13164 ); 13165 } 13166 } 13167 } finally { 13168 reader.releaseLock(); 13169 } 13170 let remaining = decoder.decode(); 13171 if (remaining.length) { 13172 writeChunk(JSON.stringify(remaining), controller); 13173 } 13174} 13175function writeChunk(chunk, controller) { 13176 controller.enqueue( 13177 encoder2.encode( 13178 `<script>${escapeScript( 13179 `(self.__FLIGHT_DATA||=[]).push(${chunk})` 13180 )}<\/script>` 13181 ) 13182 ); 13183} 13184function escapeScript(script) { 13185 return script.replace(/<!--/g, "<\\!--").replace(/<\/(script)/gi, "</\\$1"); 13186} 13187var RSCRouterGlobalErrorBoundary = class extends import_react.default.Component { 13188 constructor(props) { 13189 super(props); 13190 this.state = { error: null, location: props.location }; 13191 } 13192 static getDerivedStateFromError(error) { 13193 return { error }; 13194 } 13195 static getDerivedStateFromProps(props, state) { 13196 if (state.location !== props.location) { 13197 return { error: null, location: props.location }; 13198 } 13199 return { error: state.error, location: state.location }; 13200 } 13201 render() { 13202 if (this.state.error) { 13203 return import_react.default.createElement( 13204 RSCDefaultRootErrorBoundaryImpl, 13205 { 13206 error: this.state.error, 13207 renderAppShell: true 13208 } 13209 ); 13210 } else { 13211 return this.props.children; 13212 } 13213 } 13214}; 13215function ErrorWrapper({ 13216 renderAppShell, 13217 title, 13218 children 13219}) { 13220 if (!renderAppShell) { 13221 return children; 13222 } 13223 return import_react.default.createElement("html", { lang: "en" }, import_react.default.createElement("head", null, import_react.default.createElement("meta", { charSet: "utf-8" }), import_react.default.createElement( 13224 "meta", 13225 { 13226 name: "viewport", 13227 content: "width=device-width,initial-scale=1,viewport-fit=cover" 13228 } 13229 ), import_react.default.createElement("title", null, title)), import_react.default.createElement("body", null, import_react.default.createElement("main", { style: { fontFamily: "system-ui, sans-serif", padding: "2rem" } }, children))); 13230} 13231function RSCDefaultRootErrorBoundaryImpl({ 13232 error, 13233 renderAppShell 13234}) { 13235 console.error(error); 13236 let heyDeveloper = import_react.default.createElement( 13237 "script", 13238 { 13239 dangerouslySetInnerHTML: { 13240 __html: ` 13241 console.log( 13242 "💿 Hey developer 👋. 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." 13243 ); 13244 ` 13245 } 13246 } 13247 ); 13248 if (isRouteErrorResponse(error)) { 13249 return import_react.default.createElement( 13250 ErrorWrapper, 13251 { 13252 renderAppShell, 13253 title: "Unhandled Thrown Response!" 13254 }, 13255 import_react.default.createElement("h1", { style: { fontSize: "24px" } }, error.status, " ", error.statusText), 13256 ENABLE_DEV_WARNINGS ? heyDeveloper : null 13257 ); 13258 } 13259 let errorInstance; 13260 if (error instanceof Error) { 13261 errorInstance = error; 13262 } else { 13263 let errorString = error == null ? "Unknown Error" : typeof error === "object" && "toString" in error ? error.toString() : JSON.stringify(error); 13264 errorInstance = new Error(errorString); 13265 } 13266 return import_react.default.createElement(ErrorWrapper, { renderAppShell, title: "Application Error!" }, import_react.default.createElement("h1", { style: { fontSize: "24px" } }, "Application Error"), import_react.default.createElement( 13267 "pre", 13268 { 13269 style: { 13270 padding: "2rem", 13271 background: "hsla(10, 50%, 50%, 0.1)", 13272 color: "red", 13273 overflow: "auto" 13274 } 13275 }, 13276 errorInstance.stack 13277 ), heyDeveloper); 13278} 13279function RSCDefaultRootErrorBoundary({ 13280 hasRootLayout 13281}) { 13282 let error = useRouteError(); 13283 if (hasRootLayout === void 0) { 13284 throw new Error("Missing 'hasRootLayout' prop"); 13285 } 13286 return import_react.default.createElement( 13287 RSCDefaultRootErrorBoundaryImpl, 13288 { 13289 renderAppShell: !hasRootLayout, 13290 error 13291 } 13292 ); 13293} 13294function createRSCRouteModules(payload) { 13295 const routeModules = {}; 13296 for (const match of payload.matches) { 13297 populateRSCRouteModules(routeModules, match); 13298 } 13299 return routeModules; 13300} 13301function populateRSCRouteModules(routeModules, matches) { 13302 matches = Array.isArray(matches) ? matches : [matches]; 13303 for (const match of matches) { 13304 routeModules[match.id] = { 13305 links: match.links, 13306 meta: match.meta, 13307 default: noopComponent 13308 }; 13309 } 13310} 13311var noopComponent = () => null; 13312var REACT_USE = "use"; 13313var useImpl = React42[REACT_USE]; 13314function useSafe(promise) { 13315 if (useImpl) { 13316 return useImpl(promise); 13317 } 13318 throw new Error("React Router v7 requires React 19+ for RSC features."); 13319} 13320async function routeRSCServerRequest({ 13321 request, 13322 serverResponse, 13323 createFromReadableStream, 13324 renderHTML, 13325 hydrate: hydrate2 = true 13326}) { 13327 const url = new URL(request.url); 13328 const isDataRequest = isReactServerRequest(url); 13329 const respondWithRSCPayload = isDataRequest || isManifestRequest(url) || request.headers.has("rsc-action-id"); 13330 if (respondWithRSCPayload || serverResponse.headers.get("React-Router-Resource") === "true") { 13331 return serverResponse; 13332 } 13333 if (!serverResponse.body) { 13334 throw new Error("Missing body in server response"); 13335 } 13336 const detectRedirectResponse = serverResponse.clone(); 13337 let serverResponseB = null; 13338 if (hydrate2) { 13339 serverResponseB = serverResponse.clone(); 13340 } 13341 const body = serverResponse.body; 13342 let buffer; 13343 let streamControllers = []; 13344 const createStream = () => { 13345 if (!buffer) { 13346 buffer = []; 13347 return body.pipeThrough( 13348 new TransformStream({ 13349 transform(chunk, controller) { 13350 buffer.push(chunk); 13351 controller.enqueue(chunk); 13352 streamControllers.forEach((c) => c.enqueue(chunk)); 13353 }, 13354 flush() { 13355 streamControllers.forEach((c) => c.close()); 13356 streamControllers = []; 13357 } 13358 }) 13359 ); 13360 } 13361 return new ReadableStream({ 13362 start(controller) { 13363 buffer.forEach((chunk) => controller.enqueue(chunk)); 13364 streamControllers.push(controller); 13365 } 13366 }); 13367 }; 13368 let deepestRenderedBoundaryId = null; 13369 const getPayload = () => { 13370 const payloadPromise = Promise.resolve( 13371 createFromReadableStream(createStream()) 13372 ); 13373 return Object.defineProperties(payloadPromise, { 13374 _deepestRenderedBoundaryId: { 13375 get() { 13376 return deepestRenderedBoundaryId; 13377 }, 13378 set(boundaryId) { 13379 deepestRenderedBoundaryId = boundaryId; 13380 } 13381 }, 13382 formState: { 13383 get() { 13384 return payloadPromise.then( 13385 (payload) => payload.type === "render" ? payload.formState : void 0 13386 ); 13387 } 13388 } 13389 }); 13390 }; 13391 let renderRedirect; 13392 let renderError; 13393 try { 13394 if (!detectRedirectResponse.body) { 13395 throw new Error("Failed to clone server response"); 13396 } 13397 const payload = await createFromReadableStream( 13398 detectRedirectResponse.body 13399 ); 13400 if (serverResponse.status === SINGLE_FETCH_REDIRECT_STATUS && payload.type === "redirect") { 13401 const headers2 = new Headers(serverResponse.headers); 13402 headers2.delete("Content-Encoding"); 13403 headers2.delete("Content-Length"); 13404 headers2.delete("Content-Type"); 13405 headers2.delete("X-Remix-Response"); 13406 headers2.set("Location", payload.location); 13407 return new Response(serverResponseB?.body || "", { 13408 headers: headers2, 13409 status: payload.status, 13410 statusText: serverResponse.statusText 13411 }); 13412 } 13413 let reactHeaders = new Headers(); 13414 let status = serverResponse.status; 13415 let statusText = serverResponse.statusText; 13416 let html = await renderHTML(getPayload, { 13417 onError(error) { 13418 if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") { 13419 renderRedirect = decodeRedirectErrorDigest(error.digest); 13420 if (renderRedirect) { 13421 return error.digest; 13422 } 13423 let routeErrorResponse = decodeRouteErrorResponseDigest(error.digest); 13424 if (routeErrorResponse) { 13425 renderError = routeErrorResponse; 13426 status = routeErrorResponse.status; 13427 statusText = routeErrorResponse.statusText; 13428 return error.digest; 13429 } 13430 } 13431 }, 13432 onHeaders(headers2) { 13433 for (const [key, value] of headers2) { 13434 reactHeaders.append(key, value); 13435 } 13436 } 13437 }); 13438 const headers = new Headers(reactHeaders); 13439 for (const [key, value] of serverResponse.headers) { 13440 headers.append(key, value); 13441 } 13442 headers.set("Content-Type", "text/html; charset=utf-8"); 13443 if (renderRedirect) { 13444 headers.set("Location", renderRedirect.location); 13445 return new Response(html, { 13446 status: renderRedirect.status, 13447 headers 13448 }); 13449 } 13450 const redirectTransform = new TransformStream({ 13451 flush(controller) { 13452 if (renderRedirect) { 13453 controller.enqueue( 13454 new TextEncoder().encode( 13455 `<meta http-equiv="refresh" content="0;url=${escapeHtml(renderRedirect.location)}"/>` 13456 ) 13457 ); 13458 } 13459 } 13460 }); 13461 if (!hydrate2) { 13462 return new Response(html.pipeThrough(redirectTransform), { 13463 status, 13464 statusText, 13465 headers 13466 }); 13467 } 13468 if (!serverResponseB?.body) { 13469 throw new Error("Failed to clone server response"); 13470 } 13471 const body2 = html.pipeThrough(injectRSCPayload(serverResponseB.body)).pipeThrough(redirectTransform); 13472 return new Response(body2, { 13473 status, 13474 statusText, 13475 headers 13476 }); 13477 } catch (reason) { 13478 if (reason instanceof Response) { 13479 return reason; 13480 } 13481 if (renderRedirect) { 13482 return new Response(`Redirect: ${renderRedirect.location}`, { 13483 status: renderRedirect.status, 13484 headers: { 13485 Location: renderRedirect.location 13486 } 13487 }); 13488 } 13489 try { 13490 reason = renderError ?? reason; 13491 let [status, statusText] = isRouteErrorResponse(reason) ? [reason.status, reason.statusText] : [500, ""]; 13492 let retryRedirect; 13493 let reactHeaders = new Headers(); 13494 const html = await renderHTML( 13495 () => { 13496 const decoded = Promise.resolve( 13497 createFromReadableStream(createStream()) 13498 ); 13499 const payloadPromise = decoded.then( 13500 (payload) => Object.assign(payload, { 13501 status, 13502 errors: deepestRenderedBoundaryId ? { 13503 [deepestRenderedBoundaryId]: reason 13504 } : {} 13505 }) 13506 ); 13507 return Object.defineProperties(payloadPromise, { 13508 _deepestRenderedBoundaryId: { 13509 get() { 13510 return deepestRenderedBoundaryId; 13511 }, 13512 set(boundaryId) { 13513 deepestRenderedBoundaryId = boundaryId; 13514 } 13515 }, 13516 formState: { 13517 get() { 13518 return payloadPromise.then( 13519 (payload) => payload.type === "render" ? payload.formState : void 0 13520 ); 13521 } 13522 } 13523 }); 13524 }, 13525 { 13526 onError(error) { 13527 if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") { 13528 retryRedirect = decodeRedirectErrorDigest(error.digest); 13529 if (retryRedirect) { 13530 return error.digest; 13531 } 13532 let routeErrorResponse = decodeRouteErrorResponseDigest( 13533 error.digest 13534 ); 13535 if (routeErrorResponse) { 13536 status = routeErrorResponse.status; 13537 statusText = routeErrorResponse.statusText; 13538 return error.digest; 13539 } 13540 } 13541 }, 13542 onHeaders(headers2) { 13543 for (const [key, value] of headers2) { 13544 reactHeaders.append(key, value); 13545 } 13546 } 13547 } 13548 ); 13549 const headers = new Headers(reactHeaders); 13550 for (const [key, value] of serverResponse.headers) { 13551 headers.append(key, value); 13552 } 13553 headers.set("Content-Type", "text/html; charset=utf-8"); 13554 if (retryRedirect) { 13555 headers.set("Location", retryRedirect.location); 13556 return new Response(html, { 13557 status: retryRedirect.status, 13558 headers 13559 }); 13560 } 13561 const retryRedirectTransform = new TransformStream({ 13562 flush(controller) { 13563 if (retryRedirect) { 13564 controller.enqueue( 13565 new TextEncoder().encode( 13566 `<meta http-equiv="refresh" content="0;url=${escapeHtml(retryRedirect.location)}"/>` 13567 ) 13568 ); 13569 } 13570 } 13571 }); 13572 if (!hydrate2) { 13573 return new Response(html.pipeThrough(retryRedirectTransform), { 13574 status, 13575 statusText, 13576 headers 13577 }); 13578 } 13579 if (!serverResponseB?.body) { 13580 throw new Error("Failed to clone server response"); 13581 } 13582 const body2 = html.pipeThrough(injectRSCPayload(serverResponseB.body)).pipeThrough(retryRedirectTransform); 13583 return new Response(body2, { 13584 status, 13585 statusText, 13586 headers 13587 }); 13588 } catch { 13589 } 13590 throw reason; 13591 } 13592} 13593function RSCStaticRouter({ getPayload }) { 13594 const decoded = getPayload(); 13595 const payload = useSafe(decoded); 13596 if (payload.type === "redirect") { 13597 throw new Response(null, { 13598 status: payload.status, 13599 headers: { 13600 Location: payload.location 13601 } 13602 }); 13603 } 13604 if (payload.type !== "render") return null; 13605 let patchedLoaderData = { ...payload.loaderData }; 13606 for (const match of payload.matches) { 13607 if (shouldHydrateRouteLoader( 13608 match.id, 13609 match.clientLoader, 13610 match.hasLoader, 13611 false 13612 ) && (match.hydrateFallbackElement || !match.hasLoader)) { 13613 delete patchedLoaderData[match.id]; 13614 } 13615 } 13616 const context = { 13617 get _deepestRenderedBoundaryId() { 13618 return decoded._deepestRenderedBoundaryId ?? null; 13619 }, 13620 set _deepestRenderedBoundaryId(boundaryId) { 13621 decoded._deepestRenderedBoundaryId = boundaryId; 13622 }, 13623 actionData: payload.actionData, 13624 actionHeaders: {}, 13625 basename: payload.basename, 13626 errors: payload.errors, 13627 loaderData: patchedLoaderData, 13628 loaderHeaders: {}, 13629 location: payload.location, 13630 statusCode: 200, 13631 matches: payload.matches.map((match) => ({ 13632 params: match.params, 13633 pathname: match.pathname, 13634 pathnameBase: match.pathnameBase, 13635 route: { 13636 id: match.id, 13637 action: match.hasAction || !!match.clientAction, 13638 handle: match.handle, 13639 hasErrorBoundary: match.hasErrorBoundary, 13640 loader: match.hasLoader || !!match.clientLoader, 13641 index: match.index, 13642 path: match.path, 13643 shouldRevalidate: match.shouldRevalidate 13644 } 13645 })) 13646 }; 13647 const router2 = createStaticRouter( 13648 payload.matches.reduceRight((previous, match) => { 13649 const route = { 13650 id: match.id, 13651 action: match.hasAction || !!match.clientAction, 13652 element: match.element, 13653 errorElement: match.errorElement, 13654 handle: match.handle, 13655 hasErrorBoundary: !!match.errorElement, 13656 hydrateFallbackElement: match.hydrateFallbackElement, 13657 index: match.index, 13658 loader: match.hasLoader || !!match.clientLoader, 13659 path: match.path, 13660 shouldRevalidate: match.shouldRevalidate 13661 }; 13662 if (previous.length > 0) { 13663 route.children = previous; 13664 } 13665 return [route]; 13666 }, []), 13667 context 13668 ); 13669 const frameworkContext = { 13670 future: { 13671 // These flags have no runtime impact so can always be false. If we add 13672 // flags that drive runtime behavior they'll need to be proxied through. 13673 v8_middleware: false, 13674 unstable_subResourceIntegrity: false, 13675 unstable_trailingSlashAwareDataRequests: true 13676 // always on for RSC 13677 }, 13678 isSpaMode: false, 13679 ssr: true, 13680 criticalCss: "", 13681 manifest: { 13682 routes: {}, 13683 version: "1", 13684 url: "", 13685 entry: { 13686 module: "", 13687 imports: [] 13688 } 13689 }, 13690 routeDiscovery: { mode: "lazy", manifestPath: "/__manifest" }, 13691 routeModules: createRSCRouteModules(payload) 13692 }; 13693 return React42.createElement(RSCRouterContext.Provider, { value: true }, React42.createElement(RSCRouterGlobalErrorBoundary, { location: payload.location }, React42.createElement(FrameworkContext.Provider, { value: frameworkContext }, React42.createElement( 13694 StaticRouterProvider, 13695 { 13696 context, 13697 router: router2, 13698 hydrate: false, 13699 nonce: payload.nonce 13700 } 13701 )))); 13702} 13703function isReactServerRequest(url) { 13704 return url.pathname.endsWith(".rsc"); 13705} 13706function isManifestRequest(url) { 13707 return url.pathname.endsWith(".manifest"); 13708} 13709function deserializeErrors2(errors) { 13710 if (!errors) return null; 13711 let entries = Object.entries(errors); 13712 let serialized = {}; 13713 for (let [key, val] of entries) { 13714 if (val && val.__type === "RouteErrorResponse") { 13715 serialized[key] = new ErrorResponseImpl( 13716 val.status, 13717 val.statusText, 13718 val.data, 13719 val.internal === true 13720 ); 13721 } else if (val && val.__type === "Error") { 13722 if (val.__subType) { 13723 let ErrorConstructor = window[val.__subType]; 13724 if (typeof ErrorConstructor === "function") { 13725 try { 13726 let error = new ErrorConstructor(val.message); 13727 error.stack = val.stack; 13728 serialized[key] = error; 13729 } catch (e) { 13730 } 13731 } 13732 } 13733 if (serialized[key] == null) { 13734 let error = new Error(val.message); 13735 error.stack = val.stack; 13736 serialized[key] = error; 13737 } 13738 } else { 13739 serialized[key] = val; 13740 } 13741 } 13742 return serialized; 13743} 13744function getHydrationData({ 13745 state, 13746 routes, 13747 getRouteInfo, 13748 location: location2, 13749 basename, 13750 isSpaMode 13751}) { 13752 let hydrationData = { 13753 ...state, 13754 loaderData: { ...state.loaderData } 13755 }; 13756 let initialMatches = matchRoutes(routes, location2, basename); 13757 if (initialMatches) { 13758 for (let match of initialMatches) { 13759 let routeId = match.route.id; 13760 let routeInfo = getRouteInfo(routeId); 13761 if (shouldHydrateRouteLoader( 13762 routeId, 13763 routeInfo.clientLoader, 13764 routeInfo.hasLoader, 13765 isSpaMode 13766 ) && (routeInfo.hasHydrateFallback || !routeInfo.hasLoader)) { 13767 delete hydrationData.loaderData[routeId]; 13768 } else if (!routeInfo.hasLoader) { 13769 hydrationData.loaderData[routeId] = null; 13770 } 13771 } 13772 } 13773 return hydrationData; 13774} 13775
vendor: 10,898 bytes, lines 13776-14124
13776// node_modules/react-router/dist/development/dom-export.mjs 13777var React13 = __toESM(require_react(), 1); 13778var ReactDOM = __toESM(require_react_dom(), 1); 13779var React23 = __toESM(require_react(), 1); 13780var React33 = __toESM(require_react(), 1); 13781var ReactDOM2 = __toESM(require_react_dom(), 1); 13782function RouterProvider2(props) { 13783 return React13.createElement(RouterProvider, { flushSync: ReactDOM.flushSync, ...props }); 13784} 13785var ssrInfo = null; 13786var router = null; 13787function initSsrInfo() { 13788 if (!ssrInfo && window.__reactRouterContext && window.__reactRouterManifest && window.__reactRouterRouteModules) { 13789 if (window.__reactRouterManifest.sri === true) { 13790 const importMap = document.querySelector("script[rr-importmap]"); 13791 if (importMap?.textContent) { 13792 try { 13793 window.__reactRouterManifest.sri = JSON.parse( 13794 importMap.textContent 13795 ).integrity; 13796 } catch (err) { 13797 console.error("Failed to parse import map", err); 13798 } 13799 } 13800 } 13801 ssrInfo = { 13802 context: window.__reactRouterContext, 13803 manifest: window.__reactRouterManifest, 13804 routeModules: window.__reactRouterRouteModules, 13805 stateDecodingPromise: void 0, 13806 router: void 0, 13807 routerInitialized: false 13808 }; 13809 } 13810} 13811function createHydratedRouter({ 13812 getContext, 13813 unstable_instrumentations 13814}) { 13815 initSsrInfo(); 13816 if (!ssrInfo) { 13817 throw new Error( 13818 "You must be using the SSR features of React Router in order to skip passing a `router` prop to `<RouterProvider>`" 13819 ); 13820 } 13821 let localSsrInfo = ssrInfo; 13822 if (!ssrInfo.stateDecodingPromise) { 13823 let stream = ssrInfo.context.stream; 13824 invariant(stream, "No stream found for single fetch decoding"); 13825 ssrInfo.context.stream = void 0; 13826 ssrInfo.stateDecodingPromise = decodeViaTurboStream(stream, window).then((value) => { 13827 ssrInfo.context.state = value.value; 13828 localSsrInfo.stateDecodingPromise.value = true; 13829 }).catch((e) => { 13830 localSsrInfo.stateDecodingPromise.error = e; 13831 }); 13832 } 13833 if (ssrInfo.stateDecodingPromise.error) { 13834 throw ssrInfo.stateDecodingPromise.error; 13835 } 13836 if (!ssrInfo.stateDecodingPromise.value) { 13837 throw ssrInfo.stateDecodingPromise; 13838 } 13839 let routes = createClientRoutes( 13840 ssrInfo.manifest.routes, 13841 ssrInfo.routeModules, 13842 ssrInfo.context.state, 13843 ssrInfo.context.ssr, 13844 ssrInfo.context.isSpaMode 13845 ); 13846 let hydrationData = void 0; 13847 if (ssrInfo.context.isSpaMode) { 13848 let { loaderData } = ssrInfo.context.state; 13849 if (ssrInfo.manifest.routes.root?.hasLoader && loaderData && "root" in loaderData) { 13850 hydrationData = { 13851 loaderData: { 13852 root: loaderData.root 13853 } 13854 }; 13855 } 13856 } else { 13857 hydrationData = getHydrationData({ 13858 state: ssrInfo.context.state, 13859 routes, 13860 getRouteInfo: (routeId) => ({ 13861 clientLoader: ssrInfo.routeModules[routeId]?.clientLoader, 13862 hasLoader: ssrInfo.manifest.routes[routeId]?.hasLoader === true, 13863 hasHydrateFallback: ssrInfo.routeModules[routeId]?.HydrateFallback != null 13864 }), 13865 location: window.location, 13866 basename: window.__reactRouterContext?.basename, 13867 isSpaMode: ssrInfo.context.isSpaMode 13868 }); 13869 if (hydrationData && hydrationData.errors) { 13870 hydrationData.errors = deserializeErrors2(hydrationData.errors); 13871 } 13872 } 13873 if (window.history.state && window.history.state.masked) { 13874 window.history.replaceState( 13875 { ...window.history.state, masked: void 0 }, 13876 "" 13877 ); 13878 } 13879 let router2 = createRouter({ 13880 routes, 13881 history: createBrowserHistory(), 13882 basename: ssrInfo.context.basename, 13883 getContext, 13884 hydrationData, 13885 hydrationRouteProperties, 13886 unstable_instrumentations, 13887 mapRouteProperties, 13888 future: { 13889 middleware: ssrInfo.context.future.v8_middleware 13890 }, 13891 dataStrategy: getTurboStreamSingleFetchDataStrategy( 13892 () => router2, 13893 ssrInfo.manifest, 13894 ssrInfo.routeModules, 13895 ssrInfo.context.ssr, 13896 ssrInfo.context.basename, 13897 ssrInfo.context.future.unstable_trailingSlashAwareDataRequests 13898 ), 13899 patchRoutesOnNavigation: getPatchRoutesOnNavigationFunction( 13900 () => router2, 13901 ssrInfo.manifest, 13902 ssrInfo.routeModules, 13903 ssrInfo.context.ssr, 13904 ssrInfo.context.routeDiscovery, 13905 ssrInfo.context.isSpaMode, 13906 ssrInfo.context.basename 13907 ) 13908 }); 13909 ssrInfo.router = router2; 13910 if (router2.state.initialized) { 13911 ssrInfo.routerInitialized = true; 13912 router2.initialize(); 13913 } 13914 router2.createRoutesForHMR = /* spacer so ts-ignore does not affect the right hand of the assignment */ 13915 createClientRoutesWithHMRRevalidationOptOut; 13916 window.__reactRouterDataRouter = router2; 13917 return router2; 13918} 13919function HydratedRouter(props) { 13920 if (!router) { 13921 router = createHydratedRouter({ 13922 getContext: props.getContext, 13923 unstable_instrumentations: props.unstable_instrumentations 13924 }); 13925 } 13926 let [criticalCss, setCriticalCss] = React23.useState( 13927 false ? ssrInfo?.context.criticalCss : void 0 13928 ); 13929 React23.useEffect(() => { 13930 if (false) { 13931 setCriticalCss(void 0); 13932 } 13933 }, []); 13934 React23.useEffect(() => { 13935 if (false) { 13936 document.querySelectorAll(`[${CRITICAL_CSS_DATA_ATTRIBUTE}]`).forEach((element) => element.remove()); 13937 } 13938 }, [criticalCss]); 13939 let [location2, setLocation] = React23.useState(router.state.location); 13940 React23.useLayoutEffect(() => { 13941 if (ssrInfo && ssrInfo.router && !ssrInfo.routerInitialized) { 13942 ssrInfo.routerInitialized = true; 13943 ssrInfo.router.initialize(); 13944 } 13945 }, []); 13946 React23.useLayoutEffect(() => { 13947 if (ssrInfo && ssrInfo.router) { 13948 return ssrInfo.router.subscribe((newState) => { 13949 if (newState.location !== location2) { 13950 setLocation(newState.location); 13951 } 13952 }); 13953 } 13954 }, [location2]); 13955 invariant(ssrInfo, "ssrInfo unavailable for HydratedRouter"); 13956 useFogOFWarDiscovery( 13957 router, 13958 ssrInfo.manifest, 13959 ssrInfo.routeModules, 13960 ssrInfo.context.ssr, 13961 ssrInfo.context.routeDiscovery, 13962 ssrInfo.context.isSpaMode 13963 ); 13964 return ( 13965 // This fragment is important to ensure we match the <ServerRouter> JSX 13966 // structure so that useId values hydrate correctly 13967 React23.createElement(React23.Fragment, null, React23.createElement( 13968 FrameworkContext.Provider, 13969 { 13970 value: { 13971 manifest: ssrInfo.manifest, 13972 routeModules: ssrInfo.routeModules, 13973 future: ssrInfo.context.future, 13974 criticalCss, 13975 ssr: ssrInfo.context.ssr, 13976 isSpaMode: ssrInfo.context.isSpaMode, 13977 routeDiscovery: ssrInfo.context.routeDiscovery 13978 } 13979 }, 13980 React23.createElement(RemixErrorBoundary, { location: location2 }, React23.createElement( 13981 RouterProvider2, 13982 { 13983 router, 13984 unstable_useTransitions: props.unstable_useTransitions, 13985 onError: props.onError 13986 } 13987 )) 13988 ), React23.createElement(React23.Fragment, null)) 13989 ); 13990} 13991var renderedRoutesContext = createContext4(); 13992export { 13993 Await, 13994 BrowserRouter, 13995 Form, 13996 HashRouter, 13997 HydratedRouter, 13998 IDLE_BLOCKER, 13999 IDLE_FETCHER, 14000 IDLE_NAVIGATION, 14001 Link, 14002 Links, 14003 MemoryRouter, 14004 Meta, 14005 NavLink, 14006 Navigate, 14007 Action as NavigationType, 14008 Outlet, 14009 PrefetchPageLinks, 14010 Route, 14011 Router, 14012 RouterContextProvider, 14013 RouterProvider2 as RouterProvider, 14014 Routes, 14015 Scripts, 14016 ScrollRestoration, 14017 ServerRouter, 14018 StaticRouter, 14019 StaticRouterProvider, 14020 AwaitContextProvider as UNSAFE_AwaitContextProvider, 14021 DataRouterContext as UNSAFE_DataRouterContext, 14022 DataRouterStateContext as UNSAFE_DataRouterStateContext, 14023 ErrorResponseImpl as UNSAFE_ErrorResponseImpl, 14024 FetchersContext as UNSAFE_FetchersContext, 14025 FrameworkContext as UNSAFE_FrameworkContext, 14026 LocationContext as UNSAFE_LocationContext, 14027 NavigationContext as UNSAFE_NavigationContext, 14028 RSCDefaultRootErrorBoundary as UNSAFE_RSCDefaultRootErrorBoundary, 14029 RemixErrorBoundary as UNSAFE_RemixErrorBoundary, 14030 RouteContext as UNSAFE_RouteContext, 14031 ServerMode as UNSAFE_ServerMode, 14032 SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol, 14033 ViewTransitionContext as UNSAFE_ViewTransitionContext, 14034 WithComponentProps as UNSAFE_WithComponentProps, 14035 WithErrorBoundaryProps as UNSAFE_WithErrorBoundaryProps, 14036 WithHydrateFallbackProps as UNSAFE_WithHydrateFallbackProps, 14037 createBrowserHistory as UNSAFE_createBrowserHistory, 14038 createClientRoutes as UNSAFE_createClientRoutes, 14039 createClientRoutesWithHMRRevalidationOptOut as UNSAFE_createClientRoutesWithHMRRevalidationOptOut, 14040 createHashHistory as UNSAFE_createHashHistory, 14041 createMemoryHistory as UNSAFE_createMemoryHistory, 14042 createRouter as UNSAFE_createRouter, 14043 decodeViaTurboStream as UNSAFE_decodeViaTurboStream, 14044 deserializeErrors2 as UNSAFE_deserializeErrors, 14045 getHydrationData as UNSAFE_getHydrationData, 14046 getPatchRoutesOnNavigationFunction as UNSAFE_getPatchRoutesOnNavigationFunction, 14047 getTurboStreamSingleFetchDataStrategy as UNSAFE_getTurboStreamSingleFetchDataStrategy, 14048 hydrationRouteProperties as UNSAFE_hydrationRouteProperties, 14049 invariant as UNSAFE_invariant, 14050 mapRouteProperties as UNSAFE_mapRouteProperties, 14051 shouldHydrateRouteLoader as UNSAFE_shouldHydrateRouteLoader, 14052 useFogOFWarDiscovery as UNSAFE_useFogOFWarDiscovery, 14053 useScrollRestoration as UNSAFE_useScrollRestoration, 14054 withComponentProps as UNSAFE_withComponentProps, 14055 withErrorBoundaryProps as UNSAFE_withErrorBoundaryProps, 14056 withHydrateFallbackProps as UNSAFE_withHydrateFallbackProps, 14057 createBrowserRouter, 14058 createContext4 as createContext, 14059 createCookie, 14060 createCookieSessionStorage, 14061 createHashRouter, 14062 createMemoryRouter, 14063 createMemorySessionStorage, 14064 createPath, 14065 createRequestHandler, 14066 createRoutesFromChildren, 14067 createRoutesFromElements, 14068 createRoutesStub, 14069 createSearchParams, 14070 createSession, 14071 createSessionStorage, 14072 createStaticHandler2 as createStaticHandler, 14073 createStaticRouter, 14074 data, 14075 generatePath, 14076 href, 14077 isCookie, 14078 isRouteErrorResponse, 14079 isSession, 14080 matchPath, 14081 matchRoutes, 14082 parsePath, 14083 redirect, 14084 redirectDocument, 14085 renderMatches, 14086 replace, 14087 resolvePath, 14088 HistoryRouter as unstable_HistoryRouter, 14089 RSCStaticRouter as unstable_RSCStaticRouter, 14090 routeRSCServerRequest as unstable_routeRSCServerRequest, 14091 setDevServerHooks as unstable_setDevServerHooks, 14092 usePrompt as unstable_usePrompt, 14093 useRoute as unstable_useRoute, 14094 useActionData, 14095 useAsyncError, 14096 useAsyncValue, 14097 useBeforeUnload, 14098 useBlocker, 14099 useFetcher, 14100 useFetchers, 14101 useFormAction, 14102 useHref, 14103 useInRouterContext, 14104 useLinkClickHandler, 14105 useLoaderData, 14106 useLocation, 14107 useMatch, 14108 useMatches, 14109 useNavigate, 14110 useNavigation, 14111 useNavigationType, 14112 useOutlet, 14113 useOutletContext, 14114 useParams, 14115 useResolvedPath, 14116 useRevalidator, 14117 useRouteError, 14118 useRouteLoaderData, 14119 useRoutes, 14120 useSearchParams, 14121 useSubmit, 14122 useViewTransitionState 14123}; 14124//# sourceMappingURL=react-router-dom.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.