| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928 |
- import{s as e,u as t,av as n,n as r,p as o,d as a,X as s,m as c,af as l,B as i,h as u,i as f}from"./@vue-37836d09.js";
- /*!
- * vue-router v4.5.0
- * (c) 2024 Eduardo San Martin Morote
- * @license MIT
- */const p="undefined"!=typeof document;
- /**
- * Allows differentiating lazy components from functional components and vue-class-component
- * @internal
- *
- * @param component
- */function h(e){return"object"==typeof e||"displayName"in e||"props"in e||"__vccOpts"in e}const d=Object.assign;function m(e,t){const n={};for(const r in t){const o=t[r];n[r]=v(o)?o.map(e):e(o)}return n}const g=()=>{},v=Array.isArray,y=/#/g,b=/&/g,w=/\//g,E=/=/g,R=/\?/g,k=/\+/g,O=/%5B/g,x=/%5D/g,P=/%5E/g,C=/%60/g,j=/%7B/g,$=/%7C/g,S=/%7D/g,A=/%20/g;
- /**
- * Typesafe alternative to Array.isArray
- * https://github.com/microsoft/TypeScript/pull/48228
- */ // }
- /**
- * Encode characters that need to be encoded on the path, search and hash
- * sections of the URL.
- *
- * @internal
- * @param text - string to encode
- * @returns encoded string
- */
- function q(e){return encodeURI(""+e).replace($,"|").replace(O,"[").replace(x,"]")}
- /**
- * Encode characters that need to be encoded on the hash section of the URL.
- *
- * @param text - string to encode
- * @returns encoded string
- */
- /**
- * Encode characters that need to be encoded query values on the query
- * section of the URL.
- *
- * @param text - string to encode
- * @returns encoded string
- */
- function L(e){return q(e).replace(k,"%2B").replace(A,"+").replace(y,"%23").replace(b,"%26").replace(C,"`").replace(j,"{").replace(S,"}").replace(P,"^")}
- /**
- * Like `encodeQueryValue` but also encodes the `=` character.
- *
- * @param text - string to encode
- */
- /**
- * Encode characters that need to be encoded on the path section of the URL as a
- * param. This function encodes everything {@link encodePath} does plus the
- * slash (`/`) character. If `text` is `null` or `undefined`, returns an empty
- * string instead.
- *
- * @param text - string to encode
- * @returns encoded string
- */
- function M(e){return null==e?"":
- /**
- * Encode characters that need to be encoded on the path section of the URL.
- *
- * @param text - string to encode
- * @returns encoded string
- */
- function(e){return q(e).replace(y,"%23").replace(R,"%3F")}(e).replace(w,"%2F")}
- /**
- * Decode text using `decodeURIComponent`. Returns the original text if it
- * fails.
- *
- * @param text - string to decode
- * @returns decoded string
- */function B(e){try{return decodeURIComponent(""+e)}catch(t){}return""+e}const G=/\/$/;
- /**
- * Transforms a URI into a normalized history location
- *
- * @param parseQuery
- * @param location - URI to normalize
- * @param currentLocation - current absolute location. Allows resolving relative
- * paths. Must start with `/`. Defaults to `/`
- * @returns a normalized history location
- */
- function _(e,t,n="/"){let r,o={},a="",s="";
- // Could use URL and URLSearchParams but IE 11 doesn't support it
- // TODO: move to new URL()
- const c=t.indexOf("#");let l=t.indexOf("?");
- // the hash appears before the search, so it's not part of the search string
- // empty path means a relative query or hash `?foo=f`, `#thing`
- return c<l&&c>=0&&(l=-1),l>-1&&(r=t.slice(0,l),a=t.slice(l+1,c>-1?c:t.length),o=e(a)),c>-1&&(r=r||t.slice(0,c),
- // keep the # character
- s=t.slice(c,t.length)),
- // no search and no query
- r=
- /**
- * Resolves a relative path that starts with `.`.
- *
- * @param to - path location we are resolving
- * @param from - currentLocation.path, should start with `/`
- */
- function(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/"),o=r[r.length-1];
- // make . and ./ the same (../ === .., ../../ === ../..)
- // this is the same behavior as new URL()
- ".."!==o&&"."!==o||r.push("");let a,s,c=n.length-1;for(a=0;a<r.length;a++)
- // we stay on the same position
- if(s=r[a],"."!==s){
- // go up in the from array
- if(".."!==s)break;
- // we can't go below zero, but we still need to increment toPosition
- c>1&&c--;
- // continue
- }return n.slice(0,c).join("/")+"/"+r.slice(a).join("/")}
- /**
- * Initial route location where the router is. Can be used in navigation guards
- * to differentiate the initial navigation.
- *
- * @example
- * ```js
- * import { START_LOCATION } from 'vue-router'
- *
- * router.beforeEach((to, from) => {
- * if (from === START_LOCATION) {
- * // initial navigation
- * }
- * })
- * ```
- */(null!=r?r:t,n),{fullPath:r+(a&&"?")+a+s,path:r,query:o,hash:B(s)}}
- /**
- * Stringifies a URL object
- *
- * @param stringifyQuery
- * @param location
- */
- /**
- * Strips off the base from the beginning of a location.pathname in a non-case-sensitive way.
- *
- * @param pathname - location.pathname
- * @param base - base to strip off
- */
- function I(e,t){
- // no base or base is not found at the beginning
- return t&&e.toLowerCase().startsWith(t.toLowerCase())?e.slice(t.length)||"/":e}
- /**
- * Checks if two RouteLocation are equal. This means that both locations are
- * pointing towards the same {@link RouteRecord} and that all `params`, `query`
- * parameters and `hash` are the same
- *
- * @param stringifyQuery - A function that takes a query object of type LocationQueryRaw and returns a string representation of it.
- * @param a - first {@link RouteLocation}
- * @param b - second {@link RouteLocation}
- */
- /**
- * Check if two `RouteRecords` are equal. Takes into account aliases: they are
- * considered equal to the `RouteRecord` they are aliasing.
- *
- * @param a - first {@link RouteRecord}
- * @param b - second {@link RouteRecord}
- */
- function T(e,t){
- // since the original record has an undefined value for aliasOf
- // but all aliases point to the original record, this will always compare
- // the original record
- return(e.aliasOf||e)===(t.aliasOf||t)}function W(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!D(e[n],t[n]))return!1;return!0}function D(e,t){return v(e)?U(e,t):v(t)?U(t,e):e===t}
- /**
- * Check if two arrays are the same or if an array with one single entry is the
- * same as another primitive value. Used to check query and parameters
- *
- * @param a - array of values
- * @param b - array of values or a single value
- */function U(e,t){return v(t)?e.length===t.length&&e.every(((e,n)=>e===t[n])):1===e.length&&e[0]===t}const V={path:"/",
- // TODO: could we use a symbol in the future?
- name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};var F,z;
- // Generic utils
- /**
- * Normalizes a base by removing any trailing slash and reading the base tag if
- * present.
- *
- * @param base - base to normalize
- */
- function K(e){if(!e)if(p){
- // respect <base> tag
- const t=document.querySelector("base");
- // strip full URL origin
- e=(e=t&&t.getAttribute("href")||"/").replace(/^\w+:\/\/[^\/]+/,"")}else e="/";
- // ensure leading slash when it was removed by the regex above avoid leading
- // slash with hash because the file could be read from the disk like file://
- // and the leading slash would cause problems
- // remove the trailing slash so all other method can just do `base + fullPath`
- // to build an href
- return"/"!==e[0]&&"#"!==e[0]&&(e="/"+e),e.replace(G,"")}
- // remove any character before the hash
- !function(e){e.pop="pop",e.push="push"}(F||(F={})),function(e){e.back="back",e.forward="forward",e.unknown=""}(z||(z={}));const H=/^[^#]+#/;function X(e,t){return e.replace(H,"#")+t}const Q=()=>({left:window.scrollX,top:window.scrollY});function Y(e){let t;if("el"in e){const n=e.el,r="string"==typeof n&&n.startsWith("#"),o="string"==typeof n?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!o)return;t=function(e,t){const n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}(o,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(null!=t.left?t.left:window.scrollX,null!=t.top?t.top:window.scrollY)}function N(e,t){return(history.state?history.state.position-t:-1)+e}const Z=new Map;
- // TODO: RFC about how to save scroll position
- /**
- * ScrollBehavior instance used by the router to compute and restore the scroll
- * position when navigating.
- */
- // export interface ScrollHandler<ScrollPositionEntry extends HistoryStateValue, ScrollPosition extends ScrollPositionEntry> {
- // // returns a scroll position that can be saved in history
- // compute(): ScrollPositionEntry
- // // can take an extended ScrollPositionEntry
- // scroll(position: ScrollPosition): void
- // }
- // export const scrollHandler: ScrollHandler<ScrollPosition> = {
- // compute: computeScroll,
- // scroll: scrollToPosition,
- // }
- let J=()=>location.protocol+"//"+location.host
- /**
- * Creates a normalized history location from a window.location object
- * @param base - The base path
- * @param location - The window.location object
- */;function ee(e,t){const{pathname:n,search:r,hash:o}=t,a=e.indexOf("#");
- // allows hash bases like #, /#, #/, #!, #!/, /#!/, or even /folder#end
- if(a>-1){let t=o.includes(e.slice(a))?e.slice(a).length:1,n=o.slice(t);
- // prepend the starting slash to hash so the url starts with /#
- return"/"!==n[0]&&(n="/"+n),I(n,"")}return I(n,e)+r+o}
- /**
- * Creates a state object
- */
- function te(e,t,n,r=!1,o=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:o?Q():null}}
- /**
- * Creates an HTML5 history. Most common history for single page applications.
- *
- * @param base -
- */
- function ne(e){const t=function(e){const{history:t,location:n}=window,r={value:ee(e,n)},o={value:t.state};
- // private variables
- function a(r,a,s){
- /**
- * if a base tag is provided, and we are on a normal domain, we have to
- * respect the provided `base` attribute because pushState() will use it and
- * potentially erase anything before the `#` like at
- * https://github.com/vuejs/router/issues/685 where a base of
- * `/folder/#` but a base of `/` would erase the `/folder/` section. If
- * there is no host, the `<base>` tag makes no sense and if there isn't a
- * base tag we can just use everything after the `#`.
- */
- const c=e.indexOf("#"),l=c>-1?(n.host&&document.querySelector("base")?e:e.slice(c))+r:J()+e+r;try{
- // BROWSER QUIRK
- // NOTE: Safari throws a SecurityError when calling this function 100 times in 30 seconds
- t[s?"replaceState":"pushState"](a,"",l),o.value=a}catch(i){
- // Force the navigation, this also resets the call count
- n[s?"replace":"assign"](l)}}
- // build current history entry as this is a fresh navigation
- return o.value||a(r.value,{back:null,current:r.value,forward:null,
- // the length is off by one, we need to decrease it
- position:t.length-1,replaced:!0,
- // don't add a scroll as the user may have an anchor, and we want
- // scrollBehavior to be triggered without a saved position
- scroll:null},!0),{location:r,state:o,push:function(e,n){
- // Add to current entry the information of where we are going
- // as well as saving the current position
- const s=d({},
- // use current history state to gracefully handle a wrong call to
- // history.replaceState
- // https://github.com/vuejs/router/issues/366
- o.value,t.state,{forward:e,scroll:Q()});a(s.current,s,!0),a(e,d({},te(r.value,e,null),{position:s.position+1},n),!1),r.value=e},replace:function(e,n){a(e,d({},t.state,te(o.value.back,
- // keep back and forward entries but override current position
- e,o.value.forward,!0),n,{position:o.value.position}),!0),r.value=e}}}(e=K(e)),n=function(e,t,n,r){let o=[],a=[],s=null;const c=({state:a})=>{const c=ee(e,location),l=n.value,i=t.value;let u=0;if(a){
- // ignore the popstate and reset the pauseState
- if(n.value=c,t.value=a,s&&s===l)return void(s=null);u=i?a.position-i.position:0}else r(c);
- // Here we could also revert the navigation by calling history.go(-delta)
- // this listener will have to be adapted to not trigger again and to wait for the url
- // to be updated before triggering the listeners. Some kind of validation function would also
- // need to be passed to the listeners so the navigation can be accepted
- // call all listeners
- o.forEach((e=>{e(n.value,l,{delta:u,type:F.pop,direction:u?u>0?z.forward:z.back:z.unknown})}))};function l(){const{history:e}=window;e.state&&e.replaceState(d({},e.state,{scroll:Q()}),"")}
- // set up the listeners and prepare teardown callbacks
- return window.addEventListener("popstate",c),
- // TODO: could we use 'pagehide' or 'visibilitychange' instead?
- // https://developer.chrome.com/blog/page-lifecycle-api/
- window.addEventListener("beforeunload",l,{passive:!0}),{pauseListeners:function(){s=n.value},listen:function(e){
- // set up the listener and prepare teardown callbacks
- o.push(e);const t=()=>{const t=o.indexOf(e);t>-1&&o.splice(t,1)};return a.push(t),t},destroy:function(){for(const e of a)e();a=[],window.removeEventListener("popstate",c),window.removeEventListener("beforeunload",l)}}}(e,t.state,t.location,t.replace);const r=d({
- // it's overridden right after
- location:"",base:e,go:function(e,t=!0){t||n.pauseListeners(),history.go(e)},createHref:X.bind(null,e)},t,n);return Object.defineProperty(r,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(r,"state",{enumerable:!0,get:()=>t.state.value}),r}function re(e){return"string"==typeof e||"symbol"==typeof e}const oe=Symbol("");
- /**
- * Enumeration with all possible types for navigation failures. Can be passed to
- * {@link isNavigationFailure} to check for specific failures.
- */var ae;
- /**
- * Creates a typed NavigationFailure object.
- * @internal
- * @param type - NavigationFailureType
- * @param params - { from, to }
- */
- function se(e,t){return d(new Error,{type:e,[oe]:!0},t)}function ce(e,t){return e instanceof Error&&oe in e&&(null==t||!!(e.type&t))}
- // default pattern for a param: non-greedy everything but /
- !function(e){
- /**
- * An aborted navigation is a navigation that failed because a navigation
- * guard returned `false` or called `next(false)`
- */
- e[e.aborted=4]="aborted",
- /**
- * A cancelled navigation is a navigation that failed because a more recent
- * navigation finished started (not necessarily finished).
- */
- e[e.cancelled=8]="cancelled",
- /**
- * A duplicated navigation is a navigation that failed because it was
- * initiated while already being at the exact same location.
- */
- e[e.duplicated=16]="duplicated"}(ae||(ae={}));const le="[^/]+?",ie={sensitive:!1,strict:!1,start:!0,end:!0},ue=/[.+*?^${}()[\]/\\]/g;
- /**
- * Compares an array of numbers as used in PathParser.score and returns a
- * number. This function can be used to `sort` an array
- *
- * @param a - first array of numbers
- * @param b - second array of numbers
- * @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b
- * should be sorted first
- */
- function fe(e,t){let n=0;for(;n<e.length&&n<t.length;){const r=t[n]-e[n];
- // only keep going if diff === 0
- if(r)return r;n++}
- // if the last subsegment was Static, the shorter segments should be sorted first
- // otherwise sort the longest segment first
- return e.length<t.length?1===e.length&&80/* PathScore.Segment */===e[0]?-1:1:e.length>t.length?1===t.length&&80/* PathScore.Segment */===t[0]?1:-1:0}
- /**
- * Compare function that can be used with `sort` to sort an array of PathParser
- *
- * @param a - first PathParser
- * @param b - second PathParser
- * @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b
- */function pe(e,t){let n=0;const r=e.score,o=t.score;for(;n<r.length&&n<o.length;){const e=fe(r[n],o[n]);
- // do not return if both are equal
- if(e)return e;n++}if(1===Math.abs(o.length-r.length)){if(he(r))return 1;if(he(o))return-1}
- // if a and b share the same score entries but b has more, sort b first
- return o.length-r.length;
- // this is the ternary version
- // return aScore.length < bScore.length
- // ? 1
- // : aScore.length > bScore.length
- // ? -1
- // : 0
- }
- /**
- * This allows detecting splats at the end of a path: /home/:id(.*)*
- *
- * @param score - score to check
- * @returns true if the last entry is negative
- */function he(e){const t=e[e.length-1];return e.length>0&&t[t.length-1]<0}const de={type:0/* TokenType.Static */,value:""},me=/[a-zA-Z0-9_]/;function ge(e,t,n){const r=
- /**
- * Creates a path parser from an array of Segments (a segment is an array of Tokens)
- *
- * @param segments - array of segments returned by tokenizePath
- * @param extraOptions - optional options for the regexp
- * @returns a PathParser
- */
- function(e,t){const n=d({},ie,t),r=[];
- // the amount of scores is the same as the length of segments except for the root segment "/"
- // the regexp as a string
- let o=n.start?"^":"";
- // extracted keys
- const a=[];for(const l of e){
- // the root segment needs special treatment
- const e=l.length?[]:[90/* PathScore.Root */];
- // allow trailing slash
- n.strict&&!l.length&&(o+="/");for(let t=0;t<l.length;t++){const r=l[t];
- // resets the score if we are inside a sub-segment /:a-other-:b
- let s=40/* PathScore.Segment */+(n.sensitive?.25/* PathScore.BonusCaseSensitive */:0);if(0/* TokenType.Static */===r.type)
- // prepend the slash if we are starting a new segment
- t||(o+="/"),o+=r.value.replace(ue,"\\$&"),s+=40/* PathScore.Static */;else if(1/* TokenType.Param */===r.type){const{value:e,repeatable:n,optional:i,regexp:u}=r;a.push({name:e,repeatable:n,optional:i});const f=u||le;
- // the user provided a custom regexp /:id(\\d+)
- if(f!==le){s+=10/* PathScore.BonusCustomRegExp */;
- // make sure the regexp is valid before using it
- try{new RegExp(`(${f})`)}catch(c){throw new Error(`Invalid custom RegExp for param "${e}" (${f}): `+c.message)}}
- // when we repeat we must take care of the repeating leading slash
- let p=n?`((?:${f})(?:/(?:${f}))*)`:`(${f})`;
- // prepend the slash if we are starting a new segment
- t||(p=
- // avoid an optional / if there are more segments e.g. /:p?-static
- // or /:p?-:p2
- i&&l.length<2?`(?:/${p})`:"/"+p),i&&(p+="?"),o+=p,s+=20/* PathScore.Dynamic */,i&&(s+=-8/* PathScore.BonusOptional */),n&&(s+=-20/* PathScore.BonusRepeatable */),".*"===f&&(s+=-50/* PathScore.BonusWildcard */)}e.push(s)}
- // an empty array like /home/ -> [[{home}], []]
- // if (!segment.length) pattern += '/'
- r.push(e)}
- // only apply the strict bonus to the last score
- if(n.strict&&n.end){const e=r.length-1;r[e][r[e].length-1]+=.7000000000000001/* PathScore.BonusStrict */}
- // TODO: dev only warn double trailing slash
- n.strict||(o+="/?"),n.end?o+="$":n.strict&&!o.endsWith("/")&&(o+="(?:/|$)");const s=new RegExp(o,n.sensitive?"":"i");return{re:s,score:r,keys:a,parse:function(e){const t=e.match(s),n={};if(!t)return null;for(let r=1;r<t.length;r++){const e=t[r]||"",o=a[r-1];n[o.name]=e&&o.repeatable?e.split("/"):e}return n},stringify:function(t){let n="",r=!1;
- // for optional parameters to allow to be empty
- for(const o of e){r&&n.endsWith("/")||(n+="/"),r=!1;for(const e of o)if(0/* TokenType.Static */===e.type)n+=e.value;else if(1/* TokenType.Param */===e.type){const{value:a,repeatable:s,optional:c}=e,l=a in t?t[a]:"";if(v(l)&&!s)throw new Error(`Provided param "${a}" is an array but it is not repeatable (* or + modifiers)`);const i=v(l)?l.join("/"):l;if(!i){if(!c)throw new Error(`Missing required param "${a}"`);
- // if we have more than one optional param like /:a?-static we don't need to care about the optional param
- o.length<2&&(
- // remove the last slash as we could be at the end
- n.endsWith("/")?n=n.slice(0,-1):r=!0)}n+=i}}
- // avoid empty path when we have multiple optional params
- return n||"/"}}}(
- // After some profiling, the cache seems to be unnecessary because tokenizePath
- // (the slowest part of adding a route) is very fast
- // const tokenCache = new Map<string, Token[][]>()
- function(e){if(!e)return[[]];if("/"===e)return[[de]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);
- // if (tokenCache.has(path)) return tokenCache.get(path)!
- function t(e){throw new Error(`ERR (${n})/"${i}": ${e}`)}let n=0/* TokenizerState.Static */,r=n;const o=[];
- // the segment will always be valid because we get into the initial state
- // with the leading /
- let a;function s(){a&&o.push(a),a=[]}
- // index on the path
- let c,l=0,i="",u="";
- // char at index
- function f(){i&&(0/* TokenizerState.Static */===n?a.push({type:0/* TokenType.Static */,value:i}):1/* TokenizerState.Param */===n||2/* TokenizerState.ParamRegExp */===n||3/* TokenizerState.ParamRegExpEnd */===n?(a.length>1&&("*"===c||"+"===c)&&t(`A repeatable param (${i}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1/* TokenType.Param */,value:i,regexp:u,repeatable:"*"===c||"+"===c,optional:"*"===c||"?"===c})):t("Invalid state to consume buffer"),i="")}function p(){i+=c}for(;l<e.length;)if(c=e[l++],"\\"!==c||2/* TokenizerState.ParamRegExp */===n)switch(n){case 0/* TokenizerState.Static */:"/"===c?(i&&f(),s()):":"===c?(f(),n=1/* TokenizerState.Param */):p();break;case 4/* TokenizerState.EscapeNext */:p(),n=r;break;case 1/* TokenizerState.Param */:"("===c?n=2/* TokenizerState.ParamRegExp */:me.test(c)?p():(f(),n=0/* TokenizerState.Static */,
- // go back one character if we were not modifying
- "*"!==c&&"?"!==c&&"+"!==c&&l--);break;case 2/* TokenizerState.ParamRegExp */:
- // TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix)
- // it already works by escaping the closing )
- // https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB#
- // is this really something people need since you can also write
- // /prefix_:p()_suffix
- ")"===c?
- // handle the escaped )
- "\\"==u[u.length-1]?u=u.slice(0,-1)+c:n=3/* TokenizerState.ParamRegExpEnd */:u+=c;break;case 3/* TokenizerState.ParamRegExpEnd */:
- // same as finalizing a param
- f(),n=0/* TokenizerState.Static */,
- // go back one character if we were not modifying
- "*"!==c&&"?"!==c&&"+"!==c&&l--,u="";break;default:t("Unknown state")}else r=n,n=4/* TokenizerState.EscapeNext */;
- // tokenCache.set(path, tokens)
- return 2/* TokenizerState.ParamRegExp */===n&&t(`Unfinished custom RegExp for param "${i}"`),f(),s(),o}(e.path),n),o=d(r,{record:e,parent:t,
- // these needs to be populated by the parent
- children:[],alias:[]});return t&&!o.record.aliasOf==!t.record.aliasOf&&t.children.push(o),o}
- /**
- * Creates a Router Matcher.
- *
- * @internal
- * @param routes - array of initial routes
- * @param globalOptions - global route options
- */function ve(e,t){
- // normalized ordered array of matchers
- const n=[],r=new Map;function o(e,n,r){
- // used later on to remove by name
- const c=!r,l=be(e);
- // we might be the child of an alias
- l.aliasOf=r&&r.record;const i=ke(t,e),u=[l];
- // generate an array of records to correctly handle aliases
- if("alias"in e){const t="string"==typeof e.alias?[e.alias]:e.alias;for(const e of t)u.push(
- // we need to normalize again to ensure the `mods` property
- // being non enumerable
- be(d({},l,{
- // this allows us to hold a copy of the `components` option
- // so that async components cache is hold on the original record
- components:r?r.record.components:l.components,path:e,
- // we might be the child of an alias
- aliasOf:r?r.record:l})))}let f,p;for(const t of u){const{path:u}=t;
- // Build up the path for nested routes if the child isn't an absolute
- // route. Only add the / delimiter if the child path isn't empty and if the
- // parent path doesn't have a trailing slash
- if(n&&"/"!==u[0]){const e=n.record.path,r="/"===e[e.length-1]?"":"/";t.path=n.record.path+(u&&r+u)}
- // create the object beforehand, so it can be passed to children
- if(f=ge(t,n,i),
- // if we are an alias we must tell the original record that we exist,
- // so we can be removed
- r?r.alias.push(f):(
- // otherwise, the first record is the original and others are aliases
- p=p||f,p!==f&&p.alias.push(f),
- // remove the route if named and only for the top record (avoid in nested calls)
- // this works because the original record is the first one
- c&&e.name&&!Ee(f)&&a(e.name)),
- // Avoid adding a record that doesn't display anything. This allows passing through records without a component to
- // not be reached and pass through the catch all route
- Oe(f)&&s(f),l.children){const e=l.children;for(let t=0;t<e.length;t++)o(e[t],f,r&&r.children[t])}
- // if there was no original record, then the first one was not an alias and all
- // other aliases (if any) need to reference this record when adding children
- r=r||f}return p?()=>{
- // since other matchers are aliases, they should be removed by the original matcher
- a(p)}:g}function a(e){if(re(e)){const t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(a),t.alias.forEach(a))}else{const t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(a),e.alias.forEach(a))}}function s(e){const t=
- /**
- * Performs a binary search to find the correct insertion index for a new matcher.
- *
- * Matchers are primarily sorted by their score. If scores are tied then we also consider parent/child relationships,
- * with descendants coming before ancestors. If there's still a tie, new routes are inserted after existing routes.
- *
- * @param matcher - new matcher to be inserted
- * @param matchers - existing matchers
- */
- function(e,t){
- // First phase: binary search based on score
- let n=0,r=t.length;for(;n!==r;){const o=n+r>>1;pe(e,t[o])<0?r=o:n=o+1}
- // Second phase: check for an ancestor with the same score
- const o=function(e){let t=e;for(;t=t.parent;)if(Oe(t)&&0===pe(e,t))return t;return}
- /**
- * Checks if a matcher can be reachable. This means if it's possible to reach it as a route. For example, routes without
- * a component, or name, or redirect, are just used to group other routes.
- * @param matcher
- * @param matcher.record record of the matcher
- * @returns
- */(e);o&&(r=t.lastIndexOf(o,r-1));return r}(e,n);n.splice(t,0,e),
- // only add the original record to the name map
- e.record.name&&!Ee(e)&&r.set(e.record.name,e)}return t=ke({strict:!1,end:!0,sensitive:!1},t),
- // add initial routes
- e.forEach((e=>o(e))),{addRoute:o,resolve:function(e,t){let o,a,s,c={};if("name"in e&&e.name){if(o=r.get(e.name),!o)throw se(1/* ErrorTypes.MATCHER_NOT_FOUND */,{location:e});s=o.record.name,c=d(
- // paramsFromLocation is a new object
- ye(t.params,
- // only keep params that exist in the resolved location
- // only keep optional params coming from a parent record
- o.keys.filter((e=>!e.optional)).concat(o.parent?o.parent.keys.filter((e=>e.optional)):[]).map((e=>e.name))),
- // discard any existing params in the current location that do not exist here
- // #1497 this ensures better active/exact matching
- e.params&&ye(e.params,o.keys.map((e=>e.name)))),
- // throws if cannot be stringified
- a=o.stringify(c)}else if(null!=e.path)
- // no need to resolve the path with the matcher as it was provided
- // this also allows the user to control the encoding
- a=e.path,o=n.find((e=>e.re.test(a))),
- // matcher should have a value after the loop
- o&&(
- // we know the matcher works because we tested the regexp
- c=o.parse(a),s=o.record.name);else{if(
- // match by name or path of current route
- o=t.name?r.get(t.name):n.find((e=>e.re.test(t.path))),!o)throw se(1/* ErrorTypes.MATCHER_NOT_FOUND */,{location:e,currentLocation:t});s=o.record.name,
- // since we are navigating to the same location, we don't need to pick the
- // params like when `name` is provided
- c=d({},t.params,e.params),a=o.stringify(c)}const l=[];let i=o;for(;i;)
- // reversed order so parents are at the beginning
- l.unshift(i.record),i=i.parent;return{name:s,path:a,params:c,matched:l,meta:Re(l)}},removeRoute:a,clearRoutes:function(){n.length=0,r.clear()},getRoutes:function(){return n},getRecordMatcher:function(e){return r.get(e)}}}function ye(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}
- /**
- * Normalizes a RouteRecordRaw. Creates a copy
- *
- * @param record
- * @returns the normalized version
- */function be(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:we(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},
- // must be declared afterwards
- // mods: {},
- components:"components"in e?e.components||null:e.component&&{default:e.component}};
- // mods contain modules and shouldn't be copied,
- // logged or anything. It's just used for internal
- // advanced use cases like data loaders
- return Object.defineProperty(t,"mods",{value:{}}),t}
- /**
- * Normalize the optional `props` in a record to always be an object similar to
- * components. Also accept a boolean for components.
- * @param record
- */function we(e){const t={},n=e.props||!1;
- // props does not exist on redirect records, but we can set false directly
- if("component"in e)t.default=n;else
- // NOTE: we could also allow a function to be applied to every component.
- // Would need user feedback for use cases
- for(const r in e.components)t[r]="object"==typeof n?n[r]:n;return t}
- /**
- * Checks if a record or any of its parent is an alias
- * @param record
- */function Ee(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}
- /**
- * Merge meta fields of an array of records
- *
- * @param matched - array of matched records
- */function Re(e){return e.reduce(((e,t)=>d(e,t.meta)),{})}function ke(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function Oe({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}
- /**
- * Transforms a queryString into a {@link LocationQuery} object. Accept both, a
- * version with the leading `?` and without Should work as URLSearchParams
- * @internal
- *
- * @param search - search string to parse
- * @returns a query object
- */function xe(e){const t={};
- // avoid creating an object with an empty key and empty value
- // because of split('&')
- if(""===e||"?"===e)return t;const n=("?"===e[0]?e.slice(1):e).split("&");for(let r=0;r<n.length;++r){
- // pre decode the + into space
- const e=n[r].replace(k," "),o=e.indexOf("="),a=B(o<0?e:e.slice(0,o)),s=o<0?null:B(e.slice(o+1));
- // allow the = character
- if(a in t){
- // an extra variable for ts types
- let e=t[a];v(e)||(e=t[a]=[e]),e.push(s)}else t[a]=s}return t}
- /**
- * Stringifies a {@link LocationQueryRaw} object. Like `URLSearchParams`, it
- * doesn't prepend a `?`
- *
- * @internal
- *
- * @param query - query object to stringify
- * @returns string version of the query without the leading `?`
- */function Pe(e){let t="";for(let n in e){const r=e[n];if(n=L(n).replace(E,"%3D"),null==r){
- // only null adds the value
- void 0!==r&&(t+=(t.length?"&":"")+n);continue}
- // keep null values
- (v(r)?r.map((e=>e&&L(e))):[r&&L(r)]).forEach((e=>{
- // skip undefined values in arrays as if they were not present
- // smaller code than using filter
- void 0!==e&&(
- // only append & with non-empty search
- t+=(t.length?"&":"")+n,null!=e&&(t+="="+e))}))}return t}
- /**
- * Transforms a {@link LocationQueryRaw} into a {@link LocationQuery} by casting
- * numbers into strings, removing keys with an undefined value and replacing
- * undefined with null in arrays
- *
- * @param query - query object to normalize
- * @returns a normalized query object
- */function Ce(e){const t={};for(const n in e){const r=e[n];void 0!==r&&(t[n]=v(r)?r.map((e=>null==e?null:""+e)):null==r?r:""+r)}return t}
- /**
- * RouteRecord being rendered by the closest ancestor Router View. Used for
- * `onBeforeRouteUpdate` and `onBeforeRouteLeave`. rvlm stands for Router View
- * Location Matched
- *
- * @internal
- */const je=Symbol(""),$e=Symbol(""),Se=Symbol(""),Ae=Symbol(""),qe=Symbol("");
- /**
- * Allows overriding the router view depth to control which component in
- * `matched` is rendered. rvd stands for Router View Depth
- *
- * @internal
- */
- /**
- * Create a list of callbacks that can be reset. Used to create before and after navigation guards list
- */
- function Le(){let e=[];return{add:function(t){return e.push(t),()=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)}},list:()=>e.slice(),reset:function(){e=[]}}}function Me(e,t,n,r,o,a=e=>e()){
- // keep a reference to the enterCallbackArray to prevent pushing callbacks if a new navigation took place
- const s=r&&(
- // name is defined if record is because of the function overload
- r.enterCallbacks[o]=r.enterCallbacks[o]||[]);return()=>new Promise(((c,l)=>{const i=e=>{var a;!1===e?l(se(4/* ErrorTypes.NAVIGATION_ABORTED */,{from:n,to:t})):e instanceof Error?l(e):"string"==typeof(a=e)||a&&"object"==typeof a?l(se(2/* ErrorTypes.NAVIGATION_GUARD_REDIRECT */,{from:t,to:e})):(s&&
- // since enterCallbackArray is truthy, both record and name also are
- r.enterCallbacks[o]===s&&"function"==typeof e&&s.push(e),c())},u=a((()=>e.call(r&&r.instances[o],t,n,i)));
- // wrapping with Promise.resolve allows it to work with both async and sync guards
- let f=Promise.resolve(u);e.length<3&&(f=f.then(i)),f.catch((e=>l(e)))}))}function Be(e,t,n,r,o=e=>e()){const a=[];for(const s of e)for(const e in s.components){let c=s.components[e];
- // skip update and leave guards if the route component is not mounted
- if("beforeRouteEnter"===t||s.instances[e])if(h(c)){
- // __vccOpts is added by vue-class-component and contain the regular options
- const l=(c.__vccOpts||c)[t];l&&a.push(Me(l,n,r,s,e,o))}else{
- // start requesting the chunk already
- let l=c();a.push((()=>l.then((a=>{if(!a)throw new Error(`Couldn't resolve component "${e}" at "${s.path}"`);const c=(l=a).__esModule||"Module"===l[Symbol.toStringTag]||
- // support CF with dynamic imports that do not
- // add the Module string tag
- l.default&&h(l.default)?a.default:a;
- // keep the resolved module for plugins like data loaders
- var l;s.mods[e]=a,
- // replace the function with the resolved component
- // cannot be null or undefined because we went into the for loop
- s.components[e]=c;
- // __vccOpts is added by vue-class-component and contain the regular options
- const i=(c.__vccOpts||c)[t];return i&&Me(i,n,r,s,e,o)()}))))}}return a}
- // TODO: we could allow currentRoute as a prop to expose `isActive` and
- // `isExactActive` behavior should go through an RFC
- /**
- * Returns the internal behavior of a {@link RouterLink} without the rendering part.
- *
- * @param props - a `to` location and an optional `replace` flag
- */function Ge(e){const n=o(Se),r=o(Ae),a=c((()=>{const r=t(e.to);return n.resolve(r)})),s=c((()=>{const{matched:e}=a.value,{length:t}=e,n=e[t-1],o=r.matched;if(!n||!o.length)return-1;const s=o.findIndex(T.bind(null,n));if(s>-1)return s;
- // possible parent record
- const c=Ie(e[t-2]);
- // we are dealing with nested routes
- return t>1&&
- // if the parent and matched route have the same path, this link is
- // referring to the empty child. Or we currently are on a different
- // child of the same parent
- Ie(n)===c&&
- // avoid comparing the child with its parent
- o[o.length-1].path!==c?o.findIndex(T.bind(null,e[t-2])):s})),l=c((()=>s.value>-1&&function(e,t){for(const n in t){const r=t[n],o=e[n];if("string"==typeof r){if(r!==o)return!1}else if(!v(o)||o.length!==r.length||r.some(((e,t)=>e!==o[t])))return!1}return!0}
- /**
- * Get the original path value of a record by following its aliasOf
- * @param record
- */(r.params,a.value.params))),i=c((()=>s.value>-1&&s.value===r.matched.length-1&&W(r.params,a.value.params)));
- /**
- * NOTE: update {@link _RouterLinkI}'s `$slots` type when updating this
- */
- return{route:a,href:c((()=>a.value.href)),isActive:l,isExactActive:i,navigate:function(r={}){if(function(e){
- // don't redirect with control keys
- if(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)return;
- // don't redirect when preventDefault called
- if(e.defaultPrevented)return;
- // don't redirect on right click
- if(void 0!==e.button&&0!==e.button)return;
- // don't redirect if `target="_blank"`
- // @ts-expect-error getAttribute does exist
- if(e.currentTarget&&e.currentTarget.getAttribute){
- // @ts-expect-error getAttribute exists
- const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}
- // this may be a Weex event which doesn't have this method
- e.preventDefault&&e.preventDefault();return!0}(r)){const r=n[t(e.replace)?"replace":"push"](t(e.to)).catch(g);return e.viewTransition&&"undefined"!=typeof document&&"startViewTransition"in document&&document.startViewTransition((()=>r)),r}return Promise.resolve()}}}const _e=a({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,
- // inactiveClass: String,
- exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Ge,setup(e,{slots:t}){const n=s(Ge(e)),{options:r}=o(Se),a=c((()=>({[Te(e.activeClass,r.linkActiveClass,"router-link-active")]:n.isActive,
- // [getLinkClass(
- // props.inactiveClass,
- // options.linkInactiveClass,
- // 'router-link-inactive'
- // )]: !link.isExactActive,
- [Te(e.exactActiveClass,r.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive})));return()=>{const r=t.default&&(1===(o=t.default(n)).length?o[0]:o);var o;return e.custom?r:l("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,
- // this would override user added attrs but Vue will still add
- // the listener, so we end up triggering both
- onClick:n.navigate,class:a.value},r)}}});
- // export the public type for h/tsx inference
- // also to avoid inline import() in generated d.ts files
- /**
- * Component to render a link that triggers a navigation on click.
- */function Ie(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}
- /**
- * Utility class to get the active class based on defaults.
- * @param propClass
- * @param globalClass
- * @param defaultClass
- */const Te=(e,t,n)=>null!=e?e:null!=t?t:n;function We(e,t){if(!e)return null;const n=e(t);return 1===n.length?n[0]:n}
- // export the public type for h/tsx inference
- // also to avoid inline import() in generated d.ts files
- /**
- * Component to display the current route the user is at.
- */const De=a({name:"RouterView",
- // #674 we manually inherit them
- inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},
- // Better compat for @vue/compat users
- // https://github.com/vuejs/router/issues/1315
- compatConfig:{MODE:3},setup(e,{attrs:n,slots:r}){const a=o(qe),s=c((()=>e.route||a.value)),p=o($e,0),h=c((()=>{let e=t(p);const{matched:n}=s.value;let r;for(;(r=n[e])&&!r.components;)e++;return e})),m=c((()=>s.value.matched[h.value]));i($e,c((()=>h.value+1))),i(je,m),i(qe,s);const g=u();
- // watch at the same time the component instance, the route record we are
- // rendering, and the name
- return f((()=>[g.value,m.value,e.name]),(([e,t,n],[r,o,a])=>{
- // copy reused instances
- t&&(
- // this will update the instance for new instances as well as reused
- // instances when navigating to a new route
- t.instances[n]=e,
- // the component instance is reused for a different route or name, so
- // we copy any saved update or leave guards. With async setup, the
- // mounting component will mount before the matchedRoute changes,
- // making instance === oldInstance, so we check if guards have been
- // added before. This works because we remove guards when
- // unmounting/deactivating components
- o&&o!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=o.leaveGuards),t.updateGuards.size||(t.updateGuards=o.updateGuards))),
- // trigger beforeRouteEnter next callbacks
- !e||!t||
- // if there is no instance but to and from are the same this might be
- // the first visit
- o&&T(t,o)&&r||(t.enterCallbacks[n]||[]).forEach((t=>t(e)))}),{flush:"post"}),()=>{const t=s.value,o=e.name,a=m.value,c=a&&a.components[o];
- // we need the value at the time we render because when we unmount, we
- // navigated to a different location so the value is different
- if(!c)return We(r.default,{Component:c,route:t});
- // props from route configuration
- const i=a.props[o],u=i?!0===i?t.params:"function"==typeof i?i(t):i:null,f=l(c,d({},u,n,{onVnodeUnmounted:e=>{
- // remove the instance reference to prevent leak
- e.component.isUnmounted&&(a.instances[o]=null)},ref:g}));
- // pass the vnode to the slot as a prop.
- // h and <component :is="..."> both accept vnodes
- return We(r.default,{Component:f,route:t})||f}}});
- /**
- * Creates a Router instance that can be used by a Vue app.
- *
- * @param options - {@link RouterOptions}
- */function Ue(o){const a=ve(o.routes,o),s=o.parseQuery||xe,c=o.stringifyQuery||Pe,l=o.history,i=Le(),u=Le(),f=Le(),h=e(V);let y=V;
- // leave the scrollRestoration if no scrollBehavior is provided
- p&&o.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const b=m.bind(null,(e=>""+e)),w=m.bind(null,M),E=
- // @ts-expect-error: intentionally avoid the type check
- m.bind(null,B);function R(e,t){if(
- // const resolve: Router['resolve'] = (rawLocation: RouteLocationRaw, currentLocation) => {
- // const objectLocation = routerLocationAsObject(rawLocation)
- // we create a copy to modify it later
- t=d({},t||h.value),"string"==typeof e){const n=_(s,e,t.path),r=a.resolve({path:n.path},t),o=l.createHref(n.fullPath);
- // locationNormalized is always a new object
- return d(n,r,{params:E(r.params),hash:B(n.hash),redirectedFrom:void 0,href:o})}let n;
- // path could be relative in object as well
- if(null!=e.path)n=d({},e,{path:_(s,e.path,t.path).path});else{
- // remove any nullish param
- const r=d({},e.params);for(const e in r)null==r[e]&&delete r[e];
- // pass encoded values to the matcher, so it can produce encoded path and fullPath
- n=d({},e,{params:w(r)}),
- // current location params are decoded, we need to encode them in case the
- // matcher merges the params
- t.params=w(t.params)}const r=a.resolve(n,t),o=e.hash||"";
- // the matcher might have merged current location params, so
- // we need to run the decoding again
- r.params=b(E(r.params));const i=function(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}(c,d({},e,{hash:(u=o,q(u).replace(j,"{").replace(S,"}").replace(P,"^")),path:r.path}));var u;const f=l.createHref(i);return d({fullPath:i,
- // keep the hash encoded so fullPath is effectively path + encodedQuery +
- // hash
- hash:o,query:
- // if the user is using a custom query lib like qs, we might have
- // nested objects, so we keep the query as is, meaning it can contain
- // numbers at `$route.query`, but at the point, the user will have to
- // use their own type anyway.
- // https://github.com/vuejs/router/issues/328#issuecomment-649481567
- c===Pe?Ce(e.query):e.query||{}},r,{redirectedFrom:void 0,href:f})}function k(e){return"string"==typeof e?_(s,e,h.value.path):d({},e)}function O(e,t){if(y!==e)return se(8/* ErrorTypes.NAVIGATION_CANCELLED */,{from:t,to:e})}function x(e){return $(e)}function C(e){const t=e.matched[e.matched.length-1];if(t&&t.redirect){const{redirect:n}=t;let r="function"==typeof n?n(e):n;return"string"==typeof r&&(r=r.includes("?")||r.includes("#")?r=k(r):// force empty params
- {path:r},
- // @ts-expect-error: force empty params when a string is passed to let
- // the router parse them again
- r.params={}),d({query:e.query,hash:e.hash,
- // avoid transferring params if the redirect has a path
- params:null!=r.path?{}:e.params},r)}}function $(e,t){const n=y=R(e),r=h.value,o=e.state,a=e.force,s=!0===e.replace,l=C(n);if(l)return $(d(k(l),{state:"object"==typeof l?d({},o,l.state):o,force:a,replace:s}),
- // keep original redirectedFrom if it exists
- t||n);
- // if it was a redirect we already called `pushWithRedirect` above
- const i=n;let u;return i.redirectedFrom=t,!a&&function(e,t,n){const r=t.matched.length-1,o=n.matched.length-1;return r>-1&&r===o&&T(t.matched[r],n.matched[o])&&W(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}(c,r,n)&&(u=se(16/* ErrorTypes.NAVIGATION_DUPLICATED */,{to:i,from:r}),
- // trigger scroll to allow scrolling to the same anchor
- te(r,r,
- // this is a push, the only way for it to be triggered from a
- // history.listen is with a redirect, which makes it become a push
- !0,
- // This cannot be the first navigation because the initial location
- // cannot be manually navigated to
- !1)),(u?Promise.resolve(u):G(i,r)).catch((e=>ce(e)?// navigation redirects still mark the router as ready
- ce(e,2/* ErrorTypes.NAVIGATION_GUARD_REDIRECT */)?e:ee(e):// reject any unknown error
- J(e,i,r))).then((e=>{if(e){if(ce(e,2/* ErrorTypes.NAVIGATION_GUARD_REDIRECT */))return $(
- // keep options
- d({
- // preserve an existing replacement but allow the redirect to override it
- replace:s},k(e.to),{state:"object"==typeof e.to?d({},o,e.to.state):o,force:a}),
- // preserve the original redirectedFrom if any
- t||i)}else
- // if we fail we don't finalize the navigation
- e=D(i,r,!0,s,o);return I(i,r,e),e}))}
- /**
- * Helper to reject and skip all navigation guards if a new navigation happened
- * @param to
- * @param from
- */function A(e,t){const n=O(e,t);return n?Promise.reject(n):Promise.resolve()}function L(e){const t=ae.values().next().value;
- // support Vue < 3.3
- return t&&"function"==typeof t.runWithContext?t.runWithContext(e):e()}
- // TODO: refactor the whole before guards by internally using router.beforeEach
- function G(e,t){let n;const[r,o,a]=function(e,t){const n=[],r=[],o=[],a=Math.max(t.matched.length,e.matched.length);for(let s=0;s<a;s++){const a=t.matched[s];a&&(e.matched.find((e=>T(e,a)))?r.push(a):n.push(a));const c=e.matched[s];c&&(
- // the type doesn't matter because we are comparing per reference
- t.matched.find((e=>T(e,c)))||o.push(c))}return[n,r,o]}
- /**
- * Returns the router instance. Equivalent to using `$router` inside
- * templates.
- */(e,t);
- // all components here have been resolved once because we are leaving
- n=Be(r.reverse(),"beforeRouteLeave",e,t);
- // leavingRecords is already reversed
- for(const c of r)c.leaveGuards.forEach((r=>{n.push(Me(r,e,t))}));const s=A.bind(null,e,t);
- // run the queue of per route beforeRouteLeave guards
- return n.push(s),ie(n).then((()=>{
- // check global guards beforeEach
- n=[];for(const r of i.list())n.push(Me(r,e,t));return n.push(s),ie(n)})).then((()=>{
- // check in components beforeRouteUpdate
- n=Be(o,"beforeRouteUpdate",e,t);for(const r of o)r.updateGuards.forEach((r=>{n.push(Me(r,e,t))}));
- // run the queue of per route beforeEnter guards
- return n.push(s),ie(n)})).then((()=>{
- // check the route beforeEnter
- n=[];for(const r of a)
- // do not trigger beforeEnter on reused views
- if(r.beforeEnter)if(v(r.beforeEnter))for(const o of r.beforeEnter)n.push(Me(o,e,t));else n.push(Me(r.beforeEnter,e,t));
- // run the queue of per route beforeEnter guards
- return n.push(s),ie(n)})).then((()=>(
- // NOTE: at this point to.matched is normalized and does not contain any () => Promise<Component>
- // clear existing enterCallbacks, these are added by extractComponentsGuards
- e.matched.forEach((e=>e.enterCallbacks={})),
- // check in-component beforeRouteEnter
- n=Be(a,"beforeRouteEnter",e,t,L),n.push(s),ie(n)))).then((()=>{
- // check global guards beforeResolve
- n=[];for(const r of u.list())n.push(Me(r,e,t));return n.push(s),ie(n)})).catch((e=>ce(e,8/* ErrorTypes.NAVIGATION_CANCELLED */)?e:Promise.reject(e)))}function I(e,t,n){
- // navigation is confirmed, call afterGuards
- // TODO: wrap with error handlers
- f.list().forEach((r=>L((()=>r(e,t,n)))))}
- /**
- * - Cleans up any navigation guards
- * - Changes the url if necessary
- * - Calls the scrollBehavior
- */function D(e,t,n,r,o){
- // a more recent navigation took place
- const a=O(e,t);if(a)return a;
- // only consider as push if it's not the first navigation
- const s=t===V,c=p?history.state:{};
- // change URL only if the user did a push/replace and if it's not the initial navigation because
- // it's just reflecting the url
- n&&(
- // on the initial navigation, we want to reuse the scroll position from
- // history state if it exists
- r||s?l.replace(e.fullPath,d({scroll:s&&c&&c.scroll},o)):l.push(e.fullPath,o)),
- // accept current navigation
- h.value=e,te(e,t,n,s),ee()}let U;
- // attach listener to history to trigger navigations
- function z(){
- // avoid setting up listeners twice due to an invalid first navigation
- U||(U=l.listen(((e,t,n)=>{if(!le.listening)return;
- // cannot be a redirect route because it was in history
- const r=R(e),o=C(r);
- // due to dynamic routing, and to hash history with manual navigation
- // (manually changing the url or calling history.hash = '#/somewhere'),
- // there could be a redirect record in history
- if(o)return void $(d(o,{replace:!0,force:!0}),r).catch(g);y=r;const a=h.value;
- // TODO: should be moved to web history?
- var s,c;p&&(s=N(a.fullPath,n.delta),c=Q(),Z.set(s,c)),G(r,a).catch((e=>ce(e,12/* ErrorTypes.NAVIGATION_CANCELLED */)?e:ce(e,2/* ErrorTypes.NAVIGATION_GUARD_REDIRECT */)?(
- // Here we could call if (info.delta) routerHistory.go(-info.delta,
- // false) but this is bug prone as we have no way to wait the
- // navigation to be finished before calling pushWithRedirect. Using
- // a setTimeout of 16ms seems to work but there is no guarantee for
- // it to work on every browser. So instead we do not restore the
- // history entry and trigger a new navigation as requested by the
- // navigation guard.
- // the error is already handled by router.push we just want to avoid
- // logging the error
- $(d(k(e.to),{force:!0}),r).then((e=>{
- // manual change in hash history #916 ending up in the URL not
- // changing, but it was changed by the manual url change, so we
- // need to manually change it ourselves
- ce(e,20/* ErrorTypes.NAVIGATION_DUPLICATED */)&&!n.delta&&n.type===F.pop&&l.go(-1,!1)})).catch(g),Promise.reject()):(
- // do not restore history on unknown direction
- n.delta&&l.go(-n.delta,!1),J(e,r,a)))).then((e=>{
- // revert the navigation
- (e=e||D(
- // after navigation, all matched components are resolved
- r,a,!1))&&(n.delta&&
- // a new navigation has been triggered, so we do not want to revert, that will change the current history
- // entry while a different route is displayed
- !ce(e,8/* ErrorTypes.NAVIGATION_CANCELLED */)?l.go(-n.delta,!1):n.type===F.pop&&ce(e,20/* ErrorTypes.NAVIGATION_DUPLICATED */)&&
- // manual change in hash history #916
- // it's like a push but lacks the information of the direction
- l.go(-1,!1)),I(r,a,e)})).catch(g)})))}
- // Initialization and Errors
- let K,H=Le(),X=Le();
- /**
- * Trigger errorListeners added via onError and throws the error as well
- *
- * @param error - error to throw
- * @param to - location we were navigating to when the error happened
- * @param from - location we were navigating from when the error happened
- * @returns the error as a rejected promise
- */
- function J(e,t,n){ee(e);const r=X.list();
- // reject the error no matter there were error listeners or not
- return r.length&&r.forEach((r=>r(e,t,n))),Promise.reject(e)}function ee(e){return K||(
- // still not ready if an error happened
- K=!e,z(),H.list().forEach((([t,n])=>e?n(e):t())),H.reset()),e}
- // Scroll behavior
- function te(e,t,n,a){const{scrollBehavior:s}=o;if(!p||!s)return Promise.resolve();const c=!n&&function(e){const t=Z.get(e);
- // consume it so it's not used again
- return Z.delete(e),t}(N(e.fullPath,0))||(a||!n)&&history.state&&history.state.scroll||null;return r().then((()=>s(e,t,c))).then((e=>e&&Y(e))).catch((n=>J(n,e,t)))}const ne=e=>l.go(e);let oe;const ae=new Set,le={currentRoute:h,listening:!0,addRoute:function(e,t){let n,r;return re(e)?(n=a.getRecordMatcher(e),r=t):r=e,a.addRoute(r,n)},removeRoute:function(e){const t=a.getRecordMatcher(e);t&&a.removeRoute(t)},clearRoutes:a.clearRoutes,hasRoute:function(e){return!!a.getRecordMatcher(e)},getRoutes:function(){return a.getRoutes().map((e=>e.record))},resolve:R,options:o,push:x,replace:function(e){return x(d(k(e),{replace:!0}))},go:ne,back:()=>ne(-1),forward:()=>ne(1),beforeEach:i.add,beforeResolve:u.add,afterEach:f.add,onError:X.add,isReady:function(){return K&&h.value!==V?Promise.resolve():new Promise(((e,t)=>{H.add([e,t])}))},install(e){e.component("RouterLink",_e),e.component("RouterView",De),e.config.globalProperties.$router=this,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>t(h)}),
- // this initial navigation is only necessary on client, on server it doesn't
- // make sense because it will create an extra unnecessary navigation and could
- // lead to problems
- p&&
- // used for the initial navigation client side to avoid pushing
- // multiple times when the router is used in multiple apps
- !oe&&h.value===V&&(
- // see above
- oe=!0,x(l.location).catch((e=>{})));const r={};for(const t in V)Object.defineProperty(r,t,{get:()=>h.value[t],enumerable:!0});e.provide(Se,this),e.provide(Ae,n(r)),e.provide(qe,h);const o=e.unmount;ae.add(e),e.unmount=function(){ae.delete(e),
- // the router is not attached to an app anymore
- ae.size<1&&(
- // invalidate the current navigation
- y=V,U&&U(),U=null,h.value=V,oe=!1,K=!1),o()}}};
- // TODO: type this as NavigationGuardReturn or similar instead of any
- function ie(e){return e.reduce(((e,t)=>e.then((()=>L(t)))),Promise.resolve())}return le}function Ve(){return o(Se)}
- /**
- * Returns the current route location. Equivalent to using `$route` inside
- * templates.
- */function Fe(e){return o(Ae)}export{ne as a,Fe as b,Ue as c,Ve as u};
- //# sourceMappingURL=vue-router-c7cbbcaa.js.map
|