g(x,c))a[d]=x,a[n]=c,d=n;else break a}}return b}\nfunction g(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}if(\"object\"===typeof performance&&\"function\"===typeof performance.now){var l=performance;exports.unstable_now=function(){return l.now()}}else{var p=Date,q=p.now();exports.unstable_now=function(){return p.now()-q}}var r=[],t=[],u=1,v=null,y=3,z=!1,A=!1,B=!1,D=\"function\"===typeof setTimeout?setTimeout:null,E=\"function\"===typeof clearTimeout?clearTimeout:null,F=\"undefined\"!==typeof setImmediate?setImmediate:null;\n\"undefined\"!==typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function G(a){for(var b=h(t);null!==b;){if(null===b.callback)k(t);else if(b.startTime<=a)k(t),b.sortIndex=b.expirationTime,f(r,b);else break;b=h(t)}}function H(a){B=!1;G(a);if(!A)if(null!==h(r))A=!0,I(J);else{var b=h(t);null!==b&&K(H,b.startTime-a)}}\nfunction J(a,b){A=!1;B&&(B=!1,E(L),L=-1);z=!0;var c=y;try{G(b);for(v=h(r);null!==v&&(!(v.expirationTime>b)||a&&!M());){var d=v.callback;if(\"function\"===typeof d){v.callback=null;y=v.priorityLevel;var e=d(v.expirationTime<=b);b=exports.unstable_now();\"function\"===typeof e?v.callback=e:v===h(r)&&k(r);G(b)}else k(r);v=h(r)}if(null!==v)var w=!0;else{var m=h(t);null!==m&&K(H,m.startTime-b);w=!1}return w}finally{v=null,y=c,z=!1}}var N=!1,O=null,L=-1,P=5,Q=-1;\nfunction M(){return exports.unstable_now()-Qa||125d?(a.sortIndex=c,f(t,a),null===h(r)&&a===h(t)&&(B?(E(L),L=-1):B=!0,K(H,c-d))):(a.sortIndex=e,f(r,a),A||z||(A=!0,I(J)));return a};\nexports.unstable_shouldYield=M;exports.unstable_wrapCallback=function(a){var b=y;return function(){var c=y;y=b;try{return a.apply(this,arguments)}finally{y=c}}};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/scheduler.production.min.js');\n} else {\n module.exports = require('./cjs/scheduler.development.js');\n}\n","export interface StarFieldState {\n width: number\n height: number\n x: number\n y: number\n z: number\n stars: StarState[]\n}\n\nexport interface StarState {\n x: number\n y: number\n z: number\n stepX: number\n stepY: number\n}\n\nexport type ColorFunction = () => string\n\nexport function createStarsState(options: { width: number, height: number, count: number }): StarFieldState {\n let width = options.width\n let height = options.height\n\n let x = Math.round(width / 2)\n let y = Math.round(height / 2)\n let z = (width + height) / 2\n\n return {\n stars: createStars(x, y, z, width, height, options.count),\n width,\n height,\n x,\n y,\n z,\n }\n}\n\nexport function createStars(\n x: number,\n y: number,\n z: number,\n width: number,\n height: number,\n count: number,\n) {\n let starPool: StarState[] = []\n for (let i = 0; i < count; i++) {\n starPool.push({\n x: Math.random() * width * 2 - x * 2,\n y: Math.random() * height * 2 - y * 2,\n z: Math.round(Math.random() * z),\n stepX: 0,\n stepY: 0,\n })\n }\n return starPool\n}\n","import { MutableRefObject, RefObject, useEffect } from 'react'\n\nimport { ColorFunction, createStarsState, StarFieldState } from '../field/StarState'\nimport { drawStarField } from '../field/drawStarField'\n\nexport interface Options {\n count: number\n speed: number\n starRatio: number\n starSize: number\n width: number\n height: number\n starStyle: ColorFunction | string\n clear: boolean\n starShape: 'butt' | 'round' | 'square'\n bgStyle: string\n fps: number\n noBackground: boolean\n}\n\nexport function useStarField(\n canvasRef: RefObject,\n options: Options,\n stateReference?: MutableRefObject,\n) {\n const initialState = stateReference?.current || createStarsState({\n count: options.count,\n height: options.height,\n width: options.width,\n })\n\n if (options.count !== initialState.stars.length) {\n if (initialState.stars.length < options.count) {\n const { stars } = createStarsState({\n count: options.count - initialState.stars.length,\n height: options.height,\n width: options.width,\n })\n initialState.stars = [...initialState.stars, ...stars]\n } else {\n initialState.stars.splice(0, initialState.stars.length - options.count)\n }\n }\n\n if (options.width !== initialState.width || options.height !== initialState.height) {\n const { stars } = createStarsState({\n count: options.count,\n height: options.height,\n width: options.width,\n })\n initialState.stars = stars\n initialState.width = options.width\n initialState.height = options.height\n initialState.x = Math.round(options.width / 2)\n initialState.y = Math.round(options.height / 2)\n initialState.z = (options.width + options.height) / 2\n }\n\n useEffect(() => {\n if (!canvasRef.current) return\n const context = canvasRef.current.getContext('2d')\n if (!context) return\n\n const starLineWidthRatio = 1 / initialState.z\n const { speed, starRatio, starSize } = options\n\n if (typeof options.starStyle === 'string') {\n context.strokeStyle = options.starStyle\n }\n\n context.lineCap = options.starShape\n\n const fpsInterval = 1000 / options.fps\n let animationFrameId: number\n let then = Date.now()\n let now, elapsed\n\n animationFrameId = requestAnimationFrame(animateFrame)\n\n function animateFrame() {\n if (!context) return\n\n animationFrameId = requestAnimationFrame(animateFrame)\n\n now = Date.now()\n elapsed = now - then\n if (elapsed < fpsInterval) return\n then = now - (elapsed % fpsInterval)\n\n drawStarField({\n context,\n speed,\n starRatio,\n starSize,\n starLineWidthRatio,\n strokeStyle: options.starStyle,\n bgStyle: options.bgStyle,\n noBackground: options.noBackground,\n clear: options.clear,\n ...initialState,\n })\n }\n\n return () => cancelAnimationFrame(animationFrameId)\n }, [options])\n}\n","import { ColorFunction, StarState } from './StarState'\n\nexport type DrawState = {\n context: CanvasRenderingContext2D\n stars: StarState[]\n width: number\n height: number\n z: number\n x: number\n y: number\n starLineWidthRatio: number\n speed: number\n starRatio: number\n starSize: number\n strokeStyle: ColorFunction | string\n bgStyle: string\n clear: boolean\n noBackground: boolean\n}\n\nexport function drawStarField({\n context,\n stars,\n width,\n height,\n z,\n x,\n y,\n starLineWidthRatio,\n speed,\n starRatio,\n starSize,\n strokeStyle,\n bgStyle,\n clear,\n noBackground,\n}: DrawState) {\n if (clear) {\n context.clearRect(0, 0, width, height)\n\n if (!noBackground) {\n context.fillStyle = bgStyle\n context.fillRect(0, 0, width, height)\n }\n }\n\n let drawStarStep = false\n\n for (let i = 0; i < stars.length; i++) {\n if (typeof strokeStyle === 'function') {\n context.strokeStyle = strokeStyle()\n }\n\n let star = stars[i]\n let currentX = star.stepX\n let currentY = star.stepY\n\n drawStarStep = true\n star.z -= speed\n\n if (star.z > z) {\n star.z -= z\n drawStarStep = false\n }\n\n if (star.z < 0) {\n star.z += z\n drawStarStep = false\n }\n\n star.stepX = x + (star.x / star.z) * starRatio\n star.stepY = y + (star.y / star.z) * starRatio\n\n drawStarStep = drawStarStep &&\n currentX > 0 && currentX < width &&\n currentY > 0 && currentY < height\n\n if (drawStarStep) {\n context.beginPath()\n context.lineWidth = (1 - starLineWidthRatio * star.z) * starSize\n context.moveTo(currentX, currentY)\n context.lineTo(star.stepX, star.stepY)\n context.stroke()\n context.closePath()\n }\n }\n}\n","import React, { FC, useRef, CSSProperties } from 'react'\n\nimport { useStarField } from '../hooks/useStarField'\nimport { createStarsState, StarFieldState } from '../field/StarState'\n\nexport type StarFieldProps = {\n // Width is passed through to the html canvas element\n width?: number\n // Height is passed through to the html canvas element\n height?: number\n // To total number of stars created for the animation\n count?: number\n // The speed of travel through the Star Field\n speed?: number\n // The frames per second of the animation draw calls\n fps?: number\n // Clear the canvas on each draw call,\n // when false each draw call remains on the canvas and overlapped by the next\n clear?: boolean\n // The ratio used to determine the size of the entire Star Field\n starRatio?: number\n // The size of the stroke used for drawing each star\n starSize?: number\n // The canvas [strokeStyle](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle)\n // used for drawing each star\n // Also valid, a function that returns the strokeStyle from being invoked,\n // each draw call for special effects like random color\n starStyle?: ColorFunction | string\n // The canvas [lineCap](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap)\n // used for drawing each star\n starShape?: 'butt' | 'round' | 'square'\n // The canvas [fillStyle](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle)\n // used for drawing the background of the canvas\n bgStyle?: string\n // A flag to set no background of fillStyle of the canvas\n noBackground?: boolean\n className?: string\n style?: CSSProperties\n}\n\ntype ColorFunction = () => string\n\nexport const StarField: FC = ({\n width = 300,\n height = 300,\n starStyle = '#fff',\n bgStyle = '#000',\n count = 3000,\n speed = 3,\n starRatio = 356,\n starSize = 1.4,\n starShape = 'round',\n clear = true,\n noBackground = false,\n fps = 10,\n ...restProps\n}) => {\n const canvasRef = useRef(null)\n const stateRef = useRef(createStarsState({\n count,\n height,\n width,\n }))\n\n useStarField(canvasRef, {\n width,\n height,\n starStyle,\n bgStyle,\n count,\n fps,\n speed,\n starRatio,\n starShape,\n starSize,\n clear,\n noBackground,\n }, stateRef)\n\n return \n}\n","import { useEffect, useState } from 'react'\n\nexport interface WindowSize {\n innerHeight: number\n innerWidth: number\n outerHeight: number\n outerWidth: number\n}\n\nexport function useWindowSize(): WindowSize {\n let [windowSize, setWindowSize] = useState(getWindowSize())\n\n function handleResize() {\n setWindowSize(getWindowSize())\n }\n\n useEffect(() => {\n window.addEventListener('resize', handleResize)\n\n return () => {\n window.removeEventListener('resize', handleResize)\n }\n }, [])\n\n return windowSize\n}\n\nfunction getWindowSize(): WindowSize {\n return {\n innerHeight: window.innerHeight,\n innerWidth: window.innerWidth,\n outerHeight: window.outerHeight,\n outerWidth: window.outerWidth,\n }\n}\n","import React, { CSSProperties, FC } from 'react'\n\nimport { useWindowSize } from '../hooks/useWindowSize'\nimport { StarField, StarFieldProps } from './StarField'\n\nconst fixedPositionStyle: CSSProperties = {\n position: 'fixed',\n zIndex: -1,\n}\n\nexport const WindowSizeStarField: FC = ({ style, ...restProps }) => {\n const { innerWidth, innerHeight } = useWindowSize()\n\n return \n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","export default function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}","import arrayWithHoles from \"./arrayWithHoles.js\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableRest from \"./nonIterableRest.js\";\nexport default function _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}","export default function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}","export default function _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}","export default function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","export default function _extends() {\n _extends = Object.assign ? Object.assign.bind() : function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n return _extends.apply(this, arguments);\n}","import * as React from \"react\";\nimport type { History, Location } from \"history\";\nimport { Action as NavigationType } from \"history\";\n\nimport type { RouteMatch } from \"./router\";\n\n/**\n * A Navigator is a \"location changer\"; it's how you get to different locations.\n *\n * Every history instance conforms to the Navigator interface, but the\n * distinction is useful primarily when it comes to the low-level API\n * where both the location and a navigator must be provided separately in order\n * to avoid \"tearing\" that may occur in a suspense-enabled app if the action\n * and/or location were to be read directly from the history instance.\n */\nexport type Navigator = Pick;\n\ninterface NavigationContextObject {\n basename: string;\n navigator: Navigator;\n static: boolean;\n}\n\nexport const NavigationContext = React.createContext(\n null!\n);\n\nif (__DEV__) {\n NavigationContext.displayName = \"Navigation\";\n}\n\ninterface LocationContextObject {\n location: Location;\n navigationType: NavigationType;\n}\n\nexport const LocationContext = React.createContext(\n null!\n);\n\nif (__DEV__) {\n LocationContext.displayName = \"Location\";\n}\n\ninterface RouteContextObject {\n outlet: React.ReactElement | null;\n matches: RouteMatch[];\n}\n\nexport const RouteContext = React.createContext({\n outlet: null,\n matches: [],\n});\n\nif (__DEV__) {\n RouteContext.displayName = \"Route\";\n}\n","import type { Location, Path, To } from \"history\";\nimport { parsePath } from \"history\";\n\nexport function invariant(cond: any, message: string): asserts cond {\n if (!cond) throw new Error(message);\n}\n\nexport function warning(cond: any, message: string): void {\n if (!cond) {\n // eslint-disable-next-line no-console\n if (typeof console !== \"undefined\") console.warn(message);\n\n try {\n // Welcome to debugging React Router!\n //\n // This error is thrown as a convenience so you can more easily\n // find the source for a warning that appears in the console by\n // enabling \"pause on exceptions\" in your JavaScript debugger.\n throw new Error(message);\n // eslint-disable-next-line no-empty\n } catch (e) {}\n }\n}\n\nconst alreadyWarned: Record = {};\nexport function warningOnce(key: string, cond: boolean, message: string) {\n if (!cond && !alreadyWarned[key]) {\n alreadyWarned[key] = true;\n warning(false, message);\n }\n}\n\ntype ParamParseFailed = { failed: true };\n\ntype ParamParseSegment =\n // Check here if there exists a forward slash in the string.\n Segment extends `${infer LeftSegment}/${infer RightSegment}`\n ? // If there is a forward slash, then attempt to parse each side of the\n // forward slash.\n ParamParseSegment extends infer LeftResult\n ? ParamParseSegment extends infer RightResult\n ? LeftResult extends string\n ? // If the left side is successfully parsed as a param, then check if\n // the right side can be successfully parsed as well. If both sides\n // can be parsed, then the result is a union of the two sides\n // (read: \"foo\" | \"bar\").\n RightResult extends string\n ? LeftResult | RightResult\n : LeftResult\n : // If the left side is not successfully parsed as a param, then check\n // if only the right side can be successfully parse as a param. If it\n // can, then the result is just right, else it's a failure.\n RightResult extends string\n ? RightResult\n : ParamParseFailed\n : ParamParseFailed\n : // If the left side didn't parse into a param, then just check the right\n // side.\n ParamParseSegment extends infer RightResult\n ? RightResult extends string\n ? RightResult\n : ParamParseFailed\n : ParamParseFailed\n : // If there's no forward slash, then check if this segment starts with a\n // colon. If it does, then this is a dynamic segment, so the result is\n // just the remainder of the string. Otherwise, it's a failure.\n Segment extends `:${infer Remaining}`\n ? Remaining\n : ParamParseFailed;\n\n// Attempt to parse the given string segment. If it fails, then just return the\n// plain string type as a default fallback. Otherwise return the union of the\n// parsed string literals that were referenced as dynamic segments in the route.\nexport type ParamParseKey =\n ParamParseSegment extends string\n ? ParamParseSegment\n : string;\n\n/**\n * The parameters that were parsed from the URL path.\n */\nexport type Params = {\n readonly [key in Key]: string | undefined;\n};\n\n/**\n * A route object represents a logical route, with (optionally) its child\n * routes organized in a tree-like structure.\n */\nexport interface RouteObject {\n caseSensitive?: boolean;\n children?: RouteObject[];\n element?: React.ReactNode;\n index?: boolean;\n path?: string;\n}\n\n/**\n * Returns a path with params interpolated.\n *\n * @see https://reactrouter.com/docs/en/v6/api#generatepath\n */\nexport function generatePath(path: string, params: Params = {}): string {\n return path\n .replace(/:(\\w+)/g, (_, key) => {\n invariant(params[key] != null, `Missing \":${key}\" param`);\n return params[key]!;\n })\n .replace(/\\/*\\*$/, (_) =>\n params[\"*\"] == null ? \"\" : params[\"*\"].replace(/^\\/*/, \"/\")\n );\n}\n\n/**\n * A RouteMatch contains info about how a route matched a URL.\n */\nexport interface RouteMatch {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The route object that was used to match.\n */\n route: RouteObject;\n}\n\n/**\n * Matches the given routes to a location and returns the match data.\n *\n * @see https://reactrouter.com/docs/en/v6/api#matchroutes\n */\nexport function matchRoutes(\n routes: RouteObject[],\n locationArg: Partial | string,\n basename = \"/\"\n): RouteMatch[] | null {\n let location =\n typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n\n let pathname = stripBasename(location.pathname || \"/\", basename);\n\n if (pathname == null) {\n return null;\n }\n\n let branches = flattenRoutes(routes);\n rankRouteBranches(branches);\n\n let matches = null;\n for (let i = 0; matches == null && i < branches.length; ++i) {\n matches = matchRouteBranch(branches[i], pathname);\n }\n\n return matches;\n}\n\ninterface RouteMeta {\n relativePath: string;\n caseSensitive: boolean;\n childrenIndex: number;\n route: RouteObject;\n}\n\ninterface RouteBranch {\n path: string;\n score: number;\n routesMeta: RouteMeta[];\n}\n\nfunction flattenRoutes(\n routes: RouteObject[],\n branches: RouteBranch[] = [],\n parentsMeta: RouteMeta[] = [],\n parentPath = \"\"\n): RouteBranch[] {\n routes.forEach((route, index) => {\n let meta: RouteMeta = {\n relativePath: route.path || \"\",\n caseSensitive: route.caseSensitive === true,\n childrenIndex: index,\n route,\n };\n\n if (meta.relativePath.startsWith(\"/\")) {\n invariant(\n meta.relativePath.startsWith(parentPath),\n `Absolute route path \"${meta.relativePath}\" nested under path ` +\n `\"${parentPath}\" is not valid. An absolute child route path ` +\n `must start with the combined path of all its parent routes.`\n );\n\n meta.relativePath = meta.relativePath.slice(parentPath.length);\n }\n\n let path = joinPaths([parentPath, meta.relativePath]);\n let routesMeta = parentsMeta.concat(meta);\n\n // Add the children before adding this route to the array so we traverse the\n // route tree depth-first and child routes appear before their parents in\n // the \"flattened\" version.\n if (route.children && route.children.length > 0) {\n invariant(\n route.index !== true,\n `Index routes must not have child routes. Please remove ` +\n `all child routes from route path \"${path}\".`\n );\n\n flattenRoutes(route.children, branches, routesMeta, path);\n }\n\n // Routes without a path shouldn't ever match by themselves unless they are\n // index routes, so don't add them to the list of possible branches.\n if (route.path == null && !route.index) {\n return;\n }\n\n branches.push({ path, score: computeScore(path, route.index), routesMeta });\n });\n\n return branches;\n}\n\nfunction rankRouteBranches(branches: RouteBranch[]): void {\n branches.sort((a, b) =>\n a.score !== b.score\n ? b.score - a.score // Higher score first\n : compareIndexes(\n a.routesMeta.map((meta) => meta.childrenIndex),\n b.routesMeta.map((meta) => meta.childrenIndex)\n )\n );\n}\n\nconst paramRe = /^:\\w+$/;\nconst dynamicSegmentValue = 3;\nconst indexRouteValue = 2;\nconst emptySegmentValue = 1;\nconst staticSegmentValue = 10;\nconst splatPenalty = -2;\nconst isSplat = (s: string) => s === \"*\";\n\nfunction computeScore(path: string, index: boolean | undefined): number {\n let segments = path.split(\"/\");\n let initialScore = segments.length;\n if (segments.some(isSplat)) {\n initialScore += splatPenalty;\n }\n\n if (index) {\n initialScore += indexRouteValue;\n }\n\n return segments\n .filter((s) => !isSplat(s))\n .reduce(\n (score, segment) =>\n score +\n (paramRe.test(segment)\n ? dynamicSegmentValue\n : segment === \"\"\n ? emptySegmentValue\n : staticSegmentValue),\n initialScore\n );\n}\n\nfunction compareIndexes(a: number[], b: number[]): number {\n let siblings =\n a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);\n\n return siblings\n ? // If two routes are siblings, we should try to match the earlier sibling\n // first. This allows people to have fine-grained control over the matching\n // behavior by simply putting routes with identical paths in the order they\n // want them tried.\n a[a.length - 1] - b[b.length - 1]\n : // Otherwise, it doesn't really make sense to rank non-siblings by index,\n // so they sort equally.\n 0;\n}\n\nfunction matchRouteBranch(\n branch: RouteBranch,\n pathname: string\n): RouteMatch[] | null {\n let { routesMeta } = branch;\n\n let matchedParams = {};\n let matchedPathname = \"/\";\n let matches: RouteMatch[] = [];\n for (let i = 0; i < routesMeta.length; ++i) {\n let meta = routesMeta[i];\n let end = i === routesMeta.length - 1;\n let remainingPathname =\n matchedPathname === \"/\"\n ? pathname\n : pathname.slice(matchedPathname.length) || \"/\";\n let match = matchPath(\n { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },\n remainingPathname\n );\n\n if (!match) return null;\n\n Object.assign(matchedParams, match.params);\n\n let route = meta.route;\n\n matches.push({\n params: matchedParams,\n pathname: joinPaths([matchedPathname, match.pathname]),\n pathnameBase: normalizePathname(\n joinPaths([matchedPathname, match.pathnameBase])\n ),\n route,\n });\n\n if (match.pathnameBase !== \"/\") {\n matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);\n }\n }\n\n return matches;\n}\n\n/**\n * A PathPattern is used to match on some portion of a URL pathname.\n */\nexport interface PathPattern {\n /**\n * A string to match against a URL pathname. May contain `:id`-style segments\n * to indicate placeholders for dynamic parameters. May also end with `/*` to\n * indicate matching the rest of the URL pathname.\n */\n path: Path;\n /**\n * Should be `true` if the static portions of the `path` should be matched in\n * the same case.\n */\n caseSensitive?: boolean;\n /**\n * Should be `true` if this pattern should match the entire URL pathname.\n */\n end?: boolean;\n}\n\n/**\n * A PathMatch contains info about how a PathPattern matched on a URL pathname.\n */\nexport interface PathMatch {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The pattern that was used to match.\n */\n pattern: PathPattern;\n}\n\ntype Mutable